如何使用three.js集成令人羡慕的局部坐标系

示例

在这里插入图片描述

官方源码

https://github.com/mrdoob/three.js/blob/dev/examples/webgl_geometry_spline_editor.html

  • 使用源码的方法:
    直接将源码copy到项目中的htmldoge,然后如果你用了react框架,你要把App.jsx文件恢复到原来的样子
  • 项目的业务
    你把鼠标悬停在上面,坐标系就出来了,
    坐标系出来后,你才可以移动他,
    他并不是靠鼠标点击来实现的

阅读源码

(假设你是第一次接触前端代码,没错,我也是一次,so,作为一个对前端一无所知的萌新,接下来让我们一起来剖析官方的源代码,如果我们可以搞懂这问题,那这对于前端版本的opengl来说,你对模型与鼠标交互的理解,将大幅度提升,而且我想这段代码应该也是可以复用的,俗话说:“知道如何写代码值1分钱”,“知道把别人的某一部分代码放到自己几万行的屎山代码中,值百万dollars”.[doge])

<!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="importmap">
			{
     
				"imports": {
     
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/"
				}
			}
		</script>

		<script type="module">

			import * as THREE from 'three';

			import {
      GUI } from 'three/addons/libs/lil-gui.module.min.js';

			import {
      OrbitControls } from 'three/addons/controls/OrbitControls.js';
			import {
      TransformControls } from 'three/addons/controls/TransformControls.js';

			let container;
			let camera, scene, renderer;
			const splineHelperObjects = [];
			let splinePointsLength = 4;
			const positions = [];
			const point = new THREE.Vector3();

			const raycaster = new THREE.Raycaster();
			const pointer = new THREE.Vector2();
			const onUpPosition = new THREE.Vector2();
			const onDownPosition = new THREE.Vector2();

			const geometry = new THREE.BoxGeometry( 20, 20, 20 );
			let transformControl;

			const ARC_SEGMENTS = 200;

			const splines = {
     };

			const params = {
     
				uniform: true,
				tension: 0.5,
				centripetal: true,
				chordal: true,
				addPoint: addPoint,
				removePoint: removePoint,
				exportSpline: exportSpline
			};

			init();

			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, 3 ) );
				const light = new THREE.SpotLight( 0xffffff, 4.5 );
				light.position.set( 0, 1500, 200 );
				light.angle = Math.PI * 0.2;
				light.decay = 0;
				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 );

				const planeGeometry = new THREE.PlaneGeometry( 2000, 2000 );
				planeGeometry.rotateX( - Math.PI / 2 );
				const planeMaterial = new THREE.ShadowMaterial( {
      color: 0x000000, opacity: 0.2 } );

				const plane = new THREE.Mesh( planeGeometry, planeMaterial );
				plane.position.y = - 200;
				plane.receiveShadow = true;
				scene.add( plane );

				const helper = new THREE.GridHelper( 2000, 100 );
				helper.position.y = - 199;
				helper.material.opacity = 0.25;
				helper.material.transparent = true;
				scene.add( helper );

				renderer = new THREE.WebGLRenderer( {
      antialias: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.shadowMap.enabled = true;
				container.appendChild( renderer.domElement );

				const gui = new GUI();

				gui.add( params, 'uniform' ).onChange( render );
				gui.add( params, 'tension', 0, 1 ).step( 0.01 ).onChange( function ( value ) {
     

					splines.uniform.tension = value;
					updateSplineOutline();
					render();

				} );
				gui.add( params, 'centripetal' ).onChange( render );
				gui.add( params, 'chordal' ).onChange( render );
				gui.add( params, 'addPoint' );
				gui.add( params, 'removePoint' );
				gui.add( params, 'exportSpline' );
				gui.open();

				// Controls
				const controls = new OrbitControls( camera, renderer.domElement );
				controls.damping = 0.2;
				controls.addEventListener( 'change', render );

				transformControl = new TransformControls( camera, renderer.domElement );
				transformControl.addEventListener( 'change', render );
				transformControl.addEventListener( 'dragging-changed', function ( event ) {
     

					controls.enabled = ! event.value;

				} );
				scene.add( transformControl );

				transformControl.addEventListener( 'objectChange', function () {
     

					updateSplineOutline();

				} );

				document.addEventListener( 'pointerdown', onPointerDown );
				document.addEventListener( 'pointerup', onPointerUp );
				document.addEventListener( 'pointermove', onPointerMove );
				window.addEventListener( 'resize', onWindowResize );

				/*******
				 * Curves
				 *********/

				for ( let i = 0; i < splinePointsLength; i ++ ) {
     

					addSplineObject( positions[ i ] );

				}

				positions.length = 0;

				for ( let i = 0; i < splinePointsLength; i ++ ) {
     

					positions.push( splineHelperObjects[ i ].position );

				}

				const geometry = new THREE.BufferGeometry();
				geometry.setAttribute( 
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏过山河,踏过海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值