About Store Forum Documentation Contact



Post Reply 
Basic for Dynamic World
Author Message
Pherael Offline
Member

Post: #1
Basic for Dynamic World
Hi,
I haven't found any tutorial how make dynamic world in code, so I was wondering, if somebody figure it out, could post some basic code for it?

I know there is example in Inesis Online, but is little too complicated to start with since there is not much commentary. I know, I can figure it with some time, but with the basic I could do this a lot faster. And, I think it would be useful for others too.

So my question is realy easy, how create for example plain 4x4 area world working under World Manager?
10-15-2013 11:41 AM
Find all posts by this user Quote this message in a reply
Ozmodian Offline
Member

Post: #2
RE: Basic for Dynamic World
There is a tutorial for this called dynamic height map. Also, if you want Ineisis information, I have a video tutorial series explaining it ( in video tutorials) but it is pretty advanced if all you want is the 4x4.
10-15-2013 03:41 PM
Find all posts by this user Quote this message in a reply
Pherael Offline
Member

Post: #3
RE: Basic for Dynamic World
Yeah, I know there is heightmap tutorial, but it not what I need.

Anyway thanks, I will watch your video, I hope it will help me.
10-15-2013 04:53 PM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #4
RE: Basic for Dynamic World
I was messing around with this earlier, but found it was easier to create a blank world in the editor, then add the objects to it as needed- I kept getting memory errors otherwise. I didn't spend all that much time on it though.
10-15-2013 06:54 PM
Find all posts by this user Quote this message in a reply
Pherael Offline
Member

Post: #5
RE: Basic for Dynamic World
Thanks Rubeus, that great and simple idea.
10-15-2013 07:25 PM
Find all posts by this user Quote this message in a reply
Pherael Offline
Member

Post: #6
RE: Basic for Dynamic World
I found some old post on forum and figure it out. If anybody interesed, below is code I'm using. When you press space you will see "gap" between PathMeshes but I tested this in game, and charactes have no problem with walk through them.

Also screen from my game - fully generated world: [Image: gqx.png]

Code:
/******************************************************************************/
PathWorld Worldpath;                 // PathFinding for our world
PathSettings pathSettings;  
Memx<PathMesh> pathMeshList;
Memc<Game.WorldManager.AreaState> areas;

Game.WorldSettings worldSettings;

Map<VecI2, Heightmap> heightmaps(Compare);

int size_x=6; // number of areas width
int size_y=6; // number of areas height
        
UID grass_id=UID(3015359194, 1248539670, 3822661250, 1853126960);
/******************************************************************************/
void NewWorld() // build 'mesh', 'phys' and 'actor' from 'heightmap'
{
  
    
   pathSettings.reset();
   pathSettings.areaSize(32.0f);
   Worldpath.del();
   Worldpath.create(32.0f);
  
   Game.World.activeRange(D.viewRange());
  
   worldSettings.reset();  
   Game.World.mode(Game::WORLD_MANUAL);
  
   // creating new World
   Game.World.Create("world/dynamic.world",worldSettings);
   Game.World.New ("world/dynamic.world");
            
   Game.World.update(Cam.at);

   Image randomLand; // creating random terrain deformation
   randomLand.createSoft(32*size_x, 32*size_x, 1, IMAGE_F32);
   randomLand.noise(255, 255, 255, 0);
   randomLand.blur(4, true);
    
   FREPD(x, size_x)
   FREPD(y, size_y)
   {
        Game.WorldManager.AreaState &area = areas.New(); // create new area state
        area.set(VecI2(x, y), Game.AREA_ACTIVE);         // set as active
   }
   Game.World.areaSetState(areas, false);           // set all active areas for World
          
   FREPD(x, size_x)
   FREPD(y, size_y)
   {
      
      Heightmap * heightmap = heightmaps.get(VecI2(x, y));
      if(!heightmap) Exit("heightmap is not created");
      
      Mesh      mesh;
      PhysPart  phys;

      // create heightmap looking for existing  neighbors
      heightmap.create(32, 0, grass_id, false,
      heightmaps.find(VecI2(x-1, y)),
      heightmaps.find(VecI2(x+1, y)),
      heightmaps.find(VecI2(x, y-1)),
      heightmaps.find(VecI2(x, y+1)),
      heightmaps.find(VecI2(x-1, y-1)),
      heightmaps.find(VecI2(x-1, y+1)),
      heightmaps.find(VecI2(x+1, y-1)),  
      heightmaps.find(VecI2(x+1, y+1)) );
      
      // creating terain deformation from image
      FREPD(i, 33)
      FREPD(j, 33)
      {      
        // heightmap.height(i, j, randomLand.pixelF(x*32+i, y*32+j)*0.4f);        
      }

      // build mesh looking for existing neightbors
      heightmap.build(mesh, 0, 6, true,
      heightmaps.find(VecI2(x-1, y)),
      heightmaps.find(VecI2(x+1, y)),
      heightmaps.find(VecI2(x, y-1)),
      heightmaps.find(VecI2(x, y+1)),
      heightmaps.find(VecI2(x-1, y-1)),
      heightmaps.find(VecI2(x-1, y+1)),
      heightmaps.find(VecI2(x+1, y-1)),  
      heightmaps.find(VecI2(x+1, y+1)) );
  
      // adjust mesh scale and position
      flt scale=32;
      Vec pos  (32*x, 0,32*y);
      mesh.scaleMove(scale, pos);

      // simplify the mesh
      mesh.setBase  (       ); // set software version needed for simplification and later physical body creation
      mesh.simplify (0.05, 0); // simplify
      mesh.setRender(       ); // set rendering version from software version

   // create physical body
      MeshBase base;
      base.createPhys(mesh);
      base.simplify(0.05, 0); // create a 1 MeshBase from all MeshParts in mesh and simplify it again
  
      phys .createMesh(base); // create physical body from that MeshBase    
    
      mesh.delBase(); // mesh software version is no longer needed

      
      // Create new data for areas
      if(Game::World.areaActive(VecI2(x, y)))
         {
         Game::World.areaActive(VecI2(x, y)).getData().mesh.meshes.New().create(mesh);
         Game::World.areaActive(VecI2(x, y)).getData().phys.parts.New().createMesh(base);
      
         Game::World.areaActive(VecI2(x, y)).getData().actor.del();
         Game::World.areaActive(VecI2(x, y)).getData().actor.create(phys).group(AG_TERRAIN); // <- not sure is group(AG_TERRIN) is needed
         }
  
      }
      
      // Creating path meshes for pathfinding
      FREPD(x, size_x)
      FREPD(y, size_y)
      {
         MeshBase mb_GRID; // we need to marge neightbors paths into one
         for(Int i= -1 ;i<=(1); i++)
         for(Int j= -1 ;j<=(1); j++)
         {  
         MeshBase mb;
         if(Game::World.areaActive(VecI2(x+i, y+j)))
         mb_GRID += mb.createPhys(Game::World.areaActive(VecI2(x+i, y+j)).data().mesh.meshes[0]);
         }
        
         PathMesh &pm = pathMeshList.New();
         pm.create(mb_GRID, VecI2(x, y), pathSettings);
         Worldpath.set(&pm, VecI2(x, y)); // adding new pathmesh to global path
      }
      
}
/******************************************************************************/
void InitPre()
{
   EE_INIT();
   App.flag=APP_MS_EXCLUSIVE;

   Cam.dist=24;
   Cam.pitch=-1.3;
   Cam.at.set(16, 0, 16);

   Sky.atmospheric();
}
/******************************************************************************/
bool Init()
{
   Physics.create(EE_PHYSX_DLL_PATH);

   NewWorld();
   return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
bool Update()
{
   if(Kb.bp(KB_ESC))return false;
   CamHandle(0.01, 50, CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT));
  
   Game.World.update(Cam.at);
  
   return true;
}
/******************************************************************************/
void Render()
{
   Game.World.draw();
}
/******************************************************************************/
void Draw()
{
   Renderer.wire=Kb.b(KB_TILDE);
   Renderer(Render);

   if(Ms.b(0))
   {
      if(Renderer.rebuildDepthNeededForDebugDrawing())Renderer.rebuildDepth();
      Physics.draw();
   }
   if(Kb.b(KB_SPACE)) Worldpath.draw();
  
  
   D.text(0, 0.9, "Press LMB to draw Physics");
   D.text(0, 0.8, "Press Tilde for Wireframe view");
   D.text(0, 0.7, "Press Space to draw PathMeshes" );
}
/******************************************************************************/

You can just copy this code to Tutorial and play;
If you see any mistake in code above, please report it, I will be grateful.
(This post was last modified: 10-19-2013 08:20 AM by Pherael.)
10-18-2013 11:05 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #7
RE: Basic for Dynamic World
Hi,
The codes look pretty neat on first look, though please fix one important bug:
You need to use Memx for pathMeshList, because:
Worldpath.set(&pm, VecI2(x, y))
remembers the pointer to the path mesh.
and Memc (which you're currently using) does not guarantee const memory address.

(I've made the change to above post already, so other users won't copy the Memc version)

Some visible gaps in the path meshes are normal in Recast.

Also this could use some improvement:
Code:
Game.WorldManager.AreaState &area = areas.New(); // create new area state
       area.set(VecI2(x, y), Game.AREA_ACTIVE);         // set as active
       Game.World.areaSetState(areas, false);           // set for world
it's not a bug, but you're setting growing container each loop step, while you could just call areaSetState for just one area in that step
10-19-2013 01:55 AM
Find all posts by this user Quote this message in a reply
Pherael Offline
Member

Post: #8
RE: Basic for Dynamic World
Thank you Esenthel,

Maybe I was I little bit to hurry to post this, before check it two times, since I used Memx in my project. My shame.

Thank you about your advice about code you quote. I made little change and now should be ok.
10-19-2013 08:39 AM
Find all posts by this user Quote this message in a reply
Post Reply