123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import * as THREE from 'three';
- import { TransformControls } from 'three/examples/jsm/controls/TransformControls'; // 引入模块
- import * as dat from "dat.gui";
- let modal, cubeList:THREE.Mesh[] = [], curve, line
- //创建gui对象
- const gui = new dat.GUI();
- gui.domElement.style.top = '300'
- gui.domElement.style.clientTop = 300
- gui.domElement.style.zIndex = 9999
- // 画点
- const addCube = (initialPoints, scene) => {
- return initialPoints.map(pos => {
- const geometry = new THREE.BoxBufferGeometry(1, 1, 1);
- const material = new THREE.MeshBasicMaterial({
- color: 0xffffff,
- side: THREE.DoubleSide
- });
- const cube = new THREE.Mesh(geometry, material);
- cube.position.copy(pos);
- scene.add(cube);
- cubeList.push(cube)
- // gui.add(cube.position, 'x', -1000, 1000)
- // gui.add(cube.position, 'y', -1000, 1000)
- // gui.add(cube.position, 'z', -1000, 1000)
- });
- }
- // 画线
- export const drawLine = (initialPoints, obj) => {
- modal = obj
- addCube(initialPoints, modal.scene)
- curve = new THREE.CatmullRomCurve3(
- cubeList.map((cube) => cube.position) // 直接绑定方块的position以便后续用方块调整曲线
- );
- curve.curveType = 'chordal'; // 曲线类型
- curve.closed = false; // 曲线是否闭合
- const points = curve.getPoints(50); // 50等分获取曲线点数组
- line = new THREE.LineLoop(
- new THREE.BufferGeometry().setFromPoints(points),
- new THREE.LineBasicMaterial({ color: 0xffffff,
- linewidth: 10 })
- ); // 绘制实体线条,仅用于示意曲线,后面的向量线条同理,相关代码就省略了
- modal.scene.add(line);
- addChangeEvent()
- }
- // 获取点击位置
- const addChangeEvent = () => {
- debugger
- const control = new TransformControls(modal.camera, modal.renderer.domElement);
- // 获取点击位置
- const mouse = new THREE.Vector2();
- window.addEventListener(
- 'click',
- (event) => {
- debugger
- mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
- mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
- // mouse.x = ((event.clientX - dom.offsetLeft) / dom.clientWidth) * 2 - 1; // dom.offsetLeft -- dom元素距离浏览器左侧的距离 dom.clientWidth -- dom元素宽度
- // mouse.y = -((event.clientY - dom.offsetTop) / dom.clientHeight) * 2 + 1; // dom.offsetTop -- dom元素距离浏览器顶部的距离 dom.clientHeight -- dom元素高度
- //根据照相机,把这个向量转换到视点坐标系
- const vector = new THREE.Vector3(mouse.x, mouse.y, 0.5).unproject(modal.camera);
-
- // 方块点击检测
- // const rayCaster = new THREE.Raycaster();
- //在视点坐标系中形成射线,射线的起点向量是照相机, 射线的方向向量是照相机到点击的点,这个向量应该归一标准化。
- const rayCaster = new THREE.Raycaster(modal.camera.position, vector.sub(modal.camera.position).normalize());
- // rayCaster.setFromCamera(mouse, modal.camera);
- const intersects = rayCaster.intersectObjects(cubeList);
- if (intersects.length) {
- const target = intersects[0].object;
- control.attach(target); // 绑定controls和方块
- modal.scene.add(control);
- }
- },
- false
- );
- // 修改曲线后同步修改实体线条
- control.addEventListener('dragging-changed', (event) => {
- if (!event.value) {
- console.log(event.value);
-
- const points = curve.getPoints(50);
- line.geometry.setFromPoints(points);
- }
- });
- }
|