Javascript Cannon.js:查找骰子的边是使用四元数
使用我正在使用的一些代码 我正在掷骰子,还不是随机的,但这将在以后添加。但现在,我很难找出骰子落在了哪一边 在JS的第352行,在tick函数中,我试图找出骰子落在哪一边。我试过几种方法来观察四元数,但它从未给出我所期望的结果。我确信这是因为我不知道杰克关于四元数的事。因此,任何帮助都将不胜感激Javascript Cannon.js:查找骰子的边是使用四元数,javascript,3d,cannon.js,Javascript,3d,Cannon.js,使用我正在使用的一些代码 我正在掷骰子,还不是随机的,但这将在以后添加。但现在,我很难找出骰子落在了哪一边 在JS的第352行,在tick函数中,我试图找出骰子落在哪一边。我试过几种方法来观察四元数,但它从未给出我所期望的结果。我确信这是因为我不知道杰克关于四元数的事。因此,任何帮助都将不胜感激 function tick() { world.step(timeStep); drawScene(); if(cubeBody.velocity.norm() < 0
function tick() {
world.step(timeStep);
drawScene();
if(cubeBody.velocity.norm() < 0.001) {
var direction = cubeBody.quaternion.toAxisAngle()[0];
console.log(direction);
if (direction.x < 0.1 && direction.x > -0.1 &&
direction.y < 0.1 && direction.y > -0.1) {
console.log("side 1 or 6");
} else if (direction.y > 0.1 &&
direction.z < 0.1 && direction.z > -0.1) {
console.log("side 2");
} else if (direction.y < -0.1 &&
direction.z < 0.1 && direction.z > -0.1) {
console.log("side 5");
} else if (direction.x > 0.1 &&
direction.z < 0.1 && direction.z > -0.1) {
console.log("side 3");
} else if (direction.x > 0.1 &&
direction.z < 0.1 && direction.z > -0.1) {
console.log("side 4");
} else {
console.log("we got trouble");
}
} else {
requestAnimationFrame(tick);
}
}
函数tick(){
世界步(时间步);
drawScene();
if(立方体速度标准值()<0.001){
var direction=cubeBody.quaternion.toAxisAngle()[0];
控制台日志(方向);
如果(方向x<0.1和方向x>-0.1&&
方向y<0.1和方向y>-0.1){
控制台日志(“第1面或第6面”);
}如果(y方向>0.1),则为else&&
方向.z<0.1&&direction.z>-0.1){
控制台日志(“第2面”);
}否则,如果(y方向<-0.1&&
方向.z<0.1&&direction.z>-0.1){
控制台日志(“第5面”);
}否则,如果(方向x>0.1&&
方向.z<0.1&&direction.z>-0.1){
控制台日志(“第3面”);
}否则,如果(方向x>0.1&&
方向.z<0.1&&direction.z>-0.1){
控制台日志(“第4面”);
}否则{
log(“我们遇到麻烦了”);
}
}否则{
requestAnimationFrame(勾号);
}
}
这段代码稍后可能会使用开关或对象键,但为了帮助我“可视化”它,我将它作为一个可怕的if语句。很抱歉。我认为最简单的方法是创建6个采样点,每边一个。这些采样点应恰好位于每个面的中心。例如,如果您的骰子是从(-1,-1,-1)到(1,1,1)的立方体,则(1,0,0)是骰子“右”面的中心,-1,0,0)是骰子“左”面的中心
骰子落地后,获取骰子的四元数值。通过四元数变换每个采样点。通过每个采样点,上轴上具有最高值的采样点是骰子落下的一侧。我认为最简单的方法是创建6个采样点,每侧一个。这些采样点应恰好位于每个面的中心。例如,如果您的骰子是从(-1,-1,-1)到(1,1,1)的立方体,则(1,0,0)是骰子“右”面的中心,-1,0,0)是骰子“左”面的中心
骰子落地后,获取骰子的四元数值。通过四元数变换每个采样点。通过每个采样点,上轴上具有最高值的采样点是骰子落下的一侧。您可以使用立方体的六个局部轴(+x,-x,+y,-y,+z,-z),并使用
主体。四元数
将它们转换为世界空间,并检查这些向量中哪一个“指向最上方”
但是,如果将世界上方向向量变换为局部身体空间,并检查该向量在局部指向哪个方向,则会获得更好的性能
在游戏循环之前:
var localUp = new CANNON.Vec3();
var inverseBodyOrientation = new CANNON.Quaternion();
var limit = Math.sin(Math.PI/4);
// Transform the world up vector to local body space
localUp.set(0,1,0);
body.quaternion.inverse(inverseBodyOrientation);
inverseBodyOrientation.vmult(localUp, localUp);
// Check which side is up
if(localUp.x > limit){
// Positive x is up
} else if(localUp.x < -limit){
// Negative x is up
} else if(localUp.y > limit){
// Positive y is up
} else if(localUp.y < -limit){
// Negative y is up
} else if(localUp.z > limit){
// Positive z is up
} else if(localUp.z < -limit){
// Negative z is up
} else {
// The box is not resting flat on the ground plane
}
在游戏循环中:
var localUp = new CANNON.Vec3();
var inverseBodyOrientation = new CANNON.Quaternion();
var limit = Math.sin(Math.PI/4);
// Transform the world up vector to local body space
localUp.set(0,1,0);
body.quaternion.inverse(inverseBodyOrientation);
inverseBodyOrientation.vmult(localUp, localUp);
// Check which side is up
if(localUp.x > limit){
// Positive x is up
} else if(localUp.x < -limit){
// Negative x is up
} else if(localUp.y > limit){
// Positive y is up
} else if(localUp.y < -limit){
// Negative y is up
} else if(localUp.z > limit){
// Positive z is up
} else if(localUp.z < -limit){
// Negative z is up
} else {
// The box is not resting flat on the ground plane
}
//将世界上方向向量变换为局部身体空间
localUp.set(0,1,0);
体。四元数。逆(逆方向);
inverseBodyOrientation.vmult(localUp,localUp);
//检查哪一面朝上
如果(localUp.x>limit){
//正x向上
}else if(localUp.x<-限制){
//负x向上
}else if(localUp.y>limit){
//正y向上
}else if(localUp.y<-限制){
//负y向上
}else if(localUp.z>limit){
//正z向上
}else if(localUp.z<-limit){
//负z向上
}否则{
//箱子未平放在地平面上
}
选择限制
,以便局部上方向向量必须位于半径为1的球体的顶部、底部、右侧、左侧、前部和后部切片内。请参见下图中的灰色区域
您可以使用立方体的六个局部轴(+x,-x,+y,-y,+z,-z),并使用
body.quaternion
将它们转换为世界空间,并检查这些向量中哪一个“指向最上方”
但是,如果将世界上方向向量变换为局部身体空间,并检查该向量在局部指向哪个方向,则会获得更好的性能
在游戏循环之前:
var localUp = new CANNON.Vec3();
var inverseBodyOrientation = new CANNON.Quaternion();
var limit = Math.sin(Math.PI/4);
// Transform the world up vector to local body space
localUp.set(0,1,0);
body.quaternion.inverse(inverseBodyOrientation);
inverseBodyOrientation.vmult(localUp, localUp);
// Check which side is up
if(localUp.x > limit){
// Positive x is up
} else if(localUp.x < -limit){
// Negative x is up
} else if(localUp.y > limit){
// Positive y is up
} else if(localUp.y < -limit){
// Negative y is up
} else if(localUp.z > limit){
// Positive z is up
} else if(localUp.z < -limit){
// Negative z is up
} else {
// The box is not resting flat on the ground plane
}
在游戏循环中:
var localUp = new CANNON.Vec3();
var inverseBodyOrientation = new CANNON.Quaternion();
var limit = Math.sin(Math.PI/4);
// Transform the world up vector to local body space
localUp.set(0,1,0);
body.quaternion.inverse(inverseBodyOrientation);
inverseBodyOrientation.vmult(localUp, localUp);
// Check which side is up
if(localUp.x > limit){
// Positive x is up
} else if(localUp.x < -limit){
// Negative x is up
} else if(localUp.y > limit){
// Positive y is up
} else if(localUp.y < -limit){
// Negative y is up
} else if(localUp.z > limit){
// Positive z is up
} else if(localUp.z < -limit){
// Negative z is up
} else {
// The box is not resting flat on the ground plane
}
//将世界上方向向量变换为局部身体空间
localUp.set(0,1,0);
体。四元数。逆(逆方向);
inverseBodyOrientation.vmult(localUp,localUp);
//检查哪一面朝上
如果(localUp.x>limit){
//正x向上
}else if(localUp.x<-限制){
//负x向上
}else if(localUp.y>limit){
//正y向上
}else if(localUp.y<-限制){
//负y向上
}else if(localUp.z>limit){
//正z向上
}else if(localUp.z<-limit){
//负z向上
}否则{
//箱子未平放在地平面上
}
选择限制
,以便局部上方向向量必须位于半径为1的球体的顶部、底部、右侧、左侧、前部和后部切片内。请参见下图中的灰色区域
是的,我和cannon.js的创建者谈过,他推荐了类似的东西。我用一些代码记录骰子落在哪一边。谢谢你的建议。是的,我和cannon.js的创建者谈过,他推荐了类似的东西。我用一些代码记录骰子落在哪一边。谢谢你的建议。