threejs进阶,管道几何体高级应用,geometry几何体应用,可拖拽改变形状的管道
一、threejs是什么?
three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。
二、geometry几何体使用步骤
1.引入库
案例代码
代码如下(示例):
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry - catmull spline editor</title>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
/>
<link type="text/css" rel="stylesheet" href="main.css" />
<style>
body {
background-color: #f0f0f0;
color: #444;
}
a {
color: #08f;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a>
- geometry - catmull spline editor
</div>
<script type="module">
import * as THREE from "../build/three.module.js";
import Stats from "./jsm/libs/stats.module.js";
import { GUI } from "./jsm/libs/dat.gui.module.js";
import { DragControls } from "./jsm/controls/DragControls.js";
import { OrbitControls } from "./jsm/controls/OrbitControls.js";
import { TransformControls } from "./jsm/controls/TransformControls.js";
String.prototype.format = function () {
var str = this;
for (var i = 0; i < arguments.length; i++) {
str = str.replace("{" + i + "}", arguments[i]);
}
return str;
};
var container, stats;
var camera, scene, renderer;
var splineHelperObjects = [];
var splinePointsLength = 4;
var positions = [];
var point = new THREE.Vector3();
var geometry = new THREE.BoxBufferGeometry(20, 20, 20);
var transformControl;
var ARC_SEGMENTS = 200;
var splines = {};
var params = {
addPoint: addPoint,
removePoint: removePoint,
exportSpline: exportSpline,
};
init();
animate();
function init() {
container = document.getElementById("container");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
camera = new THREE.PerspectiveCamera(
70,
window.innerWidth / window.innerHeight,
1,
10000
);
camera.position.set(0, 250, 1000);
scene.add(camera);
scene.add(new THREE.AmbientLight(0xf0f0f0));
var light = new THREE.SpotLight(0xffffff, 1.5);
light.position.set(0, 1500, 200);
light.angle = Math.PI * 0.2;
light.castShadow = true;
light.shadow.camera.near = 200;
light.shadow.camera.far = 2000;
light.shadow.bias = -0.000222;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
scene.add(light);
var planeGeometry = new THREE.PlaneBufferGeometry(2000, 2000);
planeGeometry.rotateX(-Math.PI / 2);
var planeMaterial = new THREE.ShadowMaterial({ opacity: 0.2 });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.y = -200;
plane.receiveShadow = true;
scene.add(plane);
var helper = new THREE.GridHelper(2000, 100);
helper.position.y = -199;
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
//var axes = new AxesHelper( 1000 );
//axes.position.set( - 500, - 500, - 500 );
//scene.add( axes );
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
stats = new Stats();
container.appendChild(stats.dom);
var gui = new GUI();
gui.add(params, "addPoint");
gui.add(params, "removePoint");
gui.add(params, "exportSpline");
gui.open();
// Controls
var controls = new OrbitControls(camera, renderer.domElement);
controls.damping = 0.2;
controls.addEventListener("change", render);
controls.addEventListener("start", function () {
cancelHideTransform();
});
controls.addEventListener("end", function () {
delayHideTransform();
});
transformControl = new TransformControls(camera, renderer.domElement);
transformControl.addEventListener("change", render);
transformControl.addEventListener("dragging-changed", function (event) {
controls.enabled = !event.value;
});
scene.add(transformControl);
// Hiding transform situation is a little in a mess :()
transformControl.addEventListener("change", function () {
cancelHideTransform();
});
transformControl.addEventListener("mouseDown", function () {
cancelHideTransform();
});
transformControl.addEventListener("mouseUp", function () {
delayHideTransform();
});
transformControl.addEventListener("objectChange", function () {
updateSplineOutline();
});
var dragcontrols = new DragControls(
splineHelperObjects,
camera,
renderer.domElement
); //
dragcontrols.enabled = false;
dragcontrols.addEventListener("hoveron", function (event) {
transformControl.attach(event.object);
cancelHideTransform();
});
dragcontrols.addEventListener("hoveroff", function () {
delayHideTransform();
});
var hiding;
function delayHideTransform() {
cancelHideTransform();
hideTransform();
}
function hideTransform() {
hiding = setTimeout(function () {
transformControl.detach(transformControl.object);
}, 2500);
}
function cancelHideTransform() {
if (hiding) clearTimeout(hiding);
}
/*******
* Curves
*********/
for (var i = 0; i < splinePointsLength; i++) {
addSplineObject(positions[i]);
}
positions = [];
for (var i = 0; i < splinePointsLength; i++) {
positions.push(splineHelperObjects[i].position);
}
var geometry = new THREE.BufferGeometry();
geometry.setAttribute(
"position",
new THREE.BufferAttribute(new Float32Array(ARC_SEGMENTS * 3), 3)
);
// curve = new THREE.CatmullRomCurve3( positions );
// curve.curveType = 'centripetal';
// curve.mesh = new THREE.Line( geometry.clone(), new THREE.LineBasicMaterial( {
// color: 0x00ff00,
// opacity: 0.35
// } ) );
// curve.mesh.castShadow = true;
// splines.centripetal = curve;
// curve = new THREE.CatmullRomCurve3( positions );
// curve.curveType = 'chordal';
// curve.mesh = new THREE.Line( geometry.clone(), new THREE.LineBasicMaterial( {
// color: 0x0000ff,
// opacity: 0.35
// } ) );
// curve.mesh.castShadow = true;
// splines.chordal = curve;
for (var k in splines) {
var spline = splines[k];
scene.add(spline.mesh);
}
load([
new THREE.Vector3(
289.76843686945404,
452.51481137238443,
56.10018915737797
),
new THREE.Vector3(
-53.56300074753207,
171.49711742836848,
-14.495472686253045
),
new THREE.Vector3(
-91.40118730204415,
176.4306956436485,
-6.958271935582161
),
new THREE.Vector3(
-383.785318791128,
491.1365363371675,
47.869296953772746
),
]);
}
function addSplineObject(position) {
var material = new THREE.MeshLambertMaterial({
color: Math.random() * 0xffffff,
});
var object = new THREE.Mesh(geometry, material);
if (position) {
object.position.copy(position);
} else {
object.position.x = Math.random() * 1000 - 500;
object.position.y = Math.random() * 600;
object.position.z = Math.random() * 800 - 400;
}
object.castShadow = true;
object.receiveShadow = true;
scene.add(object);
splineHelperObjects.push(object);
return object;
}
function addPoint() {
splinePointsLength++;
positions.push(addSplineObject().position);
updateSplineOutline();
}
function removePoint() {
if (splinePointsLength <= 4) {
return;
}
splinePointsLength--;
positions.pop();
scene.remove(splineHelperObjects.pop());
updateSplineOutline();
}
function updateSplineOutline() {
for (let i = 0; i < scene.children.length; i++) {
if (scene.children[i].type === "Line") {
scene.remove(scene.children[i]);
}
}
var curve = new THREE.CatmullRomCurve3(positions);
curve.curveType = "catmullrom";
curve.mesh = new THREE.Line(
new THREE.TubeBufferGeometry(curve, 200, 10, 25, false),
new THREE.MeshToonMaterial({ color: 0xff0000 })
);
curve.mesh.castShadow = true;
scene.add(curve.mesh);
// for (var k in splines) {
// var spline = splines[k];
// var splineMesh = spline.mesh;
// var position = splineMesh.geometry.attributes.position;
// for (var i = 0; i < ARC_SEGMENTS; i++) {
// var t = i / (ARC_SEGMENTS - 1);
// spline.getPoint(t, point);
// position.setXYZ(i, point.x, point.y, point.z);
// }
// position.needsUpdate = true;
// }
}
function exportSpline() {
var strplace = [];
for (var i = 0; i < splinePointsLength; i++) {
var p = splineHelperObjects[i].position;
strplace.push(
"new THREE.Vector3({0}, {1}, {2})".format(p.x, p.y, p.z)
);
}
console.log(strplace.join(",\n"));
var code = "[" + strplace.join(",\n\t") + "]";
prompt("copy and paste code", code);
}
function load(new_positions) {
while (new_positions.length > positions.length) {
addPoint();
}
while (new_positions.length < positions.length) {
removePoint();
}
for (var i = 0; i < positions.length; i++) {
positions[i].copy(new_positions[i]);
}
updateSplineOutline();
}
function animate() {
requestAnimationFrame(animate);
render();
stats.update();
}
function render() {
// splines.uniform.mesh.visible = params.uniform;
// splines.centripetal.mesh.visible = params.centripetal;
// splines.chordal.mesh.visible = params.chordal;
renderer.render(scene, camera);
}
</script>
</body>
</html>
实现效果:
2.如果使用谷歌浏览器打不开报错,file本地文件跨域,请看本博主的另一篇博客《s访问本地文件跨域,html文件访问跨域报错》
链接: https://blog.csdn.net/qq_43305958/article/details/108089387.