Terrain Grid class v0.1 for review

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
EternalNewbye
Gnoblar
Posts: 8
Joined: Sun Dec 10, 2006 1:49 pm
x 1

Terrain Grid class v0.1 for review

Post by EternalNewbye »

Hi !

Time to give back to the community.
Here's a little class, inspired from this topic that I wrote for the current Terrain system.

For now, there is one known issue that I don't have time to solve: the class doesn't work with YZ alignment.

Any comments, advice and criticism is welcome.

Header:

Code: Select all

// OgreTerrainGrip.h v0.1

// This source file is supposed to be used with OGRE
// (Object-oriented Graphics Rendering Engine)
// For the latest info, see http://www.ogre3d.org/

// Copyright © 2014 Alain BAREILLE <firstname . name [AT] free.fr>
// This work is free. You can redistribute it and/or modify it under the
// terms of the Do What The Fuck You Want To Public License, Version 2,
// as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.

#ifndef TERRAIN_GRID_H
#define TERRAIN_GRID_H

/// default value passed to constructor
#define DEFAULT_GRID_CELL_SIZE        (Ogre::Real(1))
/// default value passed to constructor
#define DEFAULT_DISTANCE_FROM_TERRAIN (Ogre::Real(0.1))

namespace Ogre
{
	class SceneManager;
	class ManualObject;
	class TerrainGroup;
}

/** The whole point of the pudding.
 * Encapsulates a manual object that defines a grid geometry following the shape
 * of an Ogre::Terrain.
 */
class TerrainGrid
{
public:
	/** Constructor.
	 * Draws the geometry.
	 * \param grid_name a name for encapsulated manual object, must be unique
	 * \param material_name material applied to grid
	 * \param terrain_group group our target terrain is part of
	 * \param terrain_x coordinate of target terrain in terrain_group
	 * \param terrain_y coordinate of target terrain in terrain_group
	 * \param cell_size size in world units of the cells of the generated grid 
	 * \param distance_from_terrain grid to terrain distance along the axis orthogonal \
	 * to alignment of terrain_group  \see Ogre::TerrainGroup::getAlignment() 
	 * \param offset grid start offset on both axis in world units
	 * \throws pretty much whatever Ogre or the STL want to throw
	 */
	TerrainGrid(const Ogre::String & grid_name,
		const Ogre::String & material_name,
		const Ogre::TerrainGroup * terrain_group,
		long terrain_x, long terrain_y,
		Ogre::Real cell_size = DEFAULT_GRID_CELL_SIZE,
		Ogre::Real distance_from_terrain = DEFAULT_DISTANCE_FROM_TERRAIN,
		Ogre::Real offset = 0);

	/** Destructor.
	 * Collects allocated ressources.
	 */
	~TerrainGrid();

	/// access encapsulated geometry
	Ogre::ManualObject & grid() {return *mGrid;}
	/// access encapsulated geometry
	const Ogre::ManualObject & grid() const {return *mGrid;}

private:
	/// Reference to scene manager, used at destruction to collect manual object
	Ogre::SceneManager * const mSceneManager;
	/// Manual object containing the grid geometry
	Ogre::ManualObject * const mGrid;
	/// Waiting for C++11
	TerrainGrid(const TerrainGrid&);
};

#endif
Source file:

Code: Select all

// OgreTerrainGrip.cpp v0.1

// This source file is supposed to be used with OGRE
// (Object-oriented Graphics Rendering Engine)
// For the latest info, see http://www.ogre3d.org/

// Copyright © 2014 Alain BAREILLE <firstname . name [AT] free.fr>
// This work is free. You can redistribute it and/or modify it under the
// terms of the Do What The Fuck You Want To Public License, Version 2,
// as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.

#include <sstream>
#include <OgreManualObject.h>
#include <Terrain/OgreTerrainGroup.h>

#include "OgreTerrainGrid.h"

using Ogre::Real;
using Ogre::String;
using Ogre::Vector3;
using Ogre::SceneManager;
using Ogre::SceneNode;
using Ogre::Terrain;
using Ogre::TerrainGroup;

typedef Vector3 (*TerrainToWorldFunction)(Real u, Real v, Real height);

static Vector3 XZAlignement(Real u, Real v, Real height)
{
	return Vector3(u, height, -v);
}

static Vector3 XYAlignement(Real u, Real v, Real height)
{
	return Vector3(u, v, height);
}

static Vector3 YZAlignement(Real u, Real v, Real height)
{
	return Vector3(height, v, -u);
}

static TerrainToWorldFunction terrainToWorldFunctionFactory(Terrain::Alignment alignment)
{
	switch(alignment)
	{
	case Terrain::ALIGN_X_Z:
		return &XZAlignement;
	case Terrain::ALIGN_X_Y:
		return &XYAlignement;
	case Terrain::ALIGN_Y_Z:
		return &YZAlignement;
	}
	return NULL;
}

TerrainGrid::TerrainGrid(const Ogre::String & grid_name,
const Ogre::String & material_name,
const TerrainGroup * terrain_group,
long terrain_x, long terrain_y,
Real cell_size,
Real distance_from_terrain,
Real offset)
	: mSceneManager(terrain_group->getSceneManager())
	, mGrid(mSceneManager->createManualObject(grid_name))
{
	Terrain * terrain = terrain_group->getTerrain(terrain_x, terrain_y);

	OgreAssert(terrain, "Trying to access unloaded terrain");
	if(NULL == terrain)
	{
		Ogre::StringUtil::StrStreamType desc;
		desc << "Trying to access unloaded terrain at ("
			<< terrain_x << ',' << terrain_y << ')';
		throw Ogre::InvalidParametersException(0xE2202,
			desc.str(),
			"Ogre::TerrainGrid::TerrainGrid",
			__FILE__,
			__LINE__);
	}

	const Real world_size = terrain->getWorldSize();

	if(cell_size > world_size)
	{
		// do nothing
		return;
	}

	const Real high_bound = (Real(terrain_x) + Real(0.5)) * world_size;
	const Real low_bound = high_bound - world_size + offset;

	mGrid->begin(material_name, Ogre::RenderOperation::OT_LINE_LIST);

	TerrainToWorldFunction func = terrainToWorldFunctionFactory(terrain_group->getAlignment());

	for(Real i = low_bound; i < high_bound; i += cell_size)
	{
		for(Real j = low_bound; j < high_bound; j += cell_size)
		{
			const Real next_i = i + cell_size;
			const Real next_j = j + cell_size;
			mGrid->position(func(i,      j,   terrain->getHeightAtWorldPosition(func(i,      j  , 0))));
			mGrid->position(func(next_i, j,   terrain->getHeightAtWorldPosition(func(next_i, j  , 0))));
			mGrid->position(func(i,      j,   terrain->getHeightAtWorldPosition(func(i,      j  , 0))));
			mGrid->position(func(i,   next_j, terrain->getHeightAtWorldPosition(func(i,   next_j, 0))));
		}
	}

	mGrid->end();
	mSceneManager->getRootSceneNode()->createChildSceneNode(func(0, 0, distance_from_terrain))->attachObject(mGrid);
}

TerrainGrid::~TerrainGrid()
{
	mSceneManager->destroyManualObject(mGrid);
}
Attachments
OgreTerrainGrid.cpp
(3.25 KiB) Downloaded 26 times
OgreTerrainGrid.h
(2.47 KiB) Downloaded 29 times
User avatar
tod
Troll
Posts: 1394
Joined: Wed Aug 02, 2006 9:41 am
Location: Bucharest
x 94
Contact:

Re: Terrain Grid class v0.1 for review

Post by tod »

This should go in the wiki. Thanks for sharing.
Post Reply