Editable Terrain Manager [v2.2 released]

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
Post Reply
ricardo_arango
Gremlin
Posts: 158
Joined: Tue Jan 17, 2006 12:09 am

Post by ricardo_arango »

Yes. it gives a zero.

Of course normally I would use an 8bpp image as heightmap, but I had one that was 32bpp, and that's when it all happened.

ricardo_arango
Gremlin
Posts: 158
Joined: Tue Jan 17, 2006 12:09 am

Post by ricardo_arango »

How can I apply a standard material with a texture to the terrain?

Something like this:

Code: Select all

material MaterialTerreno
{
    technique
    {
        pass
        {
            ambient 0.0 0.0 0.0
            diffuse 1.0 1.0 1.0
			
            texture_unit
            {
                texture terrain.jpg
            }
        }
    }
}
I tried it but it appears completely black. Help-

Jed
Halfling
Posts: 47
Joined: Thu May 12, 2005 4:59 pm
Location: www.theFarWilds.com
Contact:

Post by Jed »

Hi great work on this.
I was wondering if there is some inverse of SplattingManager::paint to remove a texture you painted previously or at least a way to remove all the textures you have painted on?
Thanks.

Trosan
Greenskin
Posts: 101
Joined: Sun Jun 10, 2007 4:57 pm
x 1

Post by Trosan »

Jed wrote:Hi great work on this.
I was wondering if there is some inverse of SplattingManager::paint to remove a texture you painted previously or at least a way to remove all the textures you have painted on?
Thanks.
An example from the demo:

Code: Select all

mSplatMgr->paint(mChosenTexture, x, z, mEditBrush, brushIntensity);

Where brushIntensity is < 0 for "inverse SplattingManager::paint".

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Yes, you can use negative intensity, but honestly it doesn't work quite reliably, might be my calculations are wrong.

If you want to start "anew", you could do the following:

splattingMgr->setNumMaps(0);
splattingMgr->setNumMaps(x);

This will recreate the coverage maps.

Jed
Halfling
Posts: 47
Joined: Thu May 12, 2005 4:59 pm
Location: www.theFarWilds.com
Contact:

Post by Jed »

Hi again,
So I'm trying to use a camera with the PT_ORTHOGRAPHIC projection type. When I do the terrain mesh becomes clunky and no longer looks smooth. I was thinking this might be due to LOD issues. So I tried mTerrainMgr->setUseLODMorphing(false) but now terrain isn't displayed at all?
Any ideas what I need to do?
Thanks.

Jed
Halfling
Posts: 47
Joined: Thu May 12, 2005 4:59 pm
Location: www.theFarWilds.com
Contact:

Post by Jed »

Basically my question is how do I turn off LOD? Setting mTerrainMgr->setUseLODMorphing(false) doesn't seem to work in the demo project. It gives a blank screen. What is the correct way to turn it off?

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

If you turn LOD morphing of, you will probably also have to change the vertex shader in the example material.
But if you want to get rid of LOD completely, just set the number of LOD levels to 1. I wouldn't really recommend this unless your terrains are really small or your ingame view is limited, but that would effectively get rid of it.

Apart from that, unfortunately I have no insight to offer to orthogonal projection :-/

Jed
Halfling
Posts: 47
Joined: Thu May 12, 2005 4:59 pm
Location: www.theFarWilds.com
Contact:

Post by Jed »

Yes we have a small map so we don't need LOD really.
So you are saying I should do this:
mTerrainMgr->createTerrain(terrainInfo,33,1);

when I do that it throws an exception:
vector subscript out of range

Do I also need to change the vertex shader? Any hint on how I should change it?

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Hm, this may be a bug in ETM, I'll have to look into it someday. Anyway, you could also call setLODErrorMargin with a maxPixelError of 0, which should give pretty much the same result.

Without LOD morphing, you can probably simply remove the vertex shader from the material, at least for the SM2 technique. Otherwise, open up the vertex shader, there is a line somewhere that multiplies the vertex by a blendweight, remove that line.

Jed
Halfling
Posts: 47
Joined: Thu May 12, 2005 4:59 pm
Location: www.theFarWilds.com
Contact:

Post by Jed »

Ah thanks that fixes it. And the LOD was the problem with the orthogonal projection also.

User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Post by Brocan »

That's great project!! I'm going to use this terrain manager in my rts game and its editor :D

Next versions will include terrain decals like the green box with a brush in your editor's screenshot?

Great job, congratulations! :D

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

The brush in my editor is a projective decal. This is done by adding a separate pass to your material, you can look it up in the Ogre wiki. It's not a feature of this library :) But maybe, if I find some spare time, I'll add the brush to the ETM demo.

But there are still mesh decals which I'll eventually need in my own game, so I'll do something about that. But I'm not yet sure how I'll implement mesh decals, doing them the "correct" way is quite complicated and possibly performance intensive when moving. So I'll probably try a cheat first.

User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Post by Brocan »

Well, i've worked in terrain decals, and this is the result. It's only for PS2, because i don't see with technique take and i always take the first (for ps2)

This code is a ET version from PSLM Decals :)

You have to add this line to the first technique (a 3º pass):

Code: Select all

pass
    {
	//Decals' pass 
	scene_blend alpha_blend
      lighting off
	depth_bias 1
        depth_check off
	texture_unit
	{
		texture decalBase.png
	}
    }
Where decal base is a alpha texture of 2x2 pixels.

Here is the class:

ETDecal.h:

Code: Select all

#ifndef __ETDECAL_H__
#define __ETDECAL_H__

#include <Ogre.h>
#include "ETTerrainManager.h"

class ETDecal
{
public:
	ETDecal(Ogre::SceneManager* man, ET::TerrainManager *ETman, Ogre::Vector2 size, std::string tex );
	~ETDecal();

	void show();
	void hide();
	void updatePosition( Ogre::Vector3 pos );
	void updateSize(Ogre::Vector2 size);
	bool isVisible();

private:
	void init(Ogre::Vector2 size, std::string tex );
	void showTerrainDecal();
	void hideTerrainDecal();


	Ogre::Vector3 mPos;			// center
	Ogre::Vector2 mSize;		// size of decal

	std::string mTexture;		// texture to apply

	Ogre::SceneNode* mNode;		// the projection node
	Ogre::Frustum* mFrustum;	// the projection frustum
	Ogre::TextureUnitState *texState; // pointer to the texture unit state in the pass
	Ogre::Pass *pass; //pointer to the second pass (for decals)


	Ogre::SceneManager* mSceneManager;	// pointer to scene manager
	ET::TerrainManager* mTerrainMgr; //pointer to editable terrain manager

	bool mVisible;				// is the decal visible/active or not?
};

#endif
ETDecal.cpp:

Code: Select all

#include "ETDecal.h"	

void ETDecal::showTerrainDecal()
{
	if(!texState)
	{
		// set up the decal's texture unit
		texState = pass->createTextureUnitState(mTexture);
		texState->setProjectiveTexturing(true, mFrustum);
		texState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
		texState->setTextureFiltering(Ogre::FO_POINT, Ogre::FO_LINEAR, Ogre::FO_NONE);
		texState->setAlphaOperation(Ogre::LBX_ADD);
	}
}

void ETDecal::hideTerrainDecal()
{
	if(texState)
	{
		pass->removeTextureUnitState(pass->getTextureUnitStateIndex(texState));
		texState = 0;
	}
}

ETDecal::ETDecal(Ogre::SceneManager* man, ET::TerrainManager *ETman, Ogre::Vector2 size, std::string tex )
{
	this->mVisible = false;
	this->mNode = 0;
	this->pass = 0;
	this->mFrustum = 0;
	this->texState = 0;
	this->mSceneManager = man;
	this->mTerrainMgr = ETman;

	this->init(size, tex);
}

ETDecal::~ETDecal()
{
	hide();

	// delete frustum
	mNode->detachAllObjects();
	delete mFrustum;

	// destroy node
	mNode->getParentSceneNode()->removeAndDestroyChild(mNode->getName());
}

void ETDecal::init(Ogre::Vector2 size, std::string tex )
{
	using namespace Ogre;

	// get the material ptr
	const Ogre::MaterialPtr mat = mTerrainMgr->getMaterial();

	// create a new pass in the material to render the decal
	pass = mat->getTechnique(0)->getPass(2);

	// init projective decal
	// set up the main decal projection frustum
	mFrustum = new Ogre::Frustum();
	mNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
	mNode->attachObject(mFrustum);
	mFrustum->setProjectionType(Ogre::PT_ORTHOGRAPHIC);
	mNode->setOrientation(Ogre::Quaternion(Ogre::Degree(90),Ogre::Vector3::UNIT_X));

	// set given values
	updateSize(size);
	mTexture = tex;		// texture to apply

	// load the images for the decal and the filter
	TextureManager::getSingleton().load
		(mTexture, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 1);


	mVisible = false;
}

void ETDecal::show()
{
	if( !mVisible )
	{
		mVisible = true;
		showTerrainDecal();
		updatePosition(mPos);
	}
}

void ETDecal::hide()
{
	if( mVisible )
	{
		mVisible = false;
		hideTerrainDecal();
	}
}

void ETDecal::updatePosition( Ogre::Vector3 pos )
{
	// don`t do anything if pos didn`t change
	if( pos == mPos )
		return;

	// save the new position
	mPos = pos;
	mNode->setPosition(pos.x,pos.y+1000,pos.z);
}

void ETDecal::updateSize(Ogre::Vector2 size)
{
	if( mSize != size )
	{
		// save param
		mSize = size;

		// update aspect ratio
		mFrustum->setAspectRatio(mSize.x/mSize.y);

		// set fovy so that tan = 1, so 45 degree
		mFrustum->setFOVy(Ogre::Degree(45));

		// set near clip plane according to fovy:
		// distance = halfsize.y / tan(fovy)
		mFrustum->setNearClipDistance(mSize.y);
	}
}

bool ETDecal::isVisible()
{
	return mVisible;
}
For use this: (It's important that the decal image has the borders with alpha)

Code: Select all

  mPincelDecal = new ETDecal(mSceneMgr, mTerrainMgr, Vector2(50,50), "decal.png"); //Create decal
mPincelDecal->updatePosition( "where decal is positioned by you" );
mPincelDecal->show();

Here a screenshot:
Image


There is no perfect, I tested it and there no much efficient, but all implementations of proyective decals i see aren't efficient. :?

I accept critics and improvements :D

Byes!!!

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Nice effort, thanks for sharing :) The code for the decal in my editor is similar (since it's based on the same wiki code).
Problem with projective decals is that they add a whole new pass to the terrain material. That's fine for a single editor decal or so, but it won't work for a larger number of decals.

The alternative are mesh decals. They are basically a "planar" mesh whose vertex coordinates are set on top of the terrain coords. Since they are small, independent objects, they are nice on the graphics card. Problem with them is generating correct vertex coordinates for them. To be absolutely correct, you would have to align them with the terrain vertices, plus you would need to take LOD level into consideration, otherwise you'd end up with your decals getting under the terrain. This is non-trivial und unfortunately not cheap, either, and you have to perform the whole progress again when they move...

But there is one trick you can do which I will try for my own project. That is, instead of making their vertices aligned and correct, I'll just take the maximal height of the terrain vertices around each decal's vertex. This can lead to quite a high offset above the terrain if it's particularly steep. But my game is a RTS, so camera is mostly top-down and units don't move over steep terrain, anyway, so this might just be good enough :)

User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Post by Brocan »

I've tryed to improve the decals, i use only one pass for all decals, instead of add a whole pass for every decal, but i don't think that its a real performance improvement. :(

When you have around 20 decals, the performance falls. But, well, projective decals in ogre (at least the implementations that i see) have the same problem.

Mesh decals are too dificult to me :) (to/for?, ops i need more english classes xD)

Byes! :D

User avatar
AntonTheManton
Greenskin
Posts: 100
Joined: Sun Jan 14, 2007 1:47 am

Little Problem with Clipping

Post by AntonTheManton »

I've noticed when the camera is quite close to a rather large bit of terrain that is clips it out when even a little corner is touching the bottom of the screen. Is it possible that I can improve this by adjusting some of the values given to the LODErrorMargin() or is this more of an internal feature?

I'm still going strong with the ETM. It was quite easy to manage different brush sizes - I just have 3 size buttons. I can't say enough about how powerful the ETM is - I can generate and paint terrain so fast it's terrifying. I haven't ever come across a commercial game with an editor that can do that. I still haven't found a texture good enough to replace the rocky mountains with yet. I have some screenshots on my blog http://markivengine.blogspot.com

User avatar
AntonTheManton
Greenskin
Posts: 100
Joined: Sun Jan 14, 2007 1:47 am

Projects with ETM

Post by AntonTheManton »

I'm also interested to see what other people are doing with ETM. Cabalistic do you have a website for your current project?

A

User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Re: Little Problem with Clipping

Post by Brocan »

AntonTheManton wrote:I've noticed when the camera is quite close to a rather large bit of terrain that is clips it out when even a little corner is touching the bottom of the screen. Is it possible that I can improve this by adjusting some of the values given to the LODErrorMargin() or is this more of an internal feature?
I've the same problem :?

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

If the terrain tile you're over is (mostly) flat, then it may be that your camera's near clip value is too high. But there are indeed a few special camera orientations where a tile is not rendered even though it should. I suppose the bounding boxes may be slightly incorrect, I've not had the time yet to properly investigate. But the bug's noted, I'll eventually track it down (unless someone beats me to it :) ).

@Anton: We're currently in the process of "reviving" a good old RTS game, Z. We're still at the foundations though (mainly because we're just 2 guys using this as practice, mostly), once we have some more to show, we'll properly announce the project in its own thread.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Ok, I *think* I found the clipping problem. I just displayed the actual bounding boxes of the terrain tiles and it struck me that I don't update them when the terrain is edited. Don't know how I could have missed that. So if your initial terrain is all flat and you add some big mountains, the bounding boxes of the touched tiles are still all flat which results in wrong culling by the octree SM. This is less noticable for a RTS-style camera since from a top-down view the height of the bounding boxes is not as important, that's probably why I only encountered the problem so rarely.
Anyway, I've fixed the bug, the bounding boxes now look correct and stay so. A new release will follow soon :)

User avatar
fassihi
Goblin
Posts: 215
Joined: Sat Sep 16, 2006 6:51 am
x 8
Contact:

Multiple Terrains

Post by fassihi »

Cabalistic,

What would be the best way to handle multiple terrains in a scene using TSM?

Has anyone ever done this? Would it be possible to tile many terrains next to one another and create a big one?

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

With TSM? You can't. With ETM you would create multiple TerrainManagers and set their terrain positions accordingly via the TerrainInfo objects. However you will get LOD glitches at the borders since the TerrainManagers are not aware of each other. I may eventually add the possibility to link TerrainManagers together as neighbours to correct this, but it's not a high priority task for me. After all, for such things there is a good chance you'd need paging, and this lib is currently not designed to do that, there are better options out there :)

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Question about lightmaps. I am using Caelum in my project, and one of the things I want to do is interpolate lightmaps as Caelum moves the sun. Creating the lightmaps is easy enough (my editor currently creates 12 lightmaps when I save a terrain, one every two hours of elapsed time in a day). The idea here is the slowly interpolate those lightmaps over the course of an in-game day. My question is, does ETM already support interpolation between a series of lightmaps (I doubt it does), and if it doesn't, where in the ETM code should I look to begin coding this? My goal is to be able to give ETM a list of lightmap textures, and tell it at certain intervals "begin a linear interpolation of lightmap 0 to 1", and I will of course update the interpolation every frame. Then once lightmap 1 is fully visible, I tell ETM to start interpolating from lightmap 1 to lightmap 2.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Sounds like a job for a shader to me. You would have to write your own material handling class and roughly do the following:

- Possibly have one additional pass dedicated to the lightmaps which modulates the colours of the previous splatting passes by the output of your interpolating shader. The example terrain already has the separate pass.

- This pass should have two texture units which contain the two current lightmaps you want to interpolate between.

- Have a fragment shader taking one additional argument (something like interp_value) ranging from 1 to 0, where 1 means that the first lightmap is fully used and 0 means it's the second lightmap.
The shader would multiply the colours of the first lightmap with interp_value and the colours of the second lightmap with (1 - interp_value), then add the results as output.

- Update the used lightmaps and the interp_value as you see fit.

This is really not a job for the ETM, you just need your own material handler for this :)

Post Reply