节点旋转- Cocos3d



我正在开发一个使用Cocos3d的iPhone应用程序。我在XZ平面(y = 0)上画了一个场景。现在,当用户用两个手指触摸屏幕时,我想围绕XZ平面上的指定点旋转场景;旋转点将是两个接触点的中心。

我首先将两个触摸点投影到3D场景中,通过找到CC3Ray(从相机发出并经过触摸点)和XZ平面之间的交点。现在我有了XZ平面上的两个点,我可以计算旋转点(这将是这两个点之间的中点)。

为了围绕这个点旋转场景,我将它添加到父节点。现在我要做的就是通过中点坐标的负值平移它,将它的父点旋转一个角度,然后再通过中点坐标将它平移回来

这是我使用的代码(在ccTouchesMoved方法):

// Assuming that the root is a CC3Node and it is the scene that I need to rotate
// and middle refers to the center of rotation
[root translateBy:cc3v(-middle.x, 0, -middle.z)];
[root.parent rotateByAngle:30 aroundAxis:cc3v(0, 1, 0)];
[root translateBy:cc3v(middle.x, 0, middle.z)];

但是,我无法围绕中点旋转场景。有人能帮我解决这个问题吗?

谢谢!

编辑:

我还尝试在ccTouchesBegan方法中添加这些代码行:

[root translateBy:CC3VectorNegate(middle)];
[self.cc3Scene.activeCamera translateBy:CC3VectorNegate(middle)];

在ccTouchesMoved:

[root rotateByAngle:angle aroundAxis:cc3v(0, 1, 0)];

它只在用户第一次触摸屏幕时起作用,然后,每当他/她再次触摸屏幕时,就会发生不必要的翻译!我认为问题是与ccTouchesBegan方法

在任意一个节点上,旋转、平移和缩放变换是相互独立的。它们分别应用于节点的剩余姿态,并且彼此不累积。这样,控制节点的开发人员就可以很自然地看到交互。换句话说,在游戏过程中,在角色移动后旋转角色,在位置旋转角色,而不是围绕翻译位置旋转角色。类似地,无论节点之前是如何旋转的,转换节点都会转换它。

这与获取单个矩阵并累积变换到它的控制不同,这就是基于矩阵的旋转-围绕远点技术的工作原理。

但是,您可以通过以下方式有效地围绕不是其原点的位置旋转节点:

  1. 将局部旋转位置转换为全局坐标空间。
  2. 正常旋转节点
  3. 将(现在旋转的)本地旋转位置转换为全局坐标空间。
  4. 对齐步骤1 &3通过两个位置之间的差异来翻译节点。

可以执行步骤1 &3使用节点的globalTransformMatrix。以上步骤的代码如下:

CC3Vector gblRotLocBefore = [aNode.globalTransformMatrix transformLocation: rotationLoc];
[aNode rotateByAngle: angle aroundAxis: kCC3VectorUnitYPositive];
CC3Vector gblRotLocAfter = [aNode.globalTransformMatrix transformLocation: rotationLoc];
[aNode translateBy: CC3VectorDifference(gblRotLocBefore, gblRotLocAfter)];

使用这种技术,您不需要涉及节点的父节点。

最新更新