Okay, I thought this would be plain and simple, but apparently I am missing something. Let me sketch what I want to achieve:
I have my ship with a gun mounted on it. The gun has to track the destignated target and follow it by rotating around its y-axis. The gun has to be constrained when it comes to rotating to prevent it from shooting at the own ships bridge, for instance. So, in rest, the gun is pointing forward an when it starts to track, it is not allowed to rotate more then, let’s say, 120 degrees to both sides.
Tracking the target is not the problem, I solved that with something @pspeed mentioned in another topic:
targetVec = gun.getTarget().getWorldTranslation().subtract(gun.gunNode.getWorldTranslation());
gunDirection = gun.gunNode.getWorldRotation().mult(Vector3f.UNIT_Z.negate());
dotTargetToGun = gunDirection.dot(targetVec);
Rotation is then handled by:
if (dotTargetToGun > 0.0f)
{
rotationDirection = LEFT;
rotationSpeed = speedLow;
if (dotTargetToGun > 0.5f)
{
rotationSpeed = speedHigh;
}
}
else if (dotTargetToGun <= 0.0f)
{
rotationDirection = RIGHT;
rotationSpeed = speedLow;
if (dotTargetToGun < -0.5f)
{
rotationSpeed = speedHigh;
}
}
gun.gunNode.rotate(0f, rotationDirection*rotationSpeed*tpf, 0f);
Which seems to be working just fine.
Problem is the rotation constraint. If I create 4 quadrants to see where the target is in relation to the ship (Port Bow = 1, Starboard Bow = 2, Starboard Stern = 3 and Port Stern = 4) I need the gun to behave smart. When the target moves at the port side, the gun turns left and when the target is more to the back of the ship (quadrant 4), the gun will reach its constrain and should stop. As soon as the target moves more to the front on the port side, the gun has to start following it again. But when the target goes from quadrant 4 to quadrant 3, the gun should turn right until it has reached its starboard constrain and then wait until it can start tracking the target again.
I have tried a lot, but nothing is working and I am running out of ideas. I thought creating quadrants was solving my problem (I create them by a dot-product of the ships direction with the targetVector and another dot product of the ships direction (but 90 degrees rotated and the targetVector. Then with some IF-statements, I can define the quadrant:
targetVec = gun.getTarget().getWorldTranslation().subtract(gun.gunNode.getWorldTranslation());
shipsDirection = gun.ship.getDirectionVector();
shipsDirection90 = new Quaternion().fromAngleAxis(FastMath.PI/2, new Vector3f(0,1,0)).mult(shipsDirection);
dotTargetToGun = gunDirection.dot(targetVec);
dotGunToShip = gunDirection.dot(shipsDirection);
dotTargetToShip = shipsDirection.dot(targetVec);
dotTargetToShip90 = shipsDirection90.dot(targetVec);
// Get the quadrant the target is in:
if (dotTargetToShip >= 0 && dotTargetToShip90 < 0)
{
targetQuadrant = 1;
}
else if (dotTargetToShip < 0 && dotTargetToShip90 < 0)
{
targetQuadrant = 2;
}
else if (dotTargetToShip < 0 && dotTargetToShip90 >= 0)
{
targetQuadrant = 3;
}
else if (dotTargetToShip >= 0 && dotTargetToShip90 >= 0)
{
targetQuadrant = 4;
}
Whatever I try, everytime the gun bums into it’s constrain, it get’s stuck. I think it makes sence, because I am checking
if (dotGunToShip < traverseMax)
in which traverseMax is the angle where the constrain is (in this example 120 degrees) which I have converted to a value which I can compare with the dotGunToShip by simply
(1f - (angle/90f));
In which angle = traverseMax.
I assume, by rotating the gun it will never stop at exactly traversMax. I think it passes it and then if (dotGunToShip < traverseMax)
will always be true and the gun will never rotate again.
Well, long story short: I am sure there is a much easier way to accomplish this, I just don’t see it and could appreciate some help. Something tells me I am just making this too complex.
Husky