THREE.js obj装载机与面部选择

时间:2017-06-02 01:56:40

标签: javascript three.js

我正在调整THREE.js示例页面上的对象加载示例,以允许加载的对象选择并着色其面。我的总体策略是遵循概述的here步骤。

但是,由于我没有使用THREE.geometry对象,因此我无法将此策略与obj加载器代码拼凑在一起。

我目前有光线交叉工作,所以我知道当我点击这个对象时,我只是在弄脏面部时遇到了麻烦。我知道我需要将vertexColors: THREE.FaceColors应用于obj材料,这就是我被困住的地方。

我当前的obj加载代码如下:

var loader = new THREE.OBJLoader( manager );
loader.load( path, function ( object ) {
    object.traverse( function ( child ) {
        if ( child instanceof THREE.Mesh ) {
          var faceColorMaterial = new THREE.MeshBasicMaterial({ color: 0xff00ff, vertexColors: THREE.VertexColors } );
          child.material = faceColorMaterial;
          child.geometry.addAttribute( "color", new THREE.BufferAttribute( new Float32Array( 3 * 3 ), 3 ) );
          child.geometry.dynamic = true;
        }
    } );
    scene.add( object );
    targetList.push(object);
}, onProgress, onError );

我的检测和着色代码:

var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
vector.unproject( camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = ray.intersectObjects( targetList, true );

if ( intersects.length > 0 ) {
  var colorArray = intersects[0].object.geometry.attributes.color.array;
  var face = intersects[0].face;
  colorArray[face.a] = 1;
  colorArray[face.a + 1] = 0;
  colorArray[face.a + 2] = 0;
  colorArray[face.b] = 1;
  colorArray[face.b + 1] = 0;
  colorArray[face.b + 2] = 0;
  colorArray[face.c] = 1;
  colorArray[face.c + 1] = 0;
  colorArray[face.c + 2] = 0;
  intersects[0].object.geometry.attributes.color.needsUpdate = true;
}

当我运行它时,我的物体是黑色的,当我点击面部时,它们不会改变颜色。

如何更改代码以允许在选择时更改颜色?

1 个答案:

答案 0 :(得分:0)

OBJLoader应该返回BufferGeometry个对象,这些对象不使用FaceColorsBufferGeometry可以使用VertexColors为脸部指定颜色,但您需要确保将colors属性应用于BufferGeometry。如果你有一个colors属性,那么你很幸运,因为OBJLoader为每个三角形提供了唯一的顶点。

intersectObjects返回时,Face3应该有abc,我认为这应该是mesh.geometry.attributes.position.array的标记},但它们也是mesh.geometry.attributes.color.array数组的索引。

var colorArray = intersects[0].object.geometry.attributes.color.array,
    face = intersects[0].face;
colorArray[face.a] = 1;
colorArray[face.a + 1] = 0;
colorArray[face.a + 2] = 0;
colorArray[face.b] = 1;
colorArray[face.b + 1] = 0;
colorArray[face.b + 2] = 0;
colorArray[face.c] = 1;
colorArray[face.c + 1] = 0;
colorArray[face.c + 2] = 0;
intersects[0].object.geometry.attributes.color.needsUpdate = true;

这应该将特定的脸变成红色。但是我不能强调,只有当您的几何图形具有colors属性且您的材质使用THREE.VertexColors时才会有效。