x=this;
dbb=Button("debug").add();
chat.print("Coffee
script loading...");
//
===== V2R toolkit (unreleased, to be part of AREA) =====
v2r=new
Object();
//
Return the rotation that has to be applied to an object
// that
looks down the negative Z axis with the positive Y
// axis
as up vector to make it look down the forward
//
vector with up as up vector. If forward and up are not
//
perpendicular one of them will be changed to make them
//
perpendicular. If keepUp is true forward will be changed,
// if
keepUp is false up will be changed. The vector that is
//
changed will be rotated so that the cross product of
// both
vectors stays the same. If this does not make any
//
sense to you skip down to the vectorToRotation function
//
instead, it might be of more use to you.
v2r.vectorsToRotation=function(forward,
up, keepUp)
{
var forward1, forward2, up1, up2, rot1,
rot2, dot;
// Initialize the vectors for the initial
rotation.
forward1=Vector(0, 0, -1);
up1=Vector(0, 1, 0);
// Normalized the input vectors. We are
only interested
// in their directions, not their lengths.
forward2=forward.normalized;
up2=up.normalized;
// If forward or up are the zero vector
supply some
// vector that will work.
if(forward2.same(Vector(0, 0, 0)))
forward2=Vector(0, 0, -1);
if(up2.same(Vector(0, 0, 0)))
up2=Vector(0, 1, 0);
if(keepUp)
{
// Make sure forward2 and up2 are
perpendicular
// by adjusting forward2.
forward2=Rotation(
up2.cross(forward2), Math.PI/2 ).map(up2);
}
else
{
// Make sure forward2 and up2 are
perpendicular
// by adjusting up2.
up2=Rotation( forward2.cross(up2),
Math.PI/2 ).map(forward2);
}
// If both forward vectors are not equal
yet:
if(!forward1.same(forward2))
{
// Calculate the rotation necessary to
match both forward
// vectors when applied to forward1.
// Check for the special case where
both vectors are the
// exact opposite.
if(forward1.negated.same(forward2))
{
// Very lame workaround. Figure
out something better.
forward1=Rotation('XY', 0.001,
0.001).map(forward1);
}
// Rounding errors suck.
dot=Math.min(Math.max(forward1.dot(forward2), -1), 1);
rot1=Rotation(
forward1.cross(forward2), Math.acos(dot) );
}
else
{
rot1=Rotation();
}
// Apply the found rotation.
forward1=rot1.map(forward1).normalized;
up1=rot1.map(up1).normalized;
// If both up vectors are not equal yet:
if(!up1.same(up2))
{
// Calculate the rotation necessary to
match both up
// vectors too
// Check for the special case where
both vectors are the
// exact opposite.
if(up1.negated.same(up2))
{
// Very lame workaround. Figure
out something better.
up1=Rotation('XY', 0.001,
0.001).map(up1).normalized;
}
// Rounding errors suck.
dot=Math.min(Math.max(up1.dot(up2),
-1), 1);
rot2=Rotation( up1.cross(up2),
Math.acos(dot) );
}
else
{
rot2=Rotation();
}
//
The combination of the first and second found rotation is
// what we were looking for.
return Rotation(rot2, rot1);
}
// This
function works just like vectorsToRotation but
//
assumes (0, 1, 0) as up vector and false for keepUp.
// In most
of the cases this will be just what you need
// if
you try to make an object look down a certain vector,
// it
returns the rotation you have to apply to an object
//
looking down the negative Z axis when not rotated at
// all
to make it look down the vector vect.
v2r.vectorToRotation=function(vect)
{
return this.vectorsToRotation(vect,
Vector(0, 1, 0), false);
}
//
Project a vector on a plane. If component=false
// the
result vector has the same length as vect,
//
otherwise it's length will be according to it's
//
projection. Instead of defining the plane with
// two
vectors you can also use the strings XY,
// XZ
and YZ for the planes defined by the X and Y,
// X
and Z, and Y and Z axes.
v2r.projectVector=function(vect,
plane, component)
{
var vcross, vres;
// Check for the special strings.
if(plane=='XY' || plane=='xy')
plane=[Vector(1, 0, 0), Vector(0, 1,
0)];
if(plane=='XZ' || plane=='xz')
plane=[Vector(1, 0, 0), Vector(0, 0,
1)];
if(plane=='YZ' || plane=='xy')
plane=[Vector(0, 1, 0), Vector(0, 0,
1)];
// Get a vector perpendicular to the
plane.
vcross=plane[0].cross(plane[1]);
// Calculate a vector that has the same
direction
// as the vector we want.
vres=vcross.cross(vect.cross(vcross));
// Set the length of the vector we found.
if(component)
{
vres=vres.normalized.scale(Math.sqrt(Math.pow(vect.length,
2)-Math.pow(this.vectorsToRotation(vres, Vector(),
false).inverse.map(vect).y, 2)));
}
else
{
vres=vres.normalized.scale(vect.length);
}
// Done.
return vres;
}
//
===== end of V2R toolkit =====
//
//
Message object
//
this.message=function(name,
args, starttime, endtime, method, originalline)
{
this.name=name; // The name of the abstract action that should be performed.
this.arguments=args; // The arguments for the action.
this.starttime=starttime; // The time at which the action should
start (-1 for asap)
this.endtime=endtime; // The time at which the action should end
(-1 for 'when there's something else in the queue')
this.method=method; // "queue" if the action should
be queued, "insert" if the action should be inserted.
this.originalline=originalline; // The line that resulted in this message.
}
//
// Area
object
//
this.area=function(name,
agentname, position, orientation)
{
this.name=name;
this.agentname=agentname;
this.position=position;
this.orientation=orientation;
}
//
//
Action base object
//
this.action=function(name,
owner)
{
this.name=name || "base object";
this.owner=owner || undefined;
this.randanims=new Array();
this.randaStart=0;
this.randaEnd=0;
this.randaDuration=0;
this.randaIndex=0;
this.randaName="";
// This is a default implementation. The
inheriting action should
// redefine it if necessary.
this.start=function(args)
{
if(typeof(this.owner)!="undefined")
this.owner.processQueue();
}
// This is a default implementation. The
inheriting action should
// redefine it if necessary.
this.stop=function()
{
}
//
This is a default implementation. The inheriting action should
// redefine it if necessary.
this.stimestep=function(now, del)
{
}
// Add a random animation.
this.addRandAnim=function(name, duration)
{
this.randanims.push(new Array(name, duration));
}
// Clear the list of random animations.
this.clearRandAnims=function()
{
this.randanims=new Array();
}
// Start playing random animations.
this.startRandAnims=function(now)
{
this.nextRandAnim(now);
}
// Play the next random animation.
this.nextRandAnim=function(now)
{
this.randaIndex=Math.round( (0 - 0.5)
+( ( (this.randanims.length-1+0.49999) - (0-0.5) ) * Math.random() ) );
this.randaName=this.randanims[this.randaIndex][0];
this.randaStart=now;
this.randaDuration=this.randanims[this.randaIndex][1];
this.randaEnd=this.randaStart+this.randaDuration;
this.owner.playAnim(this.randaName);
}
// Random animation timestep function.
this.randaTimestep=function(now, del)
{
if(now>this.randaEnd)
this.nextRandAnim();
}
}
//
// idle
action object
//
this.actionIdle=function()
{
this.name="idle";
this.owner=undefined;
this.sitanims=new Array(
new Array(
new
Array("TurntofaceSB",
1+2*Math.random()),
new
Array("LookatSB",
1+2*Math.random()),
new
Array("TurnbackSB",
1+2*Math.random())
),
new Array(
new
Array("TurntofaceKQ",
1+2*Math.random()),
new
Array("LookatKQ",
1+2*Math.random()),
new
Array("TurnbackKQ", 1+2*Math.random())
),
new Array(
new
Array("TurntofaceBC",
1+2*Math.random()),
new
Array("LookatBC",
1+2*Math.random()),
new
Array("TurnbackBC",
1+2*Math.random())
),
new Array(
new
Array("TurntofaceRZ",
1+2*Math.random()),
new
Array("LookatRZ",
1+2*Math.random()),
new
Array("TurnbackRZ",
1+2*Math.random())
),
new Array(
new Array("TurntofaceCC", 1+2*Math.random()),
new
Array("LookatCC",
1+2*Math.random()),
new
Array("TurnbackCC",
1+2*Math.random())
),
new Array(
new
Array("TurntofaceVP",
1+2*Math.random()),
new
Array("LookatVP",
1+2*Math.random()),
new
Array("TurnbackVP",
1+2*Math.random())
),
// High frequency. Add multiple times.
new Array(
new
Array("Talksitting",
3+6*Math.random())
),
new Array(
new
Array("Talksitting",
3+6*Math.random())
),
new Array(
new
Array("Talksitting",
3+6*Math.random())
),
new Array(
new Array("Talksitting", 3+6*Math.random())
),
new Array(
new
Array("Talksitting",
3+6*Math.random())
),
new Array(
new
Array("Talksitting",
3+6*Math.random())
),
new Array(
new Array("Meetingend", 3+6*Math.random())
),
new Array(
new
Array("Meetingend",
3+6*Math.random())
)
);
this.csitanim=0;
this.csitanimpart=0;
this.csitnexttime=0;
this.tsActive=false;
this.start=function(args)
{
// See if we can play the random
sitting animations.
if(this.owner.queryProp("poseType")=="sitting")
{
// Looks like we can. Start
playing.
this.nextsitanim(args[0]);
this.tsActive=true;
}
else
this.tsActive=false;
}
this.nextsitanim=function(now)
{
this.csitanim=Math.round( (0 - 0.5) +(
( (this.sitanims.length-1+0.49999) - (0-0.5) ) * Math.random() ) )
this.csitanimpart=0;
// See if the chosen animation exists.
if(typeof(this.owner.getAnim(this.sitanims[this.csitanim][this.csitanimpart][0]))=="undefined")
{
// Doesn't exist. Choose another
one.
// Technically this is not a
proper way to do it...
this.nextsitanim(now);
}
else
{
this.owner.playAnim(this.sitanims[this.csitanim][this.csitanimpart][0]);
this.csitnexttime=now+this.sitanims[this.csitanim][this.csitanimpart][1];
}
}
this.stimestep=function(now, del)
{
if(!this.tsActive)
return;
if(now>this.csitnexttime)
{
this.csitanimpart++;
// Next anim or next anim part?
if(this.sitanims[this.csitanim].length>this.csitanimpart)
{
// Next anim part.
this.owner.playAnim(this.sitanims[this.csitanim][this.csitanimpart][0]);
this.csitnexttime=now+this.sitanims[this.csitanim][this.csitanimpart][1];
}
else
{
// Next anim.
this.nextsitanim(now);
}
}
}
}
this.actionIdle.prototype=new
this.action;
//
//
PlaySomeAnim action object (variable timing)
//
this.actionPlaySomeAnim=function()
{
this.name="PlaySomeAnim";
this.owner=undefined;
this.start=function(args)
{
// This is no real animation.
return 0;
}
this.startbutton=Button("Start
someanim").add();
this.startbutton.owner=this;
this.startbutton.onClick=function(state)
{
this.label=this.owner.name;
this.owner.owner.playAnim(this.owner.name);
}
}
this.actionPlaySomeAnim.prototype=new
this.action;
//
//
PlayGenericAction action object (variable timing)
//
this.actionPlayGenericAction=function()
{
this.name="PlayGenericAction";
this.owner=undefined;
this.start=function(args)
{
// Play the provided animation and
block the queue.
this.owner.playAnim(this.yargs.animation);
this.owner.blockQueue();
// This animation takes some seconds.
return this.yargs.duration;
}
this.stimestep=function(now, del)
{
if(now>=this.yargs.duration)
{
//
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionPlayGenericAction.prototype=new
this.action;
//
//
Water action object (variable timing)
//
this.actionWater=function()
{
this.name="Water";
this.owner=undefined;
this.start=function(args)
{
// Play the Water animation and block
the queue.
this.owner.playAnim("Water");
this.owner.blockQueue();
// This animation takes 5 seconds.
return 5;
}
this.stimestep=function(now, del)
{
if(now>=5)
{
//
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionWater.prototype=new
this.action;
//
//
Downladder action object (variable timing)
//
this.actionDownladder=function()
{
this.name="Downladder";
this.owner=undefined;
this.start=function(args)
{
// Play the Downladder animation and
block the queue.
this.owner.playAnim("Downladder");
this.owner.blockQueue();
// This animation takes 8 seconds.
return 8;
}
this.stimestep=function(now, del)
{
if(now>=8)
{
//
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionDownladder.prototype=new
this.action;
//
//
Upladder action object (variable timing)
//
this.actionUpladder=function()
{
this.name="Upladder";
this.owner=undefined;
this.start=function(args)
{
// Play the Upladder animation and
block the queue.
this.owner.playAnim("Upladder");
this.owner.blockQueue();
// This animation takes 8 seconds.
return 8;
}
this.stimestep=function(now, del)
{
if(now>=8)
{
// this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionUpladder.prototype=new
this.action;
//
//
RequestingWeatherReport action object (variable timing)
//
this.actionRequestingWeatherReport=function()
{
this.name="RequestingWeatherReport";
this.owner=undefined;
this.start=function(args)
{
// Play the Weather animation and
block the queue.
this.owner.playAnim("Weather");
this.owner.blockQueue();
// This animation takes 3 seconds.
return 3;
}
this.stimestep=function(now, del)
{
if(now>=3)
{
//
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionRequestingWeatherReport.prototype=new
this.action;
//
//
RequestingGeneratorStatus action object (variable timing)
//
this.actionRequestingGeneratorStatus=function()
{
this.name="RequestingGeneratorStatus";
this.owner=undefined;
this.start=function(args)
{
// Play the Generator animation and
block the queue.
this.owner.playAnim("Generator");
this.owner.blockQueue();
// This animation takes 3 seconds.
return 3;
}
this.stimestep=function(now, del)
{
if(now>=3)
{
//
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionRequestingGeneratorStatus.prototype=new
this.action;
//
//
AnnouncingStartOfPlanning action object (variable timing)
//
this.actionAnnouncingStartOfPlanning=function()
{
this.name="AnnouncingStartOfPlanning";
this.owner=undefined;
this.start=function(args)
{
// Play the Meetingstart animation and
block the queue.
this.owner.playAnim("Meetingstart");
this.owner.blockQueue();
// This animation takes n seconds.
return 2;
}
this.stimestep=function(now, del)
{
if(now>=2)
{
//
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionAnnouncingStartOfPlanning.prototype=new
this.action;
//
//
ReportingFoodAvailabilityToCommander action object (variable timing)
//
this.actionReportingFoodAvailabilityToCommander=function()
{
this.name="ReportingFoodAvailabilityToCommander";
this.owner=undefined;
this.start=function(args)
{
// Play the Food animation and block
the queue.
this.owner.playAnim("Food");
this.owner.blockQueue();
// This animation takes 3 seconds.
return 120;
}
this.stimestep=function(now, del)
{
if(now>=120)
{
// this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionReportingFoodAvailabilityToCommander.prototype=new
this.action;
//
//
CheckingFoodAvailability action object (variable timing)
//
this.actionCheckingFoodAvailability=function()
{
this.name="CheckingFoodAvailability";
this.owner=undefined;
this.phase=0;
this.start=function(args)
{
// Play the Lookincabinet animation
and block the queue.
this.owner.playAnim("Lookincabinet");
this.owner.blockQueue();
// This animation takes 260 seconds.
return 260;
this.phase=0;
}
this.stimestep=function(now, del)
{
switch(this.phase)
{
case 0:
if(now>=3)
{
// Time to go to the next
phase.
this.owner.getAnim("Lookincabinet").stop();
this.owner.getAnim("Lookincabinet").time=3;
this.phase++;
}
break;
case 1:
if(now>=257)
{
// Time to go to the next
phase.
this.owner.getAnim("Lookincabinet").start();
this.phase++;
}
break;
case 2:
if(now>=260)
{
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
break;
}
}
}
this.actionCheckingFoodAvailability.prototype=new
this.action;
//
//
PickingUpNotepad action object (variable timing)
//
this.actionPickingUpNotepad=function()
{
this.name="PickingUpNotepad";
this.owner=undefined;
this.duration=-1;
this.start=function(args)
{
// Block the queue.
this.owner.blockQueue();
// Update the animation properties.
this.owner.setProp("animSit", "Sitwithnotepad");
this.owner.setProp("animGetUp", "Getupwithnotepad");
this.owner.setProp("animSitDown",
"Sitdownwithnotepad");
this.owner.setProp("animStand", "Standwithnotepad");
this.owner.setProp("animWalk", "Walkwithnotepad");
this.owner.setProp("animRotateLeft",
"l45withnotepad");
this.owner.setProp("animRotateRight",
"r45withnotepad");
this.owner.playAnim(this.owner.queryProp("animStand"));
// This animation takes whatever time
necessary.
this.duration=args[1]-args[0];
return this.duration;
}
this.stimestep=function(now, del)
{
if(now>=this.duration)
{
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionPickingUpNotepad.prototype=new
this.action;
//
//
SittingThroughPlanning action object
//
this.actionSittingThroughPlanning=function()
{
this.name="SittingThroughPlanning";
this.owner=undefined;
this.endtime=-1;
this.start=function(args)
{
// Make sure the avatar is seated and
block the queue.
this.owner.playAnim(this.owner.queryProp("animSit"));
this.owner.blockQueue();
// Calculate when to transfer control
back to the agent.
this.endtime=args[1];
}
this.stimestep=function(now, del)
{
if(now>this.endtime)
{
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionSittingThroughPlanning.prototype=new
this.action;
//
//
SetTransform action object
//
this.actionSetTransform=function()
{
this.name="SetTransform";
this.owner=undefined;
this.start=function(args)
{
this.owner.playAnim("moveModel", args[4].position);
this.owner.playAnim("rotateModel",
args[4].orientation);
this.owner.processQueue();
}
}
this.actionSetTransform.prototype=new
this.action;
//
//
BeSeated action object
//
this.actionBeSeated=function()
{
this.name="BeSeated";
this.owner=undefined;
this.start=function(args)
{
// Make sure the agent is seated.
this.owner.playAnim(this.owner.queryProp("animSit"));
this.owner.setProp("poseType", "sitting");
this.owner.processQueue();
}
}
this.actionBeSeated.prototype=new
this.action;
//
//
Sitdown action object (variable timing)
//
this.actionSitdown=function()
{
this.name="Sitdown";
this.owner=undefined;
this.duration=2;
this.endtime=0;
this.start=function(args)
{
// Play the sitDown animation and
block the queue.
this.owner.playAnim(this.owner.queryProp("animSitDown"));
this.owner.blockQueue();
// Update the poseType property.
this.owner.setProp("poseType",
"sitting");
// This animation takes 2.2 seconds.
return 2.2;
}
this.stop=function()
{
this.owner.playAnim(this.owner.queryProp("animSit"));
}
this.stimestep=function(now, del)
{
if(now>=2.2)
{
this.owner.playAnim(this.owner.queryProp("animSit"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionSitdown.prototype=new
this.action;
//
//
Getup action object (variable timing)
//
this.actionGetup=function()
{
this.name="Getup";
this.owner=undefined;
this.start=function(args)
{
// Play the getUp animation and block
the queue.
this.owner.playAnim(this.owner.queryProp("animGetUp"));
this.owner.blockQueue();
// Update the poseType property.
this.owner.setProp("poseType", "standing");
// This animation takes 2.2 seconds.
return 2.2;
}
this.stop=function()
{
this.owner.playAnim(this.owner.queryProp("animStand"));
}
this.stimestep=function(now, del)
{
if(now>=2.2)
{
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionGetup.prototype=new
this.action;
//
// Walk
action object (variable timing)
//
this.actionWalk=function()
{
this.name="Walk";
this.owner=undefined;
this.sections=new Array();
this.currentSection=0;
this.totaltime=0;
this.start=function(args)
{
var
i, irot, tlength;
var
section=function(frompos, topos)
{
this.frompos=frompos;
this.topos=topos;
}
if(typeof(args[5])!="undefined")
{
// We have a path.
this.sections=new Array();
for(i=0;i<args[5].length-1;i++)
{
this.sections.push(new
section(
args[5][i],
args[5][i+1]
));
}
}
else
{
// We don't have a path.
this.sections=new Array(
new section(
args[3].position,
args[4].position
)
);
}
// Calculate the sections.
irot=this.owner.queryProp("modelOrientation");
for(i=0;i<this.sections.length-1;i++)
{
// The rotation this section
should start at.
this.sections[i].startrot=irot;
// The rotation this section
should stop at.
irot=v2r.vectorToRotation(this.sections[i].topos.subtract(this.sections[i].frompos)).blend(
v2r.vectorToRotation(this.sections[i+1].topos.subtract(this.sections[i+1].frompos)),
0.5);
this.sections[i].endrot=irot;
}
this.sections[this.sections.length-1].startrot=irot;
this.sections[this.sections.length-1].endrot=args[4].orientation;
/*
this.sections[this.sections.length-1].endrot=v2r.vectorToRotation(
this.sections[this.sections.length-1].topos.subtract(
this.sections[this.sections.length-1].frompos)
);
*/
this.currentSection=-1;
this.prepareNext(0);
this.owner.blockQueue();
// chat.print("Found
", this.sections.length, " sections.");
//
Calculate the total length and use it to calculate the
//
total time the animation will take.
tlength=0;
for(i=0;i<this.sections.length;i++)
{
tlength+=this.sections[i].topos.subtract(this.sections[i].frompos).length;
}
// chat.print("Walking
over a distance of ", tlength, " units.");
this.totaltime=tlength/this.owner.queryProp("walkSpeed");
this.owner.playAnim(this.owner.queryProp("animWalk"));
return
this.totaltime;
}
// Prepare the next section.
this.prepareNext=function(now)
{
var sec;
this.currentSection++;
//
If all sections are done, stop this action.
if(this.currentSection>=this.sections.length)
{
this.owner.playAnim("moveModel",
this.sections[this.sections.length-1].topos);
this.owner.playAnim("rotateModel",
this.sections[this.sections.length-1].endrot);
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
return;
}
// Get the new section.
sec=this.sections[this.currentSection];
//
Find start time, end time for moving, and for now also for rotation.
this.secStartTime=now;
this.secEndTime=now+(sec.topos.subtract(sec.frompos).length/this.owner.queryProp("walkSpeed"));
this.secTotalTime=this.secEndTime-this.secStartTime;
this.secStartPos=sec.frompos;
this.secEndPos=sec.topos;
this.secStartRot=sec.startrot;
this.secEndRot=sec.endrot;
}
this.stimestep=function(now, del)
{
//
Set the position of the agent.
this.owner.playAnim("moveModel",
this.secStartPos.blend(this.secEndPos,
(now-this.secStartTime)/this.secTotalTime));
// Set the orientation of the agent.
this.owner.playAnim("rotateModel",
this.secStartRot.blend(this.secEndRot,
(now-this.secStartTime)/this.secTotalTime));
if(now>=this.secEndTime)
this.prepareNext(now);
}
}
this.actionWalk.prototype=new
this.action;
/////////// Old coffee actions below ////////////
//
//
setPosition action object
//
this.actionSetPosition=function()
{
this.name="setPosition";
this.owner=undefined;
this.start=function(args)
{
this.owner.playAnim("moveModel", args[2]);
this.owner.processQueue();
}
}
this.actionSetPosition.prototype=new
this.action;
//
//
GrabMug action object (non-blocking)
//
this.actionGrabMug=function()
{
this.name="GrabMug";
this.owner=undefined;
this.start=function(args)
{
// Grab the mug.
this.owner.addToInventory(args[3]);
// Go on.
this.owner.processQueue();
}
}
this.actionGrabMug.prototype=new
this.action;
//
//
TurningMicrowaveOn action object (non-blocking)
//
this.actionTurningMicrowaveOn=function()
{
this.name="TurningMicrowaveOn";
this.owner=undefined;
this.start=function(args)
{
// Turn it on.
args[2][0].start();
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
0-(args[1]-args[0]) );
// Go on.
this.owner.processQueue();
}
}
this.actionTurningMicrowaveOn.prototype=new
this.action;
//
//
TurningMicrowaveOff action object (non-blocking)
//
this.actionTurningMicrowaveOff=function()
{
this.name="TurningMicrowaveOff";
this.owner=undefined;
this.start=function(args)
{
// Turn it off.
args[2][0].stop();
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
0-(args[1]-args[0]) );
// Go on.
this.owner.processQueue();
}
}
this.actionTurningMicrowaveOff.prototype=new
this.action;
//
//
GettingUp action object (self-timing)
//
this.actionGettingUp=function()
{
this.name="GettingUp";
this.owner=undefined;
this.duration=2;
this.endtime=0;
this.start=function(args)
{
// Play the getUp animation and block
the queue.
this.owner.playAnim("Getupwithfullmug");
this.owner.blockQueue();
// Calculate when to transfer control
back to the agent.
this.endtime=this.owner.getTime()+this.duration;
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
this.duration-(args[1]-args[0]) );
}
this.stimestep=function(now, del)
{
if(now>this.endtime)
{
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.setProp("state", "standing");
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionGettingUp.prototype=new
this.action;
//
//
SittingDown action object (self-timing)
//
this.actionSittingDown=function()
{
this.name="SittingDown";
this.owner=undefined;
this.duration=2;
this.endtime=0;
this.start=function(args)
{
// Play the sitDown animation and
block the queue.
this.owner.playAnim("Sitdownwithfullmug");
this.owner.blockQueue();
// Calculate when to transfer control
back to the agent.
this.endtime=this.owner.getTime()+this.duration;
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
this.duration-(args[1]-args[0]) );
}
this.stimestep=function(now, del)
{
if(now>this.endtime)
{
this.owner.playAnim("Sitwithfullmug"); // Must do this with a property!
this.owner.setProp("state", "seated");
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionSittingDown.prototype=new
this.action;
//
//
WaitingForCoffeeToWarmUp action object (self-timing)
//
this.actionWaitingForCoffeeToWarmUp=function()
{
this.name="WaitingForCoffeeToWarmUp";
this.owner=undefined;
this.duration=2;
this.endtime=0;
this.start=function(args)
{
// Play the wait animation and block
the queue.
this.owner.playAnim("Wait");
this.owner.blockQueue();
// Calculate when to transfer control
back to the agent.
this.endtime=this.owner.getTime()+this.duration;
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
this.duration-(args[1]-args[0]) );
}
this.stimestep=function(now, del)
{
if(now>this.endtime)
{
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
}
}
}
this.actionWaitingForCoffeeToWarmUp.prototype=new
this.action;
//
//
PuttingCupInMicrowave action object (self-timing)
//
this.actionPuttingCupInMicrowave=function()
{
this.name="PuttingCupInMicrowave";
this.owner=undefined;
this.duration=2.5;
this.start=function(args)
{
this.owner.playAnim("Putmugina");
this.part=0;
this.next=this.owner.getTime()+0.5; //1.13;
this.owner.blockQueue();
this.microwave=args[4];
this.mug=args[3];
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
this.duration-(args[1]-args[0]) );
}
this.stimestep=function(now, del)
{
if(this.next>now)
return;
switch(this.part)
{
case 0:
this.microwave.openDoor();
this.next+=0.63;
this.part++;
break;
case 1:
this.owner.playAnim("HideMug");
this.owner.playAnim("Putmuginb");
this.owner.removeFromInventory(this.mug);
this.microwave.addToInventory(this.mug);
this.next=now+0.4; //0.97;
this.part++;
break;
case 2:
this.microwave.closeDoor();
this.next+=0.57;
this.part++;
break;
case 3:
// chat.print("STATUS: Ok,
done putting mug in.");
this.owner.playAnim("Stand"); // Must do this with a property!
this.owner.unBlockQueue();
this.owner.processQueue();
break;
default:
throw("Euh?");
}
}
}
this.actionPuttingCupInMicrowave.prototype=new
this.action;
//
//
TakingCupOutOfMicrowave action object (self-timing)
//
this.actionTakingCupOutOfMicrowave=function()
{
this.name="TakingCupOutOfMicrowave";
this.owner=undefined;
this.duration=2.5;
this.start=function(args)
{
this.owner.playAnim("Takemugouta");
this.part=0;
this.next=this.owner.getTime()+0.4;
this.owner.blockQueue();
this.microwave=args[4];
this.mug=args[3];
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
this.duration-(args[1]-args[0]) );
}
this.stimestep=function(now, del)
{
if(this.next>now)
return;
switch(this.part)
{
case 0:
this.microwave.openDoor();
this.next+=0.56;
this.part++;
break;
case 1:
this.owner.playAnim("ShowMug");
this.owner.playAnim("Takemugoutb");
this.next=now+0.5; //1.13;
this.part++;
break;
case 2:
this.microwave.closeDoor();
this.next+=0.63;
this.part++;
break;
case 3:
// chat.print("STATUS: Ok,
got mug.");
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.unBlockQueue();
this.owner.processQueue();
break;
default:
throw("Euh?");
}
}
}
this.actionTakingCupOutOfMicrowave.prototype=new
this.action;
//
//
RotateTo action object (self-timing)
//
this.actionRotateTo=function()
{
this.name="RotateTo";
this.owner=undefined;
this.duration=-1;
this.starttime=-1;
this.endtime=-1;
this.startrot=Rotation();
this.endrot=Rotation();
this.start=function(args)
{
// Find the start and end rotations.
this.startrot=this.owner.queryProp("modelOrientation");
this.endrot=args[4][2];
// Find out whether to rotate left or
right and play
// the corresponding animation.
if(this.startrot.inverse.map(this.endrot.map(Vector(0, 0, -1))).x<0)
this.owner.playAnim("45lwithfullmug")
else
this.owner.playAnim("45rwithfullmug");
// Calculate the start and end times.
this.starttime=this.owner.getTime();
this.duration=(this.owner.queryProp("fullRotationTime")/2)*(Math.acos(this.startrot.map(Vector(0,
0, 1)).dot(this.endrot.map(Vector(0, 0, 1))))/Math.PI);
this.endtime=this.starttime+this.duration;
// Block the queue.
this.owner.blockQueue();
// Calculate the queue offset due to
self-timing.
this.owner.shiftQueue(
this.duration-(args[1]-args[0]) );
}
this.stimestep=function(now, del)
{
if(now>this.endtime)
{
this.owner.playAnim("rotateModel", this.endrot);
this.owner.playAnim(this.owner.queryProp("animStand"));
this.owner.setProp("state", "standing");
this.owner.unBlockQueue();
this.owner.processQueue();
}
else
this.owner.playAnim("rotateModel",
this.startrot.blend(this.endrot, (now-this.starttime)/this.duration));
}
}
this.actionRotateTo.prototype=new
this.action;
//
//
MovingToArea action object (self-timing)
//
this.actionMovingToArea=function()
{
this.name="MovingToArea";
this.owner=undefined;
this.actionPlannedEnd=-1;
this.stops=new Array();
this.rots=new Array();
this.endrot=Rotation();
// this.duration=2;
// this.endtime=0;
this.doNext=function()
{
var msg;
if(this.nextStop>=this.stops.length)
// If we are done walking:
{
this.owner.playAnim("moveModel",
this.endpos);
this.owner.playAnim("rotateModel",
this.rots[this.rots.length-1]);
this.owner.playAnim(this.owner.queryProp("animStand"));
// Shift the queue.
this.owner.shiftQueue(this.owner.getTime()-this.actionPlannedEnd);
// Do the final rotation.
msg=new
this.owner.controller.owner.message("RotateTo",
new
Array(this.owner.getTime(), this.owner.getTime(),
0, 0, new Array(0, 0,
this.endrot)),
this.owner.getTime(),
this.owner.getTime(), "insert"),
this.owner.processMessage(msg);
this.owner.unBlockQueue();
this.owner.processQueue();
return;
}
// Init movement.
this.startpos=this.owner.queryProp("modelPosition");
this.endpos=this.stops[this.nextStop];
this.starttime=this.owner.getTime();
this.totaltime=this.startpos.subtract(this.endpos).length/2;
this.endtime=this.starttime+this.totaltime;
// Init rotations.
this.rotpart=0;
this.rot0=this.owner.queryProp("modelOrientation");
this.rot1=this.rots[this.nextStop];
this.rot2=this.rot1.blend(this.rots[this.nextStop+1],
0.5);
this.rot01time=Math.acos(this.rot0.map(Vector(0, 0,
-1)).dot(this.rot1.map(Vector(0, 0, -1))))/(Math.PI*0.1);
this.rot12time=Math.acos(this.rot1.map(Vector(0, 0,
-1)).dot(this.rot2.map(Vector(0, 0, -1))))/(Math.PI*0.1);
this.rotstart=this.rot0;
this.rotend=this.rot1;
this.rotstarttime=this.owner.getTime();
this.rottotaltime=this.rot01time;
this.rotendtime=this.rotstarttime+this.rot01time;
this.nextStop++;
}
this.start=function(args)
{
var pos2, msg, xzproj, yangle, xangle,
i, from, to;
this.stops=new Array();
this.rots=new Array();
// See if we need to play RotateTo
first.
if(typeof(args[5])=="undefined")
{
// chat.print("Taking final
position.");
pos2=args[3][1]
}
else
{
// chat.print("Taking inbetween
position.");
pos2=args[5][2];
}
if(
Math.acos(pos2.subtract(this.owner.queryProp("modelPosition")).normalized.negated.dot(this.owner.queryProp("modelOrientation").map(Vector(0,
0, 1))))>0.1)
{
// chat.print("STATUS: Going for
RotateTo first.");
this.owner.blockQueue();
//this.message=function(name,
args, starttime, endtime, method)
// Insert this action again.
msg=new
this.owner.controller.owner.message("MovingToArea", args, args[0],
args[1], "insert");
this.owner.processMessage(msg);
// Insert the RotateTo action.
xzproj=Vector(0, 1,
0).cross(pos2.subtract(args[3][1])).cross(Vector(0, 1, 0)).normalized;
yangle=(args[3][1].x<pos2.x?1:-1)*Math.acos((xzproj.dot(Vector(0, 0,
-1))));
xangle=0;
msg=new
this.owner.controller.owner.message("RotateTo",
new Array(args[0], args[0], 0,
0, new Array(0, 0, Rotation('YX', yangle, xangle).inverse)),
args[0], args[0], "insert"),
this.owner.processMessage(msg);
this.owner.unBlockQueue();
this.owner.processQueue();
return;
}
// else
// chat.print("STATUS: RotateTo
was not necessary.");
// Remember when the action was
planned to end.
this.actionPlannedEnd=args[1];
// Remember the planned final
rotation.
this.endrot=args[4][2];
// Fill the stops array.
// this.stops.push(args[3][1]);
if(args[5].length>2)
{
for(i=2;i<args[5].length;i++)
this.stops.push(args[5][i]);
}
this.stops.push(args[4][1]);
// Create rotations.
for(i=0;i<this.stops.length;i++)
{
if(i==0)
from=this.owner.queryProp("modelPosition");
else
from=this.stops[i-1];
to=this.stops[i];
xzproj=Vector(0, 1, 0).cross(to.subtract(from)).cross(Vector(0,
1, 0)).normalized;
yangle=(from.x<to.x?1:-1)*Math.acos((xzproj.dot(Vector(0, 0, -1))));
xangle=0;
this.rots.push(Rotation('YX',
yangle, xangle).inverse);
}
this.rots.push(this.rots[this.rots.length-1]);
this.nextStop=0;
this.endpos=this.owner.queryProp("modelPosition");
this.owner.playAnim("Walkwithfullmug");
this.owner.blockQueue();
this.doNext();
// Calculate the queue offset due to
self-timing.
//
this.owner.shiftQueue( this.duration-(args[1]-args[0]) );
}
this.stimestep=function(now, del)
{
if(this.rotpart!=2)
{
if(now>(this.endtime-this.rot12time))
{
this.rotpart=2;
this.rotstart=this.rot1;
this.rotend=this.rot2;
this.rotstarttime=this.endtime-this.rot12time;
this.rottotaltime=this.rot12time; //02
this.rotendtime=this.endtime;;
}
}
switch(this.rotpart)
{
case 0:
if(now>this.rotendtime)
{
this.owner.playAnim("rotateModel", this.rotend);
this.rotpart=1;
}
this.owner.playAnim("rotateModel",
this.rotstart.blend(this.rotend, (now-this.rotstarttime)/this.rottotaltime));
break;
case 1:
break;
case 2:
this.owner.playAnim("rotateModel",
this.rotstart.blend(this.rotend, (now-this.rotstarttime)/this.rottotaltime));
break;
}
if(now>this.endtime)
{
this.doNext();
}
else
this.owner.playAnim("moveModel",
(this.startpos.blend(this.endpos, (now-this.starttime)/this.totaltime)));
}
}
this.actionMovingToArea.prototype=new
this.action;
//
//
Worldobject object
//
this.worldobject=function()
{
this.inObject=undefined; // What object this world object is
currently in.
this.inventory=new Array; //The list of items currently in this
object.
// Returns true if obj is in the inventory.
this.isInInventory=function(obj)
{
for(i=0;i<this.inventory.length;i++)
{
if(this.inventory[i]==obj)
return true;
}
return false;
}
// Add an object to the inventory of this
object.
// obj is a worldobject too.
this.addToInventory=function(obj)
{
var i;
if(typeof(obj.inObject)!="undefined")
{
obj.inObject.removeFromInventory(obj);
}
for(i=0;i<this.inventory.length;i++)
{
if(this.inventory[i]==obj)
return;
}
this.inventory.push(obj);
obj.inObject=this;
}
// Remove an object from the inventory of
this object.
this.removeFromInventory=function(obj)
{
var i;
if(obj.inObject==this)
obj.inObject=undefined;
for(i=0;i<this.inventory.length;i++)
{
if(this.inventory[i]==obj)
{
this.inventory.splice(i, 1);
return;
}
}
}
}
//
// Prop
object
//
this.prop=function()
{
// Nothing here yet...
}
this.prop.prototype=new
this.worldobject;
//
//
Agent object
//
this.agent=function()
{
//
// Variables
//
this.ready=false; // Is this agent ready to be used?
this.vpObjLoaded=false; // Is the viewpoint object ready to be
used?
this.vpObj=undefined; // The viewpoint object.
this.vpAnims=new Array(); // The viewpoint animations.
this.vpGeometry=new Array(); // The viewpoint geometry objects.
this.model=undefined; // The model.
this.modelLoaded=false; // Is the model ready to be used?
this.properties=new Array(); // The properties.
this.queue=new Array(); // The message queue.
this.queueBlocked=false; // Whether the queue is blocked.
this.controller=undefined; // The controller object.
this.modelurl=""; // The url of the model.
this.actions=new Array(); // The actions.
this.currentAction=undefined; // The currently running action.
this.idleAction=undefined; // The idle action.
this.name=""; //
The name of the agent.
this.asZeroBased=false; // Whether the action script wants a
zero-based now.
this.asStart=-1; // The time the action script started at.
this.asDuration=-1; // The time the action script said it
takes to finish.
this.asRealDuration=-1; // The time the action script should
really take.
this.asTimeMultiplier=1; // Time multiplier due to script duration.
this.asLast=0; // For calculating del for action scripts.
//
// Misc stuff.
//
// The inheriting agent object must call
this function to
// set up the model (and therefore it's
viewpoint animations).
// This function takes care of everything,
there's no need
// for Model(url).add() or something like
that.
this.initModel=function(url, controller)
{
this.model=Model(url).add();
this.model.owner=this;
this.modelurl=url;
this.controller=controller;
this.model.timestep=function(now, del)
{
if(!this.loaded)
return;
this.owner.auxInitModel();
removeAnimator(this);
}
addAnimator(this.model);
}
// This function is called once the model
has finished trying to load.
this.auxInitModel=function()
{
if(this.model.getSolidObjectCount==0)
{
chat.print("ERROR: Model
\"" + this.modelurl + "\" failed to load.");
return;
}
this.modelLoaded=true;
this.initViewpointObject();
if(this.vpObjLoaded)
{
this.ready=true;
chat.print("STATUS: Actor
with model \"" + this.modelurl + "\" is ready to be
used.");
this.controller.agentIsReady(this);
}
else
{
chat.print("ERROR: Actor with
model \"" + this.modelurl + "\" seems to have failed
loading.");
}
}
// Return the current simulation time.
this.getTime=function()
{
return this.controller.getTime();
}
// Return the simulation time intervall
since the simulation timestep.
this.getDeltaTime=function()
{
return this.controller.getDeltaTime();
}
// Return the current simulation time
multiplier - 1 is real time,
// 2 is 2x real time, etc.
this.getTimeMultiplier=function()
{
return
this.controller.getTimeMultiplier();
}
// Custom timestep function.
this.auxstimestep=function(now, del)
{
}
// Simulation timestep function.
this.stimestep=function(now, del)
{
var i, asNow;
this.auxstimestep(now, del);
if(asZeroBased)
asNow=((now-this.asStart)/this.asRealDuration)*this.asDuration;
else
asNow=(((now-this.asStart)/this.asRealDuration)*this.asDuration)+this.asStart;
// Special case for the idle
action.
if(this.currentAction==this.idleAction)
this.currentAction.stimestep(now,
del);
else
this.currentAction.stimestep(asNow, asNow-this.asLast);
this.asLast=asNow;
// Update the speed multipliers of the
viewpoint anims if necessary.
for(i=0;i<this.vpAnims.length;i++)
{
this.vpAnims[i].speed=this.getTimeMultiplier()*this.asTimeMultiplier;
dbb.label="tm1 " +
this.getTimeMultiplier() + " tm2 " + this.asTimeMultiplier;
}
// Call processQueue in case something
has to be done.
this.processQueue();
}
// Add an action to the list of available
actions. Actions have
// their own name, but it can be overrided
by the optional name
// argument here. The yargs argument can
be used to pass extra
// arguments to an action.
this.addAction=function(action, name,
yargs)
{
action.owner=this;
if(typeof(name)!="undefined")
action.name=name;
action.yargs=yargs;
this.actions.push(action);
chat.print("STATUS: Added action
\"", action.name, "\".");
}
// Set the idle action.
this.setIdleAction=function(action)
{
action.owner=this;
this.idleAction=action;
// Make sure it's running if there's
nothing else running so far.
this.processQueue();
}
//
// Viewpoint animation control.
//
// Find the animation named name and
return it, or 'undefined'
// if it couldn't be found.
this.getAnim=function(name)
{
var i, found, anim;
// See if there's an animation named
name
found=false;
for(i=0;i<this.vpAnims.length;i++)
{
if(this.vpAnims[i].getName()==name)
{
anim=this.vpAnims[i];
found=true;
break;
}
}
if(found)
{
return anim;
}
else
{
return undefined;
}
}
// Make sure all true viewpoint animations
are stopped.
this.stopTrueAnims=function()
{
for(i=0;i<this.vpAnims.length;i++)
{
this.vpAnims[i].stop();
}
}
// Play the abstract animation named name.
This is a default
// implementation, the inheriting agent
object is supposed to redefine
// this function (best copy and then
modify it). Return true if
// done, return false if you want playAnim
to try to play it.
// args is an array of arguments passed
along with the animation
// name. Remember to do stopTrueAnims()
before triggering any other
// true viewpoint animation.
this.auxPlayAnim=function(name, args)
{
return false;
}
// Play the abstract animation named name.
All actions will call
// this function to play any kind of
animation. This function does some
// checking, then hands over control to
auxPlayAnim which then gets
// a chance to play it first. If aux deceides
not to play it playAnim
// will try to do it the default way.
this.playAnim=function(name)
{
var anim, i, found, args;
// chat.print("STATUS: playAnim was
called for the animation named \"", name, "\".");
// Capture the arguments.
args=new Array();
i=1;
while(arguments[i]!=undefined)
{
args.push(arguments[i]);
i++;
}
// See if the viewpoint object is
loaded.
if(!this.vpObjLoaded)
return;
// Give auxPlayAnim a chance to handle
this animation.
if(this.auxPlayAnim(name, args))
{
// chat.print("STATUS:
auxPlayAnim handled the animation.");
return;
}
// Still here? Then aux did not do
this animation. Try to do it
// ourselves.
// chat.print("STATUS: auxPlayAnim
did not handle the animation.");
// Try the default non-true
animations.
switch(name)
{
// moveModel moves the model to
the position indicated by
// the first extra argument.
case "moveModel":
this.model.position=args[0];
return;
// rotateModel rotates the model
to the orientation indicated
// by the first extra argument.
case "rotateModel":
this.model.orientation=args[0];
return;
}
// See if there is a true viewpoint
animation with name name.
// If so, play it.
anim=this.getAnim(name);
if(typeof(anim)=="undefined")
{
chat.print("WARNING: Could
not find an animation named \"", name,
"\" to play.");
}
else
{
this.stopTrueAnims();
anim.trigger();
}
}
// Find all viewpoint animations and
geometry in this.vpObj and
// put them in this.vpAnims and
this.vpGeometry respectively.
this.initViewpointObject=function()
{
var animgroup, i, anim;
this.vpObj=this.model.getViewpointObject(0);
animgroup=this.vpObj.scene.getTimeElem("PoserAnimSetsGroup");
for(i=0;i<animgroup.getChildCount();i++)
{
anim=animgroup.getChild(i);
anim.defaultTimeMultiplier=1;
this.vpAnims.push(anim);
chat.print("Loaded anim
\"", anim.getName(), "\"");
}
chat.print("STATUS: Loaded
", i, " animations.");
this.vpObjLoaded=true;
}
//
// Message, queue and action control
//
// This function is called by
processMessage. Inheriting
// objects can redefine it and do their
own message processing
// here. Return the message if you want it
to be processed
// the normal way, or undefined if you
want no further processing.
this.auxProcessMessage=function(msg)
{
return msg;
}
// Process message msg. Put it in the
queue or do whatever else
// is necessary.
this.processMessage=function(msg)
{
var rmsg;
// chat.print("STATUS:
processMessage got message with " +
// "action \"",
msg.name, "\".");
// If this agent is not ready yet
ignore the message.
if(!this.ready)
return;
// Give auz the chance to do
something.
rmsg=this.auxProcessMessage(msg);
if(typeof(rmsg)=="undefined")
{
// chat.print("STATUS:
auxProcessMessage handled the message.");
return;
}
else
{
// chat.print("STATUS:
auxProcessMessage did not handle the message.");
}
// Still here? Process the message the
default way.
// All messages for non-true actions
should be processed here.
// Those can't be queued.
// ...
// See if the message came with a
valid method.
if((rmsg.method!="queue")
&& (rmsg.method!="insert"))
{
chat.print("WARNING: message
came with unknown method, was ignored.");
return;
}
// Queue or insert it.
if(rmsg.method=="queue")
{
this.queue.push(rmsg);
// chat.print("STATUS: Queued
message for \"", rmsg.name, "\".");
}
else
if(rmsg.method=="insert")
{
this.queue.unshift(rmsg);
// chat.print("STATUS: Inserted
message for \"", rmsg.name, "\".");
}
// Try to process the queue.
this.processQueue();
}
// Process the next item in the queue
unless the queue is blocked.
this.processQueue=function()
{
var msg, idx, done, startres;
// If blocked, do nothing.
if(this.queueBlocked)
{
return;
}
// See if there's something in the
queue.
if(this.queue.length)
{
// See if the next message can be
started already.
if(this.queue[0].starttime<=this.getTime())
{
// Get the next message and
figure out what to do.
msg=this.queue.shift();
idx=0;
done=false;
while((idx<this.actions.length)
&& !done)
{
if(this.actions[idx].name==msg.name)
{
act=this.actions[idx];
done=true;
}
idx++;
}
if(!done) // Oops, that message isn't recognized...
{
chat.print("WARNING:
processQueue: did not recognize message " +
"for action named
\"", msg.name, "\".");
chat.print("NOTE: The
above warning can now be ignored unless " +
"you see unusual
things happening.");
// Play the idle action
instead.
act=this.idleAction;
// Set up the message for
the idle action here.
msg=new
this.controller.owner.message("", new Array(this.getTime(), 0),
this.getTime(), -1, "queue");
}
}
else // If the next message can't
be started yet, do the idle animation.
{
act=this.idleAction;
// Set up the message for the
idle action here.
msg=new
this.controller.owner.message("", new Array(this.getTime(), 0),
this.getTime(), -1, "queue");
}
}
else
// If the queue is empty:
{
act=this.idleAction;
// Set up the message for the idle
action here.
msg=new this.controller.owner.message("",
new Array(this.getTime(), 0), this.getTime(), -1, "queue",
"nothing");
}
// If the idle animation has to be
played and it's already playing, do nothing.
if( (act==this.idleAction) &&
(this.currentAction==this.idleAction) )
return;
// Stop the current action.
if(typeof(this.currentAction)!="undefined")
this.currentAction.stop();
// act now contains the action we want
to do, so do it.
this.currentAction=act;
chat.print("STATUS: Starting
", act.name, ".");
startres=act.start(msg.arguments);
// Figure out how long the animation
should take.
if(typeof(startres)!="number")
{
asZeroBased=false;
startres=msg.endtime-msg.starttime;
this.asLast=msg.starttime;
}
else
{
asZeroBased=true;
this.asLast=0;
}
// Store when the action script started
(now).
this.asStart=this.getTime();
// Store the time the action script
thinks it takes.
this.asDuration=startres;
// Store the time the action script
really takes.
this.asRealDuration=msg.endtime-msg.starttime;
// Calculate the time multiplier.
if(this.asDuration==0)
this.asTimeMultiplier=1;
else
this.asTimeMultiplier=this.asDuration/this.asRealDuration;
// Special case for the idle anim.
if(act==this.idleAction)
this.asTimeMultiplier=1;
// Tell us about the multiplier.
chat.print("Running ",
msg.originalline, ". Natural duration ",
this.asDuration, ", current
duration ", this.asRealDuration, ".");
}
// Block the queue.
this.blockQueue=function()
{
this.queueBlocked=true;
}
// Unblock the queue.
this.unBlockQueue=function()
{
this.queueBlocked=false;
}
// Shift the start/endtimes in the queue
by the specified offset.
this.shiftQueue=function(offset)
{
var i;
chat.print("STATUS: Shifting
queue by ", offset, ".");
for(i=0;i<this.queue.length;i++)
{
this.queue[i].starttime=Number(offset)+Number(this.queue[i].starttime);
this.queue[i].endtime=Number(offset)+Number(this.queue[i].endtime);
this.queue[i].arguments[0]=Number(offset)+Number(this.queue[i].arguments[0]);
this.queue[i].arguments[1]=Number(offset)+Number(this.queue[i].arguments[1]);
}
}
//
// Property control
//
// Set a property named name with data
data. If the property
// already exists it is overwritten.
this.setProp=function(name, data)
{
var i;
for(i=0;i<this.properties.length;i++)
{
if(this.properties[i][0]==name)
{
this.properties[i][1]=data;
return;
}
}
this.properties.push(new Array(name,
data));
}
// This function returns the data part of
the property with
// name name, or undefined if there is no
such property. Since
// the property can have undefined as a
value too, use propExists
// to determine whether it exists or not.
this.queryProp=function(name)
{
var i;
// Special properties
switch(name)
{
case "modelPosition":
return this.model.position;
break;
case "modelOrientation":
return this.model.orientation;
break;
}
for(i=0;i<this.properties.length;i++)
if(this.properties[i][0]==name)
return this.properties[i][1];
return undefined;
}
// This function returns true if a
property named name exists,
// or false if such a property does not
exist.
this.propExists=function(name)
{
var i;
// Special properties
switch(name)
{
case "modelPosition":
case "modelOrientation":
return true;
break;
}
for(i=0;i<this.properties.length;i++)
if(this.properties[i][0]==name)
return true;
return false;
}
// If there is a property named name it is
removed by this
// function. If there is no such property
nothing happens.
this.deleteProp=function(name)
{
var i;
for(i=0;i<this.properties.length;i++)
{
if(this.properties[i][0]==name)
{
this.properties.splice(i, 1);
return;
}
}
}
}
this.agent.prototype=new
this.worldobject;
//
// SB
agent object
//
this.sbagent=function(controller)
{
this.initModel("sb_001.aer",
controller);
// Set properties.
this.setProp("animSit",
"Sit");
// Set up actions.
this.setIdleAction(new
controller.owner.actionIdle());
// this.addAction(new
controller.owner.actionSittingThroughPlanning());
this.addAction(new
controller.owner.actionSetTransform());
this.addAction(new
controller.owner.actionBeSeated());
this.auxPlayAnim=function(name, args)
{
// Some animation fixes.
return false;
}
}
this.sbagent.prototype=new
this.agent;
//
// KQ
agent object
//
this.kqagent=function(controller)
{
this.initModel("kq_001.aer",
controller);
// Set properties.
this.setProp("animSit",
"Sit");
this.setProp("animGetUp",
"Getup");
this.setProp("animSitDown",
"Sitdown");
this.setProp("animStand",
"Stand");
this.setProp("animWalk",
"Walk");
this.setProp("animRotateLeft",
"l45");
this.setProp("animRotateRight",
"r45");
this.setProp("poseState",
"standing");
this.setProp("walkSpeed", 1.7);
this.setProp("rotateSpeed",
0.25);
// Set up actions.
this.setIdleAction(new
controller.owner.actionIdle());
this.addAction(new
controller.owner.actionBeSeated());
this.addAction(new
controller.owner.actionSetTransform());
this.addAction(new controller.owner.actionGetup());
this.addAction(new
controller.owner.actionWalk());
this.addAction(new
controller.owner.actionPickingUpNotepad());
this.addAction(new
controller.owner.actionWalk()
,"Walkwithnotepad");
this.addAction(new
controller.owner.actionSitdown()
,"Sitdownwithnotepad");
this.auxPlayAnim=function(name, args)
{
// Some animation fixes.
this.getAnim("Getup").setPlayOnce(true);
this.getAnim("TurntofaceVP").setPlayOnce(true);
this.getAnim("TurnbackVP").setPlayOnce(true);
this.getAnim("TurntofaceSB").setPlayOnce(true);
this.getAnim("TurnbackSB").setPlayOnce(true);
this.getAnim("TurntofaceBC").setPlayOnce(true);
this.getAnim("TurnbackBC").setPlayOnce(true);
this.getAnim("TurntofaceRZ").setPlayOnce(true);
this.getAnim("TurnbackRZ").setPlayOnce(true);
return false;
}
}
this.kqagent.prototype=new
this.agent;
//
// BC
agent object
//
this.bcagent=function(controller)
{
var yarg=new Object();
this.initModel("bc_001.aer",
controller);
// Set properties.
this.setProp("animSit",
"Sit");
this.setProp("animGetUp",
"Getup");
this.setProp("animSitDown",
"Sitdown");
this.setProp("animStand",
"Stand");
this.setProp("animWalk",
"Walk");
this.setProp("animRotateLeft",
"l45");
this.setProp("animRotateRight",
"r45");
this.setProp("poseState",
"standing");
this.setProp("walkSpeed", 1.7);
this.setProp("rotateSpeed",
0.25);
// Set up actions.
this.setIdleAction(new
controller.owner.actionIdle());
this.addAction(new
controller.owner.actionBeSeated());
this.addAction(new
controller.owner.actionSetTransform());
this.addAction(new
controller.owner.actionGetup());
this.addAction(new
controller.owner.actionWalk());
yarg.animation="Standwithlaptop", yarg.duration=400;
this.addAction(new
controller.owner.actionPlayGenericAction(), "CheckingWeatherReport",
yarg);
this.addAction(new
controller.owner.actionSitdown());
// this.addAction(new
controller.owner.actionPlaySomeAnim(),
"Standwithlaptop");
this.auxPlayAnim=function(name, args)
{
this.getAnim("Standwithlaptop").setPlayOnce(false);
return false;
}
}
this.bcagent.prototype=new
this.agent;
//
// VP
agent object
//
this.vpagent=function(controller)
{
this.initModel("vp_001.aer",
controller);
// Set properties.
this.setProp("animSit", "Sit");
this.setProp("animGetUp",
"Getup");
this.setProp("animSitDown",
"Sitdown");
this.setProp("animStand",
"Stand");
this.setProp("animWalk",
"Walk");
this.setProp("animRotateLeft",
"l45");
this.setProp("animRotateRight",
"r45");
this.setProp("poseState",
"standing");
this.setProp("walkSpeed", 1.7);
this.setProp("rotateSpeed",
0.25);
// Set up actions.
this.setIdleAction(new
controller.owner.actionIdle());
this.addAction(new
controller.owner.actionBeSeated());
this.addAction(new
controller.owner.actionSetTransform());
this.addAction(new
controller.owner.actionGetup());
this.addAction(new
controller.owner.actionWalk());
this.addAction(new controller.owner.actionCheckingFoodAvailability());
this.addAction(new
controller.owner.actionSitdown());
// this.addAction(new
controller.owner.actionReportingFoodAvailabilityToCommander());
this.auxPlayAnim=function(name, args)
{
this.getAnim("Food").setPlayOnce(false);
return false;
}
}
this.vpagent.prototype=new
this.agent;
//
// RZ
agent object
//
this.rzagent=function(controller)
{
var yarg=function(aname, time)
{
this.animation=aname;
this.duration=time;
}
this.initModel("rz_001.aer",
controller);
// Set properties.
this.setProp("animSit",
"Sit");
this.setProp("animGetUp",
"Getup");
this.setProp("animSitDown",
"Sitdown");
this.setProp("animStand",
"Stand");
this.setProp("animWalk",
"Walk");
this.setProp("animRotateLeft",
"l45");
this.setProp("animRotateRight",
"r45");
this.setProp("poseState",
"standing");
this.setProp("walkSpeed", 1.7);
this.setProp("rotateSpeed",
0.25);
// Set up actions.
this.setIdleAction(new
controller.owner.actionIdle());
this.addAction(new
controller.owner.actionBeSeated());
this.addAction(new
controller.owner.actionSetTransform());
this.addAction(new
controller.owner.actionAnnouncingStartOfPlanning());
this.addAction(new
controller.owner.actionRequestingGeneratorStatus());
this.addAction(new
controller.owner.actionRequestingGeneratorStatus(), "OrderingToRefuelGenerator");
this.addAction(new
controller.owner.actionRequestingWeatherReport());
this.addAction(new
controller.owner.actionGetup());
this.addAction(new
controller.owner.actionWalk());
this.addAction(new
controller.owner.actionUpladder());
this.addAction(new
controller.owner.actionWater());
this.addAction(new
controller.owner.actionDownladder());
this.addAction(new
controller.owner.actionPlayGenericAction(),
"OrderingToFillWaterTank", new yarg("Talksitting", 40));
// this.addAction(new controller.owner.actionPlayGenericAction(),
"OrderingAdditionalATVs", new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(), "OrderingTrailer", new
yarg("Talksitting", 5));
this.addAction(new controller.owner.actionPlayGenericAction(),
"CheckingWeatherThroughObservation", new yarg("Look", 5));
this.addAction(new
controller.owner.actionSitdown());
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"RequestingRadioRepairStatus", new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(), "OrderingToFixRadio", new
yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"RequestingFoodAvailability", new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"WaitingForRequestStatus", new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"RequestingToilerLinersAvailability", new yarg("Talksitting",
5));
// this.addAction(new
controller.owner.actionPlayGenericAction(), "OrderingToiletLiners",
new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"DecidingWhereToGoForEVA", new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"AnnouncingWhereToGoForEVA", new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(), "DecidingWhoGoesForEVA",
new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"AnnouncingWhoGoesForEVA", new yarg("Talksitting", 5));
// this.addAction(new
controller.owner.actionPlayGenericAction(),
"AnnouncingEndOfPlanning", new yarg("Meetingend", 5));
// this.addAction(new
controller.owner.actionPlaySomeAnim(),
"Look");
// this.addAction(new
controller.owner.actionPlaySomeAnim(),
"Water");
// this.addAction(new
controller.owner.actionPlaySomeAnim(),
"Downladder");
this.auxPlayAnim=function(name, args)
{
//
this.getAnim("Talksitting").setPlayOnce(false);
return false;
}
}
this.rzagent.prototype=new
this.agent;
//
// CC
agent object
//
this.ccagent=function(controller)
{
this.initModel("cc_001.aer",
controller);
// Set properties.
this.setProp("animSit",
"Sit");
this.setProp("animGetUp",
"Getup");
this.setProp("animSitDown",
"Sitdown");
this.setProp("animStand",
"Stand");
this.setProp("animWalk",
"Walk");
this.setProp("animRotateLeft",
"l45");
this.setProp("animRotateRight",
"r45");
this.setProp("poseState",
"standing");
this.setProp("walkSpeed", 1.7);
this.setProp("rotateSpeed",
0.25);
// Set up actions.
this.setIdleAction(new
controller.owner.actionIdle());
this.addAction(new
controller.owner.actionBeSeated());
this.addAction(new
controller.owner.actionSetTransform());
this.auxPlayAnim=function(name, args)
{
return false;
}
}
this.ccagent.prototype=new
this.agent;
//
//
Coffee agent object
//
this.coffeeagent=function(controller)
{
this.initModel("bc003.aer",
controller);
// Set properties for animation names.
this.setProp("animSit",
"Sitwithfullmug");
this.setProp("animStand",
"Standwithfullmug");
this.setProp("state",
"seated");
this.setProp("fullRotationTime",
8);
this.setIdleAction(new
controller.owner.actionIdle());
// this.addAction(new controller.owner.actionSetPosition());
this.addAction(new
controller.owner.actionBeSeated());
this.addAction(new
controller.owner.actionSetTransform());
this.addAction(new
controller.owner.actionGettingUp());
this.addAction(new controller.owner.actionRotateTo());
this.addAction(new
controller.owner.actionMovingToArea());
this.addAction(new
controller.owner.actionGrabMug());
this.addAction(new
controller.owner.actionPuttingCupInMicrowave());
this.addAction(new controller.owner.actionTurningMicrowaveOn());
this.addAction(new
controller.owner.actionWaitingForCoffeeToWarmUp());
this.addAction(new
controller.owner.actionTurningMicrowaveOff());
this.addAction(new
controller.owner.actionTakingCupOutOfMicrowave());
this.addAction(new
controller.owner.actionSittingDown());
this.auxstimestep=function(now, del)
{
if(this.isInInventory(this.controller.getProp("projects.cup.MugBC")))
{
this.setProp("animStand", "Stand");
}
else
{
this.setProp("animStand", "Standwithfullmug");
}
}
this.auxPlayAnim=function(name, args)
{
// Some animation fixes.
this.getAnim("45lwithfullmug").setPlayOnce(false);
this.getAnim("45rwithfullmug").setPlayOnce(false);
this.getAnim("Wait").setPlayOnce(false);
// Mug geometry special animations.
switch(name)
{
case "HideMug":
this.vpObj.scene.getInstance("Withfullmug018_MESH_0").visible=false;
return true;
break;
case "ShowMug":
this.vpObj.scene.getInstance("Withfullmug018_MESH_0").visible=true;
return true;
break;
}
return false;
}
}
this.coffeeagent.prototype=new
this.agent;
//
// Mug
object
//
this.propMug=function(controller)
{
this.controller=controller;
}
this.propMug.prototype=new
this.prop;
//
//
Microwave object
//
this.propMicrowave=function(controller)
{
this.controller=this;
this.status="closed/off";
this.closedtrans=stageModel.getSolidObject(0).rootPrimitive.find(".../a-mwdoor").transform;
this.openedtrans=Transform(this.closedtrans, Rotation('Y', Math.PI/-2));
this.dooron=Model("don002.aer").add();
this.dooron.visible=false;
this.dooron.transform=this.closedtrans;
this.dooroff=Model("doff002.aer").add();
this.dooroff.transform=this.closedtrans;
this.openDoor=function()
{
this.dooroff.visible=true;
this.dooroff.transform=this.openedtrans;
this.dooron.visible=false;
}
this.closeDoor=function()
{
this.dooroff.visible=true;
this.dooroff.transform=this.closedtrans;
this.dooron.visible=false;
}
this.stop=function()
{
this.dooroff.visible=true;
this.dooroff.transform=this.closedtrans;
this.dooron.visible=false;
}
this.start=function()
{
this.dooron.visible=true;
this.dooron.transform=this.closedtrans;
this.dooroff.visible=false;
}
}
this.propMicrowave.prototype=new
this.prop;
//
//
Controller object
//
this.controller=function(base)
{
this.stime=0; // The current simulation time.
this.sdtime=0; // The current simulation delta time.
this.timeMultiplier=1; // The current simulation time multiplier.
this.xtimeMultiplier=0; // Time multiplier before pausing.
this.agents=new Array(); // The agents currently in the simulation.
this.agentsLoading=0; // The number of agents currently loading.
this.objects=new Array(); // The objects currently in the
simulation.
this.objectsLoading=0; // The number of objects currently
loading.
this.owner=base; // The script's base object.
this.paused=false; // Whether the simulation is paused.
this.linebuffer=new Array(); // Buffer of incoming lines.
this.areas=new Array(); // List of area's.
this.paths=new Array(); // List of paths.
this.props=new Array(); // List of props.
this.fixedFrameRate=false; // Fixed framerate if true, real-time
(with multiplier) if false.
this.fr=1; // The actual fixed 1/framerate;
//
// Timing functions
//
// Time multiplier slider.
this.tmSlider=Slider("Timer
multiplier").add();
this.tmSlider.owner=this;
this.tmSlider.range=[0, 60];
this.tmSlider.onChange=function(value)
{
this.owner.setSpeed(value);
}
this.tmSliderRes=Toggle("Fine
control").add();
this.tmSliderRes.slider=this.tmSlider;
this.tmSliderRes.onClick=function(state)
{
if(state)
{
this.slider.range=[0, 1];
this.slider.value=1;
this.slider.onChange(1);
}
else
{
this.slider.range=[0, 60];
}
}
// Checkbox for fixed intervals.
this.tmFixIV=Toggle("Fixed
intervals").add();
this.tmFixIV.owner=this;
this.tmFixIV.onClick=function(state)
{
if(state)
{
this.owner.setFixedFramerate(this.owner.tmFrameRate.value);
}
else
this.owner.fixedFrameRate=false;
}
this.tmFrameRate=Slider("Framerate").add();
this.tmFrameRate.range=[0, 30];
this.tmFrameRate.owner=this;
this.tmFrameRate.onChange=function(value)
{
this.owner.tmFixIV.state=true;
this.owner.tmFixIV.onClick(true);
// this.owner.setFixedFramerate(value);
}
// Set a fixed framerate
this.setFixedFramerate=function(framerate)
{
if(framerate<=0)
{
chat.print("ERROR: ",
framerate, " is not a valid framerate.");
return;
}
var fr=1/framerate;
this.tmSlider.value=fr;
this.setSpeed(fr);
this.fr=fr;
this.fixedFrameRate=true;
}
// Return the current simulation time.
this.getTime=function()
{
return this.stime;
}
// Return the time intervall since the
last simulation timestep.
this.getDeltaTime=function()
{
return this.sdtime;
}
// Return the simulation time multiplier.
this.getTimeMultiplier=function()
{
return this.timeMultiplier;
}
// The real timestep function.
this.timestep=function(now, del)
{
var i;
if(this.fixedFrameRate)
{
this.sdtime=this.fr;
this.stime+=this.fr;
}
else
{
this.sdtime=del*this.timeMultiplier;
this.stime+=del*this.timeMultiplier;
}
this.tbtn.label=this.stime;
// Call stimestep functions in the
agents.
for(i=0;i<this.agents.length;i++)
this.agents[i].stimestep(this.stime, this.sdtime);
this.owner.clocktext.setTime(this.stime);
}
addAnimator(this);
// Pause the simulation.
this.pause=function()
{
if(this.paused)
return;
this.xTimeMultiplier=this.timeMultiplier;
this.paused=true;
chat.print("Simulation
paused.");
}
// Resume the simulation.
this.resume=function()
{
if(!this.paused)
return;
if(this.agentsLoading ||
this.objectsLoading)
return;
this.TimeMultiplier=this.xtimeMultiplier;
this.paused=false;
chat.print("Simulation
resumed.");
// Handle any lines that got in during
the pause.
this.handleLine("");
}
// Set the speed of the simulation.
this.setSpeed=function(newspeed)
{
if(this.paused)
{
this.xtimeMultiplier=newspeed;
}
else
{
this.timeMultiplier=newspeed;
}
}
// Button to see the current time.
this.tbtn=Button("0").add();
//
// The parser / line processor and aux
functions.
//
// Add an area to the list of areas.
this.addArea=function(name, agentname,
position, orientation)
{
this.areas.push(new this.owner.area(name, agentname,
position, orientation));
}
// Add a path to the list of paths.
this.addPath=function() // from, inbetween1, inbetween2, inbetween3,
etc, to
{
var i, args;
// Capture the arguments.
args=new Array();
i=0;
while(arguments[i]!=undefined)
{
args.push(arguments[i]);
i++;
}
if(args.length<2)
{
chat.print("WARNING: addPath:
not enough arguments, ignoring path.");
return;
}
this.paths.push(args);
}
// Find an area and return the
corresponding array, or undefined.
this.findArea=function(name, agentname)
{
var i, area=undefined;
if(typeof(agentname)!="string")
agentname="default";
for(i=0;i<this.areas.length;i++)
{
if(this.areas[i].name==name)
{
if(this.areas[i].agentname==agentname)
return this.areas[i];
else
if(this.areas[i].agentname=="default")
area=this.areas[i];
}
}
return area;
}
// Find a path and return the
corresponding array, or undefined.
this.findPath=function(from, to)
{
var i;
chat.print("STATUS: Searching for
path...");
for(i=0;i<this.paths.length;i++)
{
if( (this.paths[i][0]==from)
&& (this.paths[i][this.paths[i].length-1]==to) )
{
chat.print("STATUS: Found
a path.");
return this.paths[i];
}
}
chat.print("STATUS: Did not find
a path.");
return undefined;
}
// Global function for outside access.
handleLine=function(line)
{
chat.print("STATUS: Handling line
\"" + line + "\".");
handleLine.owner.handleLine(line);
}
handleLine.owner=this;
// Handle a line of input.
this.handleLine=function(line)
{
var cline, agent, msg, starttime,
endtime, activityname, xargs, from, to, prop;
// Store the line in the buffer.
if(line!="")
this.linebuffer.push(line);
// If paused, return.
if(this.paused)
{
chat.print("Not handling line
yet, simulation is paused.");
return;
}
// Handle all lines in the buffer.
//
// Parser
//
while(this.linebuffer.length>0)
{
cline=this.linebuffer.shift().split('|');
if(!cline.length)
continue;
switch(cline[0])
{
// Do the abstract stuff
first.
case "resetTime":
this.stime=0;
this.sdtime=0;
break;
case "setupSBagent":
this.addAgent("sbagent",
"projects.fmarsvre.SB");
break;
case "setupKQagent":
this.addAgent("kqagent", "projects.fmarsvre.KQ");
break;
case "setupBCagent":
this.addAgent("bcagent", "projects.fmarsvre.BC");
break;
case "setupVPagent":
this.addAgent("vpagent", "projects.fmarsvre.VP");
break;
case "setupRZagent":
this.addAgent("rzagent", "projects.fmarsvre.RZ");
break;
case "setupCCagent":
this.addAgent("ccagent", "projects.fmarsvre.CC");
break;
case
"setupcoffeeguy":
this.addAgent("coffeeagent", "projects.cup.BC");
break;
case "setupmug":
this.addProp("mug", "projects.cup.MugBC");
break;
case
"setupmicrowave":
this.addProp("microwave",
"projects.cup.GalleyMicrowave");
break;
// Handle the activity lines.
case "activity":
// All lines here must
have at least 6 parts.
if(cline.length<6)
{
chat.print("WARNING: Not enough parts in line, ignored it.");
continue;
}
// The third and fourth
part must be numbers.
if(isNaN(cline[2]))
{
chat.print("WARNING: Third line part is not a number. Ignoring
line.");
continue;
}
if(isNaN(cline[3]))
{
chat.print("WARNING: Fourth line part is not a number. Ignoring
line.");
continue;
}
starttime=cline[2];
endtime=cline[3];
// Find the agent.
agent=this.getAgent(cline[4]);
if(typeof(agent)=="undefined")
{
chat.print("WARNING: Unknown agent \"", cline[4],
"\". Ignoring line.");
continue;
}
// Get the activity name.
activityname=cline[5];
// Create the arguments
array that's to be passed to the
// action objects.
xargs=new Array();
xargs.push(starttime);
xargs.push(endtime);
// Parse activity subtype
specific stuff (starts at cline[6]).
switch(cline[1])
{
case "move":
// Move has 3
xargs: props, from, to.
if(cline.length<9)
{
chat.print("WARNING: Not enough extra line parts. Ignoring
line.");
continue;
}
xargs.push(new
Array()); // Ignore props for now.
from=this.findArea(cline[7], cline[4]);
xargs.push(from);
// Handle from.
to=this.findArea(cline[8], cline[4]);
xargs.push(to); // Handle to.
// We might have a
path. Take care of it.
if(from && to)
xargs.push(this.findPath(from.position, to.position));
else
xargs.push(undefined);
break;
case "get":
// Get has 3
xargs: props, what, from
xargs.push(new
Array()); // Ignore props for now.
prop=this.getProp(cline[7]); // Try to find the prop.
if(typeof(prop)=="undefined")
{
chat.print("WARNING: Unknown prop \"", cline[7],
"\". Get activity is
ignored.");
}
xargs.push(prop);
from=this.getProp(cline[8]);
// Try to find where to get the prop from.
// Does not have to exist.
xargs.push(from);
break;
case "put":
// Put has 3
xargs: props, what, where
xargs.push(new Array()); // Ignore props for now.
prop=this.getProp(cline[7]);
// Try to find the prop.
if(typeof(prop)=="undefined")
{
chat.print("WARNING: Unknown prop
\"", cline[7],
"\". Put activity is ignored.");
}
xargs.push(prop);
from=this.getProp(cline[8]);
// Try to find where to put the prop.
// Does not have
to exist.
xargs.push(from);
break;
case
"primitive":
// Primitive has 1 xarg, props.
chat.print("Parsed as primitive.");
xargs.push(new
Array(this.getProp(cline[6])));
break;
}
//this.message=function(name, args, starttime, endtime, method)
msg=new
this.owner.message(activityname, xargs, starttime, endtime, "queue",
cline.join("|"));
agent.processMessage(msg);
break;
// Everything else is
unrecognized.
default:
chat.print("WARNING:
Unknown line type. Ignored.");
break;
}
}
}
//
// Object and agent control.
//
// Add a prop.
this.addProp=function(propclass, name)
{
var newprop;
switch(propclass)
{
case "mug":
newprop=new
this.owner.propMug(this);
break;
case "microwave":
newprop=new
this.owner.propMicrowave(this);
break;
default:
chat.print("WARNING:
addProp: prop class \"" + propclass +
"\" is unknown.
The prop was not added.");
return;
}
newprop.name=name;
this.props.push(newprop);
}
// Add an agent.
this.addAgent=function(agentclass, name)
{
var newagent;
switch(agentclass)
{
case "sbagent":
newagent=new
this.owner.sbagent(this);
break;
case "kqagent":
newagent=new
this.owner.kqagent(this);
break;
case "bcagent":
newagent=new
this.owner.bcagent(this);
break;
case "vpagent":
newagent=new
this.owner.vpagent(this);
break;
case "rzagent":
newagent=new
this.owner.rzagent(this);
break;
case "ccagent":
newagent=new
this.owner.ccagent(this);
break;
case "coffeeagent":
newagent=new this.owner.coffeeagent(this);
break;
default:
chat.print("WARNING:
addAgent: agent class \"" + agentclass +
"\" is unknown.
The agent was not added.");
return;
}
// Pause the simulation.
this.pause();
this.agentsLoading++;
// Set up the new agent.
newagent.name=name;
this.agents.push(newagent);
// For debugging
xagent=newagent;
}
// This function is called by an agent
when it's ready to be used.
this.agentIsReady=function(agent)
{
// One agent less is loading.
this.agentsLoading--;
// See if no agents and objects are
loading, if so unpause.
if( (!this.agentsLoading) &&
(!this.objectsLoading) )
this.resume();
}
// Get a named agent.
this.getAgent=function(name)
{
var i;
for(i=0;i<this.agents.length;i++)
{
if(this.agents[i].name==name)
return this.agents[i];
}
return undefined;
}
// Get a named prop.
this.getProp=function(name)
{
var i;
for(i=0;i<this.props.length;i++)
{
if(this.props[i].name==name)
return this.props[i];
}
return undefined;
}
}
//
//
Debug stuff
//
//
Create a controller.
this.ctrl=new
this.controller(this);
// Set
up the area's manually.
//
//
Area's for SB
//
this.ctrl.addArea(
"projects.fmarsvre.WardroomTableArea",
"projects.fmarsvre.SB",
stageModel.getSolidObject(0).rootPrimitive.find(".../sbfcp_001").position,
Rotation('Y', Math.PI*-0.75)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
//
//
Area's for KQ
//
this.ctrl.addArea(
"projects.fmarsvre.WardroomTableArea",
"projects.fmarsvre.KQ",
stageModel.getSolidObject(0).rootPrimitive.find(".../kqfcp_001").position,
Rotation('Y', Math.PI*-0.25)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
this.ctrl.addArea(
"projects.fmarsvre.StateRoomKQ",
"projects.fmarsvre.KQ",
stageModel.getSolidObject(0).rootPrimitive.find(".../kqwcp_002").position,
Rotation('Y', Math.PI*-0.75)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
//
//
Area's for BC
//
this.ctrl.addArea(
"projects.fmarsvre.WardroomTableArea",
"projects.fmarsvre.BC",
stageModel.getSolidObject(0).rootPrimitive.find(".../bcfcp_001").position,
Rotation('Y', Math.PI*0.5)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
this.ctrl.addArea(
"projects.fmarsvre.WorkstationArea",
"projects.fmarsvre.BC",
stageModel.getSolidObject(0).rootPrimitive.find(".../bcwcp_007").position,
Rotation('Y', Math.PI*0.25) //stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
//
//
Area's for VP
//
this.ctrl.addArea(
"projects.fmarsvre.WardroomTableArea",
"projects.fmarsvre.VP",
stageModel.getSolidObject(0).rootPrimitive.find(".../vpfcp_001").position,
Rotation('Y', Math.PI*-0.75)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
this.ctrl.addArea(
"projects.fmarsvre.GalleyArea",
"projects.fmarsvre.VP",
stageModel.getSolidObject(0).rootPrimitive.find(".../vpwcp_003").position,
Rotation('Y', Math.PI*0)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
//
//
Area's for RZ
//
this.ctrl.addArea(
"projects.fmarsvre.WardroomTableArea",
"projects.fmarsvre.RZ",
stageModel.getSolidObject(0).rootPrimitive.find(".../rzscp_001").position,
Rotation('Y', Math.PI*0.3)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
this.ctrl.addArea(
"projects.fmarsvre.GalleyLadderArea",
"projects.fmarsvre.RZ",
stageModel.getSolidObject(0).rootPrimitive.find(".../rzlcp_001").position,
Rotation('Y', Math.PI*-0.75)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
this.ctrl.addArea(
"projects.fmarsvre.NWPortalArea",
"projects.fmarsvre.RZ",
stageModel.getSolidObject(0).rootPrimitive.find(".../rzwcp_003").position,
Rotation('Y', Math.PI*-0.2)
//stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
//
//
Area's for CC
//
this.ctrl.addArea(
"projects.fmarsvre.WardroomTableArea",
"projects.fmarsvre.CC",
stageModel.getSolidObject(0).rootPrimitive.find(".../ccwcp_001").position,
Rotation('Y', Math.PI*1) //stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation
);
/* Old
coffee seq
this.ctrl.addArea("projects.cup.ChairBCArea",
stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").orientation);
this.ctrl.addArea("projects.cup.GalleyCabinetArea",
stageModel.getSolidObject(0).rootPrimitive.find(".../a-microwave").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-microwave").orientation);
this.ctrl.addArea("projects.cup.testarea",
Vector(0, 0, 0),
Rotation('Y', Math.PI/2));
*/
// Set
up the paths.
//
//
Paths for KQ
//
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../kqfcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../kqwcp_003").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../kqwcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../kqwcp_002").position);
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../kqwcp_002").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../kqwcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../kqwcp_003").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../kqfcp_001").position);
//
//
Paths for VP
//
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../vpfcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../vpwcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../vpwcp_004").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../vpwcp_003").position);
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../vpwcp_003").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../vpwcp_004").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../vpwcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../vpfcp_001").position);
//
//
Paths for RZ
//
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../rzscp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzwcp_002").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzlcp_001").position);
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../rzlcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzwcp_002").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzscp_001").position);
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../rzscp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzwcp_002").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzwcp_003").position);
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../rzwcp_003").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzwcp_002").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../rzscp_001").position);
//
//
Paths for BC
//
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../bcfcp_001").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../bcrcp1").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../bcrcp2").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../bcwcp_007").position);
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../bcwcp_007").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../bcrcp2").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../bcrcp1").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../bcfcp_001").position);
/* Old
coffee seq
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-microwave").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-cp1").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-cp2").position);
this.ctrl.addPath(stageModel.getSolidObject(0).rootPrimitive.find(".../a-microwave").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-chair").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-cp2").position,
stageModel.getSolidObject(0).rootPrimitive.find(".../a-cp1").position);
*/
// Feed
the controller lines. First the world initialization lines:
/* New
seq */
//*
this.ctrl.handleLine("setupSBagent");
//*/
//*
this.ctrl.handleLine("setupKQagent");
//*/
//*
this.ctrl.handleLine("setupBCagent");
//*/
//*
this.ctrl.handleLine("setupVPagent");
//*/
//*
this.ctrl.handleLine("setupRZagent");
//*/
//*
this.ctrl.handleLine("setupCCagent");
//*/
/* Old
coffee seq
this.ctrl.handleLine("setupcoffeeguy"); // Should become a create agent activity.
this.ctrl.handleLine("setupmug"); // Should become a create object activity.
this.ctrl.handleLine("setupmicrowave"); // Should become a create object activity.
*/
player.transform=Transform("T(-2.29386,15.1393,-0.563022;-0.154011,0.0170633,0.00266007)");
this.b1=Button("Init").add();
this.b1.ctrl=this.ctrl; // This is for the
sequence initialization.
buttoninit=this.b1;
this.b1.onClick=function(state)
{
/* New
seq */
//* //
SB
this.ctrl.handleLine("activity|move|0|0|projects.fmarsvre.SB|SetTransform|||projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|0|0|projects.fmarsvre.SB|BeSeated|");
//*/
//* //
KQ
this.ctrl.handleLine("activity|move|0|0|projects.fmarsvre.KQ|SetTransform|||projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|0|0|projects.fmarsvre.KQ|BeSeated|");
//*/
//* //
BC
this.ctrl.handleLine("activity|move|0|0|projects.fmarsvre.BC|SetTransform|||projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|0|0|projects.fmarsvre.BC|BeSeated|");
//*/
//* //
VP
this.ctrl.handleLine("activity|move|0|0|projects.fmarsvre.VP|SetTransform|||projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|0|0|projects.fmarsvre.VP|BeSeated|");
//*/
//* //
RZ
this.ctrl.handleLine("activity|move|0|0|projects.fmarsvre.RZ|SetTransform|||projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|0|0|projects.fmarsvre.RZ|BeSeated|");
//*/
//* //
CC
this.ctrl.handleLine("activity|move|0|0|projects.fmarsvre.CC|SetTransform|||projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|0|0|projects.fmarsvre.CC|BeSeated|");
//*/
/* Old
coffee seq
this.ctrl.handleLine("activity|move|0|0|projects.cup.BC|SetTransform|||projects.cup.ChairBCArea");
this.ctrl.handleLine("activity|primitive|0|0|projects.cup.BC|BeSeated|");
this.ctrl.handleLine("activity|get|0|0|projects.cup.BC|GrabMug||projects.cup.MugBC|");
*/
}
this.b2=Button("Sequence").add();
this.b2.ctrl=this.ctrl; // This plays the actual
sequence.
this.b2.onClick=function(state)
{
this.ctrl.handleLine("resetTime");
//
Newest seq.
this.ctrl.handleLine("activity|move|0|0|projects.fmarsvre.SB|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|0|45|projects.fmarsvre.SB|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|45|46|projects.fmarsvre.SB|CheckingGeneratorStatus|");
this.ctrl.handleLine("activity|primitive|46|208|projects.fmarsvre.SB|ReportingGeneratorStatusToCommander|");
this.ctrl.handleLine("activity|primitive|208|528|projects.fmarsvre.SB|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|528|529|projects.fmarsvre.SB|CheckingRadioRepairStatus|");
this.ctrl.handleLine("activity|primitive|529|926|projects.fmarsvre.SB|ReportingRadioRepairStatusToCommander|");
this.ctrl.handleLine("activity|primitive|926|1099|projects.fmarsvre.SB|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|0|3|projects.fmarsvre.KQ|Getup|");
this.ctrl.handleLine("activity|move|3|11|projects.fmarsvre.KQ|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.StateRoomKQ");
this.ctrl.handleLine("activity|primitive|11|41|projects.fmarsvre.KQ|PickingUpNotepad|projects.fmarsvre.NotepadKQ");
this.ctrl.handleLine("activity|move|41|46|projects.fmarsvre.KQ|Walkwithnotepad||projects.fmarsvre.StateRoomKQ|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|46|51|projects.fmarsvre.KQ|Sitdownwithnotepad|");
this.ctrl.handleLine("activity|primitive|51|858|projects.fmarsvre.KQ|Sitwithnotepad|");
this.ctrl.handleLine("activity|primitive|858|859|projects.fmarsvre.KQ|CheckingToilerLinersAvailability|");
this.ctrl.handleLine("activity|primitive|859|981|projects.fmarsvre.KQ|ReportingToilerLinersAvailabilityToCommander|");
this.ctrl.handleLine("activity|primitive|981|1099|projects.fmarsvre.KQ|Sitwithnotepad|");
this.ctrl.handleLine("activity|primitive|0|45|projects.fmarsvre.RZ|AnnouncingStartOfPlanning|");
this.ctrl.handleLine("activity|primitive|45|46|projects.fmarsvre.RZ|RequestingGeneratorStatus|");
this.ctrl.handleLine("activity|primitive|46|97|projects.fmarsvre.RZ|OrderingToRefuelGenerator|");
this.ctrl.handleLine("activity|primitive|97|153|projects.fmarsvre.RZ|RequestingWeatherReport|");
this.ctrl.handleLine("activity|primitive|153|156|projects.fmarsvre.RZ|Getup|");
this.ctrl.handleLine("activity|move|156|164|projects.fmarsvre.RZ|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.GalleyLadderArea");
this.ctrl.handleLine("activity|move|164|169|projects.fmarsvre.RZ|Upladder||projects.fmarsvre.GalleyLadderArea|projects.fmarsvre.WaterTankArea");
this.ctrl.handleLine("activity|primitive|169|256|projects.fmarsvre.RZ|Water|");
this.ctrl.handleLine("activity|move|256|261|projects.fmarsvre.RZ|Downladder||projects.fmarsvre.WaterTankArea|projects.fmarsvre.GalleyLadderArea");
this.ctrl.handleLine("activity|move|261|269|projects.fmarsvre.RZ|Walk||projects.fmarsvre.GalleyLadderArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|269|312|projects.fmarsvre.RZ|OrderingToFillWaterTank|");
this.ctrl.handleLine("activity|primitive|312|360|projects.fmarsvre.RZ|OrderingAdditionalATVs|");
this.ctrl.handleLine("activity|primitive|360|414|projects.fmarsvre.RZ|OrderingTrailer|");
this.ctrl.handleLine("activity|move|414|421|projects.fmarsvre.RZ|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.NWPortalArea");
this.ctrl.handleLine("activity|primitive|421|518|projects.fmarsvre.RZ|CheckingWeatherThroughObservation|");
this.ctrl.handleLine("activity|move|518|525|projects.fmarsvre.RZ|Walk||projects.fmarsvre.NWPortalArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|525|528|projects.fmarsvre.RZ|Sitdown|");
this.ctrl.handleLine("activity|primitive|528|529|projects.fmarsvre.RZ|RequestingRadioRepairStatus|");
this.ctrl.handleLine("activity|primitive|529|576|projects.fmarsvre.RZ|OrderingToFixRadio|");
this.ctrl.handleLine("activity|primitive|576|630|projects.fmarsvre.RZ|RequestingFoodAvailability|");
this.ctrl.handleLine("activity|primitive|630|653|projects.fmarsvre.RZ|WaitingForRequestStatus|");
this.ctrl.handleLine("activity|primitive|653|858|projects.fmarsvre.RZ|WaitingForRequestStatus|");
this.ctrl.handleLine("activity|primitive|858|859|projects.fmarsvre.RZ|RequestingToilerLinersAvailability|");
this.ctrl.handleLine("activity|primitive|859|908|projects.fmarsvre.RZ|OrderingToiletLiners|");
this.ctrl.handleLine("activity|primitive|908|968|projects.fmarsvre.RZ|DecidingWhereToGoForEVA|");
this.ctrl.handleLine("activity|primitive|968|1010|projects.fmarsvre.RZ|AnnouncingWhereToGoForEVA|");
this.ctrl.handleLine("activity|primitive|1010|1054|projects.fmarsvre.RZ|DecidingWhoGoesForEVA|");
this.ctrl.handleLine("activity|primitive|1054|1099|projects.fmarsvre.RZ|AnnouncingWhoGoesForEVA|");
this.ctrl.handleLine("activity|primitive|1099|1159|projects.fmarsvre.RZ|AnnouncingEndOfPlanning|");
this.ctrl.handleLine("activity|primitive|0|97|projects.fmarsvre.BC|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|97|100|projects.fmarsvre.BC|Getup|");
this.ctrl.handleLine("activity|move|100|105|projects.fmarsvre.BC|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.WorkstationArea");
this.ctrl.handleLine("activity|primitive|105|645|projects.fmarsvre.BC|CheckingWeatherReport|");
this.ctrl.handleLine("activity|move|645|650|projects.fmarsvre.BC|Walk||projects.fmarsvre.WorkstationArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|650|653|projects.fmarsvre.BC|Sitdown|");
this.ctrl.handleLine("activity|primitive|653|790|projects.fmarsvre.BC|ReportingWeatherConditionsToCommander|");
this.ctrl.handleLine("activity|primitive|790|1099|projects.fmarsvre.BC|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|0|576|projects.fmarsvre.VP|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|576|579|projects.fmarsvre.VP|Getup|");
this.ctrl.handleLine("activity|move|579|587|projects.fmarsvre.VP|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.GalleyArea");
this.ctrl.handleLine("activity|primitive|587|847|projects.fmarsvre.VP|CheckingFoodAvailability|projects.fmarsvre.GalleyCabinet");
this.ctrl.handleLine("activity|move|847|855|projects.fmarsvre.VP|Walk||projects.fmarsvre.GalleyArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|855|858|projects.fmarsvre.VP|Sitdown|");
this.ctrl.handleLine("activity|primitive|858|1028|projects.fmarsvre.VP|ReportingFoodAvailabilityToCommander|");
this.ctrl.handleLine("activity|primitive|1028|1099|projects.fmarsvre.VP|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|0|1099|projects.fmarsvre.CC|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|0|300|projects.fmarsvre.HabClock|Waiting|");
this.ctrl.handleLine("activity|primitive|300|600|projects.fmarsvre.HabClock|Waiting|");
this.ctrl.handleLine("activity|primitive|600|900|projects.fmarsvre.HabClock|Waiting|");
this.ctrl.handleLine("activity|primitive|900|1200|projects.fmarsvre.HabClock|Waiting|");
this.ctrl.handleLine("activity|primitive|0|1159|projects.fmarsvre.WaterTank|RetainingSteadyWaterLevel|");
// Old
seq.
/* // ===== SB =====
this.ctrl.handleLine("activity|primitive|0|57|projects.fmarsvre.SB|SittingThroughPlanning|");
this.ctrl.handleLine("activity|primitive|195|545|projects.fmarsvre.SB|SittingThroughPlanning|");
// ===== KQ =====
this.ctrl.handleLine("activity|primitive|0|5|projects.fmarsvre.KQ|Getup|");
this.ctrl.handleLine("activity|move|5|50|projects.fmarsvre.KQ|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.StateRoomKQ");
this.ctrl.handleLine("activity|primitive|50|80|projects.fmarsvre.KQ|PickingUpNotepad|projects.fmarsvre.NotepadKQ");
this.ctrl.handleLine("activity|move|80|85|projects.fmarsvre.KQ|Walkwithnotepad||projects.fmarsvre.StateRoomKQ|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|85|90|projects.fmarsvre.KQ|Sitdownwithnotepad|");
// ===== BC =====
this.ctrl.handleLine("activity|primitive|114|119|projects.fmarsvre.BC|Getup|");
this.ctrl.handleLine("activity|move|119|124|projects.fmarsvre.BC|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.WorkstationArea");
this.ctrl.handleLine("activity|primitive|124|664|projects.fmarsvre.BC|CheckingWeatherReport|");
this.ctrl.handleLine("activity|move|664|669|projects.fmarsvre.BC|Walk||projects.fmarsvre.WorkstationArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|669|674|projects.fmarsvre.BC|Sitdown|");
//
this.ctrl.handleLine("activity|primitive|674|833|projects.fmarsvre.BC|ReportingWeatherConditionsToCommander|");
// ===== VP =====
this.ctrl.handleLine("activity|primitive|589|594|projects.fmarsvre.VP|Getup|");
this.ctrl.handleLine("activity|move|594|604|projects.fmarsvre.VP|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.GalleyArea");
this.ctrl.handleLine("activity|primitive|604|869|projects.fmarsvre.VP|CheckingFoodAvailability|projects.fmarsvre.GalleyCabinet");
this.ctrl.handleLine("activity|move|869|879|projects.fmarsvre.VP|Walk||projects.fmarsvre.GalleyArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|879|884|projects.fmarsvre.VP|Sitdown|");
this.ctrl.handleLine("activity|primitive|884|1009|projects.fmarsvre.VP|ReportingFoodAvailabilityToCommander|");
// ===== RZ =====
this.ctrl.handleLine("activity|primitive|0|57|projects.fmarsvre.RZ|AnnouncingStartOfPlanning|");
this.ctrl.handleLine("activity|primitive|57|58|projects.fmarsvre.RZ|RequestingGeneratorStatus|");
this.ctrl.handleLine("activity|primitive|58|114|projects.fmarsvre.RZ|OrderingToRefuelGenerator|");
this.ctrl.handleLine("activity|primitive|114|171|projects.fmarsvre.RZ|RequestingWeatherReport|");
this.ctrl.handleLine("activity|primitive|171|176|projects.fmarsvre.RZ|Getup|");
this.ctrl.handleLine("activity|move|176|186|projects.fmarsvre.RZ|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.GalleyLadderArea");
this.ctrl.handleLine("activity|move|186|191|projects.fmarsvre.RZ|Upladder||projects.fmarsvre.GalleyLadderArea|projects.fmarsvre.WaterTankArea");
this.ctrl.handleLine("activity|primitive|191|259|projects.fmarsvre.RZ|Water|");
this.ctrl.handleLine("activity|move|259|264|projects.fmarsvre.RZ|Downladder||projects.fmarsvre.WaterTankArea|projects.fmarsvre.GalleyLadderArea");
this.ctrl.handleLine("activity|move|264|274|projects.fmarsvre.RZ|Walk||projects.fmarsvre.GalleyLadderArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|274|315|projects.fmarsvre.RZ|OrderingToFillWaterTank|");
this.ctrl.handleLine("activity|primitive|274|315|projects.fmarsvre.RZ|OrderingToFillWaterTank|");
this.ctrl.handleLine("activity|primitive|315|371|projects.fmarsvre.RZ|OrderingAdditionalATVs|");
this.ctrl.handleLine("activity|primitive|371|429|projects.fmarsvre.RZ|OrderingTrailer|");
this.ctrl.handleLine("activity|move|429|439|projects.fmarsvre.RZ|Walk||projects.fmarsvre.WardroomTableArea|projects.fmarsvre.NWPortalArea");
this.ctrl.handleLine("activity|primitive|439|530|projects.fmarsvre.RZ|CheckingWeatherThroughObservation|");
this.ctrl.handleLine("activity|move|530|540|projects.fmarsvre.RZ|Walk||projects.fmarsvre.NWPortalArea|projects.fmarsvre.WardroomTableArea");
this.ctrl.handleLine("activity|primitive|540|545|projects.fmarsvre.RZ|Sitdown|");
this.ctrl.handleLine("activity|primitive|545|546|projects.fmarsvre.RZ|RequestingRadioRepairStatus|");
this.ctrl.handleLine("activity|primitive|546|589|projects.fmarsvre.RZ|OrderingToFixRadio|");
this.ctrl.handleLine("activity|primitive|589|639|projects.fmarsvre.RZ|RequestingFoodAvailability|");
this.ctrl.handleLine("activity|primitive|639|674|projects.fmarsvre.RZ|WaitingForRequestStatus|");
this.ctrl.handleLine("activity|primitive|674|884|projects.fmarsvre.RZ|WaitingForRequestStatus|");
this.ctrl.handleLine("activity|primitive|884|885|projects.fmarsvre.RZ|RequestingToilerLinersAvailability|");
this.ctrl.handleLine("activity|primitive|885|941|projects.fmarsvre.RZ|OrderingToiletLiners|");
this.ctrl.handleLine("activity|primitive|941|1001|projects.fmarsvre.RZ|DecidingWhereToGoForEVA|");
this.ctrl.handleLine("activity|primitive|1001|1054|projects.fmarsvre.RZ|AnnouncingWhereToGoForEVA|");
this.ctrl.handleLine("activity|primitive|1054|1097|projects.fmarsvre.RZ|DecidingWhoGoesForEVA|");
this.ctrl.handleLine("activity|primitive|1097|1148|projects.fmarsvre.RZ|AnnouncingWhoGoesForEVA|");
this.ctrl.handleLine("activity|primitive|1148|1208|projects.fmarsvre.RZ|AnnouncingEndOfPlanning|");
// ===== CC =====
// just sit there the whole time
*/
/* Old
coffee seq
this.ctrl.handleLine("activity|primitive|0|3|projects.cup.BC|GettingUp|");
this.ctrl.handleLine("activity|move|3|13|projects.cup.BC|MovingToArea||projects.cup.ChairBCArea|projects.cup.GalleyCabinetArea");
this.ctrl.handleLine("activity|put|13|43|projects.cup.BC|PuttingCupInMicrowave||projects.cup.MugBC|projects.cup.GalleyMicrowave");
this.ctrl.handleLine("activity|primitive|43|46|projects.cup.BC|TurningMicrowaveOn|projects.cup.GalleyMicrowave");
this.ctrl.handleLine("activity|primitive|46|76|projects.cup.BC|WaitingForCoffeeToWarmUp|");
this.ctrl.handleLine("activity|primitive|76|79|projects.cup.BC|TurningMicrowaveOff|projects.cup.GalleyMicrowave");
this.ctrl.handleLine("activity|get|79|109|projects.cup.BC|TakingCupOutOfMicrowave||projects.cup.MugBC|projects.cup.GalleyMicrowave");
this.ctrl.handleLine("activity|move|109|119|projects.cup.BC|MovingToArea||projects.cup.GalleyCabinetArea|projects.cup.ChairBCArea");
this.ctrl.handleLine("activity|primitive|119|122|projects.cup.BC|SittingDown|projects.cup.ChairBC");
*/
}
this.cams=new
Array
(
new Array( "Overview cam" ,
'T(-2.29386,15.1393,-0.563022;-0.154011,0.0170633,0.00266007)' ),
new Array( "Table cam" , 'T(-4.68961,12.3032,-3.21342;-0.0129616,0.346784,0.00479279)' ),
new Array( "Desk cam" ,
'T(-6.68645,12.5044,-10.1982;-0.00552088,-0.753863,-0.00633505)' ),
new Array( "Water cam" ,
'T(6.8729,18.1519,-5.83161;-0.395855,0.169974,0.0748164)' ),
new Array( "Microwave cam" ,
'T(5.96457,14.5068,-12.1645;0.000440504,0.983427,-0.00238955)' ),
new Array( "Ceiling cam" ,
'T(-0.522917,20.6985,-5.13829;-0.540361,0.0433786,0.0279099)' ),
new Array( "Corner cam" ,
'T(-7.3643,12.7788,8.63468;-0.0136314,-0.164368,-0.00227168)' ),
new Array( "Window cam" ,
'T(11.7907,13.4458,-9.15095;-0.0191577,0.770339,0.0231706)' ),
new Array( "First floor
cam" ,
'T(-2.67312,9.42406,-0.340209;0.09437,0.00223896,-0.000212238)' ),
new Array( "Second floor
cam" ,
'T(-2.98313,9.5652,-11.4189;0.031537,0.948674,-0.100308)' ),
new Array( "Top-bottom cam" ,
'T(3.4477,19.9658,-10.7116;-0.0338801,0.773012,0.63213)' ),
new Array( "Timelapse cam" ,
'T(-8.94759,13.335,10.0704;-0.0403093,-0.182646,0.00749479)' )
)
this.initcams=function()
{
var i;
for(i=0;i<this.cams.length;i++)
{
this.cambt=Button(this.cams[i][0]).add();
this.cambt.trans=Transform(this.cams[i][1]);
this.cambt.onClick=function(state)
{
player.transform=this.trans;
}
}
}
this.initcams();
//
//
Viewpoint text clock.
//
this.vptc=function()
{
this.init=function()
{
this.vpobj=stageModel.getViewpointObject(1);
this.txt=undefined;
}
this.init();
this.timestep=function(now, del)
{
var text, i, tsres;
if(!this.vpobj.loaded)
return;
if(!this.txt)
{
this.txt=this.vpobj.scene.getInstance("ins").getInstance2d();
this.txt.font="Verdana";
this.txt.textColor=[1,1,1];
this.txt.dstPinRelative=true;
this.txt.dstPin=[0.9,0.94];
this.txt.shadowColor=[0,0,0];
this.txt.shadowRadius=1;
this.txt.textSize=20;
// this.txt.text="test!";
y=this.txt;
}
}
addAnimator(this);
this.setTime=function(time)
{
var h, m, s, ms, tt, text,
idiv=function(a, b){var c=a%b;
return (a-c)/b};
if(!this.vpobj.loaded)
return;
if(!this.txt)
return;
tt=time+33434; // Add offset for
9:17:14 start time
h=idiv(tt, 3600);
tt=tt%3600;
m=idiv(tt, 60);
tt=tt%60;
s=idiv(tt, 1);
tt=tt%1;
ms=idiv(Math.round(1000*tt), 1);
text=(h<10?'0':'')+h+':'+
(m<10?'0':'')+m+':'+
(s<10?'0':'')+s+':'+
(ms<10?'0':'')+(ms<100?'0':'')+ms;
this.txt.text=text;
}
}
this.clocktext=new
this.vptc();
//
screen capture button
this.captgl=Toggle("Start
shooting").add();
this.captgl.onClick=function(state)
{
if(state)
{
application.getView(0).animationTimeStep=0;
application.getView(0).frameCount=0;
application.getView(0).frameName="footage";
application.getView(0).frameWidth=application.getView(0).imageWidth;
application.getView(0).frameHeight=application.getView(0).imageHeight;
application.getView(0).padFrameNameWithZeroes=true;
application.getView(0).frameNumberDigits=8;
application.getView(0).saveAnimationFrames=true;
this.label="Stop shooting";
}
else
{
application.getView(0).saveAnimationFrames=false;
this.label="Start shooting";
}
}
this.captgl.lastWidth=0;
this.captgl.lastHeight=0;
this.captgl.timestep=function(now,
del)
{
var newWidth, newHeight;
newWidth=application.getView(0).imageWidth;
newHeight=application.getView(0).imageHeight;
if(newWidth!=this.lastWidth)
{
chat.print("New 3D part width:
", newWidth, ".");
this.lastWidth=newWidth;
//
application.getView(0).getCamera(0).aspectRatio=newWidth/newHeight;
}
if(newHeight!=this.lastHeight)
{
chat.print("New 3D part height:
", newHeight, ".");
this.lastHeight=newHeight;
//
application.getView(0).getCamera(0).aspectRatio=newWidth/newHeight;
}
}
addAnimator(this.captgl);
chat.print("Coffee
script done loading.");