CC3Node旋转 - Cocos3d

时间:2014-05-08 10:51:49

标签: ios 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 个答案:

答案 0 :(得分:0)

在任何一个节点上,旋转,平移和缩放变换彼此独立。它们各自应用于节点的其余姿势,并且彼此不累积。这使得交互看起来很自然并且由控制节点的开发者预期。换句话说,在游戏过程中,在移动角色后旋转角色,将角色旋转到位,而不是在翻译位置周围旋转。同样,无论先前如何旋转节点,翻译节点都会对其进行翻译。

这与采用单个矩阵并将变换累积到其中的方式不同,这就是基于矩阵的旋转远点技术的工作原理。

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

  1. 将局部旋转位置转换为全局坐标空间。
  2. 正常旋转节点。
  3. 将(现在旋转的)局部旋转位置转换为全局坐标空间。
  4. 对齐步骤1和步骤1中找到的旋转位置。 3通过两个位置之间的差异来翻译节点。
  5. 您可以执行第1步和第2步。 3使用节点globalTransformMatrix。上述步骤的代码如下:

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

    使用此技术,您无需涉及节点的父级。