我创造了一个物体,它有大约7个以上的部分,包括它的身体和在不同的地方“附着”它的较小的部分。我的目标是旋转整个对象。我试着在构造整个对象之前简单地调用glRotatef(angle, 0, 1, 0)
,但我意识到这似乎围绕原点旋转“一切”,无论翻译如何。以下代码试图旋转主体本身并将附件旋转到它。
// glRotatef(angle, 0, 1, 0); //old way of rotating the object
// body
glPushMatrix();
// movement
glTranslatef(subx, suby + y, subz);
//rotating the body itself
glRotatef(angle, 0, 1, 0);
// starting position of the body
glScalef(9.0, 1.75, 1.75);
glTranslatef(-subx, -suby, -subz);
glTranslatef(subx, suby, subz);
glutSolidSphere(1.0, 50, 50);
glPopMatrix();
// attached part
glPushMatrix();
// movement
glTranslatef(rot1x, rot1y + y, rot1z);
// attempting to rotate the part while 'attached to' the body
glRotatef(angle, 0, 1, 0);
//placing the part on the object in starting position
glRotatef(rot1angle, rot1xrot, rot1yrot, rot1zrot);
glTranslatef(-rot1x, -rot1y, -rot1z);
glTranslatef(rot1x, rot1y, rot1z);
gluPartialDisk(gluNewQuadric(), 0, 1, 50, 1, 0, 100.0);
glPopMatrix();
为了让对象的较小部分与对象的主体(固定点?)正确旋转,我似乎无法绕过需要发生的事情。谢谢你的帮助。
答案 0 :(得分:2)
您缺少glMatrixMode
次来电
如果你只使用GL_MODELVIEW
而不是它的工作(如果最后设置为活动状态)但是当你的代码变长并且你添加了其他调用时你可能会破坏它,突然你的代码将无法按预期工作(并且很难调试)。因此,最好在任何转换代码块之前添加glMatrixMode(GL_MODELVIEW);
。
您push/pop
错误地
您的对象是嵌套的,因此矩阵也必须嵌套。这意味着附加到所有者部分的任何部分必须以所有者部分矩阵开头。所以你需要有一些零件的层次结构(装配顺序),这样你才能知道哪些零件附加到哪些零件和哪里。
所以你应该有一个连接到任何部分的部件列表......如:
List<int> part[noOfObj];
所以part[i], i=<0,noOfObj-1>
所有part[i][0,1,2...,part[i].num-1]
子项部件num
都与其相关联(其中part[0]
是列表的大小)。 void part_draw(int ix) // this is just recursion call used by the main function do not use it directly
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(subPosX[ix], subPosY[ix], subPosZ[ix]);
glPushMatrix(); // this should not be here
glScalef(9.0, 1.75, 1.75); // this should not be here
..... // draw the object ix here
glMatrixMode(GL_MODELVIEW);// this should not be here
glPopMatrix(); // this should not be here
for (int iy=0;iy<part[ix].num,iy++)
part_draw(part[ix][iy]);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void mesh_draw() // this is the main rendering routine which you should use
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(refPosX, refPosX, refPosZ);
glRotatef(angle, 0, 1, 0);
part_draw(0);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
是主要部分。这会改变一些事情,但简单的递归会有所帮助:
subPosX/Y/Z
现在提防 @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.Name = (TextView) convertView.findViewById(R.id.Recipe_Name);
holder.Image_Block = (ImageView) convertView.findViewById(R.id.Recipe_Image);
holder.Text_Recipe = (TextView) convertView.findViewById(R.id.Recipe_Text);
holder.Text_Rarity = (TextView) convertView.findViewById(R.id.Recipe_Rarity);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
RowItem row_pos = rowItems.get(position);
holder.Image_Block.setImageResource(row_pos.getImage_Block());
holder.Name.setText(row_pos.getName());
holder.Text_Recipe.setText(row_pos.getText_Recipe());
holder.Text_Rarity.setText(row_pos.getText_Rarity());
return convertView;
}
位置必须位于父部件坐标系中。此外,这不适用于循环嵌套对象(循环),因为这会导致无限循环导致堆栈溢出。
答案 1 :(得分:1)
矩阵堆栈上的操作基于彼此。每个操作的参考系统是当前的转换。如果要转换由一堆对象组成的对象,则必须知道每个子对象与对象并集的引用位置的相对位置。然后你必须执行以下步骤:
glTranslate
)。glRotate
)
// dynamic position in the world
float refPosX, refPosY, refPosZ;
// dynamic orientation
float angle;
// constant positions of the sub object relative to the object union
float subPosX[], subPosY[], subPosZ[];
for ( int i = 0 i < noOfObj, ++i ) // for each object
{
glPushMatrix();
glTranslatef(refPosX, refPosY, refPosZ);
glRotatef(angle, 0, 1, 0);
glTranslatef(subPosX[i], subPosY[i], subPosZ[i]);
glScalef(9.0, 1.75, 1.75);
..... // draw the object here
glPopMatrix();
}
请参阅glTranslate
的文档:
glTranslate
按x y z
生成翻译。当前矩阵(参见glMatrixMode
)乘以此平移矩阵,产品替换当前矩阵,
并查看glRotate
的文档:
glRotate
围绕向量x y z
产生角度旋转。当前矩阵(参见glMatrixMode
)乘以旋转矩阵,产品替换当前矩阵,
注意,翻译矩阵如下所示:
Matrix4x4 translate;
translate[0] : ( 1, 0, 0, 0 )
translate[1] : ( 0, 1, 0, 0 )
translate[2] : ( 0, 0, 1, 0 )
translate[3] : ( tx, ty, tz, 1 )
围绕Y轴的旋转矩阵如下所示:
Matrix4x4 rotate;
float angle;
rotate[0] : ( cos(angle), 0, sin(angle), 0 )
rotate[1] : ( 0, 1, 0, 0 )
rotate[2] : ( -sin(angle), 0, cos(angle), 0 )
rotate[3] : ( 0, 0, 0, 1 )
矩阵乘法的工作原理如下:
Matrix4x4 A, B, C;
// C = A * B
for ( int k = 0; k < 4; ++ k )
for ( int l = 0; l < 4; ++ l )
C[k][l] = A[0][l] * B[k][0] + A[1][l] * B[k][1] + A[2][l] * B[k][2] + A[3][l] * B[k][3];
translate * rotate
的结果是:
model[0] : ( cos(angle), 0, sin(angle), 0 )
model[1] : ( 0, 1, 0, 0 )
model[2] : ( -sin(angle), 0, cos(angle), 0 )
model[3] : ( tx, ty, tz, 1 )
请注意,rotate * translate
的结果为:
model[0] : ( cos(angle), 0, sin(angle), 0 )
model[1] : ( 0, 1, 0, 0 )
model[2] : ( -sin(angle), 0, cos(angle), 0 )
model[3] : ( cos(angle)*tx - sin(angle)*tx, ty, sin(angle)*tz + cos(angle)*tz, 1 )