[SOLVED] Vector direction left or right tip

Ok, I am trying to simulate an “turn effect” in an enemy ship (boss) slowly going in the direction of the player ship.
I will do the translation using slerp in the 0,0 owner nodes since they are orbiting an planet, my problem here is how to detect if the ship will do the turn effect to left or right.
So, I have this two vectors, toShipDirection and bossFowardDirection from the objects around the sphere, how to I detect if the boss should do the turn left or right ?
Just to ask this in another way, I just want to detect if some vector is at right or left from my own up/foward vector.
I guess I should convert both vectors to some kind of 2d plane and compare, but how to do that ?
I tried the toShipDirection.mult(bossFowardDirection) but didnt get the expected results…
I really fell I am missing something obvious here…
Obs: sorry if its hard to understand, I can make an video or post pictures if necessary, I never know if I was clear enough…

Well I think you might get the required result by comparing the vector components like: if vector1.y > vector2.y then vector1 is higher than vector2. Maybe.

But then again you could just point the boss into the player’s direction by using lookat on a dummy node and use that lookat vector in the slerp method like so:

Node temp = new Node();
temp.setLocalTranslation(boss.getWorldTranslation());
temp.lookAt(player.getWorldTranslation(),Vector3f.UNIT_Y);
Quaternion fin = boss.getLocalRotation();
fin.slerp(temp.getLocalRotation(),0.05f);

Where “boss” is the boss node, “player” is the player node and “fin” is the final rotation that you need.

Do you want to turn the boss to face the player or just turn it somewhere at will?

Actually neater, I just want to make the ship turn a bit , as its always hard to explain in words, see this video :

The boss suppose to turn left when the player is at left and right when the player is at right.
The boss is not moving yet, but it will and I will use slerp and lookat as you suggest, my problem here actually is just this particular animation effect…

This is the code I used in the video :

    Vector3f toShipDirection = AppStateGamePhaseRun.shipRotNode.getWorldTranslation().subtract(  spatial.getWorldTranslation() );
    Vector3f fowardDirection = Utils.getFowardVector(spatial);
    Vector3f direction = toShipDirection.mult(fowardDirection); //fowardDirection.add(toShipDirection);
    if(toShipDirection.z > fowardDirection.z) { // ship turning Left a bit effect
        spatial.getControl(ShipTurningLeftRightEffect.class).setTurningLeft();
        Utils.ShowMessage("turning left");
    } else {                                      // ship turning Right a bit effect
        spatial.getControl(ShipTurningLeftRightEffect.class).setTurningRight();
        Utils.ShowMessage("turning right");
    }
    new Utils.timerArrow(spatial.getWorldTranslation(), direction.mult(4), Main.ref_assetManager, Main.ref_rootNode , ColorRGBA.Red );
    new Utils.timerArrow(spatial.getWorldTranslation(), toShipDirection.mult(4), Main.ref_assetManager, Main.ref_rootNode , ColorRGBA.Green );
    new Utils.timerArrow(spatial.getWorldTranslation(), fowardDirection.mult(4), Main.ref_assetManager, Main.ref_rootNode , ColorRGBA.Blue );

As you can see, my problem is in the Vector3f direction and how to compare if its in the left and right…

So uh the way I understand it is that you want it to roll a bit? Aka like a plane banking, or do you want it to yaw? Turn is kinda ambigous.

To roll left / right a bit yes.
In the video its doing that, but since the vector and the comparation is wrong, its not doing right.
Its just an effect, together with the movement it suppose to make the boss moviment a bit more realistic.
It suppose to be easy to do, I really fell stupid asking this but I could not figure out yet how to determine this vector comparations…

I think this may be a typo on your end, try this:

if(toShipDirection.z < direction.z) { // ship turning Left a bit effect

instead of

if(toShipDirection.z > fowardDirection.z) { // ship turning Left a bit effect

I already tried, but you see, since the position of the objects can be anywhere around the sphere, that comparation is not allways true, it will depend if they are align with the z plane I guess …

I see, obviously. How did I not see that sooner. slaps himself

Well I don’t know how to really fix that, but I just came up with a cool workaround. No idea if this will work but how about this:

  • you make two nodes one on the left and another on the right of the boss ship, but still on it.
  • then you measure the distance between each those nodes and the player (via distance formula).
  • whichever one of those distances is shorter should be the one the boss needs to turn to.
    I’d be so awesome if this works. :smiley:
1 Like

Thats is an very cool idea indeed :slight_smile: :grinning:
Probably will work, I let you know !

Funny this reminds me of that time I was making a custom chase cam that would smoothly follow rotations. I was converting quaternions into euler angles to slowly increment them and just couldnt get it right.
Then I realised slerp existed and facedesked before I reduced 200 lines of code to 4.

Friend, your simple idea worked like a charm !

Code :

    float leftdistance  = armLeftNode.getWorldTranslation().distance(AppStateGamePhaseRun.shipRotNode.getWorldTranslation());
    float rightdistance = armRightNode.getWorldTranslation().distance(AppStateGamePhaseRun.shipRotNode.getWorldTranslation());
    if(leftdistance>rightdistance) {
        spatial.getControl(ShipTurningLeftRightEffect.class).setTurningRight();
    } else {
        spatial.getControl(ShipTurningLeftRightEffect.class).setTurningLeft();
    }

Thank you !

1 Like

AWESOME :smiley:

Thats true, sometimes you just need an good idea to fix problems…

1 Like

Dot product with the left or right vector (one will do).

Vector3f relative = shipLoc.subtract(enemyLoc).normalizeLocal();
float turnAmount = relative.dot(enemyRotation.mult(Vector3f.UNIT_X);

Turn amount will be -1.0 to 1.0 depending on if the shipLoc is -90 degrees to +90 degrees from the enemy ship. 0 = directly ahead.

Thanks pspeed, I was really looking for this function ( dot ) , besides there is a lot of information about what it does in the internet, there is almost none in the jm site, not even mentioned in the math for dummies for example, it would be good to have it there something illustrating what it does since it is so much useful…

What sorcery is this? :stuck_out_tongue:

EDIT: The wiki says:

Algebraically, it is the sum of the products of the corresponding entries of the two sequences of numbers. Geometrically, it is the product of the Euclidean magnitudes of the two vectors and the cosine of the angle between them.

Interesting, I didn’t even know this existed.

EDIT 2: Just found out how this is called in my first language and I did know this thing. Just never thought of it as meaning anything. Really good to know.

Which means if they are both normalized vectors then you get the cosine of the angle between the vectors.

Looked at another way, it’s the projection of one vector onto another vector… well the length of it which can then easily be used to project.

The dot product is one of my very favorite magic things. It has about a dozen uses in 2D and 3D graphics.

My explanation of how transform matrixes work… essentially just a bunch of dot-products:

2 Likes

Although unrelated, that is the single best matrix rotation explanaton I’ve seen ever. Makes so much sense now.