How do I make a gun turret that is child of a node point at another node in the root scene?
Posted: Sun Sep 08, 2024 10:25 pm
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:
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:
Now my attempts at getting this right aren't even close, but here's what i've been trying to do today:
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?
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();
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();
}
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)