correct transforming

Hi all!
I have some problems with moving objects in java3D.

I tryed this code:

…extends Transvorm3D

public Transformer(Vector3f pos,double heading, double pitch, double bank) {

  Transform3D t = new Transform3D();
  
  t.rotZ(bank);
  this.mul(t);
        
  t.rotX(pitch);
  this.mul(t);
  
  t.rotY(heading);
  this.mul(t);

  t.set(pos);
  this.mul(t);

}

the problem is that the object will not correctly moved, because it will rotated first z, then x and then y.

Is it possible to rotate it x, y and z at the same time?
(without much math)

thanks,
bienator

I’m not sure I quite understand the question- is there a difference between rotating something in x then y then z rather than a single simultaneous matrix operation? The object you are shifting will not be transformed until you apply the Transform3D to it, surely?

OK
I want that a object should be rotated with three values:
pitch bank and heading

The problem is, that after I rotate an object for example in the z axis(bank) it has an other position.
And THEN I rotate it in the x axis(pitch) it has an other position too, but an wrong one. Because it will be rotated from his NEW position. This is mathematical correct but the object has not the pitch pitch and the bank bank.
This should not happen if I do this at the same time but how?
I hope you understand me now.

I am 16 and I have not very much experience with matrices, please tell me if I think wrong

The problem is that you can’t do it all at the same time, I’m afraid. When you apply a transformation (like a “roll”) you change the coordinate system that is used as a reference from that point on.

What you need to do is to work out the order of transformations you need and apply them in order. In the case of an aeroplane, for example, I think you want to pitch, yaw, then roll - I think this corresponds to pitch, heading, then bank in your code.

(I haven’t played with matrices for a while - to my disgust - I’m afraid. I think the above is true, but if it’s wrong someone is sure to jump in and correct me!)

Okay, I’ve just read what I’ve written and I think I’ll clarify it a bit better. :wink:

Given two matrices A and B, A multiplied by B is not necessarily equal to B multiplied by A (AB != BA).

You can apply all your transformations at the same time, but they must be gathered together in the specified order, so you want to create a matrix B as follows:

B = ApitchAheadingAbank

You can then apply matrix B to your object. This will give the same effect as applying the transformations one after the other.

I don’t know enough about the Java3D API but I’d guess from looking at your code that you shouldn’t be applying the transform after setting each rotation - set all the rotations one by one and apply the lot at the end.

Thank you very much cfmdobbie :slight_smile: :smiley: ;D
that is what I want to hear, I need just the right order of transformations.

bienator

I have the exact same problem.

I am trying to program a spacecraft/airplane that moves around in java 3D, I cant get the rotations correct though…

I have tried to put the transforms together in all kinds of orders but it still wont work. :frowning: :frowning:

Are there no way to use a local set of coordinate axis (that will follow the airplanes rotation) or a matematical way to calculate how to rotate it correctly?

Working with eulers in a 6DOF environment isn’t a good idea just because the order does matter. So you cannot roll a plane by just increasing a certain angle.

What I do is to define an spin vector in the local coordinate system of the aircraft where the vectors direction denotes the spin axis and its length the angle.


spin.x = mController.getElevator() * mDesc.mKpitch;
spin.y = -mController.getRudder() * mDesc.mKyaw;
spin.z = -mController.getAileron() * mDesc.mKroll;

Later on, I scale this vector as I need it, make an AxisAngle out of it and multiply it to my transform.


axisangle.set( spin, spin.length() * dt );
rotation.set( axisangle );
mRot.mul( rotation );

How do you calculate “dt”?

Me? Oh, I always do things complicated…

A class ‘Ticker’ gets called from an object of class ‘Ticking’ that uses an object implementing ‘Clock’.

Ticker does this:

      /**
       * Ticking callback for the ticking object.
       */
      public void tick( long ticktime )
      {
            mTicks ++; 
        
        mDeltaT = ticktime - mCurrentTickTime;
        mCurrentTickTime = ticktime;

        //
        // Tell all listeners.
        //
        int listenercount = mListeners.size();
        for ( int i = listenercount-1; i >= 0; i-- )
        {
            ((TickerListener)mListeners.get( i )).tick( this );
        }
      }

The caller retrieves the necessary millisecond from a ‘Clock’ that is implemented like that:

public class HiResClock implements Clock
{
      private         long        mBaseMS = 0;
    
    /**
     * Creates a new instance of SystemClock.
     */
    public HiResClock()
    {
        adjust( 0 );
    }
 
    
    /** 
     * Check wether hires timer is available on this installation.
     */
    public final static boolean isAvailable()
    {
        try
        {
            ClassLoader.getSystemClassLoader().loadClass( "com.sun.j3d.utils.timer.J3DTimer" );
                  return true;
        }
        catch ( ClassNotFoundException cnfe )
        {
            return false;
        }
    }
    
    /** 
     * Adjust the clock to a certain value.
     * Calling <code>getCurrentTime()</code> immediately after <code>adjust()</code>
     * should return <code>refvalue</code>.
     */
    public void adjust(long refvalue)
    {        
        mBaseMS = getMS() - refvalue;
    }
    
    /**
     * The current time from the start in milliseconds.
     */
    public long getCurrentTime()
    {            
        return getMS() - mBaseMS;
    }
    
    
    /**
     * Internal time retrieval function.
     */
    private final long getMS()
    {
        return com.sun.j3d.utils.timer.J3DTimer.getValue() / 1000000;        
    }
    
}

cool :slight_smile:

I forgot, ‘Ticking’ is implemented by an Java3D Behavior that uses either WakeupOnElapsedFrames(0) or WakeupOnElapsedTime() for a 3D client.
For a server that needs to be ticked, I have a Thread-implementation right in place … :slight_smile: