2012-07-13 4 views
32

three.js를 사용하고 있습니다.three.js에서 충돌을 감지하는 방법은 무엇입니까?

내 장면에 두 개의 메쉬 지오메트리가 있습니다.

이러한 지오메트리가 교차되는 경우 (또는 이 교차하는 경우과 교차합니다) 충돌로 감지하고 싶습니다.

three.js로 충돌 탐지를 수행하려면 어떻게해야합니까? three.js에 충돌 감지 기능이 없으면 three.js와 함께 사용할 수있는 다른 라이브러리가 있습니까?

+2

충돌 탐지와 같이 광범위한 작업을 수행하는 방법에 대한 한 가지 질문은 실제로 질문이 아니라 학습 주제입니다. Google은 귀하의 친구입니다. – Nate

+2

Google에서 검색했지만 광선 충돌 만 발견했습니다. – eqiproo

+4

나는 광선 충돌이 갈 길이라고 생각합니다. Adnan이 (아마) 참조하고있는 CollisionUtils.js와 Collisions.js 파일은 최신이며 최신 (작성시 v49)의 일부가 아닙니다. js 버전. –

답변

85

Three.js에서 utili collisionUtils.js와 Collisions.js는 더 이상 지원되지 않는 것 같고, mrdoob (three.js의 생성자) 자신이 최신 버전의 three.js로 업데이트하고 대신이 목적으로 Ray 클래스를 사용하도록 권장합니다. 다음은 그 문제를 해결하는 한 가지 방법입니다.

아이디어는 다음과 같습니다. "player"라고하는 지정된 메쉬가 "collidableMeshList"라는 배열에 포함 된 메쉬와 교차하는지 확인하려고한다고 가정 해 봅시다. 우리가 할 수있는 일은 플레이어 메쉬 (Player.position)의 좌표에서 시작하여 플레이어 메쉬의 기하 도형에있는 각 꼭지점까지 연장되는 광선 세트를 만드는 것입니다. 각 Ray에는 "intersectObjects"라는 메서드가 있습니다.이 메서드는 Ray가 교차 한 객체의 배열과 이러한 객체 각각에 대한 거리를 반환합니다 (Ray의 원점에서 측정). 교차점까지의 거리가 플레이어의 위치와 지오메트리의 정점 사이의 거리보다 작 으면 플레이어의 메쉬 내부에서 충돌이 발생합니다. 즉 실제 "충돌"이라고합니다. 당신은 화살표 키를 사용하여 빨간색 와이어 큐브를 이동하고 W/A/S/D로 회전 할 수 있습니다

http://stemkoski.github.io/Three.js/Collision-Detection.html

:

I은 ​​작업 예제를 기록했다. 파란색 큐브 중 하나와 교차 할 때 위에서 설명한대로 교차로마다 "Hit"라는 단어가 화면 상단에 한 번 나타납니다. 코드의 중요한 부분은 다음과 같습니다.

for (var vertexIndex = 0; vertexIndex < Player.geometry.vertices.length; vertexIndex++) 
{  
    var localVertex = Player.geometry.vertices[vertexIndex].clone(); 
    var globalVertex = Player.matrix.multiplyVector3(localVertex); 
    var directionVector = globalVertex.subSelf(Player.position); 

    var ray = new THREE.Ray(Player.position, directionVector.clone().normalize()); 
    var collisionResults = ray.intersectObjects(collidableMeshList); 
    if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) 
    { 
     // a collision occurred... do something... 
    } 
} 

이 접근법에는 두 가지 잠재적 인 문제점이 있습니다.

(1) 광선의 원점이 메쉬 M 내에 있으면 광선과 M 사이의 충돌 결과가 반환되지 않습니다.

(2) 플레이어 광선과 관련하여 작은 물체가 다양한 광선 사이에서 "미끄러질"수 있으므로 충돌이 등록되지 않을 수 있습니다. 이 문제의 가능성을 줄이기위한 두 가지 방법은 코드를 작성하여 작은 오브젝트가 광선을 생성하고 원근감에서 충돌 감지 작업을 수행하거나 메시에 더 많은 정점을 포함하도록 코드를 작성하는 것입니다 (예 : CubeGeometry (100, 100, 100, CubeGeometry (100, 100, 100, 1, 1)보다는 오히려 20, 20, 20). 후자의 접근 방식은 성능에 영향을 미칠 수 있으므로 사용하지 않는 것이 좋습니다.

다른 사람들이이 질문에 대한 해결책으로이 질문에 기여하기를 바랍니다. 여기에 설명 된 솔루션을 개발하기 전에 나는 오랫동안 혼자 힘들었습니다.

+4

이 상세한 설명을 해주셔서 감사합니다! 나는 여전히 지형과 3D 오브젝트로 게임에 알맞은 솔루션을 찾는 데 어려움을 겪고 있으며, 당신의 대답은 나에게 새로운 통찰력을주었습니다! – Nick

+3

이 방법은 꼭지점이 꼭지점과 교차하는지 테스트하는 것처럼 보이지만 모든 가장자리 (연결된 꼭지점)를 테스트하는 데 두 배나 느리지 만 100 % 정확합니다. 정교하게하려면 각면을 반복하고 모든 꼭짓점을 얻기 위해 정점 [n]과 정점 [(n + 1) % len]을 가져야합니다. 제가 누군가를 안아 주면, 그들은 내 위치와 손의 중심을 가로 지르지 만 가장자리 검사를 할 때 내 피부를 교차시키지 않습니다. – Funkodebat

+0

그건 좋은 생각이야! 100 % (?)의 정확도를 얻으려면 두 메시 각각의 가장자리를 테스트해야하며 두 방향으로 진행하는 테스트가 필요하다고 생각합니다. 충돌이 한 방향으로 만 감지 되었기 때문에 광선은 메쉬의 바깥 쪽. 물론 조금 느려질 수도 있지만, 구형 반경 검사를 통해 속도를 높일 수 있습니다. 하지만 가장 중요한 점은 정확도가 100 % 정확하다고 생각합니다. –

6

이 정말 SO 질문에 충당하기 위해 주제의 너무 광범위하지만, 사이트의 검색 엔진 최적화를 조금 윤활을 위해, 여기에 간단한 시작 지점의 몇 가지 : 당신이 정말로 원하는 경우

간단한 충돌 감지하지 전체에 물리 엔진 다음, 당신은 몇 가지 충돌 응답을 원하십니까 반면에, 그냥 "A와 B가 충돌 했습니까?"하지 않으면 Three.js: Simple Collision Detection

을 확인, Physijs 살펴 보도록한다 사용하기 쉽고 Three.js 주위에 빌드 된 Ammo.js 래퍼

+3

당신이 링크 한 데모는 레이 충돌입니다 – eqiproo

관련 문제