About Store Forum Documentation Contact



Post Reply 
group move test script
Author Message
sivan Offline
Member

Post: #1
group move test script
hi

I just created a performance test for myself based on the tutorials, please let me know if someone is interested, and I will upload it with resources.

it includes:
- a group of 100 units in 10x10 formation
- one leader, the others are moving relatively to him, so obstacles are avoided, but not very smoothly
- a custom character mesh and animations converted from MTW2
- a custom map imported from L3DT (using heightmap and texture alpha maps), and some own textures
- the group can be moved together by mouse clicks on target position using the navmesh pathfinder
- free camera movements by arrows, rotate by mouse look

it's really a simple few line thingie, so do not expect intelligent behaviour, just a test. the group does not rotate due to its direction, and collisions are not handled.

[Image: esenthelscreenshot04.png]

probably there is a better approach for this task, but I'm really new in Esenthel engine. any idea welcome smile

Code:
/******************************************************************************/
#include "stdafx.h"

//#include <stdlib.h>
//#include <time.h>
/******************************************************************************

   A group of custom mesh characters with own skeleton and own animation,
   and with custom animation and movement speeds, in a custom world.

/******************************************************************************/
Image skybox; // sky box texture

STRUCT(Player , Game::Chr) // extend character class by defining a player class based on the character
//{
    virtual void create(Game::ObjParams &obj); // override default creation method to setup custom default animations after character creation
    virtual Bool update(); // here we'll update the player (please note that this is a virtual method)

    // formation data
    int row;
    int column;
    int arraynum;
};
/******************************************************************************/
Player player[100]; // player - A NEW GROUP CLASS OR STRUCT WOULD BE BETTER WITH OWN UNIT CREATOR FUNCTIONS
/******************************************************************************/
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
void Player::create(Game::ObjParams &obj)
{
   super::create(obj); // call default creation
    
   sac.stand    = &cskel.getSkelAnim("obj/chr/sergeant/idle.anim");
   sac.run        = &cskel.getSkelAnim("obj/chr/sergeant/walk.anim");
   sac.walk        = &cskel.getSkelAnim("obj/chr/sergeant/walk.anim");

   speed        = 3;
   anim.speed    = 1;
}
/*******************************************************************************/
Bool Player::update()
{
   // here we update character input according to mouse and keyboard
   // before we set the input, we need to check if the character isn't controlled by an automatic action
   if(action) // ACTION_NONE , ACTION_MOVE_TO , ACTION_MOVE_DIR
   {      
      // if it's controlled by an action we leave the input with no changes,
      // however we can optionally break that action, by pressing for example movement keys
      if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
   }
   if(!action) // if the character isn't controlled by an automatic action, we can set the input
   {
      // turn & move
      input.turn.x=Kb.b(KB_Q)-Kb.b(KB_E);
      input.turn.y=Kb.b(KB_T)-Kb.b(KB_G);
      input.move.x=Kb.b(KB_D)-Kb.b(KB_A);
      input.move.z=Kb.b(KB_W)-Kb.b(KB_S);
      input.move.y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);

      // dodge, crouch, walk, jump
      input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
      input.crouch= Kb.b (KB_LSHIFT);
      input.walk  = Kb.b (KB_LCTRL );
      input.jump  =(Kb.bp(KB_SPACE) ? 3.5f : 0);
   }

   return super::update(); // call Game::Chr::update on which Player is based on
}
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics;    // container for static    objects
//Game::ObjMemx<Game::Chr  > Chrs;        // container for item      objects
Game::ObjMemx<        Player> Players;    // container for character objects
/******************************************************************************/
void InitPre()
{
   App.name("Group of Game Characters on Terrain");
   App.flag=APP_FULL_TOGGLE;            // APP_MS_EXCLUSIVE| to hide mouse
   DataPath("../data");
   Paks.add("engine.pak");

   D.full(true).hdr(false).viewRange(500).viewFov(DegToRad(60),FOV_Y);   // fullscreen, hdr on, range 500, camera arc 60 degree
   D.shadowMapSize(2048).shadowMapNum(4).shadowJitter(false).shadowSoft(0).shadowMo​de(SHADOW_MAP);

   Cam.dist =10;
   Cam.yaw  =-PI_4;    // -45° DIRECTION
   Cam.pitch=-0.5f;
   Cam.at.set(-50,20,-75);

}
/******************************************************************************/
Bool Init()
{
   Physics.create(CSS_NONE, true, "../Installation/PhysX");
   Sun.image="Env/Sky/sun.gfx";
  
   // 1) skybox
   skybox.Import("../data/Env/Sky/scube03b_clearnoon+6.tga", IMAGE_B8G8R8A8, IMAGE_CUBE);  
   Sky.skybox     (skybox); // set sky from skybox

   // 2) atmospheric sky with fog
   //Sky.atmospheric();
   Sky.atmosphericColor(Vec4(0.3f), Vec4(0.1f));    // horizon and sky colour
   Sky.frac(0);
   Sky.atmosphericDensityExponent(0.5);

   Game::World.init()
              .setObjType(Statics, OBJ_STATIC)        // set 'Statics' memory container for 'OBJ_STATIC' objects
              //.setObjType(Chrs  , OBJ_CHR  )        
              .setObjType(Players, OBJ_PLAYER);        

   // create the world by giving path to builded world
   Game::World.New("world/mydry1.world");
   Game::World.update(Cam.at);
    
   // set water
   Water.images(Images("Env/Water/0.gfx"), Images("Env/Water/0.n.gfx"), Images("Env/Water/reflection.gfx")); // set water from textures
   Water.draw      =true;    // enable drawing
   Water.wave_scale=0.8f;    // adjust wave scales
   Water.validate();        // must be used after manual settings

   //---------------------------------------------------------
   // original : from character.cpp
   Game::ObjParams obj; // set object parameters
   obj.mesh(true, Meshes.ptrRequire("obj/chr/sergeant/0.mesh"));    

   // modified : group of units
   int i;
   for(i=0;i<100;i++)
   {
        obj.matrix.setScalePos(1.8f, Vec(i%10*2-50, 10, -Int(i/10)*2-75));        // adjust height to terrain level
        player[i].create(obj); // create player from object parameters        
        // create skeleton here, not inside void create
        player[i].cskel.create(Skeletons("../data/obj/chr/sergeant/0.skel")); // create controlled skeleton from skel file, with default height
        // assign animation inside void Player::create
        // set speed and anim speed in void Player::create

        // set player properties used for group movement - first row created from left to right
        player[i].arraynum = i;
        player[i].column = i%10;
        player[i].row = Int(i/10);
   }
    
   //-----------------------------------------------------------
   return true;
}
/******************************************************************************/
void Shut()
{
    // empty
}
/******************************************************************************/
Bool Update()
{
   if(Kb.bp(KB_ESC))return false;
   Physics.startSimulation().stopSimulation();

   // update water waves movement - requires Water.validate()
   Water.update(Vec2(0.01f, 0.01f));

   //------------------------------------------------------------------------------------------------
   // move leader of player group
   if(Ms.bp(0)) // on LMB pressed
   {
      Vec     pos, dir; ScreenToPosDir(Ms.pos(), pos, dir); // convert screen mouse position to world position and direction
      PhysHit phys_hit;
      if(Physics.ray(pos, dir*D.viewRange(), &phys_hit)) // if ray-test hit something
      {
          player[0].actionMoveTo(Vec(phys_hit.plane.pos.x, phys_hit.plane.pos.y, phys_hit.plane.pos.z)); // order character to move to that location      
      }
   }
   //------------------------------------------------------------------------------------------------
   // player group movement
   Vec leaderpos = player[0].pos();
   int i;
   for(i=1;i<100;i++)    
   {
        player[i].actionMoveTo(Vec(leaderpos.x+player[i].column*2,leaderpos.y,leaderpos.z-player[i].row*2));
   }
   //------------------------------------------------------------------------------------------------
   // entity update
   for(i=0;i<100;i++)
      player[i].update();
   //------------------------------------------------------------------------------------------------
   // free camera
   Cam.yaw  -=Ms.d().x;                         // modify yaw      according to mouse delta x
   Cam.pitch+=Ms.d().y;                         // modify pitch    according to mouse delta y
   Cam.roll +=(Kb.b(KB_Z)-Kb.b(KB_X))*Time.d(); // modify roll     according to Z and X keyboard buttons
   Cam.dist -=Ms.wheel()*0.4f;                  // modify distance according to mouse wheel
   Clamp(Cam.dist, 0.1f, 50);                   // clamp  distance to minimum and maximum values

   if(Kb.b(KB_LEFT ))Cam.at-=Cam.matrix.x*Time.d()*5; // move camera left  on left  arrow key
   if(Kb.b(KB_RIGHT))Cam.at+=Cam.matrix.x*Time.d()*5; // move camera right on right arrow key
   if(Kb.b(KB_UP   ))Cam.at+=Cam.matrix.z*Time.d()*5; // move camera fwd   on up    arrow key
   if(Kb.b(KB_DOWN ))Cam.at-=Cam.matrix.z*Time.d()*5; // move camera bckw  on down  arrow key
   if(Kb.b(KB_HOME ))Cam.at+=Cam.matrix.y*Time.d()*5; // move camera up    on Home key
   if(Kb.b(KB_END  ))Cam.at-=Cam.matrix.y*Time.d()*5; // move camera down  on End key

   Cam.setSpherical    (Cam.at, Cam.yaw, Cam.pitch, Cam.roll, Cam.dist); // set spherical camera with 'look at' position, angles and distance
   Cam.updateVelocities(                                              ); // after camera settings are up, we need to update camera velocities in order to achieve correct motion blur when enabled
   Cam.set             (                                              ); // set as active camera
  
   return true;
}
/******************************************************************************/
void Render()
{
    // world.cpp
    Game::World.draw(); // draw world (this is done outside of 'switch(Renderer())' because world automatically detects active rendering mode)
    //-------------------------------------
    int i;
    switch(Renderer())
    {
      case RM_PREPARE:
          {        
             for(i=0;i<100;i++)
                player[i].drawPrepare();
          }break;
      case RM_SHADOW:
          {
              for(i=0;i<100;i++)
                player[i].drawShadow();
          }break;
    }
}
void Draw()
{
   Renderer(Render);

   D.text(0, 0.9f, S+"Fps "+Time.fps());
}
/******************************************************************************/

Edit: I updated the screenshot, and the code too (shadows, water, sky settings)
(This post was last modified: 01-15-2013 11:14 AM by sivan.)
07-12-2012 11:11 AM
Visit this user's website Find all posts by this user Quote this message in a reply
Post Reply