THREE.js识别单击一个几何体(合并的几何体)

时间:2019-05-22 16:09:27

标签: three.js raycasting

我只想更改一种几何图形的颜色。我正在通过克隆并将它们合并到一个缓冲区几何中来创建几何。因此,存在一个具有许多buffergeometry属性的大网格。现在,通过单击网格,我可以为所有网格更改颜色,但是是否可以仅为一个元素(框)更改颜色?

这是我的代码:

// set up threejs
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 50, window.innerWidth/window.innerHeight, 0.01, 1000 );

var renderer = new THREE.WebGLRenderer(); 
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
camera.position.z = 5;


// add merged geometries
var allGeometries = new THREE.Geometry();
var geometry = new THREE.BoxGeometry( 0.5, 0.5, 0.5 );
var geoVerticeAmm = geometry.vertices.length;
var amm = 50;

for(var i=0; i<amm; i++){
  var x = (0.5-Math.random())*3;
  var y = (0.5-Math.random())*3;
  var z = (0.5-Math.random())*3;
  
  var newGeo = geometry.clone();
  newGeo.translate(x, y, z);
  allGeometries.merge( newGeo );
}

var material = new THREE.MeshBasicMaterial( { 
  color: 0x005E99,
  vertexColors: THREE.VertexColors,
  transparent: true,
} );
var buffGeometry = new THREE.BufferGeometry().fromGeometry(allGeometries);
var mesh = new THREE.Mesh( buffGeometry, material );

var allGeoVerticeAmm = mesh.geometry.attributes.position.count;
var colorsArray = new Float32Array(allGeoVerticeAmm * 3);
mesh.geometry.addAttribute('color', new THREE.BufferAttribute(colorsArray, 3));

for(var i=0; i<allGeoVerticeAmm; i++){
  var col = i/allGeoVerticeAmm;
  mesh.geometry.attributes.color.array[ i * 3 ] = col;
  mesh.geometry.attributes.color.array[ i * 3 + 1 ] = col;
  mesh.geometry.attributes.color.array[ i * 3 + 2 ] = col;
} 
mesh.geometry.colorsNeedUpdate = true;

mesh.callback = function() { 
  // change color only for one box
  var r = Math.round( Math.random()*255 );
  var g = Math.round( Math.random()*255 );
  var b = Math.round( Math.random()*255 );
  
  this.material.color = new THREE.Color("rgb(" + r + ", " + g + ", " + b + ")");
}

scene.add(mesh);


// raycaster
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();


function onDocumentMouseDown( event ) {
  event.preventDefault();
  mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
  mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;

  raycaster.setFromCamera( mouse, camera );

  var intersects = raycaster.intersectObjects( scene.children ); 

  if ( intersects.length > 0 ) {
      intersects[0].object.callback();
  }
}

document.addEventListener('mousedown', onDocumentMouseDown, false);

// render
var render = function () {
  requestAnimationFrame( render );
  renderer.render(scene, camera);
};
render();
Click on box
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>

1 个答案:

答案 0 :(得分:2)

您有2个选择:

  1. 执行射线投射时,具有the returned object has a face and faceIndex属性。您可以使用该信息遍历您创建的网格color BufferAttribute,并进行比较:如果顶点是连接到该面的几何图形的一部分,请更改其颜色值。

  2. 您可以将几何作为独立的网格保持独立。这要简单得多,因为在执行光线投射后,您可以简单地进行设置:
    intersects[0].object.material.color = '0xff9900';,而不必遍历各个顶点。