OK, I believe I a figured out how to work with heightmaps to build a custom world. The last thing left to do is build a custom PathWorld for agent navigation.
The problem I'm having is that the path world is not stiching neighbour areas together as seen in this screen shot.
I have modified the Heightmap tutorial to illustrate the problem. I create the PathWorld in the Init method and then add each heightmap to it at the end of the Build method. Is that all I need to do? Is there a setting I might have wrong or another step I'm missing?
Code:
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Edit::Heightmap heightmap1,heightmap2,heightmap3,heightmap4;
Mesh mesh1,mesh2,mesh3,mesh4;
PhysPart phys1,phys2,phys3,phys4;
Actor actor1,actor2,actor3,actor4;
PathMesh pathMesh1,pathMesh2,pathMesh3,pathMesh4;
PathWorld path;
PathSettings ps;
/******************************************************************************/
void Build(Edit::Heightmap &heightmap, Mesh &mesh, PhysPart &phys, Actor &actor, PathMesh &pathMesh, VecI2 &posI, Vec &pos, Edit::Heightmap *l, Edit::Heightmap *r, Edit::Heightmap *b, Edit::Heightmap *f, Edit::Heightmap *lb, Edit::Heightmap *lf, Edit::Heightmap *rb, Edit::Heightmap *rf) // build 'mesh', 'phys' and 'actor' from 'heightmap'
{
// later we will create a new physical body, that's why we must first delete the actor, so the old physical body will no longer be used by any actors
actor.del();
// build mesh
heightmap.build(mesh, 0, 6, true, l, r, b, f, lb, lf, rb, rf);
// adjust mesh scale and position
Flt scale=32;
mesh.scaleMove(scale, pos);
// simplify the mesh
mesh.setBase ( ); // set software version needed for simplification and later physical body creation
mesh.simplify (0, 0, 0.05f); // simplify
mesh.setRender( ); // set rendering version from software version
// create physical body
MeshBase base; base.createPhys(mesh); base.simplify(0, 0, 0.05f); // create a 1 MeshBase from all MeshParts in mesh and simplify it again
phys .createMesh(base); // create physical body from that MeshBase
actor.create (phys); // create actor from physical body
mesh.delBase(); // mesh software version is no longer needed
ps.reset();
ps.areaSize(32);
pathMesh.create(base, posI, ps);
path.set(&pathMesh, posI);
}
/******************************************************************************/
void InitPre()
{
App.name("Heightmap");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE|APP_MAXIMIZABLE|APP_MINIMIZABLE;
DataPath("../data");
Paks.add("engine.pak");
D.sync(true);
Cam.dist=24;
Cam.pitch=-1.3f;
Cam.at.set(16,0,16);
Sky.atmospheric();
}
/******************************************************************************/
Bool Init()
{
Physics.create(CSS_NONE, true, "../Installation/PhysX");
path.create( 32 );
heightmap1.create(32, 0, Materials.ptrRequire("mtrl/grass/0.mtrl"), false, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // create heightmap
heightmap2.create(32, 0, Materials.ptrRequire("mtrl/grass/0.mtrl"), false, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // create heightmap
heightmap3.create(32, 0, Materials.ptrRequire("mtrl/grass/0.mtrl"), false, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // create heightmap
heightmap4.create(32, 0, Materials.ptrRequire("mtrl/grass/0.mtrl"), false, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // create heightmap
Vec2 pos; SinCos(pos.y, pos.x, PI2); pos=pos*16+16;
REPD(x, heightmap1.resolution())
REPD(y, heightmap1.resolution())
{
Flt d=Dist(Vec2(x,y), pos);
heightmap1.height(x, y, BlendGaus(d/10)*0.1f);
}
SinCos(pos.y, pos.x, PI); pos=pos*16+16;
REPD(x, heightmap2.resolution())
REPD(y, heightmap2.resolution())
{
Flt d=Dist(Vec2(x,y), pos);
heightmap2.height(x, y, BlendGaus(d/10)*0.1f);
}
Build(heightmap1, mesh1, phys1, actor1, pathMesh1, VecI2(0,0), Vec(0,0,0), NULL, &heightmap2, NULL, &heightmap3, NULL, NULL, NULL, &heightmap4); // build mesh phys actor from heightmap
Build(heightmap2, mesh2, phys2, actor2, pathMesh2, VecI2(1,0), Vec(32,0,0), &heightmap1, NULL, NULL, &heightmap4, NULL, &heightmap3, NULL, NULL); // build mesh phys actor from heightmap
Build(heightmap3, mesh3, phys3, actor3, pathMesh3, VecI2(0,1), Vec(0,0,32), NULL, &heightmap4, &heightmap1, NULL, NULL, NULL, &heightmap2, NULL); // build mesh phys actor from heightmap
Build(heightmap4, mesh4, phys4, actor4, pathMesh4, VecI2(1,1), Vec(32,0,32), &heightmap3, NULL, &heightmap2, NULL, &heightmap1, NULL, NULL, NULL); // build mesh phys actor from heightmap
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Update()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01f, 50, CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT));
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_PREPARE:
{
mesh1.draw(MatrixIdentity); // draw mesh
mesh2.draw(MatrixIdentity); // draw mesh
mesh3.draw(MatrixIdentity); // draw mesh
mesh4.draw(MatrixIdentity); // draw mesh
LightDir(Cam.matrix.z, 1-D.ambientColor()).add();
}break;
}
}
/******************************************************************************/
void Draw()
{
Renderer.wire=Kb.b(KB_TILDE);
Renderer(Render);
if(Ms.b(0))
{
if(Renderer.rebuildDepthNeededForDebugDrawing())Renderer.rebuildDepth();
Physics.draw();
}
path.draw( 64, 0.1f );
D.text(0, 0.9f, "Press LMB to draw Physics");
D.text(0, 0.8f, "Press Tilde for Wireframe view");
}
/******************************************************************************/