0

I am developing a robot hand simulation program in which I can load and draw a robot hand model(the model built in 3DS MAX) and perform some actions according to the inputs, for an example, joint angles.

the hand model contains many different parts, each part have it's own model matrix and VBO storing vertex coordinates, normals and uvs.

I want to perform rotation using glm::rotate() on a joint around a certain axis(not coordinate axis), so I was going to translate it to the world origin, and perform rotation, and finally move back.

The problem here is that when I perform rotation after translation, the world origin it rotates around seems changed as well, it looks like the world origin have been translated in the same way.

also, I don't really know whether glm::rotate rotates around world origin? it's confusing that why it changes, I have tested rotating directly not to translate before rotation, and it actually rotates around world origin,but when I perform translation before rotation, it changes.

More details:

I also think the problem are most likely in the coordinate system. I used a Robothand class to represent the robot hand object, and those "parts" are objects of Model class, there are parent-child relationships among models, so every transformation performed in one specific model will have the same effect on their children model.

Vertex shader

void main(){

    mat4 MVP = P * V * M;

    gl_Position = MVP * vec4(vertexPosition_modelspace,1);

    Position_worldspace = (M * vec4(vertexPosition_modelspace,1)).xyz;

    vec3 vertexPosition_cameraspace = (V * M * vec4(vertexPosition_modelspace,1)).xyz;

    EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;

    vec3 LightPosition_cameraspace = (V * vec4(LightPosition_worldspace,1)).xyz;
    LightDirection_cameraspace = LightPosition_cameraspace + EyeDirection_cameraspace;

    Normal_cameraspace = ( V * M * vec4(vertexNormal_modelspace,0)).xyz;

    UV = vertexUV;

    Color = vertexColor;
}

I have to explain that the robot hand model is built in 3ds max, and exported as .obj file.In 3DS MAX, all the models share the same world origin, which means the their origin of model coordinate systems are in the same position. There are not any problems if I rotate any model without translation, it will rotate around world coordinate axis, but the real problem is, if I translate first, the world origin will be translated in the same way, it looks like rotating in a new coordinate system.

Spektre
  • 49,595
  • 11
  • 110
  • 380
CXC_SCUT
  • 1
  • 2
  • Translations are a commutative operation. (You may perform multiple of them in any order without difference of result.) This is not true for rotation. You may try this out (even with your hand or anything): Rotate first and then translate does not end up in the same point than translate and then rotate. (The base coordinate system for following transformation is effected by every transformation.) – Scheff's Cat Jul 21 '17 at 06:02
  • There are many parts in the model, some parts need not to be rotated when one joint rotates, so I think it's may not be helpful to fix it in glsl – CXC_SCUT Jul 21 '17 at 06:06
  • Possible duplicate of [How to create a cylinderical bone stored as a vector made of 2 points (Head, Tail)?](https://stackoverflow.com/questions/29095508/how-to-create-a-cylinderical-bone-stored-as-a-vector-made-of-2-points-head-tai) – Spektre Jul 21 '17 at 07:04
  • @CXC_SCUT see the linked duplicate what you want to do is chain the transformations to obtain transform matrix of each part of the robot (that is called **Direct Kinematics**) also see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) and look for the difference between local and global rotations ... Without any code and example input is hard to tell where the problem is but most likely you are translating in wrong coordinate system ... – Spektre Jul 21 '17 at 07:06
  • maybe try to compute your coordonates from your new axis origin and then perform your rotation. Translate your model from where you want to place your rotation axis and then rotate in the same new coordonate system. Then go back to your world coordonates. – Paltoquet Jul 21 '17 at 07:10
  • @DraykoonD I would not go back to world coordinates ... For chained transformations I usually stay in actual part local coordinate system (for both rendering and computations). – Spektre Jul 21 '17 at 07:12
  • @Spektre You are probably right but I think he may have a lot of new coordonate system, maybe one for each finger or joint. I don't see how at render he can use thoose coordonates for the glPosition variable. – Paltoquet Jul 21 '17 at 07:21
  • @DraykoonD "each part have it's own model matrix and VBO" so it has also its own transform matrix for rendering ... – Spektre Jul 21 '17 at 07:25
  • I have added some details, I think you are right, the problem is in the coordinate system, rotations on different model seems yielding different result, the rotation axis is different and origin is different, but I don't know why – CXC_SCUT Jul 21 '17 at 07:40
  • after the draw call on the robot hand object, each model(or part) will bind it's VBO, uniforms( model matrix) and finally call glDrawElements() – CXC_SCUT Jul 21 '17 at 07:43
  • The robot hand is exported by 3ds max, all the models are in the same coordinate system, there is only one world origin (0,0,0), which means the origin of each models' model coordinate system are in the same point, is that right? although each model has different transformation matrix, it seems doesn't matter – CXC_SCUT Jul 21 '17 at 07:52
  • @Spektre That's a great help, thanks for the link, I think I didn't fully understand the difference between local coordinate and global coordinate. I should rotate the model in the global coordinate rather than local coordinate – CXC_SCUT Jul 21 '17 at 09:15
  • @CXC_SCUT the chaining works usually like this: set your robot model matrix. Then multiply it by base object matrix and render base VBO. Then for each of its direct child multiply the resulting matrix by the child matrix and render child (for more childs at the same layer you need to use the original parrent resulting matrix so push/pop) and recursively do this for each child of child ... The problem is that we do not know the notations your model and you are using... so matrix multiplication can vary or you need to use inverse matrices instead etc ... you need to trial and error ... – Spektre Jul 21 '17 at 09:21
  • @Spektre I have a lot to learn, thanks~ – CXC_SCUT Jul 21 '17 at 09:52
  • @Spektre There is question about global rotation M' = inverse(inverse(M) * Rotation). Actually, it equals to M' = inverse(Rotation) * M, that have the same effect with M' = Rotation * M,but I don't know why? whether it is because Rotation matrix is both orthogonal and symmetric? – CXC_SCUT Jul 21 '17 at 11:19
  • @Spektre seems orthogonality holding during rotation transformation since orthogonal basis still remains orthogonal after rotation transformation, so if it is both orthogonal and symmetric, we can just simplified it as M' = Rotation * M instead. is that right? – CXC_SCUT Jul 21 '17 at 11:31
  • @CXC_SCUT yes exactly ... inverse matrix of rotation part of matrix is its transpose (that is because rotation is symmetric with symmetric kernel) but once you got translation in the matrix it no longer holds ... Yes the rotation part will be the transpose but the translation will not and need to be recomputed see the full pseudo inverse matrix usage in the last links of the Understanding transform matrix QA... – Spektre Jul 21 '17 at 11:43
  • @CXC_SCUT the inverse matrix has the order of operations reversed ... you can look at it as a stack problem.... you got transformation que `M= A*B*C` and want to go back to `A` so `A = M*inv(C)*Inv(B)` so you are applying inverse transforms in the reverse order ...keeping in mind that matrix multiplication is not commutative ... – Spektre Jul 21 '17 at 11:54
  • @Spektre understand,thanks~~ – CXC_SCUT Jul 21 '17 at 12:11

0 Answers0