Spider

#VRML V2.0 utf8

NavigationInfo { type "EXAMINE" }
Viewpoint { position 0 10 10  orientation 1 0 0 -.8 }

EXTERNPROTO SpiderLeg [
                        field SFVec3f base
			field SFVec3f target
			eventIn SFVec3f set_base
			eventIn SFVec3f set_target
		       ] "spiderLeg.wrl"

PROTO Spider [ field SFVec3f position 0 0 0
	       field SFFloat height .5
	       field SFFloat footWidth .5
	       field SFFloat footDepth .5
	       eventIn SFVec3f set_position
	       eventIn SFFloat set_rotation
	       eventIn SFFloat set_height
	       eventIn SFFloat set_footWidth
	       eventIn SFFloat set_footDepth
	      ]
{
   Group {
      children [

	 # body
	 DEF MOVEBODY Transform  {
	    translation 0 .5 0
	    children [
	       Shape { 
		  appearance Appearance {
		     material Material { diffuseColor .5 .4 .2 }
		  }
		  geometry Box { size .2 .2 .2 } 
	       }
	      ]
	 }
	 
	 # shadow
	 DEF MOVESHADOW Transform  {
	    scale .1 1 .1
	    children [
	       Shape { 
		  appearance Appearance {
		     material Material { diffuseColor 0 0 0 } 
		  }
		  geometry IndexedFaceSet {
		     coord Coordinate { 
			point [ 1 .01 1, 1 .01 -1, -1 .01 -1, -1 .01 1 ] }
		     coordIndex [ 0 1 2 3 ]
		  }
	       }
	      ]
	 }

	 DEF LEG0 SpiderLeg { base 0 .5 0  target .33 0 .5 }
	 DEF LEG1 SpiderLeg { base 0 .5 0  target -.33 0 .5 }
	 DEF LEG2 SpiderLeg { base 0 .5 0  target .5 0 .152 }
	 DEF LEG3 SpiderLeg { base 0 .5 0  target -.5 0 .152 }
	 DEF LEG4 SpiderLeg { base 0 .5 0  target .5 0 -.152 }
	 DEF LEG5 SpiderLeg { base 0 .5 0  target -.5 0 -.152 }
	 DEF LEG6 SpiderLeg { base 0 .5 0  target .33 0 -.5 }
	 DEF LEG7 SpiderLeg { base 0 .5 0  target -.33 0 -.5 }

	 # generate leg targets based on position
	 # also position body based on position and height
	 DEF SCRIPT Script {
	    eventIn SFVec3f set_position IS set_position
	    eventIn SFFloat set_height IS set_height
	    eventIn SFFloat set_rotation IS set_rotation
	    eventIn SFFloat set_footWidth IS set_footWidth
	    eventIn SFFloat set_footDepth IS set_footDepth
	    eventOut SFVec3f body_changed
	    eventOut SFVec3f shadow_changed
	    eventOut SFRotation rotation_changed
	    eventOut SFVec3f target0_changed
	    eventOut SFVec3f target1_changed
	    eventOut SFVec3f target2_changed
	    eventOut SFVec3f target3_changed
	    eventOut SFVec3f target4_changed
	    eventOut SFVec3f target5_changed
	    eventOut SFVec3f target6_changed
	    eventOut SFVec3f target7_changed
	    field SFVec3f position IS position
	    field SFFloat rotation 0
	    field SFFloat height IS height
	    field SFFloat footWidth IS footWidth
	    field SFFloat footDepth IS footDepth
	    url "vrmlscript:

function calcTargets() {
   r = new SFRotation(0, 1, 0, rotation);
   p = new SFVec3f(position.x, 0, position.z);
   if(rotation != 0) {
      target0_changed = p.add(r.multVec(new SFVec3f(footWidth*.66, 0, footDepth)));
      target1_changed = p.add(r.multVec(new SFVec3f(-footWidth*.66, 0, footDepth)));
      target2_changed = p.add(r.multVec(new SFVec3f(footWidth, 0, footDepth/3)));
      target3_changed = p.add(r.multVec(new SFVec3f(-footWidth, 0, footDepth/3)));
      target4_changed = p.add(r.multVec(new SFVec3f(footWidth, 0, -footDepth/3)));
      target5_changed = p.add(r.multVec(new SFVec3f(-footWidth, 0, -footDepth/3)));
      target6_changed = p.add(r.multVec(new SFVec3f(footWidth*.66, 0, -footDepth)));
      target7_changed = p.add(r.multVec(new SFVec3f(-footWidth*.66, 0, -footDepth)));
   }

   // don't bother with rotation calculations if rotation is zero
   else {
      target0_changed = p.add(new SFVec3f(footWidth*.66, 0, footDepth));
      target1_changed = p.add(new SFVec3f(-footWidth*.66, 0, footDepth));
      target2_changed = p.add(new SFVec3f(footWidth, 0, footDepth/3));
      target3_changed = p.add(new SFVec3f(-footWidth, 0, footDepth/3));
      target4_changed = p.add(new SFVec3f(footWidth, 0, -footDepth/3));
      target5_changed = p.add(new SFVec3f(-footWidth, 0, -footDepth/3));
      target6_changed = p.add(new SFVec3f(footWidth*.66, 0, -footDepth));
      target7_changed = p.add(new SFVec3f(-footWidth*.66, 0, -footDepth));
   }
}

function set_footWidth(val) { 
   footWidth = val; 
   calcTargets();
}

function set_footDepth(val) { 
   footDepth = val; 
   calcTargets();
}

// spider's position has changed, recalc foot positions
function translateBody() {
   position = position.add(direction.multiply(speed));
   body_changed = new SFVec3f(position.x, height, position.z);
   shadow_changed = new SFVec3f(position.x, 0, position.z);
   calcTargets();
}

function rotateBody() {
   r = new SFRotation(0, 1, 0, rotation);
   rotation_changed = r;
   calcTargets();
}

// spider's position has changed, recalc foot positions
function set_position(val) {
   if(touched) {
      position = val;
      translateBody();
   }
}

// spider's rotation has changed, recalc foot positions
function set_rotation(val) {
   rotation = val;
   rotateBody();
}

// change body height above ground
function set_height(val) { 
   height = val; 
   body_changed = new SFVec3f(position.x, height, position.z);
}

function initialize() {
   set_height(height);
   calcTargets();
}

"
	 }
     ] 
   }
   ROUTE SCRIPT.body_changed TO MOVEBODY.translation
   ROUTE SCRIPT.shadow_changed TO MOVESHADOW.translation
   ROUTE SCRIPT.rotation_changed TO MOVEBODY.rotation
   ROUTE SCRIPT.rotation_changed TO MOVESHADOW.rotation
   ROUTE SCRIPT.body_changed TO LEG0.set_base
   ROUTE SCRIPT.body_changed TO LEG1.set_base
   ROUTE SCRIPT.body_changed TO LEG2.set_base
   ROUTE SCRIPT.body_changed TO LEG3.set_base
   ROUTE SCRIPT.body_changed TO LEG4.set_base
   ROUTE SCRIPT.body_changed TO LEG5.set_base
   ROUTE SCRIPT.body_changed TO LEG6.set_base
   ROUTE SCRIPT.body_changed TO LEG7.set_base
   ROUTE SCRIPT.target0_changed TO LEG0.set_target
   ROUTE SCRIPT.target1_changed TO LEG1.set_target
   ROUTE SCRIPT.target2_changed TO LEG2.set_target
   ROUTE SCRIPT.target3_changed TO LEG3.set_target
   ROUTE SCRIPT.target4_changed TO LEG4.set_target
   ROUTE SCRIPT.target5_changed TO LEG5.set_target
   ROUTE SCRIPT.target6_changed TO LEG6.set_target
   ROUTE SCRIPT.target7_changed TO LEG7.set_target
}

EXTERNPROTO TouchFloor [ field SFVec3f scale ] "touchFloor.wrl"

EXTERNPROTO Slider [ field SFFloat mult
		     field SFVec3f position
		     eventOut SFFloat value_changed 
		    ] "slider.wrl"


DEF SPIDER Spider {}
TouchFloor { scale 5 1 5 }

DEF SLIDER1 Slider { mult 1.75  position -.1 .2 -.5 }
ROUTE SLIDER1.value_changed TO SPIDER.set_height

DEF SLIDER2 Slider { mult 6.28  position -.1 .175 -.5 }
ROUTE SLIDER2.value_changed TO SPIDER.set_rotation

DEF SLIDER3 Slider { mult 1.5  position -.1 .15 -.5 }
ROUTE SLIDER3.value_changed TO SPIDER.set_footWidth

DEF SLIDER4 Slider { mult 1.5  position -.1 .125 -.5 }
ROUTE SLIDER4.value_changed TO SPIDER.set_footDepth


mrl