package NET.worlds.scape; import NET.worlds.core.Std; import java.io.IOException; import java.util.Enumeration; public class MoveAction extends Action { int startTime; boolean killOthers = true; boolean killed = false; public int cycleTime = 1000; public int cycles = 1; public boolean loopInfinite = false; public Point3 startPoint = new Point3(); public Point3 startScale = new Point3(1.0F, 1.0F, 1.0F); public Point3 startSpin = new Point3(0.0F, 0.0F, -1.0F); public float startRotation; public Point3 extentPoint = new Point3(); public Point3 extentScale = new Point3(1.0F, 1.0F, 1.0F); public Point3 extentSpin = new Point3(0.0F, 0.0F, -1.0F); public float extentRotation; protected Persister activeID; private static Object classCookie = new Object(); @Override public void noteAddingTo(SuperRoot owner) { if (this.startPoint.x == 0.0F && this.startPoint.y == 0.0F && this.startPoint.z == 0.0F && this.startScale.x == 1.0F && this.startScale.y == 1.0F && this.startScale.z == 1.0F && this.startSpin.x == 0.0F && this.startSpin.y == 0.0F && this.startSpin.z == -1.0F && this.startRotation == 0.0F) { this.updateStored(true); } } public void updateStored(boolean start) { Object owner = this.getOwner(); if (owner != null && owner instanceof WObject) { WObject o = (WObject)owner; if (!start) { this.extentPoint.copy(o.getPosition()); this.extentScale.copy(o.getScale()); Point3Temp newSpin = Point3Temp.make(); this.endToExtent(o.getSpin(newSpin), newSpin); } else { this.startPoint.copy(o.getPosition()); this.startScale.copy(o.getScale()); this.startRotation = o.getSpin(this.startSpin); } } } public void endToExtent(float rot, Point3Temp spinAxis) { this.extentPoint.minus(this.startPoint); this.extentScale.dividedBy(this.startScale); Transform t = Transform.make(); t.spin(spinAxis, rot); t.spin(this.startSpin, -this.startRotation); rot = t.getSpin(spinAxis); t.recycle(); if (this.equivalentSpinAxises(spinAxis, this.extentSpin)) { int wholeTurns = Math.round((this.extentRotation - rot) / 360.0F); this.extentRotation = rot + wholeTurns * 360; } else if (this.equivalentSpinAxises(spinAxis, this.extentSpin.negate())) { this.extentSpin.negate(); rot = -rot; int wholeTurns = Math.round((this.extentRotation - rot) / 360.0F); this.extentRotation = rot + wholeTurns * 360; } else { this.extentSpin.copy(spinAxis); this.extentRotation = rot; } } private boolean equivalentSpinAxises(Point3Temp a, Point3Temp b) { return Math.abs(a.x - b.x) + Math.abs(a.y - b.y) + Math.abs(a.z - b.z) < 0.001F; } public void updateOwner(boolean start) { Object owner = this.getOwner(); if (owner != null && owner instanceof WObject) { WObject o = (WObject)owner; o.makeIdentity(); if (!start) { o.spin(this.extentSpin, this.extentRotation); o.moveBy(this.extentPoint); o.scale(this.extentScale); } o.scale(this.startScale); o.spin(this.startSpin, this.startRotation); o.moveBy(this.startPoint); } } public void kill() { this.killed = true; } public boolean isRunning() { return this.activeID != null; } @Override public Persister trigger(Event e, Persister seqID) { Object owner = this.getOwner(); if (owner != null && owner instanceof WObject) { WObject o = (WObject)owner; if (this.killed) { this.killed = false; this.activeID = null; return null; } else { if (seqID == null) { if (this.activeID != null) { return this.activeID; } if (this.killOthers) { Enumeration acts = o.getActions(); while (acts.hasMoreElements()) { Action a = (Action)acts.nextElement(); if (a != this && a instanceof MoveAction) { MoveAction ma = (MoveAction)a; if (ma.isRunning()) { ma.kill(); } } } } this.startTime = Std.getRealTime(); this.activeID = new SuperRoot(); seqID = this.activeID; } if (seqID != this.activeID) { return null; } else { int currentTime = Std.getRealTime(); int cycleNo = (currentTime - this.startTime) / this.cycleTime; float frameLoc = 1.0F; if (cycleNo >= this.cycles && !this.loopInfinite) { this.activeID = null; } else { frameLoc = (float)((currentTime - this.startTime) % this.cycleTime) / this.cycleTime; } boolean var10000 = o instanceof Camera; if (o instanceof PosableDrone) { float yaw = -(this.startRotation + this.extentRotation * frameLoc); Point3Temp dest = Point3Temp.make(this.extentPoint).times(frameLoc).plus(this.startPoint); o.makeIdentity().moveTo(dest).yaw(yaw); } else { o.makeIdentity(); o.spin(this.extentSpin, this.extentRotation * frameLoc); o.spin(this.startSpin, this.startRotation); Point3Temp p = Point3Temp.make( (float)Math.pow(this.extentScale.x, frameLoc), (float)Math.pow(this.extentScale.y, frameLoc), (float)Math.pow(this.extentScale.z, frameLoc) ); o.scale(p.times(this.startScale)); o.moveTo(Point3Temp.make(this.extentPoint).times(frameLoc).plus(this.startPoint)); } return this.activeID; } } } else { return null; } } @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 = FloatPropertyEditor.make(new Property(this, index, "Cycle Time (in seconds)")); } else if (mode == 1) { ret = new Float(this.cycleTime / 1000.0F); } else if (mode == 2) { this.cycleTime = (int)(1000.0F * (Float)value); } break; case 1: 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 2: if (mode == 0) { ret = IntegerPropertyEditor.make(new Property(this, index, "Copy Start/End 1/2:Action->Owner 3/4:Owner->Action")); } else if (mode == 1) { ret = new Integer(0); } else if (mode == 2) { switch ((Integer)value) { case 1: this.updateOwner(true); return ret; case 2: this.updateOwner(false); return ret; case 3: this.updateStored(true); return ret; case 4: this.updateStored(false); } } break; case 3: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "Translation Extent")); } else if (mode == 1) { ret = new Point3(this.extentPoint); } else if (mode == 2) { this.extentPoint.copy((Point3)value); } break; case 4: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "Scale Extent")); } else if (mode == 1) { ret = new Point3(this.extentScale); } else if (mode == 2) { this.extentScale.copy((Point3)value); } break; case 5: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "Spin Axis For Extent")); } else if (mode == 1) { Point3 p = new Point3(this.extentSpin); p.x = Math.round(p.x * 10000.0F) / 10000.0F; p.y = Math.round(p.y * 10000.0F) / 10000.0F; p.z = Math.round(p.z * 10000.0F) / 10000.0F; ret = p; } else if (mode == 2) { this.extentSpin.copy((Point3)value); } break; case 6: if (mode == 0) { ret = FloatPropertyEditor.make(new Property(this, index, "Extent Rotation Amount")); } else if (mode == 1) { ret = new Float(this.extentRotation); } else if (mode == 2) { this.extentRotation = (Float)value; } break; case 7: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "Start Point")); } else if (mode == 1) { ret = new Point3(this.startPoint); } else if (mode == 2) { this.startPoint.copy((Point3)value); } break; case 8: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "Start Scale")); } else if (mode == 1) { ret = new Point3(this.startScale); } else if (mode == 2) { this.startScale.copy((Point3)value); } break; case 9: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "Start Spin")); } else if (mode == 1) { ret = new Point3(this.startSpin); } else if (mode == 2) { this.startSpin.copy((Point3)value); } break; case 10: if (mode == 0) { ret = FloatPropertyEditor.make(new Property(this, index, "Start Rotation")); } else if (mode == 1) { ret = new Float(this.startRotation); } else if (mode == 2) { this.startRotation = (Float)value; } break; case 11: if (mode == 0) { ret = BooleanPropertyEditor.make(new Property(this, index, "Kill Other Move Actions"), "Let other moves finish", "Kill other move actions"); } else if (mode == 1) { ret = new Boolean(this.killOthers); } else if (mode == 2) { this.killOthers = (Boolean)value; } break; case 12: if (mode == 0) { ret = BooleanPropertyEditor.make(new Property(this, index, "Loop Infinite"), "False", "True"); } else if (mode == 1) { ret = new Boolean(this.loopInfinite); } else if (mode == 2) { this.loopInfinite = (Boolean)value; } break; default: ret = super.properties(index, offset + 13, mode, value); } return ret; } @Override public String toString() { String retVal = super.toString() + "[cycleTime " + this.cycleTime / 1000.0F + ", cycles " + this.cycles + ","; if (!this.loopInfinite) { retVal = retVal + " not "; } return retVal + " Infinite ]"; } @Override public void saveState(Saver s) throws IOException { s.saveVersion(6, classCookie); super.saveState(s); s.saveBoolean(this.loopInfinite); s.saveInt(this.cycleTime); s.saveInt(this.cycles); s.save(this.extentPoint); s.save(this.startPoint); s.save(this.extentScale); s.save(this.startScale); s.save(this.extentSpin); s.save(this.startSpin); s.saveFloat(this.extentRotation); s.saveFloat(this.startRotation); s.saveBoolean(this.killOthers); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { this.restoreStateMoveActionHelper(r, classCookie); } public void restoreStateMoveActionHelper(Restorer r, Object cookie) throws IOException, TooNewException { switch (r.restoreVersion(cookie)) { case 1: super.restoreState(r); case 0: r.setOldFlag(); this.cycleTime = (int)r.restoreFloat(); this.cycles = r.restoreInt(); this.loopInfinite = this.cycles == 0; this.extentPoint = (Point3)r.restore(); this.startPoint = (Point3)r.restore(); this.extentScale = (Point3)r.restore(); this.startScale = (Point3)r.restore(); this.extentSpin = (Point3)r.restore(); this.startSpin = (Point3)r.restore(); this.extentRotation = r.restoreFloat(); this.startRotation = r.restoreFloat(); this.extentPoint.minus(this.startPoint); this.extentScale.dividedBy(this.startScale); break; case 2: r.setOldFlag(); super.restoreState(r); this.cycleTime = r.restoreInt(); this.cycles = r.restoreInt(); this.loopInfinite = this.cycles == 0; this.extentPoint = (Point3)r.restore(); this.startPoint = (Point3)r.restore(); this.extentScale = (Point3)r.restore(); this.startScale = (Point3)r.restore(); this.extentSpin = (Point3)r.restore(); this.startSpin = (Point3)r.restore(); this.extentRotation = r.restoreFloat(); this.startRotation = r.restoreFloat(); r.restoreBoolean(); break; case 3: case 4: r.setOldFlag(); super.restoreState(r); this.cycleTime = r.restoreInt(); this.cycles = r.restoreInt(); this.loopInfinite = this.cycles == 0; this.extentPoint = (Point3)r.restore(); this.startPoint = (Point3)r.restore(); this.extentScale = (Point3)r.restore(); this.startScale = (Point3)r.restore(); this.extentSpin = (Point3)r.restore(); this.startSpin = (Point3)r.restore(); this.extentRotation = r.restoreFloat(); this.startRotation = r.restoreFloat(); break; case 5: super.restoreState(r); this.cycleTime = r.restoreInt(); this.cycles = r.restoreInt(); this.loopInfinite = this.cycles == 0; this.extentPoint = (Point3)r.restore(); this.startPoint = (Point3)r.restore(); this.extentScale = (Point3)r.restore(); this.startScale = (Point3)r.restore(); this.extentSpin = (Point3)r.restore(); this.startSpin = (Point3)r.restore(); this.extentRotation = r.restoreFloat(); this.startRotation = r.restoreFloat(); this.killOthers = r.restoreBoolean(); break; case 6: super.restoreState(r); this.loopInfinite = r.restoreBoolean(); this.cycleTime = r.restoreInt(); this.cycles = r.restoreInt(); this.extentPoint = (Point3)r.restore(); this.startPoint = (Point3)r.restore(); this.extentScale = (Point3)r.restore(); this.startScale = (Point3)r.restore(); this.extentSpin = (Point3)r.restore(); this.startSpin = (Point3)r.restore(); this.extentRotation = r.restoreFloat(); this.startRotation = r.restoreFloat(); this.killOthers = r.restoreBoolean(); break; default: throw new TooNewException(); } } }