我想在线框中添加和删除几何体。我可以使用raycaster从场景中拾取对象,但很难选择线框。
我能想到的一种方法是创建一组对象及其线框,当raycaster与对象相交时(例如obj.geometry.type ==" BoxGeometry"),找到它的父对象并删除父母。但是,线框必须是一些可以作为子项添加的几何体。我正在使用Boxhelper为立方体创建线框,应该直接添加到场景中,而不是作为子项添加到任何对象。解决这个问题的好方法是什么?
感谢。
答案 0 :(得分:2)
我不确定我是否完全理解你的内容,但也许你可以创建一个对象的克隆,并将其渲染为线框。然后可以将克隆线框对象作为子项添加到原始对象。因此,当拾取原始对象时,您可以将其从场景中移除,然后线框对象也将被移除。
克隆您的对象并将其材质更改为线框:
var wireframe = cube.clone();
wireframe.material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true});
cube.add( wireframe ); // adding wireframe as child to the cube
当拾取对象时:检查它是否是立方体几何(如果你只想让它与立方体一起使用)并检查它的材质是否是线框(如果你不想在不移除立方体的情况下移除线框)
if (pickedObject.geometry.type == "BoxGeometry" &&
!pickedObject.material["wireframe"]){
pickedObject.parent.remove(pickedObject); //this will remove object from
// scene if it has no parents
}
工作示例:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var wireframe = cube.clone();
wireframe.material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true});
cube.add( wireframe );
//picking stuff
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function onMouseClick( event ) {
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// update the picking ray with the camera and mouse position
raycaster.setFromCamera( mouse, camera );
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects( scene.children );
for ( var i = 0; i < intersects.length; i++ ) {
if (intersects[ i ].object.geometry.type == "BoxGeometry" &&
!intersects[ i ].object.material["wireframe"]){
intersects[ i ].object.parent.remove(intersects[ i ].object);
}
}
}
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
window.addEventListener( 'mouseup', onMouseClick, false );
render();
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
&#13;
答案 1 :(得分:1)
还有一种方法可以使用Three.EdgesHelper
而不是克隆来执行您需要的操作,如this小提琴中所示。这显示没有对角线的线框。
即使您不想使用Three.EdgesHelper
,我也注意到在实施上面的克隆解决方案时,它没有完全显示线框,因为它稍微隐藏了。
为了避免这种隐藏,我将以下代码添加到material
的构造函数中,这会稍微抵消原始形状,以便可以完全看到线框:
var material = new THREE.MeshLambertMaterial({ polygonOffset: true, polygonOffsetFactor: 1, polygonOffsetUnits: 1 })
我希望这在某种程度上有用。