trajectory and projectile rotation

aherber

Member
Contributor
Architecture
Hello again,

its been a while since my last post. Im sorry.

Im currently working on the ballistic trajectory for projectiles. Its working the way i want it to and the arrows fly in a parabolic path. There are still some problems remaining concerning the rotation of the arrow during the flight.

There seem to be a problem when the the radians value of the pitch and the yaw of the intial velocity-vector are equal or almost equal to each other and are around PI/2 . When beeing shot the arrow is facing upwards and is is only rotating once at highest piont on the fligth curve. Im was thinking that the Problem may a gimbal lock but this should not happen when quaternions are beeing used to represent the rotation. The other Problems that i have is that the direction of the rotation is always the same. The Arrow is always turning clockwise. The consequence is that between 0 -180 degrees the arrow is rotating away from the player as it should wheras the the arrow rotates towards the player when beeing shot between 180 and 360 degress. I guess the Problem here ist that the atan2 function returns radians values between +PI and -PI.

Here the code i am using to simulate the ballistic trajectory of the a bullet thats been fired. I know there are alot of different approaches around the internet for this exact problem and i tried a lot of them. None of them really worked from me.

Therefore based on the knowlegde i gained from my research i put up my own solution. This method is called every delta within my ProjectileSystem to update the rotation.

/** Sets the rotation of the Projectile according to its current velocity
*/
private void trajectory(RigidBody projectile, EntityRef entity){
Vector3f velocity = new Vector3f();
projectile.getInterpolationLinearVelocity(velocity);
Transform transform = new Transform();
projectile.getWorldTransform(transform);
//geting the angles of the current velocity vector
double pitch = Math.atan2(velocity.y, velocity.z);
double yaw = Math.atan2(velocity.x, velocity.z);
AxisAngle4f pitchAngle = new AxisAngle4f(1, 0, 0, (float)pitch);
AxisAngle4f yawAngle = new AxisAngle4f(0, 1, 0, (float)yaw);
Quat4f quatXRotation = new Quat4f();
Quat4f quatYRotation = new Quat4f();
quatXRotation.set(yawAngle);
quatYRotation.set(pitchAngle);
Quat4f rotation = new Quat4f();
//rotate
rotation.mul(quatXRotation,quatYRotation);
transform.setRotation(rotation);
projectile.setWorldTransform(transform);
}

If you see anything suspicios in my code please let me know. Thanks.

I guess i also have to have a closer look at the special cases of the Math.atan2 function as beeing mentioned here:
http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html#atan2(double, double)
 

aherber

Member
Contributor
Architecture
I wrote a new version of the trajectory Method using the QuaternionUtil Class that comes with JBullet. But the projectiles still behave the same way.

private void trajectoryNew(RigidBody projectile, EntityRef entity){
Vector3f velocity = new Vector3f();
projectile.getInterpolationLinearVelocity(velocity);
Transform transform = new Transform();
projectile.getWorldTransform(transform);
double pitch = Math.atan2(velocity.y, velocity.z);
double yaw = Math.atan2(velocity.x, velocity.z);
Quat4f rotation = new Quat4f();
transform.getRotation(rotation);
QuaternionUtil.setEuler(rotation, (float)yaw, (float)pitch, 0);
transform.setRotation(rotation);
projectile.setWorldTransform(transform);
}
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Well, the fundamental problem is that a single direction is not enough to determine correct rotation. You need two - a direction, and a non-parallel "up" direction which determines how the roll component of the rotation is aligned. Have a look into LookAt matrices/transforms.

For the most part you can simply use the standard up vector (0,1,0), but this won't work for an arrow aimed upwards (it ends up close to parallel). An alternative would be to maintain a relative up vector, seeded from the player's view direction and then updated after each update. This may still have issues with the sharp change in direction at the apex though.

Also
Code:
Use [code] tags
 

aherber

Member
Contributor
Architecture
Immortius thank you so much for your help . I have been struggeling with this the whole weekend.I finally got it to work and the flightpath i really smooth now. Im so happy right now :). I could flip my desk. Thanks again.

This works like a charm :D .
Code:
/**
    * lookAt  is a convienence method for auto-setting the
    * quaternion based on a direction and an up vector. It computes
    * the rotation to transform the z-axis to point into 'direction'
    * and the y-axis to 'up'.
    *
    * @param direction
    *            where to look at in terms of local coordinates
    * @param up
    *            a vector indicating the local up direction.
    */
  public void lookAt(Quat4f quanterion, Vector3f direction, Vector3f up ) {
      Vector3f yAxis = new Vector3f();
      Vector3f zAxis = new Vector3f();
      Vector3f xAxis = new Vector3f();
        zAxis.set(direction);
        zAxis.normalize();
        xAxis.cross(up, direction);
        xAxis.normalize();
        yAxis.cross(direction, xAxis);
        yAxis.normalize();
        Matrix3f rotationMatrix = new Matrix3f(xAxis.x,yAxis.x,zAxis.x,
        xAxis.y,yAxis.y,zAxis.y,
        xAxis.z,yAxis.z,zAxis.z);
        quanterion.set(rotationMatrix);
    }
Next up i will implement the animation for the bow. Im thinking about implementing a general System to animate Items based on diffrent icons or maybe gif based if thats a possibility.
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
(╯°□°)╯︵ ┻━┻

There you go! :D Simply put colons around FLIP and you too can flip tables without messing with ASCII!

Also, demo video! Shaaaare!

Animation framework for in-game items as opposed to just GUI elements sounds good. Don't aim for completing every last detail before pushing your code though, better to do it in chunks so we can add stuff in and maintain it more easily. And share it with people :rainbowdetermined:
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
We have skeletal mesh support, so if you are able to rig a bow that would be my suggested avenue of attack. GIFs probably won't work so well because of lack of tweening (unless you have a clever way of animating the between the frames).
 

aherber

Member
Contributor
Architecture
Immortius i will take a look into both options. I think its possible, but i will see how much work it really is. Maybe I have to put it on hold. Its just an idea to make content production and modding easier. At least i think it could be. This maybe easier for people who doesnt have so much expirience in animating models (including me unfortunately :( ). It may also be to limited in comparision to real models.
 

Josh

Member
Contributor
Hunter
How did Minecraft do it? Maybe we could use the same way they did it in their code, or something similar, because that way was simple for modding I believe which would also benefit Immortius. (I'm talking about entities in general.)
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Minecraft actually does the animated gif trick, sort of. It doesn't actually use a gif, it just has a set of icons it switches between. Which should be pretty doable, just means it isn't a smooth effect.
 
Top