All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.j3d.utils.behaviors.interpolators.KBRotPosScaleSplinePathInterpolator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistribution of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed, licensed or
 * intended for use in the design, construction, operation or
 * maintenance of any nuclear facility.
 *
 */

package com.sun.j3d.utils.behaviors.interpolators;

import javax.media.j3d.Alpha;
import javax.media.j3d.Node;
import javax.media.j3d.NodeComponent;
import javax.media.j3d.RestrictedAccessException;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;


/**
 * KBRotPosScaleSplinePathInterpolator; A rotation and position path
 * interpolation behavior node using Kochanek-Bartels cubic splines
 * (also known as TCB or Tension-Continuity-Bias Splines).
 *
 * @since Java3D 1.2
 */

/**
 * KBRotPosScaleSplinePathInterpolator behavior.  This class defines a
 * behavior that varies the rotational, translational, and scale components
 * of its target TransformGroup by using the Kochanek-Bartels cubic spline
 * interpolation to interpolate among a series of key frames
 * (using the value generated by the specified Alpha object).  The
 * interpolated position, orientation, and scale are used to generate
 * a transform in the local coordinate system of this interpolator.
 */

public class KBRotPosScaleSplinePathInterpolator
                                        extends KBSplinePathInterpolator {

    private Transform3D    rotation    = new Transform3D();

    private Matrix4d       pitchMat    = new Matrix4d();   // pitch matrix
    private Matrix4d       bankMat     = new Matrix4d();   // bank matrix
    private Matrix4d       tMat        = new Matrix4d();   // transformation matrix
    private Matrix4d       sMat        = new Matrix4d();   // scale matrix
    //Quat4f         iQuat       = new Quat4f();     // interpolated quaternion
    private Vector3f       iPos        = new Vector3f();   // interpolated position
    private Point3f        iScale      = new Point3f();    // interpolated scale
    float          iHeading, iPitch, iBank;        // interpolated heading,
                                                   // pitch and bank

    KBCubicSplineCurve   cubicSplineCurve = new KBCubicSplineCurve();
    KBCubicSplineSegment cubicSplineSegments[];
    int                  numSegments;
    int                  currentSegmentIndex;
    KBCubicSplineSegment currentSegment;

    // non-public, default constructor used by cloneNode
    KBRotPosScaleSplinePathInterpolator() {
    }

    /**
      * Constructs a new KBRotPosScaleSplinePathInterpolator object that
      * varies the rotation, translation, and scale of the target
      * TransformGroup's transform.  At least 2 key frames are required for
      * this interpolator. The first key
      * frame's knot must have a value of 0.0 and the last knot must have a
      * value of 1.0.  An intermediate key frame with index k must have a
      * knot value strictly greater than the knot value of a key frame with
      * index less than k.
      * @param alpha the alpha object for this interpolator
      * @param target the TransformGroup node affected by this interpolator
      * @param axisOfTransform the transform that specifies the local
      * coordinate system in which this interpolator operates.
      * @param keys an array of key frames that defien the motion path
      */
    public KBRotPosScaleSplinePathInterpolator(Alpha alpha,
				       TransformGroup target,
				       Transform3D axisOfTransform,
				       KBKeyFrame keys[]) {
	super(alpha,target, axisOfTransform, keys);

        // Create a spline curve using the derived key frames
        cubicSplineCurve = new KBCubicSplineCurve(this.keyFrames);
        numSegments = cubicSplineCurve.numSegments;

    }

    /**
     * @deprecated As of Java 3D version 1.3, replaced by
     * TransformInterpolator.setTransformAxis(Transform3D)
     */
    public void setAxisOfRotPosScale(Transform3D axisOfRotPosScale) {
        setTransformAxis(axisOfRotPosScale);
    }

    /**
     * @deprecated As of Java 3D version 1.3, replaced by
     * TransformInterpolator.getTransformAxis()
     */
    public Transform3D getAxisOfRotPosScale() {
        return getTransformAxis();
    }

    /**
     * Set the key frame at the specified index to keyFrame
     * @param index Index of the key frame to change
     * @param keyFrame The new key frame
     */
    @Override
    public void setKeyFrame( int index, KBKeyFrame keyFrame ) {
	super.setKeyFrame( index, keyFrame );

	// TODO Optimize this
        // Create a spline curve using the derived key frames
        cubicSplineCurve = new KBCubicSplineCurve(this.keyFrames);
        numSegments = cubicSplineCurve.numSegments;
    }

    /**
     * Set all the key frames
     * @param keyFrame The new key frames
     */
    @Override
    public void setKeyFrames( KBKeyFrame[] keyFrame ) {
	super.setKeyFrames( keyFrame );

        // Create a spline curve using the derived key frames
        cubicSplineCurve = new KBCubicSplineCurve(this.keyFrames);
        numSegments = cubicSplineCurve.numSegments;
    }

    /**
     * Computes the new transform for this interpolator for a given
     * alpha value.
     *
     * @param alphaValue alpha value between 0.0 and 1.0
     * @param transform object that receives the computed transform for
     * the specified alpha value
     *
     * @since Java 3D 1.3
     */
    @Override
    public void computeTransform(float alphaValue, Transform3D transform) {
	// compute the current value of u from alpha and the
	// determine lower and upper knot points
	computePathInterpolation( alphaValue );

	// Determine the segment within which we will be interpolating
	currentSegmentIndex = this.lowerKnot - 1;

	// if we are at the start of the curve
	if (currentSegmentIndex == 0 && currentU == 0f) {

	    iHeading = keyFrames[1].heading;
	    iPitch = keyFrames[1].pitch;
	    iBank = keyFrames[1].bank;
	    iPos.set(keyFrames[1].position);
	    iScale.set(keyFrames[1].scale);

            // if we are at the end of the curve
	} else if (currentSegmentIndex == (numSegments-1) &&
		   currentU == 1.0) {

	    iHeading = keyFrames[upperKnot].heading;
	    iPitch = keyFrames[upperKnot].pitch;
	    iBank = keyFrames[upperKnot].bank;
	    iPos.set(keyFrames[upperKnot].position);
	    iScale.set(keyFrames[upperKnot].scale);

            // if we are somewhere in between the curve
	} else {

	    // Get a reference to the current spline segment i.e. the
	    // one bounded by lowerKnot and upperKnot
	    currentSegment
		= cubicSplineCurve.getSegment(currentSegmentIndex);

	    // interpolate quaternions
	    iHeading = currentSegment.getInterpolatedHeading (currentU);
	    iPitch = currentSegment.getInterpolatedPitch (currentU);
	    iBank = currentSegment.getInterpolatedBank (currentU);

	    // interpolate position
	    currentSegment.getInterpolatedPositionVector(currentU,iPos);

	    // interpolate position
	    currentSegment.getInterpolatedScale(currentU,iScale);

	}

	// Generate a transformation matrix in tMat using interpolated
	// heading, pitch and bank
	pitchMat.setIdentity();
	pitchMat.rotX(-iPitch);
	bankMat.setIdentity();
	bankMat.rotZ(iBank);
	tMat.setIdentity();
	tMat.rotY(-iHeading);
	tMat.mul(pitchMat);
	tMat.mul(bankMat);

	// TODO: Handle Non-Uniform scale
	// Currently this interpolator does not handle non uniform scale
	// We cheat by just taking the x scale component

	// Scale the transformation matrix
	sMat.set((double)iScale.x);
	tMat.mul(sMat);

	// Set the translation components.
	tMat.m03 = iPos.x;
	tMat.m13 = iPos.y;
	tMat.m23 = iPos.z;
	rotation.set(tMat);

	// construct a Transform3D from:  axis * rotation * axisInverse
	transform.mul(axis, rotation);
	transform.mul(transform, axisInverse);
    }

    /**
     * Copies KBRotPosScaleSplinePathInterpolator information from
     * originalNode into
     * the current node.  This method is called from the
     * cloneNode method which is, in turn, called by the
     * cloneTree method.

* * @param forceDuplicate when set to true, causes the * duplicateOnCloneTree flag to be ignored. When * false, the value of each node's * duplicateOnCloneTree variable determines whether * NodeComponent data is duplicated or copied. * * @exception RestrictedAccessException if this object is part of a live * or compiled scenegraph. * * @see Node#duplicateNode * @see Node#cloneTree * @see NodeComponent#setDuplicateOnCloneTree */ @Override public Node cloneNode(boolean forceDuplicate) { KBRotPosScaleSplinePathInterpolator spline = new KBRotPosScaleSplinePathInterpolator(); spline.duplicateNode(this, forceDuplicate); return spline; } /** * Copies KBRotPosScaleSplinePathInterpolator information from * originalNode into * the current node. This method is called from the * cloneNode method which is, in turn, called by the * cloneTree method.

* * @param originalNode the original node to duplicate. * @param forceDuplicate when set to true, causes the * duplicateOnCloneTree flag to be ignored. When * false, the value of each node's * duplicateOnCloneTree variable determines whether * NodeComponent data is duplicated or copied. * * @exception RestrictedAccessException if this object is part of a live * or compiled scenegraph. * * @see Node#duplicateNode * @see Node#cloneTree * @see NodeComponent#setDuplicateOnCloneTree */ @Override public void duplicateNode(Node originalNode, boolean forceDuplicate) { super.duplicateNode(originalNode, forceDuplicate); KBRotPosScaleSplinePathInterpolator interpolator = (KBRotPosScaleSplinePathInterpolator)originalNode; setAxisOfRotPosScale(interpolator.axis); target = interpolator.target; cubicSplineCurve = new KBCubicSplineCurve(interpolator.keyFrames); numSegments = cubicSplineCurve.numSegments; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy