threejs进阶,管道几何体高级应用,geometry几何体应用,可拖拽改变形状的管道

53 篇文章 0 订阅
3 篇文章 0 订阅

一、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.

总结

good morning
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值