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.");