我正在加载构建人类假人的.obj文件,并且在.obj文件中有几行显示了网格在哪里分割E.G. “ g“ body_part”,后跟顶点和面。当我加载对象时,它工作得很好,并且我可以控制台记录该对象并查看子对象,它们是构成对象的所有不同网格。问题是当我我正在使用raycaster来更改所徘徊的网格的颜色,它将仅在特定的部分上起作用。经过进一步的调查,我发现当对象被加载时,它会生成同一网格的重复项。有人对此有解释吗?是复制重复的网格物体还是对此的解决方案?
悬停在网格上时,使光线投射正常工作的技巧是选择交集返回的数组的最后一个索引,但这是一种技巧,不能解决复制问题。我仍在调查中。
// store reference to closest object as current intersection object
this.INTERSECTED = intersects[intersects.length - 1].object;
此外,如果我记录了相交,它会返回正确的相交网格,但也会返回所有重复的网格。例如,当我将鼠标悬停在手上时,它将返回相同对象的数组,但它们具有不同的uid:
(9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
1
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
2
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
3
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
4
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
5
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
6
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
7
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
8
:
{distance: 158.11485222188028, point: Vector3, object: Mesh, uv: Vector2, face: Face3, …}
length
:
9
__proto__
:
Array(0)
加载对象:
loadModel = (objModel) => {
//ADD Obj instantiate a loader
this.THREE = THREE;
const objLoader = new this.THREE.OBJLoader();
this.obj;
// load(URL, callback, loading, on error)
objLoader.load(objModel,
//called when resource is loaded
(object) => {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
if(child.name == "dummy_hips3 dummy_belly dummy_torso dummy_rshoulder dummy_rarm dummy_relbow dummy_rfarm dummy_rwrist dummy_rhand") {
console.log(child) <-- This will log 8x, and it should only happen once
}
child.material = new THREE.MeshBasicMaterial({color: 0x444444, wireframe: true});
}
});
object.position.y = -100;
this.obj = object;
console.log(object)
this.scene.add(object);
},
//called when loading is in progresses
(xhr) => {
this.setState({
percentageLoaded: (xhr.loaded / xhr.total * 100).toFixed(2) + '%'
});
},
//called when loading has errors
(error) => {
console.log(error);
});
}
射线广播功能
findObjIntersection = (obj) => {
// find intersections
// create a Ray with origin at the mouse position
// and direction into the scene (camera direction)
var vector = new THREE.Vector3(this.state.mouse.x, this.state.mouse.y, 1);
vector.unproject(this.camera);
var raycaster = new THREE.Raycaster(this.camera.position, vector.sub(this.camera.position).normalize());
// create an array containing all objects in the scene with which the ray intersects
// You can also pass this.scene.children for other objects
var intersects = raycaster.intersectObjects(obj);
// INTERSECTED = the object in the scene currently closest to the camera
// and intersected by the Ray projected from the mouse position
// if there is one (or more) intersections
if (intersects.length > 0) {
// if the closest object intersected is not the currently stored intersection object
if (intersects[0].object != this.INTERSECTED) {
// restore previous intersection object (if it exists) to its original color
if (this.INTERSECTED) this.INTERSECTED.material.color.setHex(this.INTERSECTED.currentHex);
// store reference to closest object as current intersection object
console.log(intersects)
this.INTERSECTED = intersects[0].object;
// store color of closest object (for later restoration)
this.INTERSECTED.currentHex = this.INTERSECTED.material.color.getHex();
// set a new color for closest object
this.INTERSECTED.material.color.setHex(0xff0000);
this.setState({
INTERSECTED: this.INTERSECTED.name
});
}
} else { // there are no intersections
// restore previous intersection object (if it exists) to its original color
if (this.INTERSECTED) this.INTERSECTED.material.color.setHex(this.INTERSECTED.currentHex);
// remove previous intersection object reference
// by setting current intersection object to "nothing"
this.INTERSECTED = null;
this.setState({
INTERSECTED: 'False'
});
}
}
我正在显示相交的网格,它会按照预期的方式变为红色,但是仅当我在某个位置悬停手臂并且需要悬停手臂时才需要发生。
这是悬停手臂的第二个图像,它正在检测相交并显示它确实是同一手臂,但是由于我没有悬停在特定点上,因此它返回了一个具有不同的ID,这就是问题所在。
答案 0 :(得分:1)
我的猜测是重复项在您的obj文件中。光线投射器会返回光线所击中的每个对象,因此,如果您要命中8次,则那里有8个几何体副本。
您要从Blender导出吗?在另一层中可能还有其他副本,还是隐藏了?
编辑:我下载了您的模型并在Blender中进行了查看。对于对象的某些部分,几何图形最多重复6次。这不是一个罕见的问题,因为作为建模者,您可能不会注意到重复项,因为它们是同一网格中的相同副本。
Mesh obj的大小从2.5兆减小到了约350 k:)
在Blender中,您可以进入对象的编辑模式,选择一个顶点,然后按Ctrl-L(选择链接的顶点),然后移动那部分几何图形,然后显示出一个重复项。
好消息是,一旦删除了这些重复项,您的模型文件就会小得多。 :)
eidt:1.5我找到了一种清理模型的简便方法。选择所有零件,然后按空格键->拆分->用松散的零件分开。.这样就可以将每个重复的网格物体变成一个易于分离的对象。选择并摆脱。
edit2:这是清除了重复项的清理后的OBJ文件。
https://drive.google.com/open?id=1Oi-hA9biuZmYuQ6ehiISOUZqCJDxd_fi