2013-11-20 4 views
0

three.js의 충돌 감지의 서버 측 사용이 클라이언트 측 사용법과 다른 이유가 있습니까? 동일한 설정 클라이언트와 서버 측에서 동일한 장면을 사용하고 있습니다.three.js 서버 측 충돌 감지 오류

세계와 충돌이 있으면 서버 측에서 결정하려고하고있는 것이 결정됩니다. 이 작업을 단순화하기 위해 우리는 세계에 2 개의 상자 만 사용합니다. 사용 된 코드는 Lee Stemkoski 충돌 감지 예제에서 가져온 것입니다 (감사의 말은 훌륭하고 명확합니다).

클라이언트 측 코드가 원활하고 문제없이 실행되지만 정확히 동일한 방식으로 시작된 서버 측 코드는 충돌을 감지하지 못합니다. 데모에서는 플레이어가 화살표를 사용하여 이동합니다. 이 이동은 클라이언트와 정확히 동일한 장면을 가진 서버로 전송됩니다. 그런 다음 변형이 적용됩니다 (회전, 위치 변경 등). 그러면 이러한 새 위치가 다시 전송됩니다. 서버와 클라이언트는 여기까지 동기화됩니다. 그러나 클라이언트는 세계 (2 박스)에서 우리의 개체와 히트를 감지하고 서버 않습니다.

클라이언트 측 :

socket.on("update", function(data){ 

var delta = clock.getDelta(); // seconds. 
var moveDistance = 200 * delta; // 200 pixels per second 
var rotateAngle = Math.PI/2 * delta; // pi/2 radians (90 degrees) per second 
if(data.type == "rot"){ 
    MovingCube.rotation.x = data.x; 
    MovingCube.rotation.y = data.y; 
    MovingCube.rotation.z = data.z; 
} 
if(data.type == "pos"){ 
    MovingCube.position.x = data.x; 
    MovingCube.position.y = data.y; 
    MovingCube.position.z = data.z; 
} 

var originPoint = MovingCube.position.clone(); 

for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++){   
    var localVertex = MovingCube.geometry.vertices[vertexIndex].clone(); 
    var globalVertex = localVertex.applyMatrix4(MovingCube.matrix); 
    var directionVector = globalVertex.sub(MovingCube.position); 

    var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize()); 
    var collisionResults = ray.intersectObjects(collidableMeshList); 
    if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) 
     console.log(" Hit "); 
    } 
}) 

서버 측 코드

socket.on("update", function(data){ 

    console.log("updating location"); 
    var delta = 0.1 ;//clock.getDelta(); // seconds. 
    var moveDistance = 200 * delta; // 200 pixels per second 
    var rotateAngle = Math.PI/2 * delta; // pi/2 radians (90 degrees) per second 
    if(data == "A"){ 
    MovingCube.rotation.y += rotateAngle; 
    socket.emit("update",{"type":"rot","x":MovingCube.rotation.x,"y":MovingCube.rotation.y,"z":MovingCube.rotation.z}); 
    } 
    if(data == "D"){ 
    MovingCube.rotation.y -= rotateAngle; 
    socket.emit("update",{"type":"rot","x":MovingCube.rotation.x,"y":MovingCube.rotation.y,"z":MovingCube.rotation.z}); 
    } 
    if (data == "left"){ 
    MovingCube.position.x -= moveDistance; 
    socket.emit("update",{"type":"pos","x":MovingCube.position.x,"y":MovingCube.position.y,"z":MovingCube.position.z}); 
    } 
    if (data == "right"){ 
    MovingCube.position.x += moveDistance; 
    socket.emit("update",{"type":"pos","x":MovingCube.position.x,"y":MovingCube.position.y,"z":MovingCube.position.z}); 
    } 
    if (data == "up"){ 
    MovingCube.position.z -= moveDistance; 
    socket.emit("update",{"type":"pos","x":MovingCube.position.x,"y":MovingCube.position.y,"z":MovingCube.position.z}); 
    } 
    if (data == "down"){ 
    MovingCube.position.z += moveDistance; 
    socket.emit("update",{"type":"pos","x":MovingCube.position.x,"y":MovingCube.position.y,"z":MovingCube.position.z}); 
    } 

    var originPoint = MovingCube.position.clone(); 

    for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++){ 
    var localVertex = MovingCube.geometry.vertices[vertexIndex].clone(); 
    var globalVertex = localVertex.applyMatrix4(MovingCube.matrix); 
    var directionVector = globalVertex.sub(MovingCube.position); 
    var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize()); 
    var collisionResults = ray.intersectObjects(collidableMeshList); 
    if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) 
    console.log(" Hit ");     
    } 
}) 

어떤 도움도 좋은 것입니다. 이것은 지금 2 주 동안 내 시간을 먹었습니다. 오류 메시지가없고 그것이 잘못되었다는 것을 알 수 없습니다.

답변

0

부동 소수점 계산은 다른 컴퓨터에서 다른 결과를 생성 할 수 있으므로 좋은 기사를 찾도록하겠습니다.

다음

가고,

Floating point determinism 그것이

+0

localhost atm에서 실행되기 때문에 동일한 시스템이 클라이언트와 서버 측 모두를 수행합니다. 동일한 초기 vertici가 계산에 사용되지만 그 이후의 어떤 경우에는 작동하지 않습니다. 서버가 위치를 업데이트 한 후에는 결과가 클라이언트로 보내지고 동일한 계산이 수행됩니다. Nodejs는 V8 엔진 (Google 크롬)의 ontop을 기반으로 만들어졌으며 클라이언트 측 테스트에도 사용됩니다. 나는 1 단계를 사용하여 int로 파싱을 시도 할 것이지만, 이것은 자바 스크립트 때문에 여전히 부동 소수점으로 간주 될 것이다. –

+0

나는 계산을 기록하고 그들이 실제로 같은지 비교하기 위해 제안 할 것이다. –

0

희망이 도움 사실 여기에 진짜 문제는 서버 측 코드는 아마 (물론 휴식 것이) threejs에서 렌더링 루프,

를 호출하지 않는다는 것입니다

그러나 렌더링 루프는 각 개체에 대해 updateMatrixWorld() 메서드를 호출합니다.

그래서 광선 추적을 수행하기 전에 (world matr ix가 실제 위치가 아님) - 반드시 전화하십시오

your_objects_you_want_to_raytrace.updateMatrixWorld();

전에 실제 광선 추적을 수행하십시오.

MovingCube.updateMatrixWorld();