Ship Lasers After Rotation

Started by AGP, November 06, 2008, 05:40:52 PM

Previous topic - Next topic

AGP

The way the ship flies forward is it's always chasing targetCone. After the following method flips firing to true, the game loop makes the lasers chase after the laserTarget variables using the very same method that always works for the ship. What's weird is that the following code only works before the ship is rotated. Then, for some bizarre reason, the laserTargets start showing up in the wrong place. It's worth mentioning that the laser cylinders are ALWAYS aligned to the ship, but they end up flying sideways after the first rotation.

      private void fireLasers() {//SETS IT UP, THEN FLIPS firing TO TRUE SO THAT THE GAME LOOP TAKES IT FROM THERE
targetCone.calcCenter();
laser1 = Primitives.getCylinder(16, 4f, 20f);
laser1.build();
laser1.translate(laserDummy1.getTransformedCenter());
align(laser1, wing1);
// laserTarget1 = Object3D.createDummyObj();
laserTarget1 = Primitives.getBox(10, 1);
align(laserTarget1, targetCone);
moveTowards(laserTarget1, targetCone.getTransformedCenter(), 1f);
theWorld.addObject(laser1);
laser2 = Primitives.getCylinder(16, 4f, 20f);
laser2.build();
laser2.translate(laserDummy2.getTransformedCenter());
align(laser2, wing2);
theWorld.addObject(laser2);
// laserTarget2 = Object3D.createDummyObj();
laserTarget2 = Primitives.getBox(10, 1);
laserTarget2.build();
moveTowards(laserTarget2, targetCone.getTransformedCenter(), 1f);

laser1.addChild(laserTarget2);
laser2.addChild(laserTarget1);
theWorld.addObject(laserTarget1);
theWorld.addObject(laserTarget2);
laser1.setAdditionalColor(Color.red);
laser2.setAdditionalColor(Color.red);
System.out.println("Laser to Ship Distance: "+calculateDistance(xWing, laser1));
firing = true;
      }

EgonOlsen

i don't quite understand what is targetCone, laserTarget and all that...maybe a screen shot would help to clarify. Apart from that and taking a quick look at the code, i find it questionable that the laserTargets get the cone's rotation matrix. That way, they are sharing the same matrix. Is that intentionally?

AGP

#2
Oh, the rotation matrix thing wasn't supposed to be there. That was a stupid shot in the dark. The code wasn't working long before that. The target cone is like the crosshair of a gun. It is by following it that the ship flies. If you look around your mailbox you'll find an old screenshot of this. But all it is is a crosshair.

And laserTarget is just that: the direction at which the laser flies. It's just an object meant to be chased by the laser. The game loop calls moveTowards(laser1, laserTarget1, .2f), which moves the laser1 cylinder 20% of the way towards laserTarget1 (but since laserTarget1 is added as its child, laserTarget1 moves away by the same amount).

paulscode

To me, this setup seems logical in theory.  I'd like to see the code for methods align() and moveTowards() though, just to rule out the possiblity of a problem there.

AGP

Voilá.


      private void align(Object3D from, Object3D to) {
// THIS IS EGON'S: As Javadocs state: The default align method doesn't take parent objects into
// account...This method takes parents into account.
float scale = from.getScale();
from.setScale(1);
Matrix matrix = to.getWorldTransformation();
float[] dm = matrix.getDump();
for (int i = 12; i < 15; i++) {
      dm[i] = 0;
}
dm[15]=1;
matrix.setDump(dm);
from.setRotationMatrix(matrix);
from.setScale(scale);
      }

      protected void moveTowards(Object3D toMove, SimpleVector direction, float amount) {
SimpleVector origin = toMove.getTransformedCenter();
float deltaX = (direction.x -origin.x)*amount;
float deltaY = (direction.y -origin.y)*amount;
float deltaZ = (direction.z -origin.z)*amount;

toMove.translate(deltaX, deltaY, deltaZ);
      }

paulscode

I do understand that the idea here is to match "from's" orientation to that of "to", taking into account "to's" parent's rotation matrix.  I assume the reason you need to be able to do this is because the two guns rotate independantly from the ship, correct?

Just to make sure I am on the same page, I assume laserDummy1 is a child of wing1, and targetCone is a child of the ship object, correct?

Just looking over this, everything looks good to me, only thing I would make sure of is that the align method is doing what it is supposed to.  That's the only part I couldn't figure out from your code (although if Egon wrote it, I'm sure it is fine).

A different way to write the align() method would be to take all the rotation matrices from the parents and apply them to direction vectors, then use those to create a new rotation matrix.  I can write you some sample code for this, if my explanation doesn't make sense ;D

AGP

Yes, laserDummy1 and 2 are a child of their wings, and targetCone is a child of the ship. All I really want is for the lasers to fly straight towards the target, but the lasers move much faster than the ship, obviously, and have to pass the targetCone. You have to keep in mind the fact that the ship rotates around any and all axis. And align works fine (the lasers are always aligned). What doesn't work is that the laserTargets show up in weird places.

paulscode

You've probably already tried this, but if not, I thought of some diagnostic type tests to run.

1) Try making the targetCone some visible object, and have the ship rotate around in various directions to see if the targetCone moves correctly in relation to the ship like it is supposed to.

2) If that works, then next try making the laserTargets visible objects.  See if they show up on top of the targetCone position like they should.  Do this with the ship stationary, but rotated at various angles BEFORE generating the laserTargets.

3) If that works, do the same thing, but this time rotate the ship AFTER generating the laserTargets.  See if they move or if they remains stationary like they are supposed to.

These tests might help pinpoint where in your code the problem is cropping up from.

AGP

1) TargetCone is ALWAYS visible. It's a crosshair.
2) In the posted code, the laserTargets are visible and showing up in weird places.
3) They remain stationary if I don't flip the firing variable. They're not supposed to be stationary otherwise.

I don't really think it's my code to be perfectly honest, but I appreciate you trying to help.

EgonOlsen

Please tell me, if i got it right now: laserTarget (or cone?) is a kind of crosshair located in front of the ship or the laser itself!? It's a child object of laser and hence part of the ship...just put somewhere in front of it? If the ship rotates, the laser (which are child objects of some other ship part) stay in place, but the target/cone doesn't. Correct?

paulscode

Quote from: AGP on November 07, 2008, 06:18:33 AM
1) TargetCone is ALWAYS visible. It's a crosshair.
2) In the posted code, the laserTargets are visible and showing up in weird places.
3) They remain stationary if I don't flip the firing variable. They're not supposed to be stationary otherwise.

I don't really think it's my code to be perfectly honest, but I appreciate you trying to help.

Seems like the laserTargets are not being moved to the correct spot initially?  i.e. the following code is not doing what it is supposed to do?

laserTarget1 = Primitives.getBox(10, 1);
align(laserTarget1, targetCone);
moveTowards(laserTarget1, targetCone.getTransformedCenter(), 1f);


I would set up a test case to be absolutely sure if this part does what it is supposed to or not.  If the problem is not there, it must be coming from somewhere after this code is run, so work from there and try to check every step along the way.  I know that isn't much help, but I agree with you that your code seems like it should work, so you have to rule out everything, even the stuff that doesn't look like it should be a problem.

AGP

Egon, laserCone is the crosshair. In the fireLasers() method I posted, you see the lasers themselves are created at the location of laserDummy (sorry if some of it seems redundant or at least confusing). LaserCone is a visible crosshair, always in the right place, laserDummy are invisible dummy objects that are part of the ship (and are always in the right place). Laser targets (supposed to be invisible but for the purposes of debugging aren't) show up in the right places (directly in front of the lasers) ONLY until the ship is rotated.

Paulscode (is your name Paul?), unfortunately, there's not a lot to test. The game loop is VERY simple. If (firing) moveTowards(laser1, laserTarget1, .2f); kind of simple.

EgonOlsen

You should create a test case for this. What exactly do the laserTarget-objects when the ship rotates?

AGP

They show up in different places, like the sides of the ship. So the lasers, which again are aligned perfectly to the ship, fly sideways.

paulscode

It seems to me that the laserTarget objects should always start out at the location of targetCone.  Wherever they are initially placed, they should not move again (unless firing is true, in which case the laser and laserTarget start moving away from the ship).  Each part of the setup needs to be tested seperately.

Test case #1
So the first thing to make sure of is that every time the following code is run:
laserTarget1 = Primitives.getBox(10, 1);
align(laserTarget1, targetCone);
moveTowards(laserTarget1, targetCone.getTransformedCenter(), 1f);


Then the laserTarget is place at the location of targetCone.  Is this happening?  Don't wory about firing the laser yet, just make sure the laserTargets are being initially placed in the correct location when the ship is at various rotations.

Test case #2
If there were no problems in test case #1, the next thing to test is ship rotations after the laserTargets have been created, but before firing is set to true.  Place some laserTargets, then rotate the ship to make sure they stay where they are supposed to.

From your description of the problem, It sounds like the actual firing part works, so the thing you need to narrow down is if the laserTargets are being initially placed in the wrong location, or if they are for some reason shifting position when the ship rotates after they have been created.