按需找到立方体的上表面
find upper face of cube on demand
我要解决的一般问题是找出立方体的哪个面朝上。立方体可以一次向任何方向滚动 90°。如果某个面朝上,立方体就会消失。我正在与补间一起旋转立方体并更改它的位置。
我目前正在尝试通过创建一条新射线来解决此问题,其原点设置在立方体上方,方向向下一小段距离,因此它仅与立方体的上表面相交。
violet thingy on top of die is ray cast downward into the cube
到目前为止一切顺利。当我根据 console.log()
检查时,我将我的立方体作为相交对象,但是当我尝试通过 faceIntersect.face
访问相交面时,它似乎是未定义的。
有问题的函数:
function checkUpperFace(posX, posZ) {
// get position from passed x- and z-values (y is always above cube)
// and set direction and length of ray
var position = new THREE.Vector3( posX, 3, posZ );
var direction = new THREE.Vector3(0, -1, 0);
var far = 2;
// create ray, that goes downwards from above the cube
var cubeRaycaster = new THREE.Raycaster( position, direction, 0, far );
// get intersection with upper face of rolled cube
var faceIntersect = cubeRaycaster.intersectObject( currentCube );
// add a helper to see the ray
var arrowHelper = new THREE.ArrowHelper( direction, position, far, 0x770077 );
scene.add( arrowHelper );
console.log(faceIntersect); // object is shown with everything I want to know
console.log(faceIntersect.face); // is shown to be undefined
}
可能不是您的光线投射问题的解决方案,而是另一种方法:您为什么不通过比较旋转欧拉角来简单地检测上表面?例如。 (伪代码):
if(cube.rotation.x % 360 == 0)
{
// upper face upwards
}
else if(cube.rotation.x % 360 == 90)
{
// left face upwards
}
您将不得不处理值公差 (85° - 95°) 负旋转值和超出 PI*2 范围的值,但除此之外,不是更容易吗?
最后我按照@unx 推荐的方式做了它,但我真的想避免巨大的 if-else 语句,所以我用一个数组 rotationLibrary
做了它,它具有所有可能的旋转和相应的模具的顶面。但是由于我用来旋转和移动模具的补间,它的旋转值并不真正准确,因此很难与我在数组中使用的固定旋转值进行比较。
所以我 "normalize" 将骰子的旋转值设置为我可以用来将它们与我在 rotationLibrary
中的值进行比较的值。最后一步是 store/update 立方体对象本身的顶部面的结果,因此我可以随时获取它。
// spawn condition:
// 1 on top, 2 facing camera, 3 facing right (seen from camera),
// 4 facing left (see 3), 5 facing away from camera, 6 facing down
var rotationLibrary = [
{x: 0, y: 0, z: 0, face: 1},
{x: 0, y: 90, z: 0, face: 1},
{x: 180, y: 0, z: 180, face: 1},
{x: 0, y: -90, z: 0, face: 1},
{x: -90, y: 0, z: 0, face: 2},
{x: -90, y: 0, z: 90, face: 2},
{x: -90, y: 0, z: 180, face: 2},
{x: -90, y: 0, z: -90, face: 2},
{x: 0, y: 0, z: 90, face: 3},
{x: 90, y: 90, z: 0, face: 3},
{x: -90, y: -90, z: 0, face: 3},
{x: -90, y: 90, z: 180, face: 3},
{x: 180, y: 0, z: -90, face: 3},
{x: 0, y: 0, z: -90, face: 4},
{x: 90, y: -90, z: 0, face: 4},
{x: -90, y: 90, z: 0, face: 4},
{x: 180, y: 0, z: 90, face: 4},
{x: 90, y: 0, z: 0, face: 5},
{x: 90, y: 0, z: -90, face: 5},
{x: 90, y: 0, z: 180, face: 5},
{x: 90, y: 0, z: 90, face: 5},
{x: 90, y: 90, z: 90, face: 5},
{x: 0, y: 0, z: 180, face: 6},
{x: 180, y: -90, z: 0, face: 6},
{x: 180, y: 90, z: 0, face: 6},
{x: 180, y: 0, z: 0, face: 6}
];
function checkRotationsToGetUpperFace(cube) {
// create object with "normalized" (brought to quarter-circle-degree-values) degrees
var normalizedRotation = {
x: 0,
y: 0,
z: 0
};
normalizedRotation.x = getNormalizedDegree(cube.rotation._x);
normalizedRotation.y = getNormalizedDegree(cube.rotation._y);
normalizedRotation.z = getNormalizedDegree(cube.rotation._z);
// go through the library that has all the degrees with the corresponding upper face
for (var i = 0; i < rotationLibrary.length; i++) {
// check if the objects match, then get the face
if (rotationLibrary[i].x == normalizedRotation.x &&
rotationLibrary[i].y == normalizedRotation.y &&
rotationLibrary[i].z == normalizedRotation.z) {
cube.face = rotationLibrary[i].face;
}
}
// reattach cube for correct movement later
THREE.SceneUtils.attach(cube, scene, pivot);
}
function getNormalizedDegree(rotationValue) {
// transform rotation value into degree value
var rotValue = rotationValue / (Math.PI / 180);
// default value is 0, so only check if it should be 90°, 180° or -90°
var normalizedDegree = 0;
// x between 45° and 135° ( ~ 90)
if (rotValue > 45 && rotValue < 135) {
normalizedDegree = 90;
}
// x between -45° and -135° ( ~ -90)
else if (rotValue < -45 && rotValue > -135) {
normalizedDegree = -90;
}
// x between 135° and 215° or x between -135° and -215° ( ~ 180)
else if ((rotValue > 135 && rotValue < 215) || (rotValue < -135 && rotValue > -215)) {
normalizedDegree = 180;
}
return normalizedDegree;
}
我要解决的一般问题是找出立方体的哪个面朝上。立方体可以一次向任何方向滚动 90°。如果某个面朝上,立方体就会消失。我正在与补间一起旋转立方体并更改它的位置。
我目前正在尝试通过创建一条新射线来解决此问题,其原点设置在立方体上方,方向向下一小段距离,因此它仅与立方体的上表面相交。 violet thingy on top of die is ray cast downward into the cube
到目前为止一切顺利。当我根据 console.log()
检查时,我将我的立方体作为相交对象,但是当我尝试通过 faceIntersect.face
访问相交面时,它似乎是未定义的。
有问题的函数:
function checkUpperFace(posX, posZ) {
// get position from passed x- and z-values (y is always above cube)
// and set direction and length of ray
var position = new THREE.Vector3( posX, 3, posZ );
var direction = new THREE.Vector3(0, -1, 0);
var far = 2;
// create ray, that goes downwards from above the cube
var cubeRaycaster = new THREE.Raycaster( position, direction, 0, far );
// get intersection with upper face of rolled cube
var faceIntersect = cubeRaycaster.intersectObject( currentCube );
// add a helper to see the ray
var arrowHelper = new THREE.ArrowHelper( direction, position, far, 0x770077 );
scene.add( arrowHelper );
console.log(faceIntersect); // object is shown with everything I want to know
console.log(faceIntersect.face); // is shown to be undefined
}
可能不是您的光线投射问题的解决方案,而是另一种方法:您为什么不通过比较旋转欧拉角来简单地检测上表面?例如。 (伪代码):
if(cube.rotation.x % 360 == 0)
{
// upper face upwards
}
else if(cube.rotation.x % 360 == 90)
{
// left face upwards
}
您将不得不处理值公差 (85° - 95°) 负旋转值和超出 PI*2 范围的值,但除此之外,不是更容易吗?
最后我按照@unx 推荐的方式做了它,但我真的想避免巨大的 if-else 语句,所以我用一个数组 rotationLibrary
做了它,它具有所有可能的旋转和相应的模具的顶面。但是由于我用来旋转和移动模具的补间,它的旋转值并不真正准确,因此很难与我在数组中使用的固定旋转值进行比较。
所以我 "normalize" 将骰子的旋转值设置为我可以用来将它们与我在 rotationLibrary
中的值进行比较的值。最后一步是 store/update 立方体对象本身的顶部面的结果,因此我可以随时获取它。
// spawn condition:
// 1 on top, 2 facing camera, 3 facing right (seen from camera),
// 4 facing left (see 3), 5 facing away from camera, 6 facing down
var rotationLibrary = [
{x: 0, y: 0, z: 0, face: 1},
{x: 0, y: 90, z: 0, face: 1},
{x: 180, y: 0, z: 180, face: 1},
{x: 0, y: -90, z: 0, face: 1},
{x: -90, y: 0, z: 0, face: 2},
{x: -90, y: 0, z: 90, face: 2},
{x: -90, y: 0, z: 180, face: 2},
{x: -90, y: 0, z: -90, face: 2},
{x: 0, y: 0, z: 90, face: 3},
{x: 90, y: 90, z: 0, face: 3},
{x: -90, y: -90, z: 0, face: 3},
{x: -90, y: 90, z: 180, face: 3},
{x: 180, y: 0, z: -90, face: 3},
{x: 0, y: 0, z: -90, face: 4},
{x: 90, y: -90, z: 0, face: 4},
{x: -90, y: 90, z: 0, face: 4},
{x: 180, y: 0, z: 90, face: 4},
{x: 90, y: 0, z: 0, face: 5},
{x: 90, y: 0, z: -90, face: 5},
{x: 90, y: 0, z: 180, face: 5},
{x: 90, y: 0, z: 90, face: 5},
{x: 90, y: 90, z: 90, face: 5},
{x: 0, y: 0, z: 180, face: 6},
{x: 180, y: -90, z: 0, face: 6},
{x: 180, y: 90, z: 0, face: 6},
{x: 180, y: 0, z: 0, face: 6}
];
function checkRotationsToGetUpperFace(cube) {
// create object with "normalized" (brought to quarter-circle-degree-values) degrees
var normalizedRotation = {
x: 0,
y: 0,
z: 0
};
normalizedRotation.x = getNormalizedDegree(cube.rotation._x);
normalizedRotation.y = getNormalizedDegree(cube.rotation._y);
normalizedRotation.z = getNormalizedDegree(cube.rotation._z);
// go through the library that has all the degrees with the corresponding upper face
for (var i = 0; i < rotationLibrary.length; i++) {
// check if the objects match, then get the face
if (rotationLibrary[i].x == normalizedRotation.x &&
rotationLibrary[i].y == normalizedRotation.y &&
rotationLibrary[i].z == normalizedRotation.z) {
cube.face = rotationLibrary[i].face;
}
}
// reattach cube for correct movement later
THREE.SceneUtils.attach(cube, scene, pivot);
}
function getNormalizedDegree(rotationValue) {
// transform rotation value into degree value
var rotValue = rotationValue / (Math.PI / 180);
// default value is 0, so only check if it should be 90°, 180° or -90°
var normalizedDegree = 0;
// x between 45° and 135° ( ~ 90)
if (rotValue > 45 && rotValue < 135) {
normalizedDegree = 90;
}
// x between -45° and -135° ( ~ -90)
else if (rotValue < -45 && rotValue > -135) {
normalizedDegree = -90;
}
// x between 135° and 215° or x between -135° and -215° ( ~ 180)
else if ((rotValue > 135 && rotValue < 215) || (rotValue < -135 && rotValue > -215)) {
normalizedDegree = 180;
}
return normalizedDegree;
}