Javascript Cannon.js:查找骰子的边是使用四元数

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

使用我正在使用的一些代码

我正在掷骰子,还不是随机的,但这将在以后添加。但现在,我很难找出骰子落在了哪一边

在JS的第352行,在tick函数中,我试图找出骰子落在哪一边。我试过几种方法来观察四元数,但它从未给出我所期望的结果。我确信这是因为我不知道杰克关于四元数的事。因此,任何帮助都将不胜感激

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的创建者谈过,他推荐了类似的东西。我用一些代码记录骰子落在哪一边。谢谢你的建议。