赞
踩
transformControl.attach(object);后,轨道控制器就变的卡顿,即使我用 transformControl.detach();之后,关于这个 three.js 中遇到的问题,即在使用 TransformControl.attach(object) 之后 OrbitControl 变得卡顿,可能是由于几个潜在的原因引起的。考虑到我们已经在 dragging-changed 事件中禁用了 OrbitControl,
即,
transformControl.addEventListener('dragging-changed', function (event) {
controls.enabled = !event.value;
});
,这个问题可能不完全是由事件处理冲突导致的。以下是一些可能导致这种行为的原因及解决方案:
卡顿的代码是这样的:
let transformControl;//变换控制器 //创建一个 TransformControls 实例(将相机 camera 和渲染器的 DOM 元素 renderer.domElement 作为参数传递进去) transformControl = new TransformControls(camera, renderer.domElement); //接下来,我们添加了两个事件监听器 //1.当 TransformControls 的变换发生变化时,即用户交互操作导致物体进行平移、旋转或缩放时,触发 animate 函数重新渲染场景。 //即,模型改变=>重新渲染 transformControl.addEventListener('change', render); //2.当用户开始或停止拖拽物体时,通过 event.value 判断拖拽状态, //如果拖拽开始(event.value 为 true),则禁用其他的控制器(如鼠标控制器 controls), //以防止在拖拽过程中出现与 TransformControls 的冲突。 transformControl.addEventListener('dragging-changed', function (event) { controls.enabled = !event.value; }); //添加到场景中 scene.add(transformControl);
在three.js中,remove,detach等类似的这些函数,仅仅只是在表面上移除可模型,但是仍旧存在于内存中.只是你在场景中看不到了而已.
也就是说,当你用detach移除变换控制器后,变换控制器只是你看不到了也点不到了,但是他依旧存在于整个内存中,其中有一个语句
transformControl.addEventListener('change', render);,他是在变换控制器附着的模型有平移、旋转或缩放操作时,会被调用,所以当你取消对模型的附着,也就是调用transformControl.detach();后,表面上变换控制器没有附着在模型上了,但是实际上还在他在幕后监听着一些东西!
当你用detach()使得变换控制器消失后,它依旧监视着这个牙齿,所以之后你再用轨道控制器对整个场景进行平移、旋转或缩放操作时,这个颗之前被transformControl附着的牙齿也属于场景中的一分子,所以,transformControl.addEventListener('change', render);还是会被触发.so,频繁的调用render是场景卡顿的罪魁祸首!!!
其实把transformControl.addEventListener('change', render);这一行注释掉就好,防止重复渲染整个场景
/********** * 转换控制器 */ const pointer = new THREE.Vector2();//客户端坐标转化为设备坐标 // const onDownPosition = new THREE.Vector2();//鼠标按下的客户端坐标 // const onUpPosition = new THREE.Vector2();//鼠标抬起的客户端坐标 let transformControl;//变换控制器 //创建一个 TransformControls 实例(将相机 camera 和渲染器的 DOM 元素 renderer.domElement 作为参数传递进去) transformControl = new TransformControls(camera, renderer.domElement); //接下来,我们添加了两个事件监听器 //1.当 TransformControls 的变换发生变化时,即用户交互操作导致物体进行平移、旋转或缩放时,触发 animate 函数重新渲染场景。 //即,模型改变=>重新渲染 //transformControl.addEventListener('change', render); //2.当用户开始或停止拖拽物体时,通过 event.value 判断拖拽状态, //如果拖拽开始(event.value 为 true),则禁用其他的控制器(如鼠标控制器 controls), //以防止在拖拽过程中出现与 TransformControls 的冲突。 transformControl.addEventListener('dragging-changed', function (event) { controls.enabled = !event.value; }); //添加到场景中 scene.add(transformControl); // document.addEventListener('pointerdown', onPointerDown); // document.addEventListener('pointerup', onPointerUp); // document.addEventListener('pointermove', onPointerMove); document.addEventListener('click', onClick); document.addEventListener("keydown", handleKeyDown); function onClick(event) { pointer.x = (event.clientX / window.innerWidth) * 2 - 1; pointer.y = - (event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(pointer, camera); intersects = raycaster.intersectObjects(objects); if (intersects.length > 0) { var object = intersects[0].object; if (object !== transformControl.object) { transformControl.detach(); transformControl.attach(object); transformControl.update(); //controls.enabled = false; } } } function handleKeyDown(event) { if (event.key === 'q') { if (transformControl.object) { transformControl.detach(); transformControl.update(); //controls.enabled = true; //render(); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。