How to use the terrain engine libmini with Irrlicht

A forum to store posts deemed exceptionally wise and useful
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

heres v0.4, changed to FPS-camera instead of using scrolling with keys, i will change the download this evening to this version, again with help from Stefan Roettger, i think the demo is more his demo than mine...:
[code]
// Example Mars for libmini-terrainengine with Irrlicht
// try to fly with the cursor keys and mouse!
// v.01 16.10.2004
// v.02 17.10.2004
// v.03 18.10.2004 delete vertex behind line of sight (deleted in v.04 cause user-defined-culling isnt part of this tutorial)
// v.04 change from keyscrolling to FPS-camera, delete the userculling from v.03
// btw: if you want user-defined-culling, you can delete vertex/indices
// from buffer after the stub->draw-function
//
// The mini library is the core of the terrain renderer described in the
// paper "Real-Time Generation of Continuous Levels of Detail for Height Fields".
// Copyright (c) 1995-2004 by Stefan Roettger (Version 5.02 as of 18.August.2004).
//
// The terrain renderer is licensed under the terms of the LGPL (see
// http://www.gnu.org/copyleft/ for more information on the license).
// Any commercial use of the code or parts of it requires the explicit
// permission of the author!
//
// The libmini-author's contact address is:
//
// mailto:roettger@cs.fau.de
// http://www9.cs.fau.de/Persons/Roettger
//
// The original terrain rendering paper and the talk are available here:
//
// http://www9.cs.fau.de/Persons/Roettger/ ... ERRAIN.PDF
// http://www9.cs.fau.de/Persons/Roettger/ ... WSCG98.PPT
//
//
// example and Irrlicht-interface-functions by zenprogramming
// (with help from Stefan Roettger ;-) )
// mailto: zenprogramming at yahoo dot de
// http://zenprogramming.tripod.com

#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;



#pragma comment(lib, "Irrlicht.lib")
#include "ministub.hpp"


int triangleindex=-1;
int vertex0=0;
SMeshBuffer* buffer = 0;
video::S3DVertex vertex;


int size=256;
float dim=1.0f;
float scale=0.2f;
float res=1000.0f;
float ex=0.0f,ey=10.0f,ez=-30.0f;
float dx=0.0f,dy=-0.25f,dz=-1.0f;
float ux=0.0f,uy=1.0f,uz=0.0f;



//libmini->Irrlichtinterfacefunctions
//this function starts every trianglefan
void mybeginfan()
{
triangleindex=0;
vertex0=buffer->getVertexCount();
}

//libmini->Irrlichtinterfacefunctions
//this function gives one vertex
void myfanvertex(float i,float y,float j)
{
vertex.Pos.set(dim*i-size/2*dim,
y*scale,
size/2*dim-dim*j);
vertex.TCoords.set(1.0f-(float)i/(size-1),
1.0f-(float)j/(size-1));

// instead of using white vertex-colors with a texture,
// you could use the vertex-colors for shadows from heightdelta
// vertex.Color.set(255,from heightdelta,from heightdelta,from heightdelta);
buffer->Vertices.push_back(vertex);
if (triangleindex==2)
{
buffer->Indices.push_back(vertex0);
buffer->Indices.push_back(buffer->getVertexCount()-2);
buffer->Indices.push_back(buffer->getVertexCount()-1);
return;
}
triangleindex++;
}


int main(int argc,char *argv[])
{
scene::IAnimatedMesh* mesh = 0;
video::IVideoDriver* driver=0;
scene::ICameraSceneNode* camera=0;
video::SMaterial material;
vector3df cameraPos;
vector3df cameraTarget;
int cameraoffset=120;

IrrlichtDevice *device =
createDevice(video::EDT_DIRECTX8, core::dimension2d<s32>(640, 480));

driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
material.Texture1=0;
material.Lighting=false;
driver->setMaterial(material);

IImage* heightimage = driver->createImageFromFile("FaceOfMarsMap.bmp");
size = heightimage->getDimension().Width;

short int *hfield = new short int[size*size];

for (int i=0; i<size; i++)
for (int j=0; j<size; j++)
hfield[i+j*size] = heightimage->getPixel(i,size-1-j).getRed();

ministub *stub;
stub=new ministub(hfield,
&size,&dim,scale,1.0f,
mybeginfan,myfanvertex,0,0,
NULL);

int lastFPS = -1;
vertex.Normal.set(0,1,0);
vertex.Color.set(255,255,255,255);

scene::IAnimatedMeshSceneNode* terrainnode = 0;
ITexture* terraintexture = driver->getTexture("faceofmars.jpg");

camera = smgr->addCameraSceneNodeFPS(0, 100, 100);
camera->setPosition(vector3df(0.0f,0.0f,0.0f));
camera->setTarget(vector3df(0.0f,0.0f,-1.0f));
camera->setUpVector(vector3df(0.0f,1.0f,0.0f));

while(device->run())
{

buffer = new SMeshBuffer();

float aspect = camera->getAspectRatio();
float fovy = 180.0f/PI*camera->getFOV();
float nearp = camera->getNearValue();
float farp = camera->getFarValue();

vector3df pos = camera->getPosition();
vector3df tgt = camera->getTarget();

float glide = stub->getheight(pos.X,pos.Z)+10.0f*nearp;
if (glide<0.0f) glide = 100.0f;

camera->setPosition(vector3df(pos.X,glide,pos.Z));

if (tgt.X==pos.X && tgt.Y==pos.Y && tgt.Z==pos.Z) tgt.Z-=1.0f;

stub->draw(res,
pos.X,glide,pos.Z,
tgt.X-pos.X,tgt.Y-pos.Y,tgt.Z-pos.Z,
0.0f,1.0f,0.0f,
2.4f*fovy,aspect,
nearp,farp);

SMesh* meshtmp = new SMesh();
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
buffer->recalculateBoundingBox();
meshtmp->addMeshBuffer(buffer);
meshtmp->recalculateBoundingBox();
animatedMesh->addMesh(meshtmp);
animatedMesh->recalculateBoundingBox();
mesh = animatedMesh;
buffer->drop();
terrainnode = smgr->addAnimatedMeshSceneNode(mesh);
terrainnode->setMaterialFlag(video::EMF_LIGHTING, false);
terrainnode->setMaterialTexture(0, terraintexture);

driver->beginScene(true, true, video::SColor(0,150,50,0));

smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Marsdemo: Terrainengine-libmini and Irrlicht Engine (fps:%d) Triangles:%d",
fps, driver->getPrimitiveCountDrawn());
device->setWindowCaption(tmp);
lastFPS = fps;
}
terrainnode->remove();
meshtmp->drop();
animatedMesh->drop();
}
delete(stub);
delete(hfield);
heightimage->drop();
device->drop();

return 0;
}

[/code]
Last edited by knightoflight on Wed Oct 20, 2004 5:43 pm, edited 3 times in total.
quark

Post by quark »

I have seen that you made Round Based Strategy. On your web site exists examples for terrain rendering with multiple textures and alphablending.

How much difficult would be to use libmini to produce same thing? I'm interested in terrain rendering and possibilites to have renderer capable to do things like AOM or Empire Earth. I don't know how fast this can be with Irrlicht, but let say that we care only about visual impression right now.

What do you think?
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

Hi, i think:
depends on what you want. I dont really know the engine of AgeofX.
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

The new demo from Stefan and me is for download ready. Thats all, i dont think there will be more versions. Now you can show us your demos.
-> download-Area, faceofmarsdemo
http://zenprogramming.tripod.com
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

The new demo from Stefan and me is for download ready. Thats all, i dont think there will be more versions.
http://zenprogramming.tripod.com -> download-Area, faceofmarsdemo

Now we want to see your demo with the engine ;-)
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

The demo-version for UNIX is now online on Stefan Roesslers terrain-engine dowload-place, too:
http://www9.informatik.uni-erlangen.de/ ... /download/
brcolow
Posts: 56
Joined: Mon Jul 19, 2004 6:15 am
Location: Arizona

Post by brcolow »

Awesome. I will work on implementing this in my game tomorrow and let you know how it goes :)
G'Day.
zola
Posts: 52
Joined: Thu Jul 15, 2004 2:31 pm
Location: switzerland
Contact:

Post by zola »

libmini scenenode based on the well know demo :)

Header

Code: Select all

#ifndef __CLMTerrainSceneNode_h__
#define __CLMTerrainSceneNode_h__

#include <irrlicht.h>
#include <ministub.hpp>

#ifdef _DEBUG
#pragma comment(lib, "libMini_d.lib")
#else
#pragma comment(lib, "libMini.lib")
#endif

namespace irr
{
	namespace scene
	{

		using namespace core;
		using namespace video;

		class CLMTerrainSceneNode : public ISceneNode
		{

		protected:

			//////////////////////////////////////////////////////////////////
			// globals for libMini callbacks
			//////////////////////////////////////////////////////////////////

			// prepares a buffer if the buffer is nonempty draws and then empties the buffer
			// this function needs to be called after stub->draw one more time
			static void _BeginFan();

			// fills the buffer with vertecis
			static void _FanVertex(float i,float y,float j);

			// pointer to the scenenode
			static CLMTerrainSceneNode* _self;

			//////////////////////////////////////////////////////////////////
			
			ministub *stub;
			IVideoDriver* driver;
			SMeshBuffer buffer;		// a buffer for fan vertecis
			S3DVertex vertex;		// a default vertex

			// draw the meshbuffer
			void BeginFan();
			// add point (i,y,j) to the meshbuffer
			void FanVertex(float i,float y,float j);

			// point spacing
			float dim;
			// height scaling factor
			float scale;
			// pixel width of the heightmap
			s32 size; 
			// resolution
			float res;
			// field of view
			float fovy;
			// aspect ratio
			float aspect;
			// near value
			float nearp;
			// far value
			float farp;

			// the height field
			float *hfield;
			// material
			SMaterial Material;
			// invere of absolute transform to calculate hf coordinates from world coordinates
			matrix4 invAbsoluteTransform;
			// current camera pos in heightfield coordinate
			vector3df pos;
			// current camera target in heightfield coordinate
			vector3df tgt;
			// current camer up in heightfield coordinate
			vector3df up;

			// Bounding box of the heightfield
			mutable aabbox3df Box;

		public:

			// constructor
			CLMTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id);

			// destructor
			virtual ~CLMTerrainSceneNode();

			/*!
			\brief create the terrain
			\param heightmap, image with height values
			\param texture, texture used for texturing the terrain
			\param detailmap, not used
			\param gridPointSpacing, spacing between the gridpoints of the heightfield
			\param heightScale, scaling value for image height values
			\param resolution, 1000.0f ... 1000000.0f
			*/
			bool create(IImage* heightmap, ITexture* texture, ITexture* detailmap, 
				f32 gridPointSpacing, f32 heightScale, f32 resolution);

			// prerender register node for rendering and call child nodes for registering
			virtual void OnPreRender();

			// render the node
			virtual void render() ;

			// post render, animation etc.
			virtual void OnPostRender(u32 timeMs);

			// get the material with given number
			virtual SMaterial& getMaterial(s32 i)
			{
				return Material;
			}

			// get the boundingbox of the node
			const aabbox3df& getBoundingBox() const
			{
				AbsoluteTransformation.transformBox(Box);
				return Box;
			}

			// get the inverse of the absolute transformation
			matrix4& getInvAbsoluteTransformation(){ return invAbsoluteTransform; }

			// get the heightfield data
			f32* getHeightField() { return hfield; }

			// get the length of the square size of the heightfield
			s32 getHeightFieldSize() { return size; }

			// spacing between the sample points
			f32 getPointSpacing() { return dim; }

			// scaling factor to modify the height values
			f32 getHeightScale() { return scale; }

			// get height at grid point (i,j)
			f32 getHeight(int i,int j);

			// get height at heightfield coordinate (x,z) 
			// transformation is inv=AbsoluteTransform.getInverse();
			// inv.transformVect(pos);
			f32 getHeight(float x,float z);

			// get fog height at heightfield coordinate (x,z) 
			// transformation is inv=AbsoluteTransform.getInverse();
			// inv.transformVect(pos);
			f32 getFogHeight(float x,float z);

			// get normal at heightfield coordinate (x,z) 
			// transformation is inv=AbsoluteTransform.getInverse();
			// inv.transformVect(pos);
			vector3df getNormal(float x,float z);

		};

	}

}


#endif
Impl

Code: Select all

#include "CLMTerrainSceneNode.h"

namespace irr
{

	namespace scene
	{

		using namespace core;
		using namespace video;

		// self pointer for callback
		CLMTerrainSceneNode* CLMTerrainSceneNode::_self=0;
		// prepares a buffer if the buffer is nonempty draws and then empties the buffer
		// this function needs to be called after stub->draw one more time
		void CLMTerrainSceneNode::_BeginFan()
		{
			if(_self) _self->BeginFan();
		}
		// fills the buffer with vertecis
		void CLMTerrainSceneNode::_FanVertex(float i,float y,float j)
		{
			if(_self) _self->FanVertex(i,y,j);
		}

	//////////////////////////////////////////////////////////////////////////


		// constructor
		CLMTerrainSceneNode::CLMTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id):
		ISceneNode(parent,mgr,id)
		{
			driver=SceneManager->getVideoDriver();
			stub=0;
			hfield=0;
			AbsoluteTransformation.getInverse(invAbsoluteTransform);
		}

		CLMTerrainSceneNode::~CLMTerrainSceneNode()
		{
			if(stub) delete stub;
			if(hfield) delete [] hfield;
		}

		//! loads the terrain
		bool CLMTerrainSceneNode::create(IImage* heightmap, ITexture* texture, ITexture* detailmap, 
			f32 gridPointSpacing, f32 heightScale, f32 resolution)
		{
			if(stub) delete stub;
			if(hfield) delete [] hfield;

			res=resolution;
			dim=gridPointSpacing;
			scale=heightScale;
			size = heightmap->getDimension().Width;
			hfield = new float[size*size];

			vector3df ext(size*dim,0,size*dim);
			f32 hmin=10000000;
			f32 hmax=-10000000;
			for (int i=0; i<size; i++)
				for (int j=0; j<size; j++)
				{
					hfield[i+j*size] = heightmap->getPixel(i,size-1-j).getRed()*scale;
					if(hmin>hfield[i+j*size]) hmin=hfield[i+j*size];
					if(hmax<hfield[i+j*size]) hmax=hfield[i+j*size];
				}
			Box.MinEdge.set(-ext.X/2.0f,hmin,-ext.Z/2.0f);
			Box.MaxEdge.set(ext.X/2.0f,hmax,ext.Z/2.0f);

			/*stub=new ministub(hfield,
				&size,&dim,scale,1.0f,
				CLMTerrainSceneNode::_BeginFan,
				CLMTerrainSceneNode::_FanVertex,
				0,0,0);*/
			stub=new ministub(hfield,
				&size,&dim,1.0f,1.0f,
				CLMTerrainSceneNode::_BeginFan,
				CLMTerrainSceneNode::_FanVertex,
				0,0,0);

			vertex.Normal.set(0,1,0);
			vertex.Color.set(255,255,255,255);

			Material.Texture1=texture;
			Material.Texture2=detailmap;

			return true;
		}

		// prepares a buffer if the buffer is nonempty draws and then empties the buffer
		// this function needs to be called after stub->draw one more time
		void CLMTerrainSceneNode::BeginFan()
		{
			if(buffer.Vertices.size()>0 && driver)
			{	
				driver->drawIndexedTriangleFan(buffer.Vertices.const_pointer(),buffer.Vertices.size(),buffer.Indices.const_pointer(),buffer.Indices.size()-2);
				buffer.Vertices.set_used(0);
				buffer.Indices.set_used(0);
			}
		}
		// fills the buffer with vertecis
		void CLMTerrainSceneNode::FanVertex(float i,float y,float j)
		{
			//vertex.Pos.set(dim*i-size/2*dim, y*scale, size/2*dim-dim*j);
			vertex.Pos.set(dim*i-size/2*dim, y, size/2*dim-dim*j);
			//vertex.TCoords.set(1.0f-(float)i/(size-1),1.0f-(float)j/(size-1));
			vertex.TCoords.set((float)i/(size-1),(float)j/(size-1));
			buffer.Indices.push_back(buffer.Indices.size());
			buffer.Vertices.push_back(vertex);
		}

		void CLMTerrainSceneNode::OnPreRender()
		{
			if(IsVisible)
				SceneManager->registerNodeForRendering(this,SNRT_DEFAULT);
			
			ISceneNode::OnPreRender();

			AbsoluteTransformation.getInverse(invAbsoluteTransform);
		}

		void CLMTerrainSceneNode::render()
		{
			ICameraSceneNode* camera=SceneManager->getActiveCamera();
			driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);


			if(stub && camera)
			{

				aspect = camera->getAspectRatio();
				fovy = f32(GRAD_PI)*camera->getFOV();
				nearp = camera->getNearValue();
				farp = camera->getFarValue();
				
				pos.set(camera->getPosition());
				tgt.set(camera->getTarget());
				up.set(camera->getUpVector());

				invAbsoluteTransform.transformVect(pos);
				invAbsoluteTransform.transformVect(tgt);
				invAbsoluteTransform.transformVect(up);

				vector3df dx=tgt-pos;
				if(dx.getLengthSQ()==0.0)
				{
					dx.Z=-1.0f;
				}
				// make callbacks to this scenenode :)
				_self=this;
				
				driver->setMaterial(Material);

				stub->draw(res,
					pos.X,pos.Y,pos.Z,
					dx.X,dx.Y,dx.Z,
					up.X,up.Y,up.Z,
					2.0f*fovy,
					aspect,
					nearp,
					farp);

				BeginFan();

				if(DebugDataVisible)
				{
					SMaterial mat;
					mat.Lighting=false;
					mat.Wireframe=true;
					mat.FogEnable=false;
					mat.EmissiveColor=SColor(255,0,255,0);
					mat.AmbientColor=SColor(255,0,255,0);
					mat.DiffuseColor=SColor(255,0,255,0);
					mat.Texture1=0;
					mat.Texture2=0;
					driver->setMaterial(mat);
					driver->draw3DBox(Box, SColor(255,0,0,255));

					stub->draw(res,
						pos.X,pos.Y,pos.Z,
						dx.X,dx.Y,dx.Z,
						up.X,up.Y,up.Z,
						2.0f*fovy,
						aspect,
						nearp,
						farp);

					BeginFan();
				}
				

			}
		}

		void CLMTerrainSceneNode::OnPostRender(u32 timeMs)
		{
			ISceneNode::OnPostRender(timeMs);
			
		}


		f32 CLMTerrainSceneNode::getHeight(int i,int j)
		{
			if(stub)
				return stub->getheight(i,j);
			else
				return 0;
		}

		f32 CLMTerrainSceneNode::getHeight(float x,float z)
		{
			if(stub)
				return stub->getheight(x,z);
			else
				return 0;
		}

		f32 CLMTerrainSceneNode::getFogHeight(float x,float z)
		{
			if(stub)
				return stub->getfogheight(x,z);
			else
				return 0;
		}

		vector3df CLMTerrainSceneNode::getNormal(float x,float z)
		{
			vector3df n(0,1,0);
			if(stub)
			{
				f32 nx,ny,nz;
				stub->getnormal(x,z,&nx,&ny,&nz);
				n.set(nx,ny,nz);
			}
			return n;
		}


	}
}
usage:

Code: Select all

CLMTerrainSceneNode* terrain = new CLMTerrainSceneNode(smgr->getRootSceneNode(), smgr, 9999);
terrain->create(heightimage,terraintexture,0,32.0f,10.0f,1000.0f);
terrain->getMaterial(0).FogEnable=true;
//terrain->setPosition(vector3df(0,4000,0)); // YES!!!
//terrain->setRotation(vector3df(0,45,0)); // and this too!!!
Take a loook at the coments in the header file for a overall look of the api.
Have fun
Tom

Edit:
There's something wrong with the BoundingBox transformation so disable autoculling if you place your terrain somewhere other than at (0,0,0) with angles (0,0,0).

Code: Select all

terrain->setAutomaticCulling(false);
Guest

Post by Guest »

i get 2 errors if i try to compile my testproject.
[Linker error] undefined reference to `irr::scene::CLMTerrainSceneNode::CLMTerrainSceneNode(irr::scene::ISceneNode*, irr::scene::ISceneManager*, int)'

[Linker error] undefined reference to `irr::scene::CLMTerrainSceneNode::create(irr::video::IImage*, irr::video::ITexture*, irr::video::ITexture*, float, float, float)'
i dont know whats wrong, here is the project code:

Code: Select all

#include <stdio.h>
#include <irrlicht.h>
#include "CLMTerrainSceneNode.h"

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;
using namespace io;

int main()
{
    IrrlichtDevice* device =
    	createDevice(EDT_OPENGL, dimension2d<s32>(640,480), 32, false, false, false, 0);
    	
   	IVideoDriver* driver = device->getVideoDriver();
   	ISceneManager* smgr = device->getSceneManager();
   	IGUIEnvironment* guienv = device->getGUIEnvironment();

	ITexture* terraintexture = driver->getTexture("data/textures/environment/grass_1024.jpg");
	IImage* terrainheightmap = driver->createImageFromFile("data/textures/heightmaps/heightmap.jpg");
  	
   	CLMTerrainSceneNode* terrain = new CLMTerrainSceneNode(smgr->getRootSceneNode(), smgr, 9999);
   	terrain->create(terrainheightmap,terraintexture,0,32.0f,10.0f,1000.0f); 
   	terrain->getMaterial(0).FogEnable=true;
   	terrain->setPosition(vector3df(0,4000,0));
   	terrain->setRotation(vector3df(0,45,0));
   	terrain->setAutomaticCulling(false);
   	
	while(device->run())
	{
		driver->beginScene(true, true, SColor(0,128,128,128));
		smgr->drawAll();
		guienv->drawAll();
		driver->endScene();
	}
	device->drop();
	return 0;
}
	

can you tell me what i have done wrong? pleaaaaaaase i dont know how to do it :)
zola
Posts: 52
Joined: Thu Jul 15, 2004 2:31 pm
Location: switzerland
Contact:

Post by zola »

looks like You are not linking with the scenenode cpp file.

and maybe its a good idea to have a camera defined aswell, although this does not explane the link error.

my test app (a minor variation of K.o.L's demo

Code: Select all

// see original faceofmars.cpp for credits :)
#include <irrlicht.h>
#include "CLMTerrainSceneNode.h"

#pragma comment(lib, "Irrlicht.lib")

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;

int main(int argc,char *argv[])
{ 
	int cameraoffset=120;

	IrrlichtDevice *device =
	createDevice(video::EDT_OPENGL, core::dimension2d<s32>(800, 600),32,false);

	ISceneManager* smgr = device->getSceneManager();
	IVideoDriver* driver= device->getVideoDriver();
	IGUIEnvironment* env= device->getGUIEnvironment();

	IGUIStaticText* txt=env->addStaticText(L"camera()", rect<s32>(0,0,350,40), true);
	txt->setOverrideColor(SColor(255,0,0,0));
	txt->enableOverrideColor(true);

    IImage* heightimage = driver->createImageFromFile("terrain.bmp");
	IImage* skyimage = driver->createImageFromFile("sky.jpg");
	ITexture* terraintexture = driver->getTexture("terr_tex.jpg");
	ITexture* skytexture = driver->getTexture("sky_tex.jpg");

	CLMTerrainSceneNode* terrain = new CLMTerrainSceneNode(smgr->getRootSceneNode(), smgr, 9999);
	terrain->create(heightimage,terraintexture,0,32.0f,10.0f,1000.0f);
	terrain->getMaterial(0).FogEnable=true;
	terrain->getMaterial(0).Lighting=false;
	terrain->setAutomaticCulling(false);
	terrain->setPosition(vector3df(100,100,0));
	terrain->setRotation(vector3df(0,37,0));
	//terrain->setDebugDataVisible(true);
	terrain->drop();
	
	
	scene::ICameraSceneNode* camera= smgr->addCameraSceneNodeFPS(0, 100, 900);
	camera->setFarValue(120000.0f);
	
	camera->setPosition(vector3df(0.0f,120.0f,0.0f));
	camera->setTarget(vector3df(0.0f,120.0f,-10.0f));
	camera->setUpVector(vector3df(0.0f,1.0f,0.0f));
	
	int lastFPS=-1;

	f32 fogDensity=0.0005f;
	SColor backgroundColor=irr::video::SColor(255,155,155,155);
	SColor fogColor=irr::video::SColor(0,155,155,155);
	wchar_t tmp[1024];
	matrix4 IDENTITY;
	IDENTITY.makeIdentity();
	SMaterial mat;
	mat.Lighting=false;
	matrix4 invTrans;
	matrix4 Trans;
	while(device->run())
	{

		vector3df pos = camera->getPosition();
		f32 nearp = camera->getNearValue();
		f32 farp=camera->getFarValue();
		Trans=terrain->getAbsoluteTransformation();
		Trans.getInverse(invTrans);

		invTrans.transformVect(pos);
		float glide = terrain->getHeight(pos.X,pos.Z)+30.0f*nearp;
		if (glide<0.0f) glide = 0.0f;
		pos.Y=pos.Y>glide? pos.Y:glide;

		Trans.transformVect(pos);

		camera->setPosition(vector3df(pos.X,pos.Y,pos.Z));
		//camera->setTarget(tgt);

		driver->setFog(fogColor, false, 10.0f, 2000.0f, fogDensity, false, false);
		swprintf(tmp,1024,L"camera( %.3f,  %.3f,  %.3f )",pos.X,pos.Y,pos.Z);
		txt->setText(tmp);

		driver->beginScene(true, true, backgroundColor);
		smgr->drawAll();

		driver->setTransform(video::ETS_WORLD, IDENTITY);
		driver->setMaterial(mat);
		driver->draw3DLine(vector3df(0,200,0),vector3df(farp,0,0),SColor(255,255,0,0));
		driver->draw3DLine(vector3df(0,200,0),vector3df(0,farp,0),SColor(255,0,255,0));
		driver->draw3DLine(vector3df(0,200,0),vector3df(0,0,farp),SColor(255,0,0,255));

		env->drawAll();
		driver->endScene();

		int fps = driver->getFPS();
		if (lastFPS != fps)
		{
			swprintf(tmp, 1024, L"Terrainengine-libmini and Irrlicht Engine (fps:%d) Triangles:%d", 
				fps, driver->getPrimitiveCountDrawn());
			device->setWindowCaption(tmp);
			lastFPS = fps;
		}
		

	}
	
	device->drop();
 
	return 0;
}
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

i think zola is a better OOP-programmer than me :-)
brcolow
Posts: 56
Joined: Mon Jul 19, 2004 6:15 am
Location: Arizona

Post by brcolow »

Nice work Zola. Any chance of that being added to NX as a define (like the other things that require external libs)?

Also, where do we include the two files...in what Irrlicht source file? Irrlicht.h?

Thanks
G'Day.
zola
Posts: 52
Joined: Thu Jul 15, 2004 2:31 pm
Location: switzerland
Contact:

Post by zola »

brcolow wrote:Nice work Zola. Any chance of that being added to NX as a define (like the other things that require external libs)?
Read my post about cal3d integration. My opinion is that many of these things - that introduce dependencies into the irrlicht code - could go very good as a seperate addon and they don't have to be included in the irrlicht sources.
What would be nice to have is a common repository for addons maybe we can open an additional CVS folder for them?
brcolow wrote: Also, where do we include the two files...in what Irrlicht source file? Irrlicht.h?
Just copy the files to Your application sources and include them where You need to.

Cheers
Tom
ZDimitor
Posts: 202
Joined: Fri Jul 16, 2004 3:27 am
Location: Russia

Post by ZDimitor »

CLMTerrainSceneNode works just perfect (rendering with incredible speed!!!),
but....

How we can use a collision detection with this scene node (his mesh buffer updates in each rendering cycle)? Any ideas?
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Post by puh »

ZDimitor:
Try instead of pos.Y=pos.Y>glide? pos.Y:glide; use pos.Y=glide;. Is it what you want?
Post Reply