6 Replies - 6310 Views - Last Post: 31 May 2011 - 07:08 AM Rate Topic: -----

#1 digithree  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 35
  • Joined: 20-September 07

Java 3D rotation on x or z axis question

Posted 25 May 2011 - 04:11 PM

Hi, I'm currently trying to get to grips with the Java 6 3D API and so far it's going pretty well. However, I've run into a problem that I can't figure out myself and can't find an answer to online.

I want to animate a group of objects rotating around the z axis. I tried to do this by using the RotationInterpolator class which takes in (at least) an Alpha class (timer) and TransformGroup (the objects to rotate).

Here's a conceptual scene graph of my object structure:
Posted Image

The rotation itself is pretty simple to achieve but unfortunately I can't figure out how to rotate around any axis other that the y axis. Here's the code I have right now:

// SphereRing is a collection of SphereObject classes (which inherit the object Sphere)
sphereRings[nextSphereRing] = new SphereRing( radius );
// The method getTG() returns the TransformGroup. This TransformGroup contains each individual SphereObjects TransformGroup as children (see concept graph above)
// variable masterTG is a TransformGroup
masterTG.addChild( sphereRings[nextSphereRing].getTG() );

// create time varying function to drive the animation, on infinite loop with a 4sec calling interval
Alpha rotationAlpha = new Alpha(-1, 4000);

RotationInterpolator rotator = new RotationInterpolator( rotationAlpha, sphereRings[nextSphereRing].getTG() );

// a bounding sphere specifies a region a behavior is active
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);

masterTG.addChild(rotator);
// variable scene is a BranchGroup
scene.addChild(masterTG);
scene.compile();
// variable simpleU is a SimpleUniverse
simpleU.addBranchGraph(scene);

The Java documentation says that in RotationInterpolator, "[t]he interpolated angle is used to generate a rotation transform about the local Y-axis of this interpolator." So is the case that this object can only rotate around this axis?

From searching online I've found several posts on the Java.net forum and other forums but these deal with adding another axis of rotation as opposed to changing it to another.

I noticed that in the tutorial I'm mainly working from, Getting Started with the Java 3D API, the authour says of behaviours (which are ancestor classes of interpolators) "All of the mentioned behaviors are possible without using an interpolator; however, interpolators make creating a behavior much easier." Perhaps the scope of RotateInterpolator is only a rough and ready y axis rotator?

In the description of the RotationInterpolar short constructor, a variable in the long constructor - axisOfTranform - is by "set to identity". So perhaps by changing this matrix I can change the axis? I'll behonest, I don't quite understand how to do this, even after reading a stackoverflow forum thread which describes a similar problem.

Can anyone clear this up for me?

Is This A Good Question/Topic? 0
  • +

Replies To: Java 3D rotation on x or z axis question

#2 nick2price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 562
  • View blog
  • Posts: 2,826
  • Joined: 23-November 07

Re: Java 3D rotation on x or z axis question

Posted 25 May 2011 - 06:29 PM

Is this one of the answers you refered to, or can this be used in your situation? It uses Quaternions
private final Vector3f yAxis = new Vector3f(0f, 1f, 0f);
private Vector3f direction; 

private void rotateCone() {
        // Get the normalized axis perpendicular to the direction 
        Vector3f axis = new Vector3f();
        axis.cross(yAxis, direction);
        axis.normalize();

        // When the intended direction is a point on the yAxis, rotate on x
        if (Float.isNaN(axis.x) && Float.isNaN(axis.y) && Float.isNaN(axis.z)) 
        {
            axis.x = 1f;
            axis.y = 0f;
            axis.z = 0f;
        }
        // Compute the quaternion transformations
        final float angleX = yAxis.angle(direction);
        final float a = axis.x * (float) Math.sin(angleX / 2f);
        final float b = axis.y * (float) Math.sin(angleX / 2f);
        final float c = axis.z * (float) Math.sin(angleX / 2f);
        final float d = (float) Math.cos(angleX / 2f);

        Transform3D t3d = new Transform3D();
        Quat4f quat = new Quat4f(a, b, c, d);
        t3d.set(quat);
        arrowheadRotationGroup.setTransform(t3d);

        Transform3D translateToTarget = new Transform3D();
        translateToTarget.setTranslation(this.direction);
        arrowheadPositionGroup.setTransform(translateToTarget);
    }


Was This Post Helpful? 1
  • +
  • -

#3 digithree  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 35
  • Joined: 20-September 07

Re: Java 3D rotation on x or z axis question

Posted 26 May 2011 - 08:16 AM

No, I haven't seen that code before. It's an interesting algorithm, thank you for posting it. But can I ask a few questions about the code?

Firstly, forgive my ignorance, but when using Java 3D are you supposed to use two different Transform3D classes, one for the position in 3D space (in the example the variable arrowheadRotationGroup) and one for the rotation information (arrowheadPositionGroup)?

Also, in the statement "translateToTarget.setTranslation(this.direction);" why did you use the this keyword where before you just used the variable direction by itself? Is this the same variable (named direction) or one of a class not described in the example?

And can I ask, where did you get this code?

Thank you for your time
Was This Post Helpful? 0
  • +
  • -

#4 digithree  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 35
  • Joined: 20-September 07

Re: Java 3D rotation on x or z axis question

Posted 26 May 2011 - 08:36 AM

Sorry, thought of another question. The variable direction, which is a Vector3f class, would you set the values to (0f, 0f, 1f) if you wanted to rotate about the z axis?

Thanks again
Was This Post Helpful? 0
  • +
  • -

#5 digithree  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 35
  • Joined: 20-September 07

Re: Java 3D rotation on x or z axis question

Posted 31 May 2011 - 05:30 AM

I fixed this problem myself, just thought I'd upload the solution for the benefit of other lost souls :online2long:
Was This Post Helpful? 0
  • +
  • -

#6 digithree  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 35
  • Joined: 20-September 07

Re: Java 3D rotation on x or z axis question

Posted 31 May 2011 - 06:27 AM

I've solved this problem myself and just thought I'd share the solution for the benefit of another lost soul :online2long:

The solution was to add a custom update() method to the SphereRing class that would rotate the Transform matrix like this:
public void update() {
        // rotate ring
        // baseTG is base TransformGroup who's children are SphereObject TransformGroups
        // t3d and rotT3d are temp Transform3D for calculations
        baseTG.getTransform(t3d);  // get current rotation
        rotT3d.setIdentity();      // reset the rotation transform object
        rotT3d.rotZ(ROTATE_AMT);   // rotate ROTATE_AMT radians on Z-axis
        t3d.mul(rotT3d);            // 'add' new rotation to current one
        baseTG.setTransform(t3d);   // update the TG
    }


This method is called periodically with a custom Timebehavior class (which extends the behavior class). I modified mine from an example program called Life3D by Dr. Andrew Davison
import java.util.Enumeration;
import javax.media.j3d.*;

public class Timebehavior extends behavior
{
  private WakeupCondition timeOut;
  private int timeDelay;
  // replace SphereRing class with whatever class that makes the rotation
  private SphereRing thisSphereRing;

  public Timebehavior(int td, SphereRing sr)
  { 
    timeDelay = td; 
    thisSphereRing = sr;
    timeOut = new WakeupOnElapsedTime(timeDelay);
  }
  
  public SphereRing getSphereRing()
  { return thisSphereRing; }

    @Override
  public void initialize()
  { wakeupOn(timeOut); }
  
    @Override
  public void processStimulus(Enumeration criteria)
  {
    thisSphereRing.update();      // ignore criteria
    wakeupOn(timeOut);
  }


Finally, in order for this behavior to be active within your 3D world, you need to set it's schedulling bounds. I achieved it with this fragment, which is inserted in my createSphereRing() method in the main program class (which is called by createSceneGraph()):
//sphereRingTimebehavior[] is a Timebehavior array. masterTG is the parent TransformGroup for SphereRings
sphereRingTimebehavior[nextSphereRing] = new Timebehavior(TIME_DELAY,newSphereRing);
sphereRingTimebehavior[nextSphereRing].setSchedulingBounds(bounds);
masterTG.addChild( sphereRingTimebehavior[nextSphereRing] );


I'm not sure if this is the fastest way to this. Obviously the Java3D engine is unable to perform it's mysterious optimisations on any code I write so perhaps using RotationInterpolator is the best solution but I can't figure out how to use it properly... :whistling: This solution will have to do for now. I would love to see a different solution if anyone has one! Ta :sweatdrop:
Was This Post Helpful? 1
  • +
  • -

#7 nick2price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 562
  • View blog
  • Posts: 2,826
  • Joined: 23-November 07

Re: Java 3D rotation on x or z axis question

Posted 31 May 2011 - 07:08 AM

If you are interested, I obtained that code from
HERE

From what they say,

Quote

I'm just learning Java 3D myself at the moment, and from my current knowledge, the rotation methods set the transform to a rotation about that axis only. Therefore, if you wish to perform rotations about multiple axes, then you will need to use a second Transform3D.

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1