我正在使用SceneManager
,它允许创建SceneNode
个对象。每个SceneNode
包含有关位置,缩放和旋转的信息。要使对象显示在场景中,它只会附加到SceneNode
,并且SceneNode
中包含的变换将应用于它。例如,要让相机查看场景中的球体,我们可以写:
Camera cam = sceneManager.createCamera("MainCamera", Camera.ProjectionType.PERSPECTIVE);
Entity sphere = sceneManager.createEntity("Sphere", "sphere_mesh.obj");
SceneNode camNode = sceneManager.createSceneNode(cam.getname() + "Node");
SceneNode sphereNode = sceneManager.createSceneNode(sphere.getname() + "Node");
// turns camera node towards the sphere node as expected
camNode.lookAt(sphereNode);
上面的简化示例应该给出一般的想法,并且会产生预期的结果,即我没有问题让事情出现在屏幕上并让相机看着它们。
我想让SceneNode
包含Entity
点,而另一个SceneNode
包含另一个Entity
,而不是Camera
,但它最终会指向相反的方向我打算看一下。
例如,如果我们的目标节点位于[0, 0, -5]
位置,而另一个观察者节点位于[0, 0, 5]
位置,我们希望对象观察者节点的前向矢量为[0, 0, -1]
,而是它最终为[0, 0, 1]
,从目标中看远。
我最近在将Light
附加到SceneNode
并告诉lookAt
多维数据集SceneNode
照亮它之后发现了这个错误,但它没有亮起来。
此图显示了问题,中心立方体应该点亮,但不是。
白色球体标记了聚光灯的位置,它应该看着中心立方体,但它没有被点亮,因为它实际上是在相反的方向上看。换句话说,我尝试过:lightNode.lookAt(cubeNode);
在调试时,我可以看到生成的旋转矩阵如下所示:
s u f = side, up, forward; column-major matrix
[1 0 0]
[0 1 0]
[0 0 1] <-- wrong: looking down the +Z axis, towards viewer
相反,它应该是这样的:
s u f
[1 0 0]
[0 1 0]
[0 0 -1] <-- good: looking down the -Z axis, into screen
(是的,底层渲染系统是基于OpenGL的,这意味着“前面”实际上是在-Z轴下方。)
如果我修改上面的代码来查看实际位置的否定,即lightNode.lookAt(cubeNode.getRelativePosition().mult(-1));
,那么它会查看多维数据集并点亮它,如下所示。
所以,为了让它看向“前面”,我不得不告诉它看起来“回来”。在过去的几天里,我一直在寻找这个错误,甚至仔细检查 look-at 矩阵是否正确构建。根据我的参考资料,它似乎是正确的,但无论如何我都把它包括在内,因为它有可能在某一点上被怀疑。
public static Matrix4 createLookAtMatrix(Vector4 eyePosition, Vector4 targetPosition, Vector4 upDirection) {
Vector4 f = targetPosition.sub(eyePosition).normalize();
Vector4 s = f.cross(upDirection).normalize();
Vector4 u = s.cross(f).normalize();
float[][] values = new float[][] {
{ s.x(), s.y(), s.z(), -s.dot(eyePosition) },
{ u.x(), u.y(), u.z(), -u.dot(eyePosition) },
{-f.x(), -f.y(), -f.z(), -f.dot(eyePosition) },
{ 0f , 0f , 0f , 1f }
};
return createFrom(values);
}
我目前缺乏想法,并希望获得导致捕获和执行此错误的任何帮助。
我真的不知道它是否与我几个月前发布过的older question有关,但仍然没有解决,但是这里包括它以防它被证明是相关的。
答案 0 :(得分:0)
我假设您创建了look_at函数以使用相机。这就是为什么它不能与其他对象一起工作的原因。相机z轴始终指向远离您所看到的位置,这就是为什么您将减号添加到我假设的矩阵的第三行。
解决它的一种方法是拥有createLookAtMatrix和createCameraLookAtMatrix。梯子就像你现在拥有的那个,另一个没有第三排的减号。
另一种方法是始终将相机置于相机控制下#34;场景图中的节点。您可以让相机局部变换始终在y轴上旋转180度,然后将矩阵的外观设置为父节点。
在任何情况下,这都适用于相机以外的物体:
public static Matrix4 createLookAtMatrixForObjects(Vector4 eyePosition, Vector4 targetPosition, Vector4 upDirection) {
Vector4 f = targetPosition.sub(eyePosition).normalize();
Vector4 s = f.cross(upDirection).normalize();
Vector4 u = s.cross(f).normalize();
float[][] values = new float[][] {
{ s.x(), s.y(), s.z(), -s.dot(eyePosition) },
{ u.x(), u.y(), u.z(), -u.dot(eyePosition) },
{ f.x(), f.y(), f.z(), -f.dot(eyePosition) },
{ 0f , 0f , 0f , 1f }
};
return createFrom(values);
}