如何将 mesh.locallyTranslate Vector3 运动转换为世界 space 运动来为物体提供动力?
How can I convert a mesh.locallyTranslate Vector3 motion into a world space motion to give momentum to an object?
我有以下场景 https://rawgit.com/bicarbon8/SpaceSim/MomentumProblem/babylon.html 我已经设置了使用以下键旋转的功能:
- i = 俯仰
- k = 向上倾斜
- j = 向左滚
- l = 向右滚动
- u = 向左偏航
- o = 向右偏航
- / = 取消所有旋转
并使用以下键移动:
- q = 前进
- a = 向后移动
- s = 向左扫射
- f = 向右扫射
- e = 向上移动
- d = 下移
- \ = 取消所有移动
可以很好地沿其指向的方向移动网格,但我想根据网格的旋转启动运动,然后继续沿原始方向移动,而不管运动开始后发生的网格旋转(保持动量)。
我通过具有 x、y 和 z 值的单独对象跟踪每个方向上的运动,以便每次按下键盘进行运动只会修改此对象,然后将其应用于网格的每个循环动画周期,但因为我正在使用:
mesh.locallyTranslate(new BABYLON.Vector3(x, y, z))
旋转网格时,运动会随着网格一起旋转。如何将网格旋转的方向性转换为可与基于世界的平移一起使用的 Vector3,以便网格的后续旋转不会影响它已有的运动?
注意:这应该模拟微重力/无重力环境中的运动
在此先感谢您的帮助。
通过结合 Unity 引擎和 Three.js 类似问题的解决方案,我自己找到了解决方案,然后搜索 Babylon.js github 页面。为了修复它,我必须将我的全局跟踪速度对象从基于按键的直接输入更改为基于网格的世界矩阵计算的 BABYLON.Vector3 和我想要移动的局部 space 方向的归一化 Vector3然后添加到现有全局 Vector3 的网格用于跟踪动量(然后随后使用 World-space 平移将其应用于网格。
原文:
var direction = new BABYLON.Vector3.Zero(); // global
...
// on keypress of 'q' key apply thrust along 'z' axis
if (map["q"]) { // forward thrust
direction.z += 0.001;
};
...
// apply translation to mesh
mesh.locallyTranslate(new BABYLON.Vector3(x, y, z));
固定:
var velocity = new BABYLON.Vector3.Zero(); // global
...
// on keypress of 'q' key apply thrust along 'z' axis using mesh world matrix to convert to world space vector
if (map["q"]) { // forward thrust
var matrix = mesh.getWorldMatrix();
var vector = new BABYLON.Vector3.Zero();
vector = BABYLON.Vector3.TransformNormal(new BABYLON.Vector3(0, 0, 1), matrix);
velocity.addInPlace(vector);
};
...
// apply translation to mesh
mesh.translate(velocity, 0.001, BABYLON.Space.WORLD);
现在 'velocity' 对象保持动量并且对象可以自由旋转并根据其旋转和推力方向对 'velocity' 对象应用其他更改。
示例代码:https://rawgit.com/bicarbon8/SpaceSim/FixTranslationMomentum/babylon.html
我有以下场景 https://rawgit.com/bicarbon8/SpaceSim/MomentumProblem/babylon.html 我已经设置了使用以下键旋转的功能:
- i = 俯仰
- k = 向上倾斜
- j = 向左滚
- l = 向右滚动
- u = 向左偏航
- o = 向右偏航
- / = 取消所有旋转
并使用以下键移动:
- q = 前进
- a = 向后移动
- s = 向左扫射
- f = 向右扫射
- e = 向上移动
- d = 下移
- \ = 取消所有移动
可以很好地沿其指向的方向移动网格,但我想根据网格的旋转启动运动,然后继续沿原始方向移动,而不管运动开始后发生的网格旋转(保持动量)。
我通过具有 x、y 和 z 值的单独对象跟踪每个方向上的运动,以便每次按下键盘进行运动只会修改此对象,然后将其应用于网格的每个循环动画周期,但因为我正在使用:
mesh.locallyTranslate(new BABYLON.Vector3(x, y, z))
旋转网格时,运动会随着网格一起旋转。如何将网格旋转的方向性转换为可与基于世界的平移一起使用的 Vector3,以便网格的后续旋转不会影响它已有的运动?
注意:这应该模拟微重力/无重力环境中的运动
在此先感谢您的帮助。
通过结合 Unity 引擎和 Three.js 类似问题的解决方案,我自己找到了解决方案,然后搜索 Babylon.js github 页面。为了修复它,我必须将我的全局跟踪速度对象从基于按键的直接输入更改为基于网格的世界矩阵计算的 BABYLON.Vector3 和我想要移动的局部 space 方向的归一化 Vector3然后添加到现有全局 Vector3 的网格用于跟踪动量(然后随后使用 World-space 平移将其应用于网格。
原文:
var direction = new BABYLON.Vector3.Zero(); // global
...
// on keypress of 'q' key apply thrust along 'z' axis
if (map["q"]) { // forward thrust
direction.z += 0.001;
};
...
// apply translation to mesh
mesh.locallyTranslate(new BABYLON.Vector3(x, y, z));
固定:
var velocity = new BABYLON.Vector3.Zero(); // global
...
// on keypress of 'q' key apply thrust along 'z' axis using mesh world matrix to convert to world space vector
if (map["q"]) { // forward thrust
var matrix = mesh.getWorldMatrix();
var vector = new BABYLON.Vector3.Zero();
vector = BABYLON.Vector3.TransformNormal(new BABYLON.Vector3(0, 0, 1), matrix);
velocity.addInPlace(vector);
};
...
// apply translation to mesh
mesh.translate(velocity, 0.001, BABYLON.Space.WORLD);
现在 'velocity' 对象保持动量并且对象可以自由旋转并根据其旋转和推力方向对 'velocity' 对象应用其他更改。
示例代码:https://rawgit.com/bicarbon8/SpaceSim/FixTranslationMomentum/babylon.html