为什么服务器端使用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 :(得分:0)
答案 1 :(得分:0)
实际上这里真正的问题是你的服务器端代码可能不会从threejs调用渲染循环(当然会破坏)
然而,渲染循环为你做了一些额外的工作,它在每个对象上调用方法updateMatrixWorld() -
所以服务器端,就在你做光线跟踪之前(使用世界矩阵而不是实际位置) - 一定要打电话
your_objects_you_want_to_raytrace.updateMatrixWorld();
在进行实际的光线跟踪之前。
在您的情况下,MovingCube.updateMatrixWorld();