我正在开发一个使用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方法。
答案 0 :(得分:0)
在任何一个节点上,旋转,平移和缩放变换彼此独立。它们各自应用于节点的其余姿势,并且彼此不累积。这使得交互看起来很自然并且由控制节点的开发者预期。换句话说,在游戏过程中,在移动角色后旋转角色,将角色旋转到位,而不是在翻译位置周围旋转。同样,无论先前如何旋转节点,翻译节点都会对其进行翻译。
这与采用单个矩阵并将变换累积到其中的方式不同,这就是基于矩阵的旋转远点技术的工作原理。
但是,您可以通过以下方式有效地围绕非原点的位置旋转节点:
您可以执行第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)];
使用此技术,您无需涉及节点的父级。