Hi Anders,
It is because in addition to the previous two
attributes that you mention, the CubicSplineCurve also
fail to clone.
Please try the file in the attachment. If it didn't work,
please send us a test program and we will fix it in FCS.
Thanks.
- Kelvin
--------------------
Java 3D Team
Sun Microsystems Inc.
>X-Originating-IP: [137.222.217.98]
>From: "Anders Breivik" <[EMAIL PROTECTED]>
>To: [EMAIL PROTECTED], [EMAIL PROTECTED]
>Cc: [EMAIL PROTECTED]
>Subject: Re: [JAVA3D] cloneTree and CubicSplineCurve.getSegment !!!
>Date: Mon, 27 Mar 2000 22:03:44 CEST
>Mime-Version: 1.0
>
>Hello Again,
>
>Kevlin, regarding the cloneTree/TCBSplinePathInerpolator issue:
>I did like you said and replaced the TCBSplinePathInterpolator.java
>However, it now gives me a different NullPointerException:
>
>Exception occurred during Behavior execution:
>java.lang.NullPointerException:
> at
>com.sun.j3d.utils.behaviors.interpolators.CubicSplineCurve.getSegment
>(CubicSplineCurve.java:131)
> at
>com.sun.j3d.utils.behaviors.interpolators.RotPosScaleTCBSplinePathInt
>erpolator.processStimulus(RotPosScaleTCBSplinePathInterpolator.java:192)
> at javax.media.j3d.BehaviorScheduler.processBehaviors(Compiled Code)
> at javax.media.j3d.BehaviorScheduler.run(Compiled Code)
>
>
>
>Does some additional code have to be added to CubicSplineCurve.java as well?
>
>Hope to hear from you.
>
>Regards
>Anders
>
>
>
>>From: Kelvin Chung <[EMAIL PROTECTED]>
>>Reply-To: Kelvin Chung <[EMAIL PROTECTED]>
>>To: [EMAIL PROTECTED]
>>CC: [EMAIL PROTECTED]
>>Subject: Re: [JAVA3D] cloneTree and TCBSplinePathInterpolator !!!!
>>Date: Mon, 20 Mar 2000 11:13:35 -0800 (PST)
>>
>>Hi Anders:
>>
>> The class RotPosScaleTCBSplinePathInterpolator
>>
>>fail to duplicate the two attributes
>>
>>Alpha alpha, TCBKeyFrame keys[] of its parent class
>>
>> TCBSplinePathInterpolator
>>
>>since the parent class did not implement
>>
>> public void duplicateNode(Node originalNode, boolean forceDuplicate)
>>
>>
>>To fix the problem,
>>
>>
>>Please add the following function in TCBSplinePathInterpolator.java
>>
>>
>> public void duplicateNode(Node originalNode, boolean forceDuplicate) {
>> super.duplicateNode(originalNode, forceDuplicate);
>> TCBSplinePathInterpolator originalSpline = (TCBSplinePathInterpolator)
>>originalNode;
>> setAlpha(originalSpline.getAlpha());
>> keysLength = originalSpline.keysLength;
>> keyFrames = new TCBKeyFrame[keysLength];
>> System.arraycopy(originalSpline.keyFrames, 0,
>> keyFrames, 0, keysLength);
>> }
>>
>>
>>(You can find the source code of j3d utility in the distribution)
>>
>>
>>This bug will be fix in FCS version (but not in the upcoming v1.2 beta2).
>>
>>Thanks for your bug report.
>>
>>- Kelvin
>>
>>-----------
>>Java 3D Team
>>Sun Microsystems Inc.
>>
>>
>> >X-Originating-IP: [137.222.217.98]
>> >Mime-Version: 1.0
>> >Date: Sat, 18 Mar 2000 18:32:39 CET
>> >From: Anders Breivik <[EMAIL PROTECTED]>
>> >Subject: [JAVA3D] cloneTree and TCBSplinePathInterpolator !!!!
>> >To: [EMAIL PROTECTED]
>> >
>> >Hello everyone!
>> >
>> >I've got a java3d problem which really starts to annoy me, can anyone
>>please
>> >help me with the following:
>> >
>> >I've got a scene with a number of objects. Some of these objects have
>> >assosiated interpolators (RotPosScaleTCBSplinePathInterpolator)
>> >which create animations. The scene is loaded from lightwave (using
>> >lw3dLoader) which creates a BranchGroup representing the entire scene.
>> >I've used cloneTree to make a copy of this BranchGroup. (I whish to do
>>this
>> >because I do not want to reload the entire scene each time my game is
>> >restarted.) The problem is that the cloned branchgroup does NOT contain
>>the
>> >TCBKeyFrame data which makes TCBSplinePathInterpolator and
>> >RotPosScaleTCBSplinePathInterpolator work! The game starts up, but no
>> >objects in the scene are moving. It then gives a NullPointerException
>> >because the TBCKeyFrame array kontaines no data - no frames! Whats going
>> >on????? Am I missing something important or is this a BUG?
>> >
>> >I tried to work around this by accessing the TCBKeyFrame field
>>'keyFrames'
>> >but it is protected wihtin the class TCBSplinePathInterpolator
>> >
>> >Help, Help... What should I do?
>> >
>> >
>> >Regards
>> >Anders
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >______________________________________________________
>> >Get Your Private, Free Email at http://www.hotmail.com
>> >
>> >===========================================================================
>> >To unsubscribe, send email to [EMAIL PROTECTED] and include in the
>>body
>> >of the message "signoff JAVA3D-INTEREST". For general help, send email
>>to
>> >[EMAIL PROTECTED] and include in the body of the message "help".
>>
>
>______________________________________________________
>Get Your Private, Free Email at http://www.hotmail.com
>
/*
* %Z%%M% %I% %E% %U%
*
* Copyright (c) 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* 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 AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE 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 SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
package com.sun.j3d.utils.behaviors.interpolators;
import javax.media.j3d.*;
import java.util.*;
import javax.vecmath.*;
/**
* RotPosScaleTCBSplinePathInterpolator; A rotation and position path
* interpolation behavior node using Kochanek-Bartels cubic splines.
*
* @since Java3D 1.1
*/
/**
* 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.
*/
public class RotPosScaleTCBSplinePathInterpolator
extends TCBSplinePathInterpolator {
TransformGroup target;
Transform3D axis = new Transform3D();
Transform3D axisInverse = new Transform3D();
Transform3D rotation = new Transform3D();
Transform3D temp = new Transform3D();
Matrix4d tMat = new Matrix4d();
Matrix4d sMat = new Matrix4d();
Quat4f iQuat = new Quat4f(); // interpolated quaternion
Vector3f iPos = new Vector3f(); // interpolated position
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 axisOfRotPosScale 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 axisOfRotPosScale,
TCBKeyFrame keys[]) {
super(alpha, keys);
this.target = target;
axis.set(axisOfRotPosScale);
axisInverse.invert(axis);
// Create a spline curve using the derived key frames
cubicSplineCurve = new CubicSplineCurve(this.keyFrames);
numSegments = cubicSplineCurve.numSegments;
}
/**
* This method sets the axis of rotation, translation, and scale
* for this interpolator, RotPosScale, which defines the local
* coordinate system in which this interpolator operates.
* @param axisOfRotPosScale the interpolators axis of RotPosScale
*/
public void setAxisOfRotPosScale(Transform3D axisOfRotPosScale) {
this.axis.set(axisOfRotPosScale);
this.axisInverse.invert(this.axis);
}
/**
* This method retrieves this interpolator's axis of rotation, translation,
* and scale.
* @return the interpolator's axis of RotPosScale
*/
public Transform3D getAxisOfRotPosScale() {
return new Transform3D(this.axis);
}
/**
* This method sets the target TransformGroup for this interpolator.
* @param target the target TransformGroup reference
*/
public void setTarget(TransformGroup target) {
this.target = target;
}
/**
* This method retrieves this interpolator's target TransformGroup
* reference.
* @return the interpolator's target TransformGroup reference
*/
public TransformGroup getTarget() {
return target;
}
/*
* The RotPosScaleTCBSplinePathInterpolator's initialize routine uses
* the default initialization routine.
*/
/**
* This method is invoked by the behavior scheduler every frame. It maps
* the alpha value that corresponds to the current time into translation,
* rotation, and scale values, computes a transform based on these values,
* and updates the specified TransformGroup node with this new transform.
* @param criteria enumeration of criteria that have triggered this wakeup
*/
public void processStimulus(Enumeration criteria) {
/* Handle stimulus */
if (this.getAlpha() != null) {
// compute the current value of u from alpha and the
// determine lower and upper knot points
computePathInterpolation();
// 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();
// TODO: Vijay - Handle Non-Uniform scale
// Currently this interpolator does not handle non uniform scale
// We cheat by just taking the x scale component
sMat.set((double)iScale.x);
tMat.set(iQuat);
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
temp.mul(axis, rotation);
temp.mul(temp, axisInverse);
target.setTransform(temp);
}
wakeupOn(defaultWakeupCriterion);
}
// Needed so cloneTree will operate correctly
public Node cloneNode(boolean forceDuplicate) {
RotPosScaleTCBSplinePathInterpolator spline =
new RotPosScaleTCBSplinePathInterpolator();
spline.duplicateNode(this, forceDuplicate);
return spline;
}
public void duplicateNode(Node originalNode, boolean forceDuplicate) {
super.duplicateNode(originalNode, forceDuplicate);
RotPosScaleTCBSplinePathInterpolator interpolator =
(RotPosScaleTCBSplinePathInterpolator)originalNode;
setAxisOfRotPosScale(interpolator.axis);
target = interpolator.target;
cubicSplineCurve = new CubicSplineCurve(interpolator.keyFrames);
numSegments = cubicSplineCurve.numSegments;
}
public void updateNodeReferences(NodeReferenceTable refTable) {
TransformGroup tg =
(TransformGroup)refTable.getNewObjectReference(target);
setTarget(tg);
}
}