package NET.worlds.scape; import NET.worlds.console.Console; import java.io.IOException; import java.text.MessageFormat; import java.util.Date; class MultiMotion extends TriggeredSwitchableBehavior implements FrameHandler, Persister, MouseDownHandler, BumpHandler { protected int motionNumber = 0; protected int motionNumberCount = 0; protected int motionNumberMax = 100; long startMultiMotionTime; long totalMultiMotionTime = 0L; protected String cycleTime; protected float[] cycleTimeArray; protected int cycles; protected Transform MultiMotionTransform; protected String startPoint; protected String endPoint; protected String deltaPoint; protected String startScale; protected String endScale; protected String deltaScale; protected String startSpin; protected String endSpin; protected Point3[] startPointArray; protected Point3[] endPointArray; protected Point3[] deltaPointArray; protected Point3[] startScaleArray; protected Point3[] endScaleArray; protected Point3[] deltaScaleArray; protected Point3[] startSpinArray; protected Point3[] endSpinArray; protected String startRotation; protected String endRotation; protected float[] startRotationArray; protected float[] endRotationArray; protected boolean MultiMotionTransformInitialized; protected boolean variableInitialized; protected boolean multiMotionEnd = true; public MultiMotion() { this.cycleTime = new String("1000"); this.cycleTimeArray = new float[this.motionNumberMax]; this.cycleTimeArray[0] = 1000.0F; this.trigger = new String("none"); this.externalTriggerTag = new String(""); this.cycles = 0; this.MultiMotionTransformInitialized = false; this.variableInitialized = false; this.startPointArray = new Point3[this.motionNumberMax]; this.endPointArray = new Point3[this.motionNumberMax]; this.deltaPointArray = new Point3[this.motionNumberMax]; this.startScaleArray = new Point3[this.motionNumberMax]; this.endScaleArray = new Point3[this.motionNumberMax]; this.deltaScaleArray = new Point3[this.motionNumberMax]; this.startSpinArray = new Point3[this.motionNumberMax]; this.endSpinArray = new Point3[this.motionNumberMax]; for (int i = 0; i < this.motionNumberMax; i++) { this.startPointArray[i] = new Point3(); this.endPointArray[i] = new Point3(); this.deltaPointArray[i] = new Point3(); this.startScaleArray[i] = new Point3(); this.endScaleArray[i] = new Point3(); this.deltaScaleArray[i] = new Point3(); this.startSpinArray[i] = new Point3(); this.endSpinArray[i] = new Point3(); } this.startRotationArray = new float[this.motionNumberMax]; this.endRotationArray = new float[this.motionNumberMax]; this.startMultiMotion(); } @Override public void ExternalTrigger(Trigger trigger_source, int sequence_no, int event_no) { this.trigger_source = trigger_source; this.sequence_no = sequence_no; this.event_no = event_no; this.startMultiMotion(); } public void startMultiMotion() { Date timer = new Date(); this.startMultiMotionTime = timer.getTime(); this.motionNumber = 0; this.multiMotionEnd = false; } public void setTotalMultiMotionTime() { this.totalMultiMotionTime = 0L; for (int i = 0; i < this.motionNumberCount; i++) { this.totalMultiMotionTime = this.totalMultiMotionTime + (int)this.cycleTimeArray[i]; } } public void parseFloatString(String floatList, float[] floatArray) { int currentIndex = 0; int currentSeparator = 0; int nextSeparator = 0; int lastSeparator = floatList.lastIndexOf(" "); if (lastSeparator != -1 || floatList.length() != 0) { if (lastSeparator == -1) { floatArray[currentIndex] = Float.valueOf(floatList); } else { nextSeparator = floatList.indexOf(" "); floatArray[currentIndex] = Float.valueOf(floatList.substring(0, nextSeparator)); currentIndex++; while (nextSeparator != lastSeparator) { currentSeparator = nextSeparator; nextSeparator = floatList.indexOf(" ", nextSeparator + 1); floatArray[currentIndex] = Float.valueOf(floatList.substring(currentSeparator + 1, nextSeparator)); currentIndex++; } floatArray[currentIndex] = Float.valueOf(floatList.substring(nextSeparator + 1)); } } } public Point3 StringToPoint3(String Point3String) { Point3 newPoint3 = new Point3(); int currentIndex = 0; newPoint3.x = Float.valueOf(Point3String.substring(currentIndex, Point3String.indexOf(",", currentIndex))); currentIndex = Point3String.indexOf(",", currentIndex) + 1; newPoint3.y = Float.valueOf(Point3String.substring(currentIndex, Point3String.indexOf(",", currentIndex))); currentIndex = Point3String.indexOf(",", currentIndex) + 1; newPoint3.z = Float.valueOf(Point3String.substring(currentIndex, Point3String.length())); return newPoint3; } public void parsePoint3String(String Point3List, Point3[] Point3Array) { int currentIndex = 0; int currentSeparator = 0; int nextSeparator = 0; int lastSeparator = Point3List.lastIndexOf(" "); if (lastSeparator != -1 || Point3List.length() != 0) { if (lastSeparator == -1) { Point3Array[currentIndex] = this.StringToPoint3(Point3List); } else { nextSeparator = Point3List.indexOf(" "); Point3Array[currentIndex] = this.StringToPoint3(Point3List.substring(0, nextSeparator)); currentIndex++; while (nextSeparator != lastSeparator) { currentSeparator = nextSeparator; nextSeparator = Point3List.indexOf(" ", nextSeparator + 1); Point3Array[currentIndex] = this.StringToPoint3(Point3List.substring(currentSeparator + 1, nextSeparator)); currentIndex++; } Point3Array[currentIndex] = this.StringToPoint3(Point3List.substring(nextSeparator + 1)); } } } @Override public boolean handle(FrameEvent e) { if (!this.MultiMotionTransformInitialized) { this.MultiMotionTransform = e.target; this.MultiMotionTransformInitialized = true; } if (!this.variableInitialized) { this.startPoint = this.MultiMotionTransform.getPosition().toString(); this.startPointArray[0].copy(this.MultiMotionTransform.getPosition()); this.endPoint = new String(this.startPoint); this.endPointArray[0].copy(this.startPointArray[0]); this.startScaleArray[0].x = this.MultiMotionTransform.getTotalScale(); this.startScaleArray[0].y = this.MultiMotionTransform.getTotalScale(); this.startScaleArray[0].z = this.MultiMotionTransform.getTotalScale(); this.startScale = this.startScaleArray[0].toString(); this.endScaleArray[0].copy(this.startScaleArray[0]); this.endScale = this.endScaleArray[0].toString(); this.startRotation = new Float(this.MultiMotionTransform.getSpin(this.startSpinArray[0])).toString(); this.startRotationArray[0] = Float.valueOf(this.startRotation); this.startSpin = this.startSpinArray[0].toString(); this.endRotation = new String("0.0"); this.endRotationArray[0] = Float.valueOf(this.endRotation); this.endSpinArray[0] = new Point3(); this.endSpin = this.endSpinArray[0].toString(); this.variableInitialized = true; } if (this.enabled) { Date timer = new Date(); long currentTime = timer.getTime(); int cycleNo = 0; if (this.totalMultiMotionTime > 0L) { cycleNo = (int)((-this.startMultiMotionTime + currentTime) / this.totalMultiMotionTime); } if (this.totalMultiMotionTime > 0L && (cycleNo < this.cycles || this.cycles == 0)) { long totalTime = 0L; int currentCycleTime = (int)((currentTime - this.startMultiMotionTime) % this.totalMultiMotionTime); int currentMotionTime = 0; for (this.motionNumber = 0; this.motionNumber < this.motionNumberCount && totalTime <= currentCycleTime; this.motionNumber++) { currentMotionTime = (int)this.cycleTimeArray[this.motionNumber]; totalTime += currentMotionTime; } this.motionNumber--; if (totalTime < currentCycleTime) { System.out.print("Error in totalMultiMotionTime computation.\n"); } currentMotionTime = (int)(currentMotionTime - (totalTime - currentCycleTime)); float frameLoc = currentMotionTime % this.cycleTimeArray[this.motionNumber] / this.cycleTimeArray[this.motionNumber]; e.receiver.makeIdentity(); e.receiver .scale( this.startScaleArray[this.motionNumber].x + (this.endScaleArray[this.motionNumber].x - this.startScaleArray[this.motionNumber].x) * frameLoc, this.startScaleArray[this.motionNumber].x + (this.endScaleArray[this.motionNumber].x - this.startScaleArray[this.motionNumber].x) * frameLoc, this.startScaleArray[this.motionNumber].x + (this.endScaleArray[this.motionNumber].x - this.startScaleArray[this.motionNumber].x) * frameLoc ); e.receiver .moveTo( this.startPointArray[this.motionNumber].x + (this.endPointArray[this.motionNumber].x - this.startPointArray[this.motionNumber].x) * frameLoc, this.startPointArray[this.motionNumber].y + (this.endPointArray[this.motionNumber].y - this.startPointArray[this.motionNumber].y) * frameLoc, this.startPointArray[this.motionNumber].z + (this.endPointArray[this.motionNumber].z - this.startPointArray[this.motionNumber].z) * frameLoc ); e.receiver.spin(this.startSpinArray[this.motionNumber], this.startRotationArray[this.motionNumber]); e.receiver.spin(this.endSpinArray[this.motionNumber], this.endRotationArray[this.motionNumber] * frameLoc); } else if (cycleNo >= this.cycles && this.cycles != 0 && !this.multiMotionEnd) { this.multiMotionEnd = true; if (this.trigger_source != null) { this.trigger_source.registerFinishedTriggerTag(this.sequence_no, this.event_no); } } } return true; } @Override public boolean handle(MouseDownEvent e) { if (this.enabled && this.trigger.equals("click")) { this.startMultiMotion(); } return true; } @Override public boolean handle(BumpEventTemp e) { if (this.enabled && this.trigger.equals("bump")) { this.startMultiMotion(); } return true; } public void startTransform() { if (this.MultiMotionTransform != null) { this.MultiMotionTransform.makeIdentity(); this.MultiMotionTransform .scale(this.startScaleArray[this.motionNumber].x, this.startScaleArray[this.motionNumber].x, this.startScaleArray[this.motionNumber].x); this.MultiMotionTransform .moveTo(this.startPointArray[this.motionNumber].x, this.startPointArray[this.motionNumber].y, this.startPointArray[this.motionNumber].z); this.MultiMotionTransform.spin(this.startSpinArray[this.motionNumber], this.startRotationArray[this.motionNumber]); } } public void endTransform() { if (this.MultiMotionTransform != null) { this.MultiMotionTransform.makeIdentity(); this.MultiMotionTransform .scale(this.endScaleArray[this.motionNumber].x, this.endScaleArray[this.motionNumber].x, this.endScaleArray[this.motionNumber].x); this.MultiMotionTransform .moveTo(this.endPointArray[this.motionNumber].x, this.endPointArray[this.motionNumber].y, this.endPointArray[this.motionNumber].z); this.MultiMotionTransform.spin(this.startSpinArray[this.motionNumber], this.startRotationArray[this.motionNumber]); this.MultiMotionTransform.spin(this.endSpinArray[this.motionNumber], this.endRotationArray[this.motionNumber]); } } @Override public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException { Object ret = null; switch (index - offset) { case 0: if (mode == 0) { ret = new ClassProperty(this, index, "MultiMotion"); } break; case 1: if (mode == 0) { ret = IntegerPropertyEditor.make(new Property(this, index, "Number of Motions")); } else if (mode == 1) { ret = new Integer(this.motionNumberCount); } else if (mode == 2) { this.motionNumberCount = (Integer)value; this.setTotalMultiMotionTime(); } break; case 2: if (mode == 0) { ret = IntegerPropertyEditor.make(new Property(this, index, "Cycles")); } else if (mode == 1) { ret = new Integer(this.cycles); } else if (mode == 2) { this.cycles = (Integer)value; } break; case 3: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Trigger")); } else if (mode == 1) { ret = new String(this.trigger); } else if (mode == 2) { this.trigger = ((String)value).toString().trim(); if (this.trigger.equals("external")) { Trigger.TriggeredSwitchableBehaviorList[Trigger.TriggeredSwitchableBehaviorListCount] = this; Trigger.TriggeredSwitchableBehaviorListCount++; } } break; case 4: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "External Trigger Tag")); } else if (mode == 1) { ret = new String(this.externalTriggerTag); } else if (mode == 2) { this.externalTriggerTag = ((String)value).toString().trim(); } break; case 5: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Cycle Time")); } else if (mode == 1) { ret = new String(this.cycleTime); } else if (mode == 2) { this.cycleTime = (String)value; this.parseFloatString(this.cycleTime, this.cycleTimeArray); this.setTotalMultiMotionTime(); } break; case 6: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "End Point")); } else if (mode == 1) { ret = new String(this.endPoint); this.endTransform(); } else if (mode == 2) { this.endPoint = (String)value; this.parsePoint3String(this.endPoint, this.endPointArray); this.endTransform(); } break; case 7: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Start Point")); } else if (mode == 1) { ret = new String(this.startPoint); this.startTransform(); } else if (mode == 2) { this.startPoint = (String)value; this.parsePoint3String(this.startPoint, this.startPointArray); this.startTransform(); } break; case 8: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "End Scale")); } else if (mode == 1) { ret = new String(this.endScale); this.endTransform(); } else if (mode == 2) { this.endScale = (String)value; this.parsePoint3String(this.endScale, this.endScaleArray); this.endTransform(); } break; case 9: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Start Scale")); } else if (mode == 1) { ret = new String(this.startScale); this.startTransform(); } else if (mode == 2) { this.startScale = (String)value; this.parsePoint3String(this.startScale, this.startScaleArray); this.startTransform(); } break; case 10: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "End Spin (Relative)")); } else if (mode == 1) { ret = new String(this.endSpin); this.endTransform(); } else if (mode == 2) { this.endSpin = (String)value; this.parsePoint3String(this.endSpin, this.endSpinArray); this.endTransform(); } break; case 11: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Start Spin")); } else if (mode == 1) { ret = new String(this.startSpin); this.startTransform(); } else if (mode == 2) { this.startSpin = (String)value; this.parsePoint3String(this.startSpin, this.startSpinArray); this.startTransform(); } break; case 12: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "End Rotation (Relative)")); } else if (mode == 1) { ret = new String(this.endRotation); this.endTransform(); } else if (mode == 2) { this.endRotation = (String)value; this.parseFloatString(this.endRotation, this.endRotationArray); this.endTransform(); } break; case 13: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Start Rotation")); } else if (mode == 1) { ret = new String(this.startRotation); this.startTransform(); } else if (mode == 2) { this.startRotation = (String)value; this.parseFloatString(this.startRotation, this.startRotationArray); this.startTransform(); } break; default: ret = super.properties(index, offset + 14, mode, value); } if (mode == 2 && this.trigger.equals("none")) { this.startMultiMotion(); } return ret; } @Override public String toString() { return "Multimotion: cycleTime " + this.cycleTime + ", cycles " + this.cycles + ", enabled " + this.enabled + ", trigger " + this.trigger + ", externalTriggerTag " + this.externalTriggerTag; } @Override public void saveState(Saver s) throws IOException { s.saveInt(this.motionNumberCount); s.saveInt(this.cycles); s.saveString(this.trigger); s.saveString(this.externalTriggerTag); s.saveString(this.cycleTime); s.saveString(this.endPoint); s.saveString(this.startPoint); s.saveString(this.endScale); s.saveString(this.startScale); s.saveString(this.endSpin); s.saveString(this.startSpin); s.saveString(this.endRotation); s.saveString(this.startRotation); } @Override public void restoreState(Restorer r) throws IOException { this.motionNumberCount = r.restoreInt(); this.cycles = r.restoreInt(); this.trigger = r.restoreString(); if (this.trigger.equals("external")) { Trigger.TriggeredSwitchableBehaviorList[Trigger.TriggeredSwitchableBehaviorListCount] = this; Trigger.TriggeredSwitchableBehaviorListCount++; } this.externalTriggerTag = r.restoreString(); this.cycleTime = r.restoreString(); this.parseFloatString(this.cycleTime, this.cycleTimeArray); this.endPoint = r.restoreString(); this.parsePoint3String(this.endPoint, this.endPointArray); this.setTotalMultiMotionTime(); this.startPoint = r.restoreString(); this.parsePoint3String(this.startPoint, this.startPointArray); this.endScale = r.restoreString(); this.parsePoint3String(this.endScale, this.endScaleArray); this.startScale = r.restoreString(); this.parsePoint3String(this.startScale, this.startScaleArray); this.endSpin = r.restoreString(); this.parsePoint3String(this.endSpin, this.endSpinArray); this.startSpin = r.restoreString(); this.parsePoint3String(this.startSpin, this.startSpinArray); this.endRotation = r.restoreString(); this.parseFloatString(this.endRotation, this.endRotationArray); this.startRotation = r.restoreString(); this.parseFloatString(this.startRotation, this.startRotationArray); this.variableInitialized = true; if (!this.trigger.equals("none")) { this.startMultiMotionTime = (int)(-(this.cycles * this.cycleTimeArray[this.motionNumber])); } else { this.startMultiMotion(); } } @Override public void postRestore(int version) { String name = this.getName(); String arg1 = name == null ? "" : name; SuperRoot owner = this.getOwner(); String oname = ""; if (owner != null) { oname = owner.getName(); } String arg2 = oname == null ? "" : oname; Object[] arguments = new Object[]{new String(arg1), new String(arg2)}; Console.println(MessageFormat.format(Console.message("MultiMotion-obs"), arguments)); } }