我的屏幕上有一个旋转和平移的物体, 但我有关于z轴旋转的2个问题。解释起来有点棘手所以我上传了2个视频来描述每个问题。
1)Reverse rotation:围绕x轴旋转物体后,z旋转正在反转,应该如此。
2)Wrong Z axis rotation:再次,围绕x轴旋转对象后,我试图围绕z轴旋转对象,旋转导致不同的轴旋转。
我相信视频会很好地描述问题。
编辑:更新#1
好吧,我以为我找到了解决方案,只围绕Z轴旋转相机, 并在模型本身上执行X和Y旋转。这似乎很好,但当然它导致了这个VIDEO中描述的一个新问题(它在23秒内,剩下的就是展示它是如何完成的)。
发生这种情况的原因是物体的轴系统正在旋转,当我进行Z轴旋转,然后是X或Y轴旋转时,结果是错误的。
我只是不知道如何从轴系统单独旋转对象,以便正确完成旋转。
现在,代码部分:
渲染功能:
- (void)render:(CADisplayLink*)displayLink {
...
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:100];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
[modelView populateFromTranslation:_currentPan];
[modelView rotateBy:_currentRotation];
[modelView rotateByZ:zRotationEnd];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
...
}
X和Y旋转:
- (void) rotateAroundX:(float) x andY:(float) y newRotate:(BOOL) isNewRotate
{
if (isNewRotate) {
rotationStart = CC3VectorMake(0.0, 0.0, 0.0);
}
int rotationDirection = ceil(zRotationEnd/90);
if (rotationDirection % 4 == 2 || rotationDirection % 4 == 3) {
rotationEnd.x = rotationEnd.x - (x-rotationStart.x);
rotationEnd.y = rotationEnd.y - (y-rotationStart.y);
} else {
rotationEnd.x = rotationEnd.x + (x-rotationStart.x);
rotationEnd.y = rotationEnd.y + (y-rotationStart.y);
}
rotationStart.x = x;
rotationStart.y = y;
_currentRotation = CC3VectorMake(rotationEnd.y, rotationEnd.x, 0);
NSLog(@"Current x is: %f y is: %f z is: %f",_currentRotation.x,_currentRotation.y,zRotationEnd);
}
相关的呼叫部分:
if(sender.numberOfTouches == 1)
{
BOOL started = false;
CGPoint rotation = [sender translationInView:sender.view];
float x = rotation.x;
float y = rotation.y;
if (sender.state == UIGestureRecognizerStateBegan)
{
started = true;
}
[self.glView rotateAroundX:x andY:y newRotate:started];
}
Z旋转功能:
- (void) rotateAroundZ:(float) z newRotate:(BOOL) isNewRotate
{
if (isNewRotate) {
zRotationStart = 0;
}
zRotationEnd = zRotationEnd - (z - zRotationStart);
zRotationStart = z;
}
相关的呼叫部分:
- (IBAction)rotation:(UIRotationGestureRecognizer *)sender {
BOOL started = false;
float rotation = RadiansToDegrees([sender rotation]);
if (sender.state == UIGestureRecognizerStateBegan)
{
started = true;
}
[self.glView rotateAroundZ:rotation newRotate:started];
NSLog(@"Rotation %f", rotation);
}
着色器:
attribute vec4 Position;
attribute vec4 SourceColor;
varying vec4 DestinationColor;
uniform mat4 Projection;
uniform mat4 Modelview;
attribute vec2 TexCoordIn;
varying vec2 TexCoordOut;
void main(void) {
DestinationColor = SourceColor;
gl_Position = Projection * Modelview * Position;
TexCoordOut = TexCoordIn;
}
非常感谢任何帮助。
干杯!
答案 0 :(得分:3)
简单的旋转。
这是根据触摸移动旋转对象的最简单方法。这是示例
pseudocode:
Matrix.setIdentity(modelMatrix);
... do other translations here ...
Matrix.rotateX(totalYMovement);
Matrix.rotateY(totalXMovement);
这是每一帧完成的。
要向上或向下旋转对象,我们围绕X轴旋转对象,并向左或向右旋转对象,我们围绕Y轴旋转它。如果我们想让它旋转,我们还可以围绕Z轴旋转一个物体。
答案 1 :(得分:1)
您似乎正在尝试实施gimbal。
虽然您似乎只使用Cocos3D作为基本数据数学结构,但请查看this post,其中介绍了如何在Cocos3D中创建云台,这可能有助于指明您正确的方向。
使用与云台结构匹配的嵌套结构对象(Cocos3D中的CC3Node
)更容易实现创建云台,而不是尝试将连续旋转应用于单个矩阵。但是,通过一些算法分析和实验,您可以提取结果矩阵数学并在单个矩阵上实现它。
请记住,成功的万向节需要以正确的顺序执行旋转。
答案 2 :(得分:1)
你的错误即将来临,因为你在同一时间围绕x,y和z旋转。问题是当你的模型矩阵是标识符时,你的z轴旋转是由对象定义的z轴。
解决此问题的最简单方法是使用复合矩阵乘法。基本上,通过将矩阵相乘,您可以指定所执行操作的顺序。
在您的情况下,您想要应用" x-y"你已经做过的动画。你那么想要执行你的z轴旋转。
如下所示:(我从未编写过cocos3d代码,因此这是基于快速搜索文档,可能存在错别字)。
CC3GLMatrix* rotationXY = [CC3GLMatrix identity];
[rotationXY rotateBy: _currentRotation];
CC3GLMatrix* rotationZ = [CC3GLMatrix rotateByZ: zRotationEnd];
[rotationXY multiplyByMatrix: rotationZ];
这应该会为您提供正确的模型矩阵。最后,您需要将视图(相机)矩阵乘以:
[rotationXY multiplyByMatrix: view];
[CC3GLMatrix copyMatrix: rotationXY into: modelView];
你现在应该看到你期望的行为。