import vrml.*; import vrml.node.*; import vrml.field.*; import java.lang.Math; import java.util.Random; public class control extends Script{ private SFVec3f bug1pos, bug2pos, bug3pos, bug4pos, bug5pos, bug6pos; private SFVec3f bug7pos, bug8pos, bug9pos, bug10pos, bug11pos, bug12pos; private SFVec3f bug13pos; float xpos[],ypos[],xvel[],yvel[],xtarget[],ytarget[], xyzpos[]; float orbit_centerx[],orbit_centery[],orbit_radius[],orbit_angle[]; int type[]; boolean wander[], follow[], followed[], orbit[]; int follow_target[], orbit_target[]; float testx, testy, randx, randy; int mindex, count; Random random; boolean done, collision; public void initialize() { bug1pos = (SFVec3f) getEventOut("bug1pos"); bug2pos = (SFVec3f) getEventOut("bug2pos"); bug3pos = (SFVec3f) getEventOut("bug3pos"); bug4pos = (SFVec3f) getEventOut("bug4pos"); bug5pos = (SFVec3f) getEventOut("bug5pos"); bug6pos = (SFVec3f) getEventOut("bug6pos"); bug7pos = (SFVec3f) getEventOut("bug7pos"); bug8pos = (SFVec3f) getEventOut("bug8pos"); bug9pos = (SFVec3f) getEventOut("bug9pos"); bug10pos = (SFVec3f) getEventOut("bug10pos"); bug11pos = (SFVec3f) getEventOut("bug11pos"); bug12pos = (SFVec3f) getEventOut("bug12pos"); bug13pos = (SFVec3f) getEventOut("bug13pos"); xpos = new float[13]; ypos = new float[13]; xvel = new float[13]; yvel = new float[13]; type = new int[13]; xtarget = new float[13]; ytarget = new float[13]; orbit_centerx = new float[13]; orbit_centery = new float[13]; orbit_radius = new float[13]; orbit_angle = new float[13]; follow = new boolean[13]; followed = new boolean[13]; wander = new boolean[13]; orbit = new boolean[13]; follow_target = new int[13]; orbit_target = new int[13]; xyzpos = new float[3]; random = new Random(); for (int j=0; j<13; j++) { follow[j]=false; followed[j]=false; follow_target[j]=-1; wander[j]=true; xpos[j]=6.0f * (random.nextFloat() - 0.5f); ypos[j]=6.0f * (random.nextFloat() - 0.5f); xtarget[j]=6.0f * (random.nextFloat() - 0.5f); ytarget[j]=6.0f * (random.nextFloat() - 0.5f); } type[0]=0; type[1]=0; type[2]=0; type[3]=0; type[4]=0; type[5]=0; type[6]=0; type[7]=1; type[8]=1; type[9]=1; type[10]=2; type[11]=2; type[12]=2; outputpositions(); } private void outputpositions() { xyzpos[0] = xpos[0]; xyzpos[1] = ypos[0]; xyzpos[2] = 0.0f; bug1pos.setValue(xyzpos); xyzpos[0] = xpos[1]; xyzpos[1] = ypos[1]; xyzpos[2] = 0.0f; bug2pos.setValue(xyzpos); xyzpos[0] = xpos[2]; xyzpos[1] = ypos[2]; xyzpos[2] = 0.0f; bug3pos.setValue(xyzpos); xyzpos[0] = xpos[3]; xyzpos[1] = ypos[3]; xyzpos[2] = 0.0f; bug4pos.setValue(xyzpos); xyzpos[0] = xpos[4]; xyzpos[1] = ypos[4]; xyzpos[2] = 0.0f; bug5pos.setValue(xyzpos); xyzpos[0] = xpos[5]; xyzpos[1] = ypos[5]; xyzpos[2] = 0.0f; bug6pos.setValue(xyzpos); xyzpos[0] = xpos[6]; xyzpos[1] = ypos[6]; xyzpos[2] = 0.0f; bug7pos.setValue(xyzpos); xyzpos[0] = xpos[7]; xyzpos[1] = ypos[7]; xyzpos[2] = 0.0f; bug8pos.setValue(xyzpos); xyzpos[0] = xpos[8]; xyzpos[1] = ypos[8]; xyzpos[2] = 0.0f; bug9pos.setValue(xyzpos); xyzpos[0] = xpos[9]; xyzpos[1] = ypos[9]; xyzpos[2] = 0.0f; bug10pos.setValue(xyzpos); xyzpos[0] = xpos[10]; xyzpos[1] = ypos[10]; xyzpos[2] = 0.0f; bug11pos.setValue(xyzpos); xyzpos[0] = xpos[11]; xyzpos[1] = ypos[11]; xyzpos[2] = 0.0f; bug12pos.setValue(xyzpos); xyzpos[0] = xpos[12]; xyzpos[1] = ypos[12]; xyzpos[2] = 0.0f; bug13pos.setValue(xyzpos); } private void calctarget(int index) { xtarget[index] = 6.0f * (random.nextFloat() - 0.5f); ytarget[index] = 6.0f * (random.nextFloat() - 0.5f); } private void calcvelocities() { float dx, dy, mag, velx, vely; int j; for (j=0;j<13;j++) { dx = xtarget[j] - xpos[j]; dy = ytarget[j] - ypos[j]; mag = dx * dx + dy * dy; mag = (float)Math.sqrt(mag); xvel[j] = 0.05f * ((1.0f/mag) * dx); yvel[j] = 0.05f * ((1.0f/mag) * dy); } } private float dist(float a, float b, float c, float d) { float x; x = ((c - a) * (c - a)) + ((d - b) * (d - b)); x = (float)Math.sqrt(x); return x; } private float mindist(int index, float x, float y) { float min = 100f; float test; for (int i = 0; i < 13; i++) { if (index != i) { test = dist(x,y,xpos[i],ypos[i]); if (test < min) { min = test; mindex = i; } } } return min; } private void orbit_update(int index) { float testx, testy; orbit_angle[index] = orbit_angle[index] + 0.15f; testx = orbit_centerx[index] + (float)Math.cos(orbit_angle[index]) * orbit_radius[index]; testy = orbit_centery[index] + (float)Math.sin(orbit_angle[index]) * orbit_radius[index]; if (mindist(index,testx,testy) < orbit_radius[index] && mindex != orbit_target[index] && (type[mindex] == 0 || type[mindex] == 2)) { followed[orbit_target[index]]=false; wander[orbit_target[index]]=true; if (!followed[mindex]) { wander[mindex]=false; followed[mindex]=true; orbit_centerx[index]=xpos[mindex]; orbit_centery[index]=ypos[mindex]; orbit_radius[index] = 0.4f; orbit_angle[index]=(float)Math.atan2(ypos[index]-ypos[mindex],xpos[index]-xpos[mindex]); orbit_target[index]=mindex; } else { wander[index] = true; orbit[index] = false; } } else { xpos[index]=testx; ypos[index]=testy; } } private void follow_update(int index) { float testx, testy; int j; if (dist(xpos[index],ypos[index],xpos[follow_target[index]],ypos[follow_target[index]]) > 0.5f) { followed[follow_target[index]]=false; wander[index]=true; follow[index]=false; } testx = xpos[index] + xvel[follow_target[index]]; testy = ypos[index] + yvel[follow_target[index]]; j=0; while (mindist(index,testx,testy) < 0.4f && j < 5) { j++; calctarget(follow_target[index]); calcvelocities(); testx = xpos[index] + xvel[follow_target[index]]; testy = ypos[index] + yvel[follow_target[index]]; } xpos[index] = testx; ypos[index] = testy; } private void wander_update(int index) { float testx, testy; int j; testx = xpos[index] + xvel[index]; testy = ypos[index] + yvel[index]; if (dist(xpos[index], ypos[index], xtarget[index], ytarget[index]) < 0.2f) calctarget(index); else if (mindist(index,testx,testy) < 0.5f && type[index] == 1 && !followed[mindex] && type[mindex] == 0) { wander[index]=false; follow[index]=true; followed[mindex]=true; follow_target[index]=mindex; } else if (mindist(index,testx,testy) < 0.48f && type[index] == 2 && !followed[mindex] && type[mindex] == 0) { wander[mindex]=false; wander[index]=false; followed[mindex]=true; orbit[index]=true; orbit_centerx[index]=xpos[mindex]; orbit_centery[index]=ypos[mindex]; orbit_radius[index] = 0.4f; orbit_angle[index]=(float)Math.atan2(ypos[index]-ypos[mindex],xpos[index]-xpos[mindex]); orbit_target[index]=mindex; } else if (mindist(index,testx,testy) < 0.42f && type[mindex] == 1 && !followed[index] && type[index] == 0) { followed[follow_target[mindex]] = false; follow_target[mindex] = index; followed[index] = true; } else { calcvelocities(); j = 0; while (mindist(index, testx, testy) < 0.4f && j < 5) { j++; calctarget(index); calcvelocities(); testx = xpos[index] + xvel[index]; testy = ypos[index] + yvel[index]; } } xpos[index] = xpos[index] + xvel[index]; ypos[index] = ypos[index] + yvel[index]; } private void set_fraction (float frac) { for (int i = 0; i < 13; i++) { if (wander[i]) wander_update(i); else if (follow[i]) follow_update(i); else if (orbit[i]) orbit_update(i); outputpositions(); } } public void processEvent (Event e) { String EventName = e.getName(); if (EventName.equals("set_fraction")) set_fraction(((ConstSFFloat)e.getValue()).getValue()); } }