import vrml.*; import vrml.node.*; import vrml.field.*; public class Missle extends Script { final static int IDLE = 0; final static int MOVING = 1; final static int EXPLODE = 2; final static int RELOAD = 3; //internal private int state; private float initial[]; private float delta[]; private float des[]; private Browser b; private float s; private boolean isHit; //fields private float velocity; private float damage; private Node thisMissle; private Node owner; private Node ownerScript; private MFNode otherRobot; private Node world; private Node choice; private Node clock; //outputs private SFVec3f translation_changed; private SFRotation rotation_changed; private SFVec3f scale_changed; private SFInt32 choice_changed; private MFNode addChildren_Robot,removeChildren_Robot; private MFNode addChildren_World,removeChildren_World; private SFInt32 missle_hit; // This method is called when the script is loaded public void initialize() { SFVec3f temp; initial = new float[3]; delta = new float[3]; des = new float[3]; state = IDLE; velocity = ((SFFloat) getField("velocity")).getValue(); damage = ((SFFloat) getField("damage")).getValue(); thisMissle = (Node) ((SFNode) getField("thisMissle")).getValue(); owner = (Node) ((SFNode) getField("owner")).getValue(); ownerScript = (Node) ((SFNode) getField("ownerScript")).getValue(); world = (Node) ((SFNode) getField("world")).getValue(); choice = (Node) ((SFNode) getField("choice")).getValue(); clock = (Node) ((SFNode) getField("clock")).getValue(); otherRobot = (MFNode) getField("otherRobot"); temp = (SFVec3f)thisMissle.getExposedField("translation"); initial[0] = temp.getX(); initial[1] = temp.getY(); initial[2] = temp.getZ(); //eventouts addChildren_Robot = (MFNode) getEventOut("addChildren_Robot"); removeChildren_Robot = (MFNode) getEventOut("removeChildren_Robot"); addChildren_World = (MFNode) getEventOut("addChildren_World"); removeChildren_World = (MFNode) getEventOut("removeChildren_World"); translation_changed = (SFVec3f) getEventOut("translation_changed"); scale_changed = (SFVec3f) getEventOut("scale_changed"); choice_changed = (SFInt32) getEventOut("choice_changed"); missle_hit = (SFInt32) getEventOut("missle_hit"); rotation_changed = (SFRotation) getEventOut("rotation_changed"); b = world.getBrowser(); //routings b.addRoute(this,"translation_changed",thisMissle,"set_translation"); b.addRoute(this,"scale_changed",thisMissle,"set_scale"); b.addRoute(this,"choice_changed",choice,"set_whichChoice"); b.addRoute(this,"rotation_changed",thisMissle,"set_rotation"); b.addRoute(this,"addChildren_Robot",owner,"addChildren"); b.addRoute(this,"removeChildren_Robot",owner,"removeChildren"); b.addRoute(this,"addChildren_World",world,"addChildren"); b.addRoute(this,"removeChildren_World",world,"removeChildren"); b.addRoute(this,"missle_hit",ownerScript,"missle_hit"); b.addRoute(clock,"fraction_changed",this,"set_fraction"); } private void set_fraction(ConstSFFloat frac) { int i; float l; SFVec3f m,d; switch (state) { case IDLE: break; case MOVING: m = (SFVec3f)thisMissle.getExposedField("translation"); isHit = false; for (i=0; i<otherRobot.getSize(); i++) { d = (SFVec3f)((Node)otherRobot.get1Value(i)).getExposedField("translation"); l = (float)Math.sqrt( (m.getX()-d.getX())*(m.getX()-d.getX())+(m.getY()-d.getY()-1.0f)*(m.getY()-d.getY()-1.0f)+ (m.getZ()-d.getZ())*(m.getZ()-d.getZ()) ); if (l < 0.5f) { isHit = true; break; } } if (!isHit) { if ( (Math.abs(m.getX()) > 8.0) || (Math.abs(m.getZ()) > 8.0) ) state = RELOAD; else translation_changed.setValue(m.getX()+delta[0],m.getY()+delta[1],m.getZ()+delta[2]); } else { choice_changed.setValue(1); s = 1.0f; state = EXPLODE; } break; case EXPLODE: if (s < 10.0) { s = s+1.0f; scale_changed.setValue(s,s,s); } else { state = RELOAD; } break; case RELOAD: if (isHit) missle_hit.setValue(0); else missle_hit.setValue(-1); scale_changed.setValue(1.0f,1.0f,1.0f); choice_changed.setValue(-1); removeChildren_World.set1Value(0,thisMissle); addChildren_Robot.set1Value(0,thisMissle); translation_changed.setValue(initial[0],initial[1],initial[2]); rotation_changed.setValue(0.0f,0.0f,0.0f,0.0f); state = IDLE; break; } } private void set_target(ConstSFVec3f t) { float l,dx,dy,dz; SFVec3f r,m; float rr[] = {0.0f,0.0f,0.0f,0.0f}; r = (SFVec3f)owner.getExposedField("translation"); m = (SFVec3f)thisMissle.getExposedField("translation"); ((SFRotation)owner.getExposedField("rotation")).getValue(rr); removeChildren_Robot.set1Value(0,thisMissle); addChildren_World.set1Value(0,thisMissle); translation_changed.setValue(m.getX()+r.getX(),m.getY()+r.getY(),m.getZ()+r.getZ()); rotation_changed.setValue(rr[0],rr[1],rr[2],rr[3]); dx = t.getX()-m.getX(); dy = t.getY()-m.getY()+1.0f; dz = t.getZ()-m.getZ(); l = (float)Math.sqrt(dx*dx+dy*dy+dz*dz); delta[0] = dx/l*velocity; delta[1] = dy/l*velocity; delta[2] = dz/l*velocity; state = MOVING; choice_changed.setValue(0); } // In Java, you have to explicitly handle each event using the // processEvent method. Use it to call a private method for each event. public void processEvent (Event e) { String EventName = e.getName(); if (EventName.equals("set_fraction")) set_fraction((ConstSFFloat)e.getValue()); else if (EventName.equals("set_target")) set_target((ConstSFVec3f)e.getValue()); } }