Vue Animated EcoSystem Following Terrain Contours Script
What the script does:

Moves animated figures in an EcoSystem across a terrain, taking terrain altitudes and instance scales into account.

Currently (28th March 2005) the script only works with figures moving exactly North South i.e. from the edge of the terrain furthest back in the Vue scene toward the front.

Updated version posted April 1st 2005.
Removed the option not to recalculate every instance every frame as performance gain was negligible.
Fixed bug which caused figures to occasionally drop to knee deep in the terrain (beware the Python division operator).
Added option to set as startup script. This was to get it to work with HyperVue, however it still doesn't! If you wish to use this option anyway, you must either save this file in; Vue 5 Infinite\Python\Scripts\EcoSystem or edit line 16 in the script to the correct path.
I haven't had time to edit the rest of this page to reflect these changes, so please ignore any reference to differences in scale between instances, these are now automatically dealt with.

N.B. In this, and the previous version, the scale value used is that entered in the population list on the "General" tab of the material editor, not the "Overall Scaling" slider on the "Scaling & Orientation" tab which should be left at 1.00 for the script to function correctly.

Updated version posted March 11th 2009.
The script stopped functioning correctly with the release of Vue 7, whilst this was fixed at Vue 7.21-04 Build 39290 the "hack" used is still useful as it means that instances walking off the terrain should continue on the ground plain.

How to use the script:

First off assess how far the full scale figure to be used in the EcoSystem travels per second, in Vue logical units. This is needed to correctly synchronise the figures' strides with ground covered.

Next set up the EcoSystem with "Direction from surface" slider set all the way to the vertical end of the scale, and Z-axis "Maximum rotation" to 0.

N.B. Figures used in the EcoSystem must NOT have an animation path.

Allow only small changes of scale between instances, or larger ones may walk into the back of smaller ones. Overall scale can be anything suitable to the terrain.

Run the script from the Vue Python menu. Enter the name of the populated terrain in the first dialog to appear. In the next dialog enter the value previously calculated for figure travel per second, for most adult Poser figures 45 works OK.

Please note that after rendering an animation, preview or for real, the instances on the system will be at their final frame positions. To reset the Ecosystem requires either reloading the Vue scene (and re-running the script), or clearing and re-populating the system.


Code (copy and paste):

      
#Vue 5i Animated EcoSystem figure control script
#by John HJ Whitham March 2005
#modified March 2009 to use last altitude if figure walks off the terrain
#Information and updates from: http://www.jwhitham.plus.com/VuePython.html

#*********** NOTE does not function correctly with V7 Infinite versions before
# build 39290 *************************************************************

s = Prompt("Enter the exact name of the terrain to apply the script to (case sensitive).", \
  "",false,"Terrain Name")
T = ObjectByName(s)
if (T==None):
  Message("Unable to find object " + s)
else:
  offset = eval(Prompt("Enter the distance travelled by figure per second in Vue units.", \
    "",true,"Distance per second"))
  offset = float(offset)
set_start = Message("Set this as the startup script?","",5)
if (set_start==2):
  SetPythonStartupScriptPath("Python/Scripts/EcoSystem/FM1Temp.py")

def pyFigureMarchCallback(k):
  for i in range(0,Eco.GetInstanceCount()):
    pos = Eco.GetInstancePosition(i)
    scale = Eco.GetInstanceScale(i)
    newpos = pos[1] - (offset / float(FrameRate()) * scale[2])
    altitude = GetAltitudeOnEcosystemAt(Eco,pos[0],newpos)
    if (altitude == 1e8):      
      Eco.SetInstancePosition(i,pos[0],newpos,pos[2])
    else:
      Eco.SetInstancePosition(i,pos[0],newpos,altitude)

if (offset!=0):
  T.SetInitFrameCallback(pyFigureMarchCallback)
if (set_start==2):
  f=open("FM1Temp.py","w")
  f.write("def pyFigureMarchCallback(k):\n")
  f.write("  T = ObjectByName(" + "'" + s + "'" + ")\n")
  f.write("  Eco = GetEcosystemOnObject(T)\n")
  f.write("  for i in range(0,Eco.GetInstanceCount()):\n")
  f.write("    pos = Eco.GetInstancePosition(i)\n")
  f.write("    scale = Eco.GetInstanceScale(i)\n")
  f.write("    newpos = pos[1] - (" + `offset` + " / float(FrameRate()) * scale[2])\n")
  f.write("    altitude = GetAltitudeOnEcosystemAt(Eco,pos[0],newpos)\n")
  f.write("    Eco.SetInstancePosition(i,pos[0],newpos,altitude)\n")
  f.write("\n")
  f.write("T.SetInitFrameCallback(pyFigureMarchCallback)")
  f.close()      
      
      

1250 "Judy Casual" Poser figures on a standard terrain
Vue 5 Infinite and Poser 5. February 2005.

1500 Poser 'bots on a procedural terrain
Vue 6 Infinite and Poser 5, composited and added "death rays" in Debugmode Wax. C. 2006?

1600 Poser 'bots on a procedural terrain
Vue 7 Infinite and Poser 7. March 2009

The strange flick of the robots' right arms in this clip is courtesy of the Poser Walk Designer.
Vue EcoSystem 'Follow My Leader' Script
What the script does:

Allows an animated object to be used as a 'leader' for EcoSystem instances. The eco instances mimic the translations and rotations of the 'leader' object.

The script does not follow terrain contours, it is intended for flocks of birds or fleets of spaceship sims. The EcoSystem can be on any type of object, and the instances will retain their original relative positions. There is no need to keep the leader within the bounds of the base object, the Eco is used here simply to create instances and distribution patterns.

23/06/05 - Updated to kill 'global already referenced' warning.

N.B. Not currently compatible with HyperVue as it can't be used as a startup script.

Code (copy and paste):

#file = Leader.py
#John Whitham (me@jwhitham.plus.com) 2005

lastpos = None
lobj = None
fobj = None
leader = Prompt("Enter the name of the object to be followed.", \
  "",false,"Enter Leader Name")
follower = Prompt("Enter the name of the object with the follower Eco", \
  "",false,"Enter Eco Object")

def BirdFlock(k):
  Eco = GetEcosystemOnObject(fobj)
  rot = lobj.GetRotationAngles()
  newpos = lobj.Position()
  xdiff = newpos[0] - lastpos[0]
  ydiff = newpos[1] - lastpos[1]
  zdiff = newpos[2] - lastpos[2]
  for boid in range(0,Eco.GetInstanceCount()):
    Eco.SetInstanceRotationV(boid,rot)
    if (CurrentFrame() > 0):  
      Eco.MoveInstance(boid,xdiff,ydiff,zdiff)
  global lastpos
  lastpos = newpos

if (ObjectByName(leader)!=None and ObjectByName(follower)!=None):
  lobj = ObjectByName(leader)
  lastpos = lobj.Position()
  fobj = ObjectByName(follower)
  fobj.SetInitFrameCallback(BirdFlock)
else:
  Message("Wrong","Try Again",1)     
      

It Came From the Starbucks!!!!
An alien flying (cup and) saucer invasion threatens Earth!
Vue 5 Infinite. February 2005
Vue EcoSystem 'Follow My Leader 1' Script
What the script does:

As per the above, but the follower object must be a terrain, and the eco instances follow the terrain contours.
The vertical position of the 'leader' is ignored in this script, but the original offset of the eco instances is applied.

N.B. Not currently compatible with HyperVue as it can't be used as a startup script.

Code (copy and paste):

#File Leader1.py
#John Whitham (me@jwhitham.plus.com) 2005

lastpos = None
lobj = None
fobj = None
eco_offset = 0.0

def SetOffset():
  eco = GetEcosystemOnObject(fobj)
  pos = eco.GetInstancePosition(0)
  alt = GetAltitudeOnEcosystemAt(eco,pos[0],pos[1])
  global eco_offset
  eco_offset = pos[2] - alt

def BirdFlock(k):
  eco = GetEcosystemOnObject(fobj)
  rot = lobj.GetRotationAngles()
  newpos = lobj.Position()
  global lastpos
  xdiff = newpos[0] - lastpos[0]
  ydiff = newpos[1] - lastpos[1]
  lastpos = newpos
  for boid in range(0,eco.GetInstanceCount()):
    fname = eco.GetInstanceFilename(boid)
    if (fname.endswith("Rocks.prv")):
      eco.SetInstanceRotationV(boid,rot)
      if (CurrentFrame()>0): 
        eco.MoveInstance(boid,xdiff,ydiff,0)
        pos = eco.GetInstancePosition(boid)
        alt = GetAltitudeOnEcosystemAt(eco,pos[0],pos[1])
        zpos = alt + eco_offset
        eco.SetInstancePosition(boid,pos[0],pos[1],zpos)

leader = Prompt("Enter the name of the object to be followed.", \
  "",false,"Enter Leader Name")
follower = Prompt("Enter the name of the object with the follower Eco", \
  "",false,"Enter Eco Object")
if (ObjectByName(leader)!=None and ObjectByName(follower)!=None):
  lobj = ObjectByName(leader)
  lastpos = lobj.Position()
  fobj = ObjectByName(follower)
  SetOffset()
  fobj.SetInitFrameCallback(BirdFlock)
else:
  Message("Wrong","Try Again",1)