📄 cubicsplinesegment.java
字号:
/* * $RCSfile: CubicSplineSegment.java,v $ * * 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. * * $Revision: 1.4 $ * $Date: 2007/02/09 17:20:11 $ * $State: Exp $ */package com.sun.j3d.utils.behaviors.interpolators;import javax.media.j3d.*;import java.util.*;import javax.vecmath.*;/** * The CubicSplineSegment class creates the representation of a * TCB (Kochanek-Bartels Spline). This class takes 4 key frames as * its input (using TCBKeyFrame). If interpolating between the i<sup>th</sup> * and (i+1)<sup>th</sup> key frame then the four key frames that need to * be specified are the (i-1)<sup>th</sup>, i<sup>th</sup>, (i+1)<sup>th</sup> * and (i+2)<sup>th</sup> keyframes in order. The CubicSegmentClass * then pre-computes the hermite interpolation basis coefficients if the * (i+1)<sup>th</sup> frame has the linear flag set to zero. These are used to * calculate the interpolated position, scale and quaternions when they * requested by the user using the getInterpolated* methods. If the the * (i+1)<sup>th</sup> frame's linear flag is set to 1 then the class uses * linear interpolation to calculate the interpolated position, sccale and * quaternions it returns through the getInterpolated* methods. * * @since Java3D 1.1 */public class CubicSplineSegment { // Legendre polynomial information for Gaussian quadrature of speed // for the domain [0,u], 0 <= u <= 1. // Legendre roots mapped to (root+1)/2 static final double modRoot[] = { 0.046910077, 0.230765345, 0.5, 0.769234655, 0.953089922 }; // original coefficients divided by 2 static final double modCoeff[] = { 0.118463442, 0.239314335, 0.284444444, 0.239314335, 0.118463442 }; // Key Frames TCBKeyFrame[] keyFrame = new TCBKeyFrame[4]; // H.C Point3f c0, c1, c2, c3; // coefficients for position Point3f e0, e1, e2, e3; // coefficients for scale // variables for destination derivative float one_minus_t_in; float one_minus_c_in; float one_minus_b_in; float one_plus_c_in; float one_plus_b_in; float ddb; float dda; // variables for source derivative float one_minus_t_out; float one_minus_c_out; float one_minus_b_out; float one_plus_c_out; float one_plus_b_out; float dsb; float dsa; // Length of the spline segment float length; // interpolation type int linear; /** * Default constructor */ CubicSplineSegment () { length = 0; } /** * Creates a cubic spline segment between two key frames using the * key frames provided. If creating a spline between the ith frame and * the (i+1)<sup>th</sup> frame then send down the (i - 1)<sup>th</sup>, * i<sup>th</sup> , (i+1)<sup>th</sup> and the (i+2)<sup>th</sup> key * frames. * * @param kf0 (i - 1)<sup>th</sup> Key Frame * @param kf1 i<sup>th</sup> Key Frame * @param kf2 (i + 1)<sup>th</sup> Key Frame * @param kf3 (i + 2)<sup>th</sup> Key Frame */ CubicSplineSegment (TCBKeyFrame kf0, TCBKeyFrame kf1, TCBKeyFrame kf2, TCBKeyFrame kf3) { // Copy KeyFrame information keyFrame[0] = new TCBKeyFrame(kf0); keyFrame[1] = new TCBKeyFrame(kf1); keyFrame[2] = new TCBKeyFrame(kf2); keyFrame[3] = new TCBKeyFrame(kf3); // if linear interpolation is requested then just set linear flag // if spline interpolation is needed then compute spline coefficients if (kf2.linear == 1) { this.linear = 1; } else { this.linear = 0; computeCommonCoefficients (kf0, kf1, kf2, kf3); computeHermiteCoefficients (kf0, kf1, kf2, kf3); } length = computeLength (1.0f); // System.out.println ("Segment length = " + length); } // compute the common coefficients private void computeCommonCoefficients (TCBKeyFrame kf0, TCBKeyFrame kf1, TCBKeyFrame kf2, TCBKeyFrame kf3) { // variables for destination derivative float one_minus_t_in = 1.0f - kf1.tension; float one_minus_c_in = 1.0f - kf1.continuity; float one_minus_b_in = 1.0f - kf1.bias; float one_plus_c_in = 1.0f + kf1.continuity; float one_plus_b_in = 1.0f + kf1.bias; // coefficients for the incoming Tangent ddb = one_minus_t_in * one_minus_c_in * one_minus_b_in; dda = one_minus_t_in * one_plus_c_in * one_plus_b_in; // variables for source derivative float one_minus_t_out = 1.0f - kf2.tension; float one_minus_c_out = 1.0f - kf2.continuity; float one_minus_b_out = 1.0f - kf2.bias; float one_plus_c_out = 1.0f + kf2.continuity; float one_plus_b_out = 1.0f + kf2.bias; // coefficients for the outgoing Tangent dsb = one_minus_t_in * one_plus_c_in * one_minus_b_in; dsa = one_minus_t_in * one_minus_c_in * one_plus_b_in; } // compute the hermite interpolation basis coefficients private void computeHermiteCoefficients (TCBKeyFrame kf0, TCBKeyFrame kf1, TCBKeyFrame kf2, TCBKeyFrame kf3) { Point3f deltaP = new Point3f(); Point3f deltaS = new Point3f(); // Find the difference in position and scale deltaP.x = kf2.position.x - kf1.position.x; deltaP.y = kf2.position.y - kf1.position.y; deltaP.z = kf2.position.z - kf1.position.z; deltaS.x = kf2.scale.x - kf1.scale.x; deltaS.y = kf2.scale.y - kf1.scale.y; deltaS.z = kf2.scale.z - kf1.scale.z; // Incoming Tangent Point3f dd_pos = new Point3f(); Point3f dd_scale = new Point3f(); // If this is the first keyframe of the animation if (kf0.knot == kf1.knot) { float ddab = 0.5f * (dda + ddb); // Position dd_pos.x = ddab * deltaP.x; dd_pos.y = ddab * deltaP.y; dd_pos.z = ddab * deltaP.z; // Scale dd_scale.x = ddab * deltaS.x; dd_scale.y = ddab * deltaS.y; dd_scale.z = ddab * deltaS.z; } else { float adj0 = (kf1.knot - kf0.knot)/(kf2.knot - kf0.knot); // Position dd_pos.x = adj0 * ((ddb * deltaP.x) + (dda * (kf1.position.x - kf0.position.x))); dd_pos.y = adj0 * ((ddb * deltaP.y) + (dda * (kf1.position.y - kf0.position.y))); dd_pos.z = adj0 * ((ddb * deltaP.z) + (dda * (kf1.position.z - kf0.position.z))); // Scale dd_scale.x = adj0 * ((ddb * deltaS.x) + (dda * (kf1.scale.x - kf0.scale.x))); dd_scale.y = adj0 * ((ddb * deltaS.y) + (dda * (kf1.scale.y - kf0.scale.y))); dd_scale.z = adj0 * ((ddb * deltaS.z) + (dda * (kf1.scale.z - kf0.scale.z))); } // Outgoing Tangent Point3f ds_pos = new Point3f(); Point3f ds_scale = new Point3f(); // If this is the last keyframe of the animation if (kf2.knot == kf3.knot) { float dsab = 0.5f * (dsa + dsb); // Position ds_pos.x = dsab * deltaP.x; ds_pos.y = dsab * deltaP.y;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -