16.1 C
New York
Monday, May 5, 2025

Why is remodel matrix order is reversed in my Scene graph implementation?


I’ve researched this so much and to this point all of the examples, tutorials and so on all the time use the next order: Scale * Rotate * Translate however for some purpose this order should all the time be backwards in my Scene Graph. I’m not positive if that is meant resulting from remodeling native matrix to world matrix or it’s an inherent bug in my software.

Right here is my easy Scene Graph implementation. I’m utilizing Vulkan and GLM math library.

void SceneNode::setTransform(glm::mat4 remodel) {
  transformLocal = remodel;
}

void SceneNode::replace() {
  // if root node
  if (parentNode == nullptr) {
    transformWorld = transformLocal;
  } else {
    transformWorld = parent->transformWorld * transformLocal;
  }

  for (auto &node : kids) {
    node->replace();
  }
}

And my shader logic:

// initialization code hidden for simplicity

void predominant() {
  // worldTransform = remodel matrix calculated throughout scene node replace
  gl_Position = UniformCameraData.projectionView * ModelPushConstants.worldTransform * vec4(vPosition, 1.0f);

  outColor = vColor;
}

As a demo, I’ve created a brilliant easy scene with spheres:

Root
  Sphere Middle -> Rotate round its personal axis
    Sphere 1 -> Place someplace close to the guardian and Rotate round its personal axis
    Sphere 2 -> Place someplace close to the guardian andRotate round its personal axis
    Sphere 2 -> Place someplace close to the guardian andRotate round its personal axis

This scene graph offers me one sphere within the center that rotates and three spheres that rotate resulting from being kids of this sphere; plus, the spheres themselves rotate round their very own axis:

Nevertheless, the implementation of it’s quiet bizarre to me. The order of transformations is Translate * Rotate * Scale as an alternative of the opposite method round:

child1->setTransform(
          glm::translate(glm::mat4{1.0}, glm::vec3{2.0, 0.0, 0.0}) *
          glm::rotate(glm::mat4{1.0f}, glm::radians(body * 0.9f),
                      glm::vec3{0.0, 0.0, -1.0}) *
          glm::scale(glm::mat4{1.0}, glm::vec3{0.4, 0.4, 0.4}));

// ...different kids transformations

scene->replace();

Once I change the order of transformations, the rotation occurs across the central sphere:

child1->setTransform(
          glm::rotate(glm::mat4{1.0f}, glm::radians(body * 0.9f),
                      glm::vec3{0.0, 0.0, -1.0}) *
          glm::translate(glm::mat4{1.0}, glm::vec3{2.0, 0.0, 0.0}) *
          glm::scale(glm::mat4{1.0}, glm::vec3{0.4, 0.4, 0.4}));

// ...different kids transformations

scene->replace();

Demo - Wrong transformation

As you possibly can see, the cyan coloration sphere rotates across the guardian as an alternative of its personal heart.

I used to be confused by this so, I added translation to the basis node (e.g (2.0, 1.0)) and obtained the identical outcome. If I rotate the sphere, then translate, it’s going to rotate in opposition to (0, 0), then translate to (2.0, 1.0) on the similar time, which can imply that it’s at (2.0, 1.0) and rotating in opposition to (0.0, 0.0). Alternatively, if I translate first, then rotate, it’s going to rotate in opposition to (2.0, 1.0) and translate to (2.0, 1.0) on the similar time, which can imply that its rotating in opposition to the newly translated heart.

Logically this is sensible to me as a result of these multiplications are occurring on the similar time and the result’s written to node however I nonetheless don’t perceive why the usually advised transformation order is Scale * Rotate * Translate. Can somebody clarify to me what I’m lacking right here that I’ve to make use of multiply transformations is in reverse order?

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles