大家好,我正在Three.js
开发一个项目,用户可以hover
一个镶嵌的面孔,每当网格相交和看不见的球体时,每个网格都应被推开,并回到原来的状态从它的区域外面的位置。我使用this和this example作为参考,但由于我不知道如何在Three.js
中使其工作,我陷入困境。
在我的代码中,我能够hover
网格的每个面,使其变红并在鼠标消失后恢复其原始颜色。但我不能做与此类似的事情。这是代码中我认为问题的一部分:
if (intersects.length > 0) {
// if the closest object intersected is not the currently stored intersection object
if (intersects[0].object != INTERSECTED) {
// Restore previous intersection objects (if they exist) to their original color
if (INTERSECTED) {
INTERSECTED.face.color.setHex(INTERSECTED.currentHex);
}
// Intersected elements
INTERSECTED = intersects[0];
var intGeometry = INTERSECTED.object.geometry;
var intFace = INTERSECTED.face;
// Difference between intersected faces and geometry
INTERSECTED.currentHex = intFace.color.getHex();
intFace.color.setHex(0xc0392b);
intGeometry.colorsNeedUpdate = true;
// Identify the vertices of each face
var intVertices = intGeometry.vertices;
var v1 = intVertices[intFace.a],
v2 = intVertices[intFace.a],
v3 = intVertices[intFace.a];
// Calculate the centroid of the selected face
var intPosition = new THREE.Vector3();
intPosition.x = (v1.x + v2.x + v3.x) / 3;
intPosition.y = (v1.y + v2.y + v3.y) / 3;
intPosition.z = (v1.z + v2.z + v3.z) / 3;
console.log(intPosition);
}
}
通过console.log()
我可以看到人脸是正确识别的,还有他们的位置,但是球体没有正确跟踪鼠标,我需要帮助这个位置。这是一个带有完整代码的 JSFiddle 。
答案 0 :(得分:4)
这是一个关于这个主题的小测试: https://jsfiddle.net/77xvepp7/
它无法正常工作,我将相机移动了一点以便可以看到这个想法。
基本思想是从曲面中选择一个顶点作为“基点”,它可以像在您的示例中那样是曲面的中心,并将该点保持为参考点以移动所有其他点相同数量的三角形。如果您不保存原始值,则下一轮可能包含无效值,三角形将随机移动。
然后计算鼠标到“基点”的距离,遍历所有顶点并将它们移动到基点的方向一定量。如果距离大于某个定义的量,则从顶点恢复原始值。
您可能尝试使用顶点着色器执行此操作,但问题是当鼠标位于曲面上时,每个顶点将朝相反方向移动,鼠标下方的三角形将缩放以填充空白。选择一个点作为“基点”可以消除此问题。
// Modify the geometry
var geometry = backgroundMesh.geometry;
for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
var face = geometry.faces[ i ];
if ( face instanceof THREE.Face3 ) {
var a = geometry.vertices[face.a];
var b = geometry.vertices[face.b];
var c = geometry.vertices[face.c];
var vList = [a,b,c];
// The trick is to save the original face positions
if(!a.origXSet) {
a.origX = a.x;
a.origY = a.y;
a.origZ = a.z;
a.origXSet = true;
}
var vect = a;
var dx = (vect.origX - pos.x),
dy = (vect.origY - pos.y),
dz = (vect.origZ - pos.z);
// distance to the mouse
var dist = Math.sqrt( dx*dx + dy*dy);
// magic constant, react if distance smaller than 4
if(dist < 4) {
vList.forEach(function(v) {
if(!v.origXSet) {
v.origX = v.x;
v.origY = v.y;
v.origZ = v.z;
v.origXSet = true;
}
var len = Math.sqrt(dx*dx + dy*dy + dz*dz);
if(len==0) return;
var ndx = dx / len,
ndy = dy / len,
ndz = dz / len;
v.x = v.origX + ndx * 2; // move 2 pixels
v.y = v.origY + ndy * 2;
v.z = v.origZ + ndz * 2;
});
} else {
// otherwise, reset coordinates
vList.forEach(function(v) {
if(v.origXSet) {
v.x = v.origX;
v.y = v.origY;
v.z = v.origZ;
}
});
}
geometry.verticesNeedUpdate = true;
geometry.normalsNeedUpdate = true;
}
}
主要问题是:未正确计算鼠标指针在世界坐标中的位置。现在我没有精力思考如何纠正这个问题,但我决定发布这个答案,以便你可以继续这样做。
答案 1 :(得分:1)
您没有将某些东西分配回几何体。有点效果:
intVertices[intFace.a].copy( intPosition );
intVertices[intFace.b].copy( intPosition );
intVertices[intFace.c].copy( intPosition );
intGeometry.verticesNeedUpdate = true;
intGeometry.normalsNeedUpdate = true;
答案 2 :(得分:0)
您遇到的问题是,您尝试targetList
的{{1}} <{1}}实例。
因此,当您尝试访问ray.intersectObjects
时,它会抛出错误