How do I make a gun turret that is child of a node point at another node in the root scene?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
SomeGuyWithAComputer
Posts: 16
Joined: Wed Jun 26, 2024 12:28 am

How do I make a gun turret that is child of a node point at another node in the root scene?

Post by SomeGuyWithAComputer »

i'm trying to make it so that a turret on a ship points at another irrlicht ISceneNode.

The turret node is a child of the ship. The targets are at the same level as the ship, there is never a situation where a turret needs to target an item that the ship is a child of or that is a child of the ship.

I can easily do this:

Code: Select all

core::vector3df parentThingRot = getParentThing()->getNode()->getAbsoluteTransformation().getRotationDegrees();
core::vector3df toTarget(pos2 - pos1);
core::vector3df requiredRotation = toTarget.getHorizontalAngle();
this gets me the rotation to set the turret to if it wasn't a child of the ship i think. I've tried a great number of different things, I can't even remember it all but I know i'm not even close to getting it figured out. I've tried to calculate what to set the turret's angle to based on the rotation of the ship so that it's still pointing at a target despite being a child node of the ship and.. i've gotten absolutely nowhere.

I'm using these old functions I found for context:

Code: Select all

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// Given 2 euler rotations find a quaternion describing the relative rotation from the old to the new rotation
irr::core::quaternion getRelativeRotation(const irr::core::vector3df &oldRotationEulerDeg, const irr::core::vector3df &newRotationEulerDeg)
{
	irr::core::quaternion q1(oldRotationEulerDeg * irr::core::DEGTORAD);
	irr::core::quaternion q2(newRotationEulerDeg * irr::core::DEGTORAD);
	irr::core::quaternion qRel(q2 * q1.makeInverse());
	return qRel;
}

//inputs have to be in radians otherwise it won't work. note that reactphysics3d ususally does quaternion stuff in radians
Quaternion getRelativeRotation_rp3d(Vector3 &oldRotationEulerDeg, Vector3 &newRotationEulerDeg)
{
	irr::core::quaternion q1(core::vector3df(oldRotationEulerDeg.x, oldRotationEulerDeg.y, oldRotationEulerDeg.z));
	irr::core::quaternion q2(core::vector3df(newRotationEulerDeg.x, newRotationEulerDeg.y, newRotationEulerDeg.z));
	irr::core::quaternion qRel(q2 * q1.makeInverse());
	Quaternion newQuat(qRel.X,qRel.Y,qRel.Z,qRel.W);

	return newQuat;
}

// Given an euler angle + a quaternion with a relative rotation do return an euler angle describing the combined absolute rotation
irr::core::vector3df applyRelativeRotation(const irr::core::vector3df &oldRotationEulerDeg, const irr::core::quaternion &relativeRotation)
{
	// Add relative rotation
	irr::core::quaternion qt(oldRotationEulerDeg * irr::core::DEGTORAD);
	irr::core::quaternion qt2(relativeRotation * qt);

	irr::core::vector3df rotateTarget;
	qt2.toEuler(rotateTarget);
	rotateTarget *= irr::core::RADTODEG;
	return rotateTarget;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
irr::core::vector3df rotateAxesXYZToEuler(const irr::core::vector3df &oldRotation, const irr::core::vector3df &rotationAngles, bool useLocalAxes)
{
	irr::core::matrix4 transformation;
	transformation.setRotationDegrees(oldRotation);
	irr::core::vector3df axisX(1, 0, 0), axisY(0, 1, 0), axisZ(0, 0, 1);
	irr::core::matrix4 matRotX, matRotY, matRotZ;

	if (useLocalAxes)
	{
		transformation.rotateVect(axisX);
		transformation.rotateVect(axisY);
		transformation.rotateVect(axisZ);
	}

	matRotX.setRotationAxisRadians(rotationAngles.X * irr::core::DEGTORAD, axisX);
	matRotY.setRotationAxisRadians(rotationAngles.Y * irr::core::DEGTORAD, axisY);
	matRotZ.setRotationAxisRadians(rotationAngles.Z * irr::core::DEGTORAD, axisZ);

	irr::core::matrix4 newTransform = matRotX * matRotY * matRotZ * transformation;
	return newTransform.getRotationDegrees();
}
Now my attempts at getting this right aren't even close, but here's what i've been trying to do today:

Code: Select all

core::quaternion idontknow = getRelativeRotation(parentThingRot+getNode()->getAbsoluteTransformation().getRotationDegrees(), requiredRotation+parentThingRot);
core::vector3df combinedStuff = applyRelativeRotation(parentThingRot+getNode()->getAbsoluteTransformation().getRotationDegrees(), idontknow);
getNode()->getJointNode("yaw_gimbal")->setRotation(core::vector3df(combinedStuff.X,combinedStuff.Y,combinedStuff.Z));//this is split into components for more rapid trial-and-error testing of stuff (sometimes setting x and z to 0 yields dfferent incorrect results which is worth checking each time I get a new idea)
I feel like if I could JUST get the solution to this one problem somehow, it would help me with all or some of my other unsolved rotational angle problems. Any ideas?
CuteAlien
Admin
Posts: 9733
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How do I make a gun turret that is child of a node point at another node in the root scene?

Post by CuteAlien »

If you use svn trunk version of Irrlicht things are slightly easier. It has a function ISceneNode::setUpdateAbsolutePosBehavior which you can set to irr::scene::ESNUA_TRANSFORM_POSITION. Then child-nodes simply ignores the parent rotation and only updates the position based on parent. So child has it's own rotations (so the position still rotates around the ship, but it's own rotation won't be affected anymore - you have full control).

Then the rest is probably the stuff described in this thread: viewtopic.php?t=1325
(sorry too late for me to write code to check if that code actually works, but using buildCameraLookAtMatrixLH followed by getRotationDegrees would also have been my first try).

With Irrlicht 1.8 this is a bit more complicated as you have to get rid of the parent rotation yourself. Meaning you first update the matrix of the parent (updateAbsolutePosition()) and then get it's transformation (getAbsoluteTransformation). Next get rid of the positions in the matrix (set last row in the 4x4 matrix to 0) as you only need rotations. Then get the inverse matrix (matrix class has a function for that - inverse rotation matrix simply rotates everything backwards) and then multiply the matrix you got from buildCameraLookAtMatrixLH by that inverse matrix. Be careful in matrix multiplication order matters so a*b is not the same as b*a ... just try both and one should work. And I hope there's no scaling involved or things get more complicated (easiest then to just build the absolute transformation matrix of the parent yourself just from the rotations of all node parents).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
SomeGuyWithAComputer
Posts: 16
Joined: Wed Jun 26, 2024 12:28 am

Re: How do I make a gun turret that is child of a node point at another node in the root scene?

Post by SomeGuyWithAComputer »

Do you know how to change the last row of a matrix to 0 like that in irrlicht 1.8? I think setTranslation() should do it. Is there a better way to do it?

Thanks for the warning about scaling, I've been really careful to make sure nothing having to do with scaling ever happens in my project.

Anyway i'm trying this now:

Code: Select all

core::matrix4 parentTransform = getParentThing()->getNode()->getAbsoluteTransformation();
parentTransform.setTranslation(core::vector3df(0,0,0));//set last row to 0
core::matrix4 newMatrix;
newMatrix.getInverse(parentTransform);
core::vector3df shipUpVector = getParentThing()->getNode()->getRotation().rotationToDirection(core::vector3df(0,1,0));
newMatrix.buildCameraLookAtMatrixLH(getNode()->getAbsolutePosition(), pos2, shipUpVector);//pos2 is the position of the target
core::matrix4 combined = newMatrix*parentTransform;
core::vector3df combinedVector = combined.getRotationDegrees();
getNode()->getJointNode("yaw_gimbal")->setRotation(core::vector3df(0,combinedVector.Y,0));
getNode()->getJointNode("pitch_gimbal")->setRotation(core::vector3df(combinedVector.X,0,combinedVector.Z));
This particular attempt isn't quite doing it. I haven't trial and errored all of the stuff im unsure about yet, I'll update after i've done all that. Who knows, maybe i'm just 1 subtract 180 operation away from it working.

Edit: Ok, the closest I got it is this.

Code: Select all

core::matrix4 parentTransform = getParentThing()->getNode()->getAbsoluteTransformation();
parentTransform[12] = 0;
parentTransform[13] = 0;
parentTransform[14] = 0;
parentTransform[15] = 0;
core::matrix4 newMatrix;
parentTransform.getInverse(parentTransform);
core::vector3df shipUpVector = getParentThing()->getNode()->getRotation().rotationToDirection(core::vector3df(0,1,0));
newMatrix.buildCameraLookAtMatrixLH(pos2, getNode()->getAbsolutePosition(), shipUpVector);//pos2 is the position of the target
core::matrix4 combined = newMatrix*parentTransform;
core::vector3df combinedVector = combined.getRotationDegrees();
getNode()->getJointNode("yaw_gimbal")->setRotation(core::vector3df(0,combinedVector.Y,0));
getNode()->getJointNode("pitch_gimbal")->setRotation(core::vector3df(combinedVector.X,0,combinedVector.Z));
If I do this, it's almost as if there are certain edge cases where the turret actually does point in the same direction as the target except for it getting the up/down inverted. I don't know the exact conditions that cause it to point at the target but it's less than 25% of the time. I've tried buildCameraLookAtMatrixLH vs buildCameraLookAtMatrixRH, swapping the position and target parameters of that function and then trying newMatrix*parentTransform vs parentTransform*newMatrix. Maybe I'm using the inverse function incorrectly.
CuteAlien
Admin
Posts: 9733
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How do I make a gun turret that is child of a node point at another node in the root scene?

Post by CuteAlien »

setPosition and manually setting to 0 both should work enough for this (as [15] should be 0 already).

Your code kinda looks like what I'd expect to work. Except for having yaw and pitch separated. I'm not sure what that is doing and maybe it's messing up things. With euler rotations the order matters. So in Irrlicht I think rotation order is x->y->z. You can't split this up or change the order or you get another result (just try it with your hand - rotate x 90° followed by z 90° and then try again with z followed by x instead - your hand will have a very different end-result).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
SomeGuyWithAComputer
Posts: 16
Joined: Wed Jun 26, 2024 12:28 am

Re: How do I make a gun turret that is child of a node point at another node in the root scene?

Post by SomeGuyWithAComputer »

hmm, i had already tried separating them vs not separating them before posting that. What visually happens and the rotational axis values are often useless and inconclusive. (x and z axises are combined based on whatever the quaternion algorithms say to do and whatnot). In my above attempt (with combinedVector x,y,z all in the same one and not separated), the y axis of the turret never changes as the ship rotates in addition to whatever other indescribably incorrect stuff happens.

Maybe I'll make a video of it if weeks go by and I discover nothing new. Hopefully I'll make some kind of breakthrough soon and at least get enough information about the problem to get better help. All of my unsolved problems right now are angle math related, I never knew angle math could be this difficult.
SomeGuyWithAComputer
Posts: 16
Joined: Wed Jun 26, 2024 12:28 am

Re: How do I make a gun turret that is child of a node point at another node in the root scene?

Post by SomeGuyWithAComputer »

hold on, parentTransform.setTranslation(core::vector3df(0,0,0)) doesn't result in the same behavior as this

Code: Select all

parentTransform[12] = 0;
parentTransform[13] = 0;
parentTransform[14] = 0;
parentTransform[15] = 0;
i'll start trying both methods every time i change and check something.
The following code makes it so that the turret points 90 degrees to the right of the target but it still points in an actually predictable direction once the ship rotates. Being consistently 90 degrees off no matter what is practically the same as correct behavior. Too bad when I start moving the ship by going to any position besides 0,0,0 it of course stops being *almost* correct and starts going way off target. That's an improvement at least.

Code: Select all

core::matrix4 parentTransform = getNode()->getParent()->getAbsoluteTransformation();
parentTransform.setTranslation(core::vector3df(0,0,0));//set last row to 0
core::matrix4 inverseParentTransform;
core::matrix4 newMatrix;
parentTransform.getInverse(inverseParentTransform);
core::vector3df shipUpVector = getParentThing()->getNode()->getRotation().rotationToDirection(core::vector3df(0,1,0));
newMatrix.buildCameraLookAtMatrixLH(getNode()->getAbsolutePosition(), pos2, shipUpVector);
core::matrix4 combined = inverseParentTransform*newMatrix;
core::vector3df combinedVector = combined.getRotationDegrees();

getNode()->getJointNode("yaw_gimbal")->setRotation(core::vector3df(combinedVector.X,combinedVector.Y,combinedVector.Z));
Edit: you know, on second thought I think that was just a coincidence. If I rotate the ship enough, it gets out of whack and stops pointing at the target except for being 90 degrees off and instead points in entirely nonsense directions. Wow, I thought I was on to something. I'm not.

Is there a different or better way to get the inverse of a matrix? It's really hard to tell with 3d angles, you can't even go by the numbers, but visually I'm pretty sure I get the same results when getting the inverse of parentTransform as when not doing the inverse. This suggests its not getting the inverse, but matrix4.h talks about cramer's rule and looks fine, it's just that it's not changing the behavior in an obvious way.

Is it possible to set a position of a node to the value of a transformation matrix? idk if that would work but i'm starting to get really desperate for new ideas here.

Edit 2: i discovered something significant. First of all, changing the rotation of the bone isn't going to work because it's a child of another bone. Once I realized this I changed it to only change the rotation of the turret object and started brute force trying everything all over again.

I arrived upon code that points the turret at the target when I rotate the ship on the y-axis only meaning no pitch or rolling at all and when I move around on the x and z axis only (meaning position translations of the ship) it still works. Tilting the ship on the x or y axis or translating on the y axis causes the turret to point in what appears to be the opposite direction of where it's supposed to go. Here's the code.

Code: Select all

getNode()->getParent()->updateAbsolutePosition();
getNode()->updateAbsolutePosition();
core::matrix4 parentTransform = getNode()->getParent()->getAbsoluteTransformation();
//parentTransform.setTranslation(core::vector3df(0,0,0));//set last row to 0
parentTransform[12] = 0;
parentTransform[13] = 0;
parentTransform[14] = 0;
//parentTransform[15] = 0;
core::matrix4 inverseParentTransform;
core::matrix4 inverseNewMatrix;
core::matrix4 newMatrix;
newMatrix.getInverse(inverseParentTransform);
parentTransform.getInverse(inverseParentTransform);
core::vector3df shipUpVector = (getParentThing()->getNode()->getRotation()).rotationToDirection(core::vector3df(0,1,0));
cout << "up vector = " << shipUpVector << endl;
newMatrix.buildCameraLookAtMatrixLH(getNode()->getAbsolutePosition(), pos2, shipUpVector);
core::matrix4 combined = parentTransform*newMatrix;
core::matrix4 inverseCombined;
combined.getInverse(inverseCombined);
core::vector3df combinedVector = inverseCombined.getRotationDegrees();
            
getNode()->setRotation(combinedVector);
This is at least sensible enough behavior to actually describe without a video, that's significant.
SomeGuyWithAComputer
Posts: 16
Joined: Wed Jun 26, 2024 12:28 am

Re: How do I make a gun turret that is child of a node point at another node in the root scene?

Post by SomeGuyWithAComputer »

I ended up finally getting entirely everything I wanted. I even successfully separated the pitch and yaw rotation so 1 bone could do only yaw and the other bone could do only pitch. This way dual point gimbal turrets work better. It just took a massive amount of brute force trial and error. I resorted to using euler angle math and a LOT of stupid special cases. There's this +/-0.6 degree yaw boundary at the +90/-90 degree bound relative to the parent where things mess up so I made the turrets just disable themselves during that edge case because it's almost not noticeable. This is as good as it's going to get.

The code that it took to accomplish all this may not be useful to everyone. The manually programmed special cases for the angle math I couldn't figure out otherwise are complicated, clunky and very use case-specific but here it all is anyway:

Code: Select all

// for testing purposes, make the guns point at the closest object. once that's working i'll make gimbal aiming do other stuff
thing *ptr = getParentThing()->getClosestThing();
if (ptr != nullptr || m_appliedTargetThisFrame)
{
    getNode()->getParent()->updateAbsolutePosition();
    getNode()->updateAbsolutePosition();
    getNode()->getJointNode((u32)0)->updateAbsolutePositionOfAllChildren(); // lazy way of hopefully getting the root bone regardless of what its Blender name is
    core::vector3df pos1 = getNode()->getJointNode("muzzle0")->getAbsolutePosition();

    core::vector3df pos2;
    if (m_appliedTargetThisFrame == true)
    {
        // convert cursor float to pixels. its important
        u32 cursorX = (m_cursorPositionAtTrack.X + 0.5f) * irrDriver->getScreenSize().Width;
        u32 cursorY = (m_cursorPositionAtTrack.Y + 0.5f) * irrDriver->getScreenSize().Height;
        // do a bunch of raycast bullshit

        scene::ISceneCollisionManager *collMan = irrsmgr->getSceneCollisionManager();
        cout << "cursor variable = " << cursorX << "," << cursorY << endl;
        core::line3d<f32> ray = collMan->getRayFromScreenCoordinates(core::vector2di(cursorX, cursorY));

        // set the turret target position to the end fo the ray - where the player's cursor is pointing
        pos2 = ray.end;
        // m_appliedTargetThisFrame = false;//don't forget to set the housekeeping bool back to false. This way if the player returns to non-manual targetting, it picks back up instead of stays disabled
        cout << "set m_appliedTargetThisFrame to false. press any key to continue" << endl;

        // weapons are getting updated twice per frame and not once for frame for some reason. will fix later but for now I need to hurry up and get this turret tracking code working
        if (m_remainingTicks > 0)
        {
            m_remainingTicks--;
        }
        else if (m_remainingTicks <= 0)
        {
            m_remainingTicks = 5;
            m_appliedTargetThisFrame = false;
        }
    }
    else
    {
        // if the player didn;t do a manual camera track for this tick, shoot at the nearest target instead
        pos2 = ptr->getNode()->getAbsolutePosition();
        cout << "set pos to to closest thing" << endl;
    }

    core::vector3df diff = pos2 - pos1;
    double distance = sqrt(powl(diff.X, 2) + powl(diff.Y, 2) + powl(diff.Z, 2));

    getNode()->setJointMode(EJUOR_CONTROL);
    getNode()->getJointNode("yaw_gimbal")->setAnimationMode(EBAM_UNANIMATED);
    getNode()->getJointNode("pitch_gimbal")->setAnimationMode(EBAM_UNANIMATED);
    getNode()->getParent()->updateAbsolutePosition();
    getNode()->updateAbsolutePosition();
    core::matrix4 parentTransform = getNode()->getParent()->getAbsoluteTransformation();
    parentTransform[12] = 0;
    parentTransform[13] = 0;
    parentTransform[14] = 0;
    // parentTransform[15] = 0;
    core::matrix4 inverseParentTransform;
    core::matrix4 inverseNewMatrix;
    core::matrix4 newMatrix;
    newMatrix.getInverse(inverseParentTransform);
    parentTransform.getInverse(inverseParentTransform);
    core::vector3df shipUpVector = (getParentThing()->getNode()->getRotation()).rotationToDirection(core::vector3df(0, 1, 0));

    // not crashing is always more important than operational correctness. In a video game, the show must go on
    if (m_hardpointBone != nullptr)
    {
        shipUpVector = m_hardpointBone->getAbsoluteTransformation().getRotationDegrees().rotationToDirection(core::vector3df(0, 1, 0)); // get absolute up vector
    }

    newMatrix.buildCameraLookAtMatrixLH(getNode()->getJointNode("yaw_gimbal")->getAbsolutePosition(), pos2, shipUpVector);
    core::matrix4 combined = newMatrix * parentTransform;
    core::matrix4 inverseCombined;
    combined.getInverse(inverseCombined);
    core::vector3df combinedVector = inverseCombined.getRotationDegrees();

    cout << core::vector3df(combinedVector.X, combinedVector.Y, combinedVector.Z) << endl;

    bool upsidedown = isUpsideDown();
    int errorCode;
    thing *thisPtr = (thing *)this;
    if (combinedVector.Z > 90 && combinedVector.Z < 270 && !upsidedown /* shipUpVector.Y > 0.01*/)
    {
        cout << "special case for top-mounted turrets" << endl;
        combinedVector.Y = 180 - combinedVector.Y;
    }
    else if ((combinedVector.Z > 270 || combinedVector.Z < 90) && upsidedown /*shipUpVector.Y < 0.01*/)
    {
        cout << "special case for bottom-mounted turrets" << endl;

        combinedVector.Y = combinedVector.Y * -1;
        combinedVector.X -= 180;
    }
    // when the special case isn't happening, upside-down turrets are exactly 90 degrees off Y
    else if (/*shipUpVector.Y < 0.01*/ upsidedown)
    {
        combinedVector.X -= 180;
    }
    else
    {
        // the default case: top mounted turret operating in the non-special case
        // it's basically just off by 180

        combinedVector.Y = combinedVector.Y - 180;
    }

    // cout << core::vector3df(combinedVector.X,combinedVector.Y,combinedVector.Z) << endl;
    // the 5th and 6th edge case. if any of the brute-force derived math above changes, all of this stuff also changes

    if (combinedVector.Y < 90.7 && combinedVector.Y > 89.3 && !upsidedown)
    {
        combinedVector.X = getNode()->getJointNode("pitch_gimbal")->getRotation().X; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Z = getNode()->getJointNode("pitch_gimbal")->getRotation().Z; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Y = getNode()->getJointNode("yaw_gimbal")->getRotation().Y;
    }
    else if (combinedVector.Y > -90.7 && combinedVector.Y < 89.3 && !upsidedown)
    {
        combinedVector.X = getNode()->getJointNode("pitch_gimbal")->getRotation().X; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Z = getNode()->getJointNode("pitch_gimbal")->getRotation().Z; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Y = getNode()->getJointNode("yaw_gimbal")->getRotation().Y;
    }
    // this is f*cking ridiculous
    else if (abs(combinedVector.Y) > 89.3 && abs(combinedVector.Y) < 90.7 && upsidedown)
    {
        combinedVector.X = getNode()->getJointNode("pitch_gimbal")->getRotation().X; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Z = getNode()->getJointNode("pitch_gimbal")->getRotation().Z; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Y = getNode()->getJointNode("yaw_gimbal")->getRotation().Y;
    }
    else if (abs(combinedVector.Y) < 270.7 && abs(combinedVector.Y) > 269.3 && upsidedown)
    {
        combinedVector.X = getNode()->getJointNode("pitch_gimbal")->getRotation().X; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Z = getNode()->getJointNode("pitch_gimbal")->getRotation().Z; // freeze the pitch rotation if any of this bullshit happens
        combinedVector.Y = getNode()->getJointNode("yaw_gimbal")->getRotation().Y;
    }

    getNode()->getJointNode("yaw_gimbal")->setRotation(core::vector3df(0, combinedVector.Y, 0));
    getNode()->getJointNode("pitch_gimbal")->setRotation(core::vector3df(combinedVector.X, 0, combinedVector.Z)); // REALLY close to working (at least for top-mounted turrets)

    getNode()->getParent()->updateAbsolutePosition();
    getNode()->updateAbsolutePosition();
    getNode()->getJointNode((u32)0)->updateAbsolutePositionOfAllChildren(); // lazy way of hopefully getting the root bone regardless of what its Blender name is
}
else
{
    cout << "closest thing equals nullptr lol" << endl;
}
I know it's really messy and that is also may contain things not talked about in this post, but this was hard enough to come up with that surely someone else will benefit from this code some day. Finding a way to incorporate quaternion and matrix math instead of that 0-360 euler crap and all those special cases should work better in theory but getting that to happen is easier said than done.
CuteAlien
Admin
Posts: 9733
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How do I make a gun turret that is child of a node point at another node in the root scene?

Post by CuteAlien »

Glad you found some solution! And doing stuff like this the hard way a few times is probably the only way to "get" it anyway. Every time I force myself through some math troubles I don't understand, I seem to have a bit easier time in my next try. Thought there is also the "Essence of linear algebra" series from 3Blue1Brown on Youtube I watched a few years ago which cleared many things up for me, especially helped me finally understanding matrices better. Now a lot of my old code also looks very messy to me ^_^ . But hey - when it works it works...
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply