Interactive World Simulation


class structure (incomplete)

This interactive world simulation originates from the begin of 2004 during my stay in Houston. The various issues that raise are discussed on linked pages. New "animated" objects - game characters - can be added easily to the framework, if one first takes a look at the classes aniAvatar and aniBomber for the conventions. I appreciate the creation of some more character types very much and would like to hear from it. The compilation works with VC++ 6.0 from the dos prompt - the batch file r.bat lists the arguments. To simply run the program execute prog.exe.

The geometric models were partially provided by rice comp460 gaming class, 3D Cafe & relaxgames.com. Sounds are due to the contributors of findsounds.com. Collision meshes around the fine triangulated models where designed in Jaya to obtain a reasonable presision with a coarser, oriented trianglar mesh. For collision detection, I use the library RAPID - Robust and Accurate Polygon Interference Detection. The sound engine is supplied by FMOD Ex sound system.

Program release 1.3 & SourceCode (C++) world_std.zip 10.5 MB
When I can't handle events,
I let them handle themselves.
Henry Ford

The credo of the simulation environment is to allow the user to switch between all different kinds of vehicles. Objects should have self control, for example animals are wandering around.

While controlling any entity, the user can select other objects that appear on the screen with ENTER (for selection don't get too close to object), to change from the current entity into a selected entity press BACKSPACE, which is also the key for exiting a machine. \ start and stops an engine of a machine. Different camera positions can be obtained with the F1-F3 keys. Implemented entities so far are:

Apache, combat helicopter, 1-5 rotorspeed, arrows roll/pitch, z and SPACE weapons - after soft collisions readjusts its orientation smoothly

Bomber, humanoid, x jump/fly, SPACE throws bombs, z shoots rockets, arrows make direction

Deformable, object like palm in picture, efficiently rendered with respect to a few control points, that catch collision events

Hover, hovercraft, z weapons.

Mustang, car, arrows steer/accelerate, each tire gives feedback, collision emits sparks

Other, armory, particles, giant scorpion (from class 460)... - as soon as I retire, but no later than in my next life, I will encorporate shadows. The last picture is from a separate simulation, to test the water wave algorithm. The lines emanating from the dinghy reveal the collision detection method. Unfortunately, I dont have an executable to this project anymore. I plan to incorporate the water waves in the sink in the center of the level of world. To manage realistic water at some agreeable frame rate and resolution is not easy.

The velocity and position control that were originally designed for the game, were used subsequentially for the control of the Marsokhod robot. The control is documented in Section 4.4 of my thesis.

Here is an excerpt of the code from the game that controls Bomber. The numbers 100 to 103 address the arrow keys.

void aniBomber::control() {
  *rforce*=0;
  if (is(ANI_HUMANIZED)) { //bomber controlled by human
    if (keys.data[100+KEY_SP+KEY_MODIFY]==4||keys.data[102+KEY_SP+KEY_MODIFY]==4)
      oforce->data[0]-=(keys.data[100+KEY_SP]-keys.data[102+KEY_SP])*ANI_BOMBER_FZ; //strive
    else 
      rforce->data[1]+=(keys.data[100+KEY_SP]-keys.data[102+KEY_SP])*ANI_BOMBER_FR; //turn
    oforce->data[2]-=(keys.data[101+KEY_SP]-keys.data[103+KEY_SP])*ANI_BOMBER_FZ;   //thrust        
    oforce->data[1]+=keys.data['x'+KEY_DOWN]*1000; //primitive jump
    if (keys.data[ANI_CHANGE]) conquer^=1;
    if (conquer&&ani_select) target(ani_select->getMat()); else conquer=0;
    ani_contact *ctc;
    while (contact.token(ctc)) //loop over all objects against bomber did collide
      if (ctc->ani==ani_select)
        if (ani_select->is(ANI_HUMANIZABLE)) {
          sound.flush(ani_bomber_smp[1]);
          ani_select->index|=ANI_HUMANIZED;
          aniCamera::singleton()->ani=ani_select;
          ani_select=NULL;
          time[1]=0;
        }
    if (keys.data['z'+KEY_DOWN]) { //fire rocket
      matrix ofs(4,1,"");
      aniRocket *roc=new aniRocket(0);
        linked_ani.append(roc);
        ofs(0)=1; ofs(1)=1;
        *roc->mat=getMat()*glTranslate(ofs.data);
        *roc->tvel=getVel(ofs);        
        roc->launch(ani_select);
    }
    if (keys.data[' '+KEY_DOWN]) { //throw bomb
      matrix ofs(4,1,""),eje(4,1,"");
      aniBomb *bom=new aniBomb();
        ofs(0)=-1; ofs(1)=1;
        eje(1)= 2; eje(2)=-60;
        *bom->mat=getMat()*glTranslate(ofs.data);        
        *bom->tvel=getVel(ofs)+getMat()*eje;
        bom->rvel->data[0]=rndn->token()*10;
        bom->rvel->data[1]=rndn->token()*10;
        bom->armed=ANI_HEAVY;
        bom->setMassAndG(1,-10);
        linked_ani.append(bom);
    }
  }
  float vel=tvel->norm(2)+rvel->norm(2);
  interp=interp+.03*vel;  //animation (handled from aniUniversal)
  time[2]+=vel*10;        //sound of steps
  if (time[2]>1500)
    if (!FSOUND_IsPlaying(channel)) {      
      FSOUND_PlaySound(channel,ani_bomber_smp[0].mod);    
      time[2]=0;
    }
};
And remember, Beethoven wrote his first symphony in C.
A.P.L. Byteswap