com.sun.j3d.utils.behaviors.interpolators.RotPosScaleTCBSplinePathInterpolator Maven / Gradle / Ivy
Show all versions of java3d-core Show documentation
/*
* 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.Quat4f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;
/**
* RotPosScaleTCBSplinePathInterpolator 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.
*
* @since Java3D 1.1
*/
public class RotPosScaleTCBSplinePathInterpolator
extends TCBSplinePathInterpolator {
private Transform3D rotation = new Transform3D();
private Matrix4d tMat = new Matrix4d();
private Matrix4d sMat = new Matrix4d();
private Quat4f iQuat = new Quat4f(); // interpolated quaternion
private Vector3f iPos = new Vector3f(); // interpolated position
private Point3f iScale = new Point3f(); // interpolated scale
CubicSplineCurve cubicSplineCurve = new CubicSplineCurve();
CubicSplineSegment cubicSplineSegments[];
int numSegments;
int currentSegmentIndex;
CubicSplineSegment currentSegment;
// non-public, default constructor used by cloneNode
RotPosScaleTCBSplinePathInterpolator() {
}
/**
* Constructs a new RotPosScaleTCBSplinePathInterpolator 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 RotPosScaleTCBSplinePathInterpolator(Alpha alpha,
TransformGroup target,
Transform3D axisOfTransform,
TCBKeyFrame keys[]) {
super(alpha, target, axisOfTransform, keys);
// Create a spline curve using the derived key frames
cubicSplineCurve = new CubicSplineCurve(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();
}
/**
* 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) {
iQuat.set(keyFrames[1].quat);
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) {
iQuat.set(keyFrames[upperKnot].quat);
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
currentSegment.getInterpolatedQuaternion(currentU,iQuat);
// interpolate position
currentSegment.getInterpolatedPositionVector(currentU,iPos);
// interpolate position
currentSegment.getInterpolatedScale(currentU,iScale);
}
// Alway normalize the quaternion
iQuat.normalize();
tMat.set(iQuat);
// 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.setScale(new Vector3d(iScale));
transform.mul(transform, axisInverse);
}
/**
* Used to create a new instance of the node. This routine is called
* by cloneTree
to duplicate the current node.
* @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.
*
* @see Node#cloneTree
* @see Node#cloneNode
* @see Node#duplicateNode
* @see NodeComponent#setDuplicateOnCloneTree
*/
@Override
public Node cloneNode(boolean forceDuplicate) {
RotPosScaleTCBSplinePathInterpolator spline =
new RotPosScaleTCBSplinePathInterpolator();
spline.duplicateNode(this, forceDuplicate);
return spline;
}
/**
* Copies RotPosScaleTCBSplinePathInterpolator 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);
RotPosScaleTCBSplinePathInterpolator interpolator =
(RotPosScaleTCBSplinePathInterpolator)originalNode;
cubicSplineCurve = new CubicSplineCurve(interpolator.keyFrames);
numSegments = cubicSplineCurve.numSegments;
}
}