2013-08-31 2 views
4

저는 3D 가상 주택 프로젝트를 진행하고 있습니다. 충돌 탐지를 제외하고는 모든 것이 잘 작동합니다. 카메라와 움직임에 PointerLockControls를 사용합니다. 하지만 모든 가능한 방향에서 충돌을 탐지하는 방법을 잘 모르겠습니다. 에 대한 간단한 큐브에 난 그냥 앞으로 시작 단순하고 이전 버전과의 충돌에 대한 (0, 0, 0) : 다음Three.js, PointerLock 및 충돌 감지

rays = [ 
    new THREE.Vector3(0, 0, 1), 
    new THREE.Vector3(0, 0, -1) 
]; 

:

function detectCollision() { 
var vector; 
var projector = new THREE.Projector(); 

for (var i = 0; i < rays.length; i++) { 
    var vector = rays[i].clone(); 
    projector.unprojectVector(vector, camera); 

    var rayCaster = new THREE.Raycaster(controls.getObject().position, vector.sub(controls.getObject().position).normalize()); 
    var intersects = rayCaster.intersectObject(cube, true); 

    if (intersects.length > 0 && intersects[0].distance < 50) { 
     console.log(vector); 
     console.log(i, intersects); 
     $("#status").text("Collision detected @ " + rays[i].x + "," + rays[i].z + 
      "<br \>" + intersects[0].distance); 
    } 
} 

하지만 난 내 큐브에 충분히 가까이 얻을 때, 콘솔은 두 광선이 입방체를 때리는 것을 보여줍니다! 왜? 내 광선에 문제가 있습니까? 벡터 (0,0,1)은 역방향이어야하고 (0,0, -1)은 전달되어야합니다. 맞습니까? 3D로 길을 잃기 전에 도와주세요! 감사합니다. .

+0

단지 하나의 광선으로 시도하고 거기에서 알아낼 수 있는지보십시오. 나는 각 광선이 당신이 생각하는 반대 방향으로 던져지고 있다고 생각합니다. 그래서 어떤 방향으로 당신이 향하고 있는지에 따라 "앞으로"가 실제로 입방체와의 교차점에서 시작하여 카메라쪽으로 간다. 반면에 "뒤로 "하나는 카메라 뒤에서 시작하여 그쪽으로 나아 간다. 따라서 레이 큐 캐스터 방향을 유도하는 뺄셈의 순서를 바꾸어보십시오. – IceCreamYou

+0

더 많은 테스트를 한 후에, 네 개의 법선 벡터 ((0,0,1), (0,0, -1), (1,0,0), (-1,0,0))) 및 카메라 (포인터 잠금 제어) ** 방향 **. 예를 들어 카메라를 180도 회전 시키면 앞으로 벡터가 뒤로 벡터가되어야합니다. 권리? 그렇다면 레이캐스팅의 실제 방향 벡터를 계산하는 공식은 무엇입니까? –

+0

예 : http://threejs.org/examples/misc_controls_pointerlock.html http://stemkoski.github.io/Three.js/Collision-Detection.html 더 일반적으로 카메라 방향을 얻고 싶다면 http :/stackoverflow.com/questions/14023764/how-to-get-orientation-of-camera-in-three-js/14024779#14024779 – IceCreamYou

답변

8

마침내 발견! 해결책. 나는 수학에 능숙하지 않다. 그러나 결국 나는 그것을 이해한다. 또한

function detectCollision() { 
unlockAllDirection(); 

var rotationMatrix; 
var cameraDirection = controls.getDirection(new THREE.Vector3(0, 0, 0)).clone(); 

if (controls.moveForward()) { 
    // Nothing to do! 
} 
else if (controls.moveBackward()) { 
    rotationMatrix = new THREE.Matrix4(); 
    rotationMatrix.makeRotationY(180 * Math.PI/180); 
} 
else if (controls.moveLeft()) { 
    rotationMatrix = new THREE.Matrix4(); 
    rotationMatrix.makeRotationY(90 * Math.PI/180); 
} 
else if (controls.moveRight()) { 
    rotationMatrix = new THREE.Matrix4(); 
    rotationMatrix.makeRotationY((360-90) * Math.PI/180); 
} 
else return; 

if (rotationMatrix !== undefined){ 
    cameraDirection.applyMatrix4(rotationMatrix); 
} 
var rayCaster = new THREE.Raycaster(controls.getObject().position, cameraDirection);  
var intersects = rayCaster.intersectObject(hitMesh, true); 

$("#status").html("camera direction x: " + cameraDirection.x + " , z: " + cameraDirection.z); 

if ((intersects.length > 0 && intersects[0].distance < 25)) { 
    lockDirection(); 
    $("#status").append("<br />Collision detected @ " + intersects[0].distance); 

    var geometry = new THREE.Geometry(); 
    geometry.vertices.push(intersects[0].point); 
    geometry.vertices.push(controls.getObject().position); 
    scene.remove(rayLine); 
    rayLine = new THREE.Line(geometry, new THREE.LineBasicMaterial({color: 0xFF00FF, linewidth: 2})); 
    scene.add(rayLine); 
} 
} 

난 :
나 포인터 로커 대조군 방향을 얻을 후, 가압되는 키에 의존한다, 나는 실제 방향 벡터 (실마리 Icemonster 주셔서 감사합니다)를 얻기 위해 회전 행렬로 방향을 넣어 카메라가 충돌 객체를 쳤을 때 PointerLockControls.js를 일부 변경하여 움직이지 않게했습니다. CameraRayCasting.zip

업데이트
마지막으로 난 내 TouchControls 프로젝트를 완료하는 데 시간이 발견했습니다 : 여기 내 샘플을 업로드 할 수 있습니다. 3js v0.77.1을 사용하고 터치 및 히트 테스트를 지원합니다.
여기를 클릭하십시오 : TouchControls

+0

이 대답은 +10 !!! three.js r71 사용. Althrough를 사용하여 충돌 대신 감지를 사용했습니다. webgl/three.js를 사용하려면 더 많은 도움이 필요합니다. –