Search code examples
c++openglglm-math

Matrix multiplication - How to make a planet spin on it's own axis, and orbit it's parent?


I've got two planets, the sun and the earth. I want them to spin on their own axis, and orbit the planet at the same time.

I can get these two behaviors to work individually, but I'm stumped as to how to combine them.

void planet::render() {
    mat4 axisPos = mat4(1.0f);
    axialRotation = rotate(axisPos, axisRotationSpeedConstant, vec3(0.0f, 1.0f, 0.0f));

    if (hostPlanet != NULL) {
        mat4 hostTransformPosition = mat4(1.0f);
        hostTransformPosition[3] = hostPlanet->getTransform()[3];
        orbitalSpeed += orbitalSpeedConstant;

        orbitRotation = rotate(hostTransformPosition, orbitalSpeed, vec3(0.0f, 1.0f, 0.0f));
        orbitRotation = translate(orbitRotation, vec3(distanceFromParent, 0.0f, 0.0f));

        //rotTransform will make them spin on their axis, but not orbit their parent planet
        mat4 rotTransform = transform * axialRotation;

        //transform *= rotTransform;

        //orbitRotation will make the planet orbit, but it won't spin on it's own axis.
        transform = orbitRotation;
    }
    else {
        transform *= axialRotation;
    }


    glUniform4fv(gColLoc, 1, &color[0]);
    glUniformMatrix4fv(gModelToWorldTransformLoc, 1, GL_FALSE, &getTransform()[0][0]);
    glDrawArrays(GL_LINES, 0, NUMVERTS);
};

Solution

  • Woohoo! As usual, asking the question lead me to being able to answer it. After the last line, knowing that transform[0 to 2] represents the rotation in the 4x4 matrix (with transform[3] representing the position in 3D space), I thought to replace the rotation from the previous matrix calculation with the current one. Badabing, I got my answer.

        transform = orbitRotation;
        transform[0] = rotTransform[0];
        transform[1] = rotTransform[1];
        transform[2] = rotTransform[2];