Cannon.js:找到骰子的一面是使用四元数

时间:2015-12-03 18:21:08

标签: javascript 3d cannon.js

Local Storage Browser Support包含我正在使用的一些代码。

我正在掷骰子,而不是随机,但这将在以后添加。但是现在我很难找到骰子落到哪一侧。

在JS的第352行,在tick函数内部是我试图找出骰子落在哪一侧的地方。我已经尝试了几种方法来查看四元数,但它从未给我我期待的结果。而且我确定它是因为我不知道关于四元数的杰克。所以任何帮助都会非常感激。

{{1}}

这段代码可能会在以后使用开关或对象键结束,但是为了帮助我“可视化”它,我将它作为一个可怕的if语句。对不起。

2 个答案:

答案 0 :(得分:2)

我认为最简单的方法是创建6个样本点,每个样本点用于骰子的每一侧。这些采样点应该恰好位于每个面的中心。例如,如果你的骰子是一个从(-1,-1,-1)到(1,1,1)的立方体,则(1,0,0)是"右边"的中心。骰子的脸和(-1,0,0)是"左"的中心。面对骰子。

骰子降落后,获取骰子的四元数值。通过四元数转换每个采样点。通过每个采样点,上轴中具有最高值的采样点是骰子降落的一侧。

答案 1 :(得分:2)

您可以使用立方体的六个局部轴(+ 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
}

选择limit以使局部向上矢量必须位于半径为1的球体的顶部,底部,右侧,左侧,前后和后切片内。请参见下图中的灰色区域。 / p>

The "up" regions to compare against.