2015-12-09 6 views
0

Общая проблема, которую я пытаюсь решить, - выяснить, какая грань куба направлена ​​вверх. Куб может поворачиваться на 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 

} 

ответ

0

не может быть решением вашей проблемы raycast, но другой подход: Почему вы не просто обнаружить верхнюю поверхность путем сравнения углов поворота Эйлер? Например. (Псевдо-код):

if(cube.rotation.x % 360 == 0) 
{ 
    // upper face upwards 
} 
else if(cube.rotation.x % 360 == 90) 
{ 
    // left face upwards 
} 

Вам придется иметь дело с допуском значения (85 ° - 95 °) отрицательные значения поворота и значения из диапазона PI * 2, но кроме этого, не так много Полегче?

+0

Это было бы проще, я думаю, и единственная причина, я не сделал это таким образом до сих пор потому, что я хотел бы избежать довольно долго, если-то еще о с большим из elses. Но я, вероятно, буду делать это таким образом, если я не смогу решить мою проблему с raycast, так что спасибо. :) – niceWeather

1

В конце концов я сделал это в некотором смысле @unx, но я действительно хотел избежать огромного выражения if-else, поэтому я сделал это с массивом rotationLibrary, который имеет все возможные вращения с соответствующей верхней гранью матрицы , Но из-за твинов, которые я использую для поворота и перемещения штампа, его значения вращения на самом деле не являются точными и поэтому трудно сравнивать с фиксированными значениями вращения, поскольку я использую их в массиве.

Поэтому я «нормализую» значения вращения матрицы для значений, которые я могу использовать для сравнения их с моими значениями в rotationLibrary. Последний шаг - сохранить/обновить результат на том, что лицо находится сверху в самом объекте куба, поэтому я могу получить его, когда захочу.

// 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; 
} 

(http://jsfiddle.net/b2an3pq7/3/)