⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lwsmotion.java

📁 JAVA3D矩陈的相关类
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * $RCSfile: LwsMotion.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:09 $ * $State: Exp $ */package com.sun.j3d.loaders.lw3d;import java.io.*;import java.util.Enumeration;import java.util.Vector;import javax.media.j3d.*;import javax.vecmath.*;import com.sun.j3d.utils.behaviors.interpolators.*;import com.sun.j3d.internal.J3dUtilsI18N;import com.sun.j3d.loaders.ParsingErrorException;import com.sun.j3d.loaders.IncorrectFormatException;/** * This class is responsible for parsing the data in a Scene file related to * an object's animation and constructing the appropriate Java3D * Behavior objects. For each keyframe defined for the animation in the * Lightwave file, this class creates a LwsFrame object to parse that * keyframe data and create the appropriate data structures. Then for * each of those LwsFrame objects created, LwsMotion creates a knot * value for a PathInterpolator and fills in the appropriate field. Finally, * the class creates a RotPosScalePathInterpolator with all of the data * from the animation. There are also some utility functions in this * class for dealing with special cases of animations, such as animations * that begin after the first frame of the scene and animations that * define frames in a way that Java3D cannot easily interpret. */class LwsMotion extends TextfileParser {    // data from the file    String motionName;    LwsFrame frames[];    int numFrames;    int numChannels;    boolean loop;    float totalTime;    int firstFrame;    int totalFrames;    Behavior behaviors;    /**     * Constructor     */    LwsMotion(StreamTokenizer st, int frames, float time) {        this(st, 0, frames, time, EXCEPTION);    }    /**     * Constructor: takes tokenizer, 1st frame of this animation, total     * number of frames, total time of animation, and the debug settings     */    LwsMotion(StreamTokenizer st, int firstFrame,		     int frames, float time, int debugVals)	throws ParsingErrorException, IncorrectFormatException {        debugPrinter.setValidOutput(debugVals);	numFrames = 0;	totalTime = time;	this.firstFrame = firstFrame;	totalFrames = frames;	debugOutputLn(LINE_TRACE, "about to get motion name");	motionName = getName(st);	debugOutputLn(LINE_TRACE, "about to get motion");	getMotion(st);    }    /**     * This method parses the tokenizer and creates the data structures     * that hold the data from that file.  For each separate keyframe,     * this method calls LwsFrame to parse and interpret that data.     */    void getMotion(StreamTokenizer st)	throws ParsingErrorException, IncorrectFormatException    {	debugOutputLn(TRACE, "getMotion()");	numChannels = (int)getNumber(st);	if (numChannels != 9) {	    throw new IncorrectFormatException(		J3dUtilsI18N.getString("LwsMotion0"));	}	debugOutputLn(LINE_TRACE, "got channels");	numFrames = (int)getNumber(st);	frames = new LwsFrame[numFrames];	debugOutputLn(VALUES, "got frames" + numFrames);	for (int i = 0; i < numFrames; ++i) {	    frames[i] = new LwsFrame(st);	}	debugOutput(LINE_TRACE, "got all frames");	getAndCheckString(st, "EndBehavior");	int repeatVal = (int)getNumber(st);	if (repeatVal == 1)	    loop = false;	else	    loop = true;	// need to make sure frame info is in sycn with j3d  	// fixFrames();    }    /**      * The previous version of this method looked for sucessive frames with      * the same rotation value (mod 2PI).  If it found such frames, it would      * divide that interval into 4 separate frames.      * This fix is not sufficient for various rotation cases, though.  For      * instance, if the rotation difference between two frames is more than      * 2PI, the rotation will not case a flag to be fixed and the resulting      * rotation will only be between the delta of the two rotations, mod 2PI.      * The real fix should behave as follows:      * - Iterate through all sucessive frames      * - For any two frames that have rotation components that differ by more      * than PI/2 (one quarter rotation - no reason for this, but let's pick a      * small value to give our resulting path interpolations a better chance      * of behaving correctly), figure out how many frames we need to create to      * get increments of <= PI/2 between each frame.        * - Create these new frames      * - Set the odl frames pointer to the new frames structures.      */    void fixFrames() {	boolean  addedFrames   = false;	Vector   newFramesList = new Vector();	double   halfPI        = (float)(Math.PI/2);	LwsFrame finalFrame    = null;	for (int i = 1 ; i < numFrames; ++i) {           LwsFrame prevFrame;	   LwsFrame lastFrame = frames[i-1];	   LwsFrame thisFrame = frames[i];           LwsFrame nextFrame;	   finalFrame = thisFrame;	   newFramesList.add(lastFrame);	   double largestAngleDifference = 0;	   double thisAngle = thisFrame.getHeading();	   double lastAngle = lastFrame.getHeading();	   double angleDifference = Math.abs(thisAngle - lastAngle);	   if (angleDifference > largestAngleDifference) 	     largestAngleDifference = angleDifference;	   thisAngle = thisFrame.getPitch();	   lastAngle = lastFrame.getPitch();	   angleDifference = Math.abs(thisAngle - lastAngle);	   if (angleDifference > largestAngleDifference) 	     largestAngleDifference = angleDifference;	   thisAngle = thisFrame.getBank();	   lastAngle = lastFrame.getBank();	   angleDifference = Math.abs(thisAngle - lastAngle);	   if (angleDifference > largestAngleDifference) 	     largestAngleDifference = angleDifference;	   if (largestAngleDifference > halfPI) {		// Angles too big - create new frames 		addedFrames = true;		int numNewFrames = (int)(largestAngleDifference/halfPI);		double increment = 1.0/(double)(numNewFrames+1);		double currentRatio = increment;                double totalf = frames[numFrames-1].getFrameNum();                double tlength = (thisFrame.getFrameNum() -                                             lastFrame.getFrameNum())/totalf;                double adj0;                 double adj1;                 // get the previous and next frames                 if ((i-1) < 1) {                    prevFrame = frames[i-1];                   adj0 = 0.0;                } else {                   prevFrame = frames[i-2];                   adj0 = tlength/((thisFrame.getFrameNum() -                                          prevFrame.getFrameNum())/totalf);                 }                if ((i+1) < numFrames) {                   nextFrame = frames[i+1];                   adj1 = tlength/((nextFrame.getFrameNum()-                                          lastFrame.getFrameNum())/totalf);                  } else {                   nextFrame = frames[i];                   adj1 = 1.0;                 }		for (int j = 0; j < numNewFrames; ++j) {                   LwsFrame newFrame;                   // if linear interpolation                   if (thisFrame.linearValue == 1) {  	              newFrame = new LwsFrame(lastFrame,                                               thisFrame, currentRatio);			                             // if spline interpolation                    } else {		      newFrame = new LwsFrame(prevFrame, lastFrame,                                               thisFrame, nextFrame,                                               currentRatio, adj0, adj1);                    } 		    currentRatio += increment;		    newFramesList.add(newFrame);		}	   }	}	// Now add in final frame	if (finalFrame != null)		newFramesList.add(finalFrame);	if (addedFrames) {		// Recreate frames array from newFramesList		LwsFrame newFrames[] = new LwsFrame[newFramesList.size()];		Enumeration elements = newFramesList.elements();		int index = 0;		while (elements.hasMoreElements()) {			newFrames[index++] = (LwsFrame)elements.nextElement();		}		frames = newFrames;		numFrames = frames.length;		for (int i = 0; i < numFrames; ++i) {		   debugOutputLn(VALUES, "frame " + i + " = " + frames[i]);		   frames[i].printVals();		}	}    }    /**     * Utility for getting integer mod value     */    int intMod(int divisee, int divisor) {	int tmpDiv = divisee;	int tmpDivisor = divisor;	if (tmpDiv < 0)	    tmpDiv = -tmpDiv;	if (tmpDivisor < 0)	    tmpDivisor = -tmpDivisor;	while (tmpDiv > tmpDivisor) {	    tmpDiv -= tmpDivisor;	}	return tmpDiv;    }    /**     * Class that associates a particular frame with its effective frame     * number (which accounts for animations that start after frame 1)     */    class FrameHolder {	double frameNumber;	LwsFrame frame;	FrameHolder(LwsFrame theFrame, double number) {	    frame = theFrame;	    frameNumber = number;	}    }        /**     * This method was added to account for animations that start after     * the first frame (e.g., Juggler.lws starts at frame 30).  We need     * to alter some of the information for the frames in this "frame subset"     */    void playWithFrameTimes(Vector framesVector) {	debugOutputLn(TRACE, "playWithFrameTimes: firstFrame = " +		      firstFrame);	if (firstFrame == 1) {	    return;	}	else if (frames[numFrames-1].getFrameNum() < totalFrames) {	    // First, create a vector that holds all LwsFrame's in frame	    // increasing order (where order is started at firstFrame Modulo	    // this motion's last frame	    int motionLastFrame =		(int)(frames[numFrames-1].getFrameNum() + .4999999);	    int newFirstFrame = intMod(firstFrame, motionLastFrame);	    int newLastFrame = intMod(totalFrames, motionLastFrame);	    int index = 0;	    while (index < numFrames) {		if (frames[index].getFrameNum() >= newFirstFrame)		    break;		++index;	    }	    int startIndex = index;	    if (frames[startIndex].getFrameNum() > firstFrame &&		startIndex > 0)		startIndex--;  // Actually, should interpolate	    index = startIndex;	    if (newFirstFrame < newLastFrame) {		while (index < numFrames &&		       frames[index].getFrameNum() <= newLastFrame) {		    FrameHolder frameHolder =			new FrameHolder(frames[index],					frames[index].getFrameNum() -					newFirstFrame);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -