Any new 1.7 terrain demos?

yubgipenguin

06-01-2010 00:49:50

I see there is ogreterrain and ogrepaging but I'm not sure if it's fully implemented yet since I can't seem to find TerrainGroup...

But if it's working, is there any demo?

andy

06-01-2010 11:04:53

The modules have been wrapped but certainly not tested -- if you'd like to convert the c++ demo I'll work with you to fix anything that is missing from the wrapper..

Otherwise I'll probably get to the demo myself in the next week or so

Andy

yubgipenguin

06-01-2010 23:16:32

I'm currently converting SampleBrowser version of code to 1.6.4 style sample code... almost done and works fine except edit terrain function toggling with keyboard keys and saving terrain with keystroke etc that used to involve traymgr sdk...

When I'm done I'll try to convert that to python code and post it here as soon as possible but no promises. :D

Here's frankenstein code(working though) of terrain demo 1.6.4 style version:
MyTerrain.cpp

#include "stdafx.h"
#include "MyTerrain.h"

#define WIN32_LEAN_AND_MEAN
#include "windows.h"

#ifdef __cplusplus
extern "C" {
#endif

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
MyTerrainApplication app;

try {
app.go();
} catch( Ogre::Exception& e ) {
MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}

return 0;
}

#ifdef __cplusplus
}
#endif

MyTerrain.h:
#ifndef __MyTerrain_H__
#define __MyTerrain_H__

#include "Ogre.h"
#include "OgreConfigFile.h"
#include "OgreStringConverter.h"
#include "OgreException.h"
#define OIS_DYNAMIC_LIB
#include <OIS/OIS.h>


#define PAGING

#define TERRAIN_PAGE_MIN_X 0
#define TERRAIN_PAGE_MIN_Y 0
#define TERRAIN_PAGE_MAX_X 0
#define TERRAIN_PAGE_MAX_Y 0

#include "OgreTerrain.h"
#include "OgreTerrainGroup.h"
#include "OgreTerrainQuadTreeNode.h"
#include "OgreTerrainMaterialGeneratorA.h"
#include "OgreTerrainPaging.h"
#include "OgreShadowCameraSetupPSSM.h"

#define TERRAIN_FILE_PREFIX String("testTerrain")
#define TERRAIN_FILE_SUFFIX String("dat")
#define TERRAIN_WORLD_SIZE 12000.0f
#define TERRAIN_SIZE 513

using namespace Ogre;

class MyTerrainFrameListener: public FrameListener, public WindowEventListener
{
protected:

virtual void updateStats(void)
{
static String currFps = "Current FPS: ";
static String avgFps = "Average FPS: ";
static String bestFps = "Best FPS: ";
static String worstFps = "Worst FPS: ";
static String tris = "Triangle Count: ";
static String batches = "Batch Count: ";

// update stats when necessary
/*
OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");

const RenderTarget::FrameStats& stats = mWindow->getStatistics();
guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
+" "+StringConverter::toString(stats.bestFrameTime)+" ms");
guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
+" "+StringConverter::toString(stats.worstFrameTime)+" ms");

OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));

OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));

OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
guiDbg->setCaption(mDebugText);
*/
}


// TERRAINSTART
TerrainGroup* mTerrainGroup;
TerrainPaging* mTerrainPaging;
PageManager* mPageManager;
SceneManager* mSceneMgr;
Root *mRoot;

#ifdef PAGING
/// This class just pretends to provide prcedural page content to avoid page loading
class DummyPageProvider : public PageProvider
{
public:
bool prepareProceduralPage(Page* page, PagedWorldSection* section) { return true; }
bool loadProceduralPage(Page* page, PagedWorldSection* section) { return true; }
bool unloadProceduralPage(Page* page, PagedWorldSection* section) { return true; }
bool unprepareProceduralPage(Page* page, PagedWorldSection* section) { return true; }
};
DummyPageProvider mDummyPageProvider;
#endif
bool mFly;
Real mFallVelocity;
enum Mode
{
MODE_NORMAL = 0,
MODE_EDIT_HEIGHT = 1,
MODE_EDIT_BLEND = 2,
MODE_COUNT = 3
};
enum ShadowMode
{
SHADOWS_NONE = 0,
SHADOWS_COLOUR = 1,
SHADOWS_DEPTH = 2,
SHADOWS_COUNT = 3
};
Mode mMode;
ShadowMode mShadowMode;
uint8 mLayerEdit;
Real mBrushSizeTerrainSpace;
SceneNode* mEditNode;
Entity* mEditMarker;
Real mUpdateCountDown;
Real mUpdateRate;
Vector3 mTerrainPos;
bool mTerrainsImported;
ShadowCameraSetupPtr mPSSMSetup;

typedef std::list<Entity*> EntityList;
EntityList mHouseList;



void defineTerrain(long x, long y, bool flat = false)
{
// if a file is available, use it
// if not, generate file from import

// Usually in a real project you'll know whether the compact terrain data is
// available or not; I'm doing it this way to save distribution size

if (flat)
{
mTerrainGroup->defineTerrain(x, y, 0.0f);
}
else
{
String filename = mTerrainGroup->generateFilename(x, y);
if (ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename))
{
mTerrainGroup->defineTerrain(x, y);
}
else
{
Image img;
getTerrainImage(x % 2 != 0, y % 2 != 0, img);
mTerrainGroup->defineTerrain(x, y, &img);
mTerrainsImported = true;
}

}
}

void getTerrainImage(bool flipX, bool flipY, Image& img)
{
img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (flipX)
img.flipAroundY();
if (flipY)
img.flipAroundX();

}

void initBlendMaps(Terrain* terrain)
{
TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1);
TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2);
Real minHeight0 = 70;
Real fadeDist0 = 40;
Real minHeight1 = 70;
Real fadeDist1 = 15;
float* pBlend0 = blendMap0->getBlendPointer();
float* pBlend1 = blendMap1->getBlendPointer();
for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y)
{
for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x)
{
Real tx, ty;

blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty);
Real height = terrain->getHeightAtTerrainPosition(tx, ty);
Real val = (height - minHeight0) / fadeDist0;
val = Math::Clamp(val, (Real)0, (Real)1);
//*pBlend0++ = val;

val = (height - minHeight1) / fadeDist1;
val = Math::Clamp(val, (Real)0, (Real)1);
*pBlend1++ = val;


}
}
blendMap0->dirty();
blendMap1->dirty();
//blendMap0->loadImage("blendmap1.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
blendMap0->update();
blendMap1->update();

// set up a colour map
/*
if (!terrain->getGlobalColourMapEnabled())
{
terrain->setGlobalColourMapEnabled(true);
Image colourMap;
colourMap.load("testcolourmap.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
terrain->getGlobalColourMap()->loadImage(colourMap);
}
*/

}

void configureTerrainDefaults(Light* l)
{
// Configure global
TerrainGlobalOptions::setMaxPixelError(8);
// testing composite map
TerrainGlobalOptions::setCompositeMapDistance(3000);
//TerrainGlobalOptions::setUseRayBoxDistanceCalculation(true);
//TerrainGlobalOptions::getDefaultMaterialGenerator()->setDebugLevel(1);
//TerrainGlobalOptions::setLightMapSize(256);
TerrainMaterialGeneratorA::SM2Profile* matProfile =
static_cast<TerrainMaterialGeneratorA::SM2Profile*>(TerrainGlobalOptions::getDefaultMaterialGenerator()->getActiveProfile());

//matProfile->setLightmapEnabled(false);
// Important to set these so that the terrain knows what to use for derived (non-realtime) data
TerrainGlobalOptions::setLightMapDirection(l->getDerivedDirection());
TerrainGlobalOptions::setCompositeMapAmbient(mSceneMgr->getAmbientLight());
//TerrainGlobalOptions::setCompositeMapAmbient(ColourValue::Red);
TerrainGlobalOptions::setCompositeMapDiffuse(l->getDiffuseColour());

// Configure default import settings for if we use imported image
Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
defaultimp.terrainSize = TERRAIN_SIZE;
defaultimp.worldSize = TERRAIN_WORLD_SIZE;
defaultimp.inputScale = 600;
defaultimp.minBatchSize = 33;
defaultimp.maxBatchSize = 65;
// textures
defaultimp.layerList.resize(3);
defaultimp.layerList[0].worldSize = 100;
defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");
defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");
defaultimp.layerList[1].worldSize = 30;
defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");
defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");
defaultimp.layerList[2].worldSize = 200;
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");


}


MaterialPtr buildDepthShadowMaterial(const String& textureName)
{
String matName = "DepthShadows/" + textureName;

MaterialPtr ret = MaterialManager::getSingleton().getByName(matName);
if (ret.isNull())
{
MaterialPtr baseMat = MaterialManager::getSingleton().getByName("Ogre/shadow/depth/integrated/pssm");
ret = baseMat->clone(matName);
Pass* p = ret->getTechnique(0)->getPass(0);
p->getTextureUnitState("diffuse")->setTextureName(textureName);

Vector4 splitPoints;
const PSSMShadowCameraSetup::SplitPointList& splitPointList =
static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get())->getSplitPoints();
for (int i = 0; i < 3; ++i)
{
splitPoints[i] = splitPointList[i];
}
p->getFragmentProgramParameters()->setNamedConstant("pssmSplitPoints", splitPoints);


}

return ret;
}

void changeShadows()
{
configureShadows(mShadowMode != SHADOWS_NONE, mShadowMode == SHADOWS_DEPTH);
}

void configureShadows(bool enabled, bool depthShadows)
{
TerrainMaterialGeneratorA::SM2Profile* matProfile =
static_cast<TerrainMaterialGeneratorA::SM2Profile*>(TerrainGlobalOptions::getDefaultMaterialGenerator()->getActiveProfile());
matProfile->setReceiveDynamicShadowsEnabled(enabled);
#ifdef SHADOWS_IN_LOW_LOD_MATERIAL
matProfile->setReceiveDynamicShadowsLowLod(true);
#else
matProfile->setReceiveDynamicShadowsLowLod(false);
#endif

// Default materials
for (EntityList::iterator i = mHouseList.begin(); i != mHouseList.end(); ++i)
{
(*i)->setMaterialName("Examples/TudorHouse");
}

if (enabled)
{
// General scene setup
mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
mSceneMgr->setShadowFarDistance(3000);

// 3 textures per directional light (PSSM)
mSceneMgr->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, 3);

if (mPSSMSetup.isNull())
{
// shadow camera setup
PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup();
pssmSetup->setSplitPadding(mCamera->getNearClipDistance());
pssmSetup->calculateSplitPoints(3, mCamera->getNearClipDistance(), mSceneMgr->getShadowFarDistance());
pssmSetup->setOptimalAdjustFactor(0, 2);
pssmSetup->setOptimalAdjustFactor(1, 1);
pssmSetup->setOptimalAdjustFactor(2, 0.5);

mPSSMSetup.bind(pssmSetup);

}
mSceneMgr->setShadowCameraSetup(mPSSMSetup);

if (depthShadows)
{
mSceneMgr->setShadowTextureCount(3);
mSceneMgr->setShadowTextureConfig(0, 2048, 2048, PF_FLOAT32_R);
mSceneMgr->setShadowTextureConfig(1, 1024, 1024, PF_FLOAT32_R);
mSceneMgr->setShadowTextureConfig(2, 1024, 1024, PF_FLOAT32_R);
mSceneMgr->setShadowTextureSelfShadow(true);
mSceneMgr->setShadowCasterRenderBackFaces(true);
mSceneMgr->setShadowTextureCasterMaterial("PSSM/shadow_caster");

MaterialPtr houseMat = buildDepthShadowMaterial("fw12b.jpg");
for (EntityList::iterator i = mHouseList.begin(); i != mHouseList.end(); ++i)
{
(*i)->setMaterial(houseMat);
}

}
else
{
mSceneMgr->setShadowTextureCount(3);
mSceneMgr->setShadowTextureConfig(0, 2048, 2048, PF_X8B8G8R8);
mSceneMgr->setShadowTextureConfig(1, 1024, 1024, PF_X8B8G8R8);
mSceneMgr->setShadowTextureConfig(2, 1024, 1024, PF_X8B8G8R8);
mSceneMgr->setShadowTextureSelfShadow(false);
mSceneMgr->setShadowCasterRenderBackFaces(false);
mSceneMgr->setShadowTextureCasterMaterial(StringUtil::BLANK);
}

matProfile->setReceiveDynamicShadowsDepth(depthShadows);
matProfile->setReceiveDynamicShadowsPSSM(static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get()));

//addTextureShadowDebugOverlay(TL_RIGHT, 3);


}
else
{
mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
}


}

/*-----------------------------------------------------------------------------
| Extends setupView to change some initial camera settings for this sample.
-----------------------------------------------------------------------------*/
void setupView()
{
mCamera->setPosition(mTerrainPos + Vector3(1683, 50, 2116));
mCamera->lookAt(Vector3(1963, 50, 1660));
mCamera->setNearClipDistance(0.1);
mCamera->setFarClipDistance(50000);

if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
{
mCamera->setFarClipDistance(0); // enable infinite far clip distance if we can
}
}


void setupContent()
{
bool blankTerrain = false;
//blankTerrain = true;

mEditMarker = mSceneMgr->createEntity("editMarker", "sphere.mesh");
mEditNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mEditNode->attachObject(mEditMarker);
mEditNode->setScale(0.05, 0.05, 0.05);


MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC);
MaterialManager::getSingleton().setDefaultAnisotropy(7);

mSceneMgr->setFog(FOG_LINEAR, ColourValue(0.7, 0.7, 0.8), 0, 10000, 25000);

Vector3 lightdir(0.55, -0.3, 0.75);
lightdir.normalise();


Light* l = mSceneMgr->createLight("tstLight");
l->setType(Light::LT_DIRECTIONAL);
l->setDirection(lightdir);
l->setDiffuseColour(ColourValue::White);
l->setSpecularColour(ColourValue(0.4, 0.4, 0.4));

mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));


mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, TERRAIN_WORLD_SIZE);
mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX);
mTerrainGroup->setOrigin(mTerrainPos);

configureTerrainDefaults(l);
#ifdef PAGING
// Paging setup
mPageManager = OGRE_NEW PageManager();
// Since we're not loading any pages from .page files, we need a way just
// to say we've loaded them without them actually being loaded
mPageManager->setPageProvider(&mDummyPageProvider);
mPageManager->addCamera(mCamera);
mTerrainPaging = OGRE_NEW TerrainPaging(mPageManager);
PagedWorld* world = mPageManager->createWorld();
mTerrainPaging->createWorldSection(world, mTerrainGroup, 2000, 3000,
TERRAIN_PAGE_MIN_X, TERRAIN_PAGE_MIN_Y,
TERRAIN_PAGE_MAX_X, TERRAIN_PAGE_MAX_Y);
#else
for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)
defineTerrain(x, y, blankTerrain);
// sync load since we want everything in place when we start
mTerrainGroup->loadAllTerrains(true);
#endif

if (mTerrainsImported)
{
TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
while(ti.hasMoreElements())
{
Terrain* t = ti.getNext()->instance;
initBlendMaps(t);
}
}

mTerrainGroup->freeTemporaryResources();



// create a few entities on the terrain
Entity* e = mSceneMgr->createEntity("tudorhouse.mesh");
Vector3 entPos(mTerrainPos.x + 2043, 0, mTerrainPos.z + 1715);
Quaternion rot;
entPos.y = mTerrainGroup->getHeightAtWorldPosition(entPos) + 65.5;
rot.FromAngleAxis(Degree(Math::RangeRandom(-180, 180)), Vector3::UNIT_Y);
SceneNode* sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(entPos, rot);
sn->setScale(Vector3(0.12, 0.12, 0.12));
sn->attachObject(e);
mHouseList.push_back(e);

e = mSceneMgr->createEntity("tudorhouse.mesh");
entPos = Vector3(mTerrainPos.x + 1850, 0, mTerrainPos.z + 1478);
entPos.y = mTerrainGroup->getHeightAtWorldPosition(entPos) + 65.5;
rot.FromAngleAxis(Degree(Math::RangeRandom(-180, 180)), Vector3::UNIT_Y);
sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(entPos, rot);
sn->setScale(Vector3(0.12, 0.12, 0.12));
sn->attachObject(e);
mHouseList.push_back(e);

e = mSceneMgr->createEntity("tudorhouse.mesh");
entPos = Vector3(mTerrainPos.x + 1970, 0, mTerrainPos.z + 2180);
entPos.y = mTerrainGroup->getHeightAtWorldPosition(entPos) + 65.5;
rot.FromAngleAxis(Degree(Math::RangeRandom(-180, 180)), Vector3::UNIT_Y);
sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(entPos, rot);
sn->setScale(Vector3(0.12, 0.12, 0.12));
sn->attachObject(e);
mHouseList.push_back(e);

mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");


}
//TERRAINEND

public:
// Constructor takes a RenderWindow because it uses that to determine input context
MyTerrainFrameListener(RenderWindow* win, Camera* cam, SceneManager* sceneMgr, Root *root,
bool bufferedKeys = false, bool bufferedMouse = false,
bool bufferedJoy = false ) :
mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0),
mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),
mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),
mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)
, mTerrainGroup(0)
, mTerrainPaging(0)
, mPageManager(0)
, mFly(false)
, mFallVelocity(0)
, mMode(MODE_NORMAL)
, mLayerEdit(1)
, mBrushSizeTerrainSpace(0.02)
, mUpdateCountDown(0)
, mTerrainPos(1000,0,5000)
, mTerrainsImported(false)
, mSceneMgr(sceneMgr)
, mRoot(root)

{

mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");

LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;

win->getCustomAttribute("WINDOW", &windowHnd);
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND") ));
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE") ));

windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

mInputManager = OIS::InputManager::createInputSystem( pl );

//Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));
mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse ));
try {
mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy ));
}
catch(...) {
mJoy = 0;
}

//Set initial mouse clipping size
windowResized(mWindow);

showDebugOverlay(true);

//Register as a Window listener
WindowEventUtilities::addWindowEventListener(mWindow, this);

// Update terrain at max 20fps
mUpdateRate = 1.0 / 20.0;


setupView();
setupContent();
}

//Adjust mouse clipping area
virtual void windowResized(RenderWindow* rw)
{
unsigned int width, height, depth;
int left, top;
rw->getMetrics(width, height, depth, left, top);

const OIS::MouseState &ms = mMouse->getMouseState();
ms.width = width;
ms.height = height;
}

//Unattach OIS before window shutdown (very important under Linux)
virtual void windowClosed(RenderWindow* rw)
{
//Only close for window that created OIS (the main window in these demos)
if( rw == mWindow )
{
if( mInputManager )
{
mInputManager->destroyInputObject( mMouse );
mInputManager->destroyInputObject( mKeyboard );
mInputManager->destroyInputObject( mJoy );

OIS::InputManager::destroyInputSystem(mInputManager);
mInputManager = 0;
}
}
}

virtual ~MyTerrainFrameListener()
{
//Remove ourself as a Window listener
WindowEventUtilities::removeWindowEventListener(mWindow, this);
windowClosed(mWindow);
if (mTerrainPaging)
{
OGRE_DELETE mTerrainPaging;
OGRE_DELETE mPageManager;
}
else
OGRE_DELETE mTerrainGroup;

}

virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
{

if(mKeyboard->isKeyDown(OIS::KC_A))
mTranslateVector.x = -mMoveScale; // Move camera left

if(mKeyboard->isKeyDown(OIS::KC_D))
mTranslateVector.x = mMoveScale; // Move camera RIGHT

if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) )
mTranslateVector.z = -mMoveScale; // Move camera forward

if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) )
mTranslateVector.z = mMoveScale; // Move camera backward

if(mKeyboard->isKeyDown(OIS::KC_PGUP))
mTranslateVector.y = mMoveScale; // Move camera up

if(mKeyboard->isKeyDown(OIS::KC_PGDOWN))
mTranslateVector.y = -mMoveScale; // Move camera down

if(mKeyboard->isKeyDown(OIS::KC_RIGHT))
mCamera->yaw(-mRotScale);

if(mKeyboard->isKeyDown(OIS::KC_LEFT))
mCamera->yaw(mRotScale);

if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) )
return false;

if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 )
{
mStatsOn = !mStatsOn;
showDebugOverlay(mStatsOn);
mTimeUntilNextToggle = 1;
}

if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 )
{
switch(mFiltering)
{
case TFO_BILINEAR:
mFiltering = TFO_TRILINEAR;
mAniso = 1;
break;
case TFO_TRILINEAR:
mFiltering = TFO_ANISOTROPIC;
mAniso = 8;
break;
case TFO_ANISOTROPIC:
mFiltering = TFO_BILINEAR;
mAniso = 1;
break;
default: break;
}
MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);

showDebugOverlay(mStatsOn);
mTimeUntilNextToggle = 1;
}

if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0)
{
std::ostringstream ss;
ss << "screenshot_" << ++mNumScreenShots << ".png";
mWindow->writeContentsToFile(ss.str());
mTimeUntilNextToggle = 0.5;
mDebugText = "Saved: " + ss.str();
}

if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0)
{
mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
switch(mSceneDetailIndex) {
case 0 : mCamera->setPolygonMode(PM_SOLID); break;
case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;
case 2 : mCamera->setPolygonMode(PM_POINTS); break;
}
mTimeUntilNextToggle = 0.5;
}

static bool displayCameraDetails = false;
if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0)
{
displayCameraDetails = !displayCameraDetails;
mTimeUntilNextToggle = 0.5;
if (!displayCameraDetails)
mDebugText = "";
}

// Print camera details
if(displayCameraDetails)
mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
" " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());

// Return true to continue rendering
return true;
}

virtual bool processUnbufferedMouseInput(const FrameEvent& evt)
{

// Rotation factors, may not be used if the second mouse button is pressed
// 2nd mouse button - slide, otherwise rotate
const OIS::MouseState &ms = mMouse->getMouseState();
if( ms.buttonDown( OIS::MB_Right ) )
{
mTranslateVector.x += ms.X.rel * 0.13;
mTranslateVector.y -= ms.Y.rel * 0.13;
}
else
{
mRotX = Degree(-ms.X.rel * 0.13);
mRotY = Degree(-ms.Y.rel * 0.13);
}

return true;
}

virtual void moveCamera()
{
// Make all the changes to the camera
// Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW
//(e.g. airplane)
mCamera->yaw(mRotX);
mCamera->pitch(mRotY);
mCamera->moveRelative(mTranslateVector);
}

virtual void showDebugOverlay(bool show)
{
if (mDebugOverlay)
{
if (show)
mDebugOverlay->show();
else
mDebugOverlay->hide();
}
}

// Override frameRenderingQueued event to process that (don't care about frameEnded)
bool frameRenderingQueued(const FrameEvent& evt)
{

if(mWindow->isClosed()) return false;

mSpeedLimit = mMoveScale * evt.timeSinceLastFrame;

//Need to capture/update each device
mKeyboard->capture();
mMouse->capture();
if( mJoy ) mJoy->capture();

bool buffJ = (mJoy) ? mJoy->buffered() : true;

Ogre::Vector3 lastMotion = mTranslateVector;

//Check if one of the devices is not buffered
if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
{
// one of the input modes is immediate, so setup what is needed for immediate movement
if (mTimeUntilNextToggle >= 0)
mTimeUntilNextToggle -= evt.timeSinceLastFrame;

// Move about 100 units per second
mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
// Take about 10 seconds for full rotation
mRotScale = mRotateSpeed * evt.timeSinceLastFrame;

mRotX = 0;
mRotY = 0;
mTranslateVector = Ogre::Vector3::ZERO;

}

//Check to see which device is not buffered, and handle it
if( !mKeyboard->buffered() )
if( processUnbufferedKeyInput(evt) == false )
return false;
if( !mMouse->buffered() )
if( processUnbufferedMouseInput(evt) == false )
return false;

// ramp up / ramp down speed
if (mTranslateVector == Ogre::Vector3::ZERO)
{
// decay (one third speed)
mCurrentSpeed -= evt.timeSinceLastFrame * 0.3;
mTranslateVector = lastMotion;
}
else
{
// ramp up
mCurrentSpeed += evt.timeSinceLastFrame;

}
// Limit motion speed
if (mCurrentSpeed > 1.0)
mCurrentSpeed = 1.0;
if (mCurrentSpeed < 0.0)
mCurrentSpeed = 0.0;

mTranslateVector *= mCurrentSpeed;


if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
moveCamera();


//TERRAIN
if (mMode != MODE_NORMAL)
{
/*
// fire ray
Ray ray;
//ray = mCamera->getCameraToViewportRay(0.5, 0.5);
ray = mTrayMgr->getCursorRay(mCamera);

TerrainGroup::RayResult rayResult = mTerrainGroup->rayIntersects(ray);
if (rayResult.hit)
{
mEditMarker->setVisible(true);
mEditNode->setPosition(rayResult.position);

// figure out which terrains this affects
TerrainGroup::TerrainList terrainList;
Real brushSizeWorldSpace = TERRAIN_WORLD_SIZE * mBrushSizeTerrainSpace;
Sphere sphere(rayResult.position, brushSizeWorldSpace);
mTerrainGroup->sphereIntersects(sphere, &terrainList);

for (TerrainGroup::TerrainList::iterator ti = terrainList.begin();
ti != terrainList.end(); ++ti)
doTerrainModify(*ti, rayResult.position, evt.timeSinceLastFrame);
}
else
{
mEditMarker->setVisible(false);
}
*/

}

//mMode, mFly to be configured by keyboard keys
if (!mFly)
{
// clamp to terrain
Vector3 camPos = mCamera->getPosition();
Ray ray;
ray.setOrigin(Vector3(camPos.x, 10000, camPos.z));
ray.setDirection(Vector3::NEGATIVE_UNIT_Y);

TerrainGroup::RayResult rayResult = mTerrainGroup->rayIntersects(ray);
Real distanceAboveTerrain = 50;
Real fallSpeed = 300;
Real newy = camPos.y;
if (rayResult.hit)
{
if (camPos.y > rayResult.position.y + distanceAboveTerrain)
{
mFallVelocity += evt.timeSinceLastFrame * 20;
mFallVelocity = std::min(mFallVelocity, fallSpeed);
newy = camPos.y - mFallVelocity * evt.timeSinceLastFrame;

}
newy = std::max(rayResult.position.y + distanceAboveTerrain, newy);
mCamera->setPosition(camPos.x, newy, camPos.z);

}

}

if (mUpdateCountDown > 0)
{
mUpdateCountDown -= evt.timeSinceLastFrame;
if (mUpdateCountDown <= 0)
{
mTerrainGroup->update();
mUpdateCountDown = 0;

}

}

if (mTerrainGroup->isDerivedDataUpdateInProgress())
{
/*
mTrayMgr->moveWidgetToTray(mInfoLabel, TL_TOP, 0);
mInfoLabel->show();
if (mTerrainsImported)
{
mInfoLabel->setCaption("Building terrain, please wait...");
}
else
{
mInfoLabel->setCaption("Updating textures, patience...");
}*/

}
else
{
/*
mTrayMgr->removeWidgetFromTray(mInfoLabel);
mInfoLabel->hide();
if (mTerrainsImported)
{
saveTerrains(true);
mTerrainsImported = false;
}
*/
}
//TERRAINEND


/*
buildingTranslate = Vector3(0,0,0);
if( mKeyboard->isKeyDown( OIS::KC_LBRACKET ) )
{
buildingTranslate = Vector3(0,-10,0);
}
if( mKeyboard->isKeyDown( OIS::KC_RBRACKET ) )
{
buildingTranslate = Vector3(0,10,0);
}

if( mKeyboard->isKeyDown( OIS::KC_LSHIFT ) ||
mKeyboard->isKeyDown( OIS::KC_RSHIFT ))
{
mMoveSpeed = 150;
}
else
{
mMoveSpeed = 15;
}
*/


return true;
}

bool frameEnded(const FrameEvent& evt)
{
updateStats();
return true;
}

//TERRAINSTART
void doTerrainModify(Terrain* terrain, const Vector3& centrepos, Real timeElapsed)
{
Vector3 tsPos;
terrain->getTerrainPosition(centrepos, &tsPos);
if (mKeyboard->isKeyDown(OIS::KC_EQUALS) || mKeyboard->isKeyDown(OIS::KC_MINUS))
{
switch(mMode)
{
case MODE_EDIT_HEIGHT:
{
// we need point coords
Real terrainSize = (terrain->getSize() - 1);
long startx = (tsPos.x - mBrushSizeTerrainSpace) * terrainSize;
long starty = (tsPos.y - mBrushSizeTerrainSpace) * terrainSize;
long endx = (tsPos.x + mBrushSizeTerrainSpace) * terrainSize;
long endy= (tsPos.y + mBrushSizeTerrainSpace) * terrainSize;
startx = std::max(startx, 0L);
starty = std::max(starty, 0L);
endx = std::min(endx, (long)terrainSize);
endy = std::min(endy, (long)terrainSize);
for (long y = starty; y <= endy; ++y)
{
for (long x = startx; x <= endx; ++x)
{
Real tsXdist = (x / terrainSize) - tsPos.x;
Real tsYdist = (y / terrainSize) - tsPos.y;

Real weight = std::min((Real)1.0,
Math::Sqrt(tsYdist * tsYdist + tsXdist * tsXdist) / Real(0.5 * mBrushSizeTerrainSpace));
weight = 1.0 - (weight * weight);

float addedHeight = weight * 250.0 * timeElapsed;
float newheight;
if (mKeyboard->isKeyDown(OIS::KC_EQUALS))
newheight = terrain->getHeightAtPoint(x, y) + addedHeight;
else
newheight = terrain->getHeightAtPoint(x, y) - addedHeight;
terrain->setHeightAtPoint(x, y, newheight);
if (mUpdateCountDown == 0)
mUpdateCountDown = mUpdateRate;

}
}
}
break;
case MODE_EDIT_BLEND:
{
TerrainLayerBlendMap* layer = terrain->getLayerBlendMap(mLayerEdit);
// we need image coords
Real imgSize = terrain->getLayerBlendMapSize();
long startx = (tsPos.x - mBrushSizeTerrainSpace) * imgSize;
long starty = (tsPos.y - mBrushSizeTerrainSpace) * imgSize;
long endx = (tsPos.x + mBrushSizeTerrainSpace) * imgSize;
long endy= (tsPos.y + mBrushSizeTerrainSpace) * imgSize;
startx = std::max(startx, 0L);
starty = std::max(starty, 0L);
endx = std::min(endx, (long)imgSize);
endy = std::min(endy, (long)imgSize);
for (long y = starty; y <= endy; ++y)
{
for (long x = startx; x <= endx; ++x)
{
Real tsXdist = (x / imgSize) - tsPos.x;
Real tsYdist = (y / imgSize) - tsPos.y;

Real weight = std::min((Real)1.0,
Math::Sqrt(tsYdist * tsYdist + tsXdist * tsXdist) / Real(0.5 * mBrushSizeTerrainSpace));
weight = 1.0 - (weight * weight);

float paint = weight * timeElapsed;
size_t imgY = imgSize - y;
float val;
if (mKeyboard->isKeyDown(OIS::KC_EQUALS))
val = layer->getBlendValue(x, imgY) + paint;
else
val = layer->getBlendValue(x, imgY) - paint;
val = Math::Clamp(val, 0.0f, 1.0f);
layer->setBlendValue(x, imgY, val);
layer->update();

}
}
}
break;



};

}

}

void saveTerrains(bool onlyIfModified)
{
mTerrainGroup->saveAllTerrains(onlyIfModified);
}

bool keyPressed (const OIS::KeyEvent &e)
{
switch (e.key)
{
case OIS::KC_S:
// CTRL-S to save
if (mKeyboard->isKeyDown(OIS::KC_LCONTROL) || mKeyboard->isKeyDown(OIS::KC_RCONTROL))
{
saveTerrains(true);
}
break;
case OIS::KC_F10:
// dump
{
TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
while (ti.hasMoreElements())
{
uint32 tkey = ti.peekNextKey();
TerrainGroup::TerrainSlot* ts = ti.getNext();
if (ts->instance && ts->instance->isLoaded())
{
ts->instance->_dumpTextures("terrain_" + StringConverter::toString(tkey), ".png");
}


}
}
break;
default:
break;
}
return true;
}
//TERRAINEND

protected:
Camera* mCamera;

Vector3 mTranslateVector;
Real mCurrentSpeed;
RenderWindow* mWindow;
bool mStatsOn;

std::string mDebugText;

unsigned int mNumScreenShots;
float mMoveScale;
float mSpeedLimit;
Degree mRotScale;
// just to stop toggles flipping too fast
Real mTimeUntilNextToggle ;
Radian mRotX, mRotY;
TextureFilterOptions mFiltering;
int mAniso;

int mSceneDetailIndex ;
Real mMoveSpeed;
Degree mRotateSpeed;
Overlay* mDebugOverlay;

//OIS Input devices
OIS::InputManager* mInputManager;
OIS::Mouse* mMouse;
OIS::Keyboard* mKeyboard;
OIS::JoyStick* mJoy;
};


class MyTerrainApplication
{
public:
MyTerrainApplication()
{
mFrameListener = 0;
mRoot = 0;
mResourcePath = "";
}
virtual ~MyTerrainApplication()
{
if (mFrameListener)
delete mFrameListener;
if (mRoot)
delete mRoot;
}

virtual void go(void)
{
if (!setup())
return;

mRoot->startRendering();

destroyScene();
}

protected:
Root *mRoot;
Camera* mCamera;
SceneManager* mSceneMgr;
MyTerrainFrameListener* mFrameListener;
RenderWindow* mWindow;
Ogre::String mResourcePath;

virtual bool setup(void)
{

String pluginsPath;
// only use plugins.cfg if not static
pluginsPath = "plugins.cfg";
mRoot = new Root(pluginsPath,
"ogre.cfg", "Ogre.log");

setupResources();

bool carryOn = configure();
if (!carryOn) return false;

chooseSceneManager();
createCamera();
createViewports();

// Set default mipmap level (NB some APIs ignore this)
TextureManager::getSingleton().setDefaultNumMipmaps(5);

// Create any resource listeners (for loading screens)
createResourceListener();
// Load resources
loadResources();

// Create the scene
createScene();

createFrameListener();

return true;

}
/** Configures the application - returns false if the user chooses to abandon configuration. */
virtual bool configure(void)
{
// Show the configuration dialog and initialise the system
// You can skip this and use root.restoreConfig() to load configuration
// settings if you were sure there are valid ones saved in ogre.cfg
if(mRoot->showConfigDialog())
{
// If returned true, user clicked OK so initialise
// Here we choose to let the system create a default rendering window by passing 'true'
mWindow = mRoot->initialise(true);
return true;
}
else
{
return false;
}
}

virtual void chooseSceneManager(void)
{
// Create the SceneManager, in this case a generic one
mSceneMgr = mRoot->createSceneManager(ST_GENERIC);
}
virtual void createCamera(void)
{
// Create the camera
mCamera = mSceneMgr->createCamera("PlayerCam");

// Position it at 500 in Z direction
mCamera->setPosition(Vector3(0,0,500));
// Look back along -Z
mCamera->lookAt(Vector3(0,0,-300));
mCamera->setNearClipDistance(5);

}
virtual void createFrameListener(void)
{
mFrameListener= new MyTerrainFrameListener(mWindow, mCamera, mSceneMgr, mRoot);
mFrameListener->showDebugOverlay(true);
mRoot->addFrameListener(mFrameListener);
}

virtual void createScene(void)
{
/*
// Set ambient light
mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));

// Create a skybox
mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 500 );
// put the skybox node in the default zone
((PCZSceneManager*)mSceneMgr)->setSkyZone(0);

// Create a light
Light* l = mSceneMgr->createLight("MainLight");
l->setPosition(0,0,0);
l->setAttenuation(500, 0.5, 1.0, 0.0);
// Accept default settings: point light, white diffuse, just set position
// attach light to a scene node so the PCZSM can handle it properly (zone-wise)
// IMPORTANT: Lights (just like cameras) MUST be connected to a scene node!
SceneNode * lightNode = mCameraNode->createChildSceneNode("light_Node");
lightNode->attachObject(l);

// Fog
// NB it's VERY important to set this before calling setWorldGeometry
// because the vertex program picked will be different
ColourValue fadeColour(0.101, 0.125, 0.1836);
mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
mWindow->getViewport(0)->setBackgroundColour(fadeColour);

// create a terrain zone
std::string terrain_cfg("terrain.cfg");
std::string zoneName("Terrain1_Zone");
PCZone * terrainZone = createTerrainZone(zoneName, terrain_cfg);

// set far clip plane to one terrain zone width (we have a LOT of terrain here, so we need to do far clipping!)
mCamera->setFarClipDistance(1500);

// create test buildinig
RoomObject roomObj;
buildingNode = roomObj.createTestBuilding(mSceneMgr, String("1"));
buildingNode->setPosition(500, 165, 570);
//Ogre::Radian r = Radian(3.1416/7.0);
//buildingNode->rotate(Vector3::UNIT_Y, r);

// create another test buildinig
RoomObject roomObj2;
buildingNode = roomObj2.createTestBuilding(mSceneMgr, String("2"));
buildingNode->setPosition(400, 165, 570);
//Ogre::Radian r = Radian(3.1416/7.0);
//buildingNode->rotate(Vector3::UNIT_Y, r);

// Position camera in the center of the building
mCameraNode->setPosition(buildingNode->getPosition());
// Look back along -Z
mCamera->lookAt(mCameraNode->_getDerivedPosition() + Vector3(0,0,-300));
// Update bounds for camera
mCameraNode->_updateBounds();

// create the ray scene query
raySceneQuery = mSceneMgr->createRayQuery(
Ray(mCamera->getParentNode()->getPosition(), Vector3::NEGATIVE_UNIT_Z));
raySceneQuery->setSortByDistance(true, 5);
*/

}

virtual void destroyScene(void){}

virtual void createViewports(void)
{
// Create one viewport, entire window
Viewport* vp = mWindow->addViewport(mCamera);
vp->setBackgroundColour(ColourValue(0,0,0));

// Alter the camera aspect ratio to match the viewport
mCamera->setAspectRatio(
Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}

/// Method which will define the source of resources (other than current folder)
virtual void setupResources(void)
{
// Load resource paths from config file
ConfigFile cf;
cf.load("resources.cfg");

// Go through all sections & settings in the file
ConfigFile::SectionIterator seci = cf.getSectionIterator();

String secName, typeName, archName;
while (seci.hasMoreElements())
{
secName = seci.peekNextKey();
ConfigFile::SettingsMultiMap *settings = seci.getNext();
ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
archName = i->second;
ResourceGroupManager::getSingleton().addResourceLocation(
archName, typeName, secName);
}
}
}

/// Optional override method where you can create resource listeners (e.g. for loading screens)
virtual void createResourceListener(void)
{

}

/// Optional override method where you can perform resource group loading
/// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
virtual void loadResources(void)
{
// Initialise, parse scripts etc
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

}



};

#endif


EDIT: oh wait I don't have to finish it... I'm starting the converting now..
And when I'm done you can use it as starting point maybe?

yubgipenguin

07-01-2010 02:53:57

Okay, I'm kinda done except for few parts which uses pointers.

You only have to look at NewTerrain class.

Here's the python code:
import os, sys
import ogre.renderer.OGRE as ogre
import ogre.renderer.ogreterrain as ogreterrain
import ogre.renderer.ogrepaging as ogrepaging
import ogre.io.OIS as OIS
import math


class GameCamera(object): # camera update
def __init__(self, scene, camera, cameraNode, defNodeOrient):
self.scene = scene
self.viewPort = scene.ogreRoot.getAutoCreatedWindow().addViewport(camera)
self.camera = camera
self.cameraNode = cameraNode
self.defNodeOrient = defNodeOrient

self.camHeight = 40
self.translateVector = ogre.Vector3(0.0, 0.0, 0.0)
self.moveScale = 0
self.moveSpeed = 400
self.rotationScale = 0.1
self.rotationSpeed = 0.5
self.key = None

self.ResetRotation()
self.MoveCamera(500, self.camHeight, 500)
self.RotateCamera(0, 0)

listener = scene.gameRoot.GetEventListener()
listener.BindMouseMoved(self._OnMouseMoved)
listener.BindKeyPressed(self._OnKeyPressed)
listener.BindKeyReleased(self._OnKeyReleased)
listener.BindTick(self._OnTick)

def _OnTick(self, frameEvent, lastMouseState, lastKeyState):
if frameEvent.timeSinceLastFrame == 0:
self.moveScale = 1
self.rotationScale = 0.1

else:
self.moveScale = self.moveSpeed * frameEvent.timeSinceLastFrame
self.rotationScale = self.rotationSpeed * frameEvent.timeSinceLastFrame

if self.key == OIS.KC_A:
self.translateVector.x = -self.moveScale

if self.key == OIS.KC_D:
self.translateVector.x = self.moveScale

if self.key == OIS.KC_W:
self.translateVector.z = -self.moveScale

if self.key == OIS.KC_S:
self.translateVector.z = self.moveScale

if self.key == OIS.KC_PGUP:
self.translateVector.y = self.moveScale

if self.key == OIS.KC_PGDOWN:
self.translateVector.y = -self.moveScale

if self.key in [OIS.KC_A, OIS.KC_D, OIS.KC_W, OIS.KC_S, OIS.KC_PGDOWN, OIS.KC_PGUP]:
self.TranslateCamera(self.translateVector)
def _OnKeyReleased(self, evt):
self.key = None
def _OnKeyPressed(self, evt):
self.key = evt.key

def _OnMouseMoved(self, lastMouseState):
self.RotateCamera(-lastMouseState.relX*self.rotationSpeed, -lastMouseState.relY*self.rotationSpeed)


def MoveCamera(self, x, y, z):
self.cameraNode.setPosition(x, y, z)

def TranslateCamera(self, translateVector):
try:
self.camera.translate(translateVector) # for using OgreRefApp
except AttributeError:
self.camera.moveRelative(translateVector)

def RotateCamera(self, yaw, pitch):
self.camera.getParentSceneNode().yaw(ogre.Degree(yaw),
ogre.Node.TS_WORLD)
self.camera.getParentSceneNode().pitch(ogre.Degree(pitch))
self.cameraNode._updateBounds()

def ResetRotation(self):
self.cameraNode.setOrientation(self.defNodeOrient)
self.camera.lookAt(
self.cameraNode._getDerivedPosition() + ogre.Vector3().NEGATIVE_UNIT_Z)

def GetViewport(self):
return self.viewPort

def GetDefaultNodeOrient(self):
return self.defNodeOrient
def GetOgreCamera(self):
return self.camera


class GameRoot(object): # Facade
def __init__(self, ogreRoot, eventListener):
self.ogreRoot = ogreRoot
self.eventListener = eventListener
self.scene = Scene(self)
self.scene.OnGameRootInit()

def GetOgreRoot(self):
return self.ogreRoot
def GetScene(self):
return self.scene
def GetEventListener(self):
return self.eventListener

class MouseState(object):
def __init__(self):
self.x = 0
self.y = 0
self.w = 0
self.h = 0
self.relX = 0
self.relY = 0
self.relZ = 0
self.pressedButtons = {}

def OnMouseMoved(self, x, y, w, h, relX, relY, relZ):
self.x = x
self.y = y
self.w = w
self.h = h
self.relX = relX
self.relY = relY
self.relZ = relZ
def OnMousePressed(self, x, y, w, h, id):
self.x = x
self.y = y
self.w = w
self.h = h
self.pressedButtons[id] = 0
def OnMouseReleased(self, x, y, w, h, id):
self.x = x
self.y = y
self.w = w
self.h = h
try:
del self.pressedButtons[id]
except:
pass
def UpdateWithMouseState(self, mouseState):
self.x, self.y, self.w, self.h = mouseState.GetValues()
self.relX, self.relY = self.GetRelativeMovements()
for key in mouseState.GetPressedButtons().iterkeys():
self.pressedButtons[key] = mouseState.GetPressedButtons()[key]
def OnTick(self, time):
for key in self.pressedButtons.iterkeys():
self.pressedButtons[key] += time

def GetValues(self):
return self.x, self.y, self.w, self.h
def GetRelativeMovements(self):
return self.relX, self.relY
def GetWheelMovement(self):
return self.relZ
def GetPressedButtons(self):
return self.pressedButtons
def _GetScreenVector(self, x, y, w, h):
if w and h:
mx = float(x) - float(w)/2.0
my = float(y) - float(h)/2.0
vectorX, vectorY = mx/(float(w)/2.0), -my/(float(h)/2.0)
return vectorX, vectorY
else:
return 0, 0
def GetScreenVector(self):
return self._GetScreenVector(*self.GetValues())

def GetScreenVectorDegree(self):
vector = self.GetScreenVector()
return Vector2ToAngle(*vector)

def Vector2ToAngle(x, y):
vecOrg = ogre.Vector2(1.0, 0.0)
vecPos = ogre.Vector2(x, y)
vecPos.normalise()
dotted = vecOrg.dotProduct(vecPos)
if dotted == 0.0:
dotted = 0.0001
convert = 360.0/(2*math.pi)

angle = math.acos(dotted)*convert
if y < 0:
angle = -angle
angle %= 360
return angle

class KeyState(object):
def __init__(self):
self.pressedKey = None
self.pressedChar = None
self.timePressedFor = None

def OnKeyPressed(self, evt):
self.pressedKey = evt.key
self.pressedChar = evt.text
self.timePressedFor = 0
def OnTick(self, time):
if self.timePressedFor:
self.timePressedFor += time
def OnKeyReleased(self):
self.pressedKey = None
self.pressedChar = None
self.timePressedFor = None

def GetPressedKey(self):
return self.pressedKey
def GetPressedTime(self):
return self.timePressedFor

class OgreEventListener(ogre.FrameListener, ogre.WindowEventListener,
OIS.MouseListener, OIS.KeyListener, OIS.JoyStickListener):
mouse = None
keyboard = None
joy = None

def __init__(self, app, renderWindow, bufferedMouse, bufferedKeys, bufferedJoy):
ogre.FrameListener.__init__(self)
ogre.WindowEventListener.__init__(self)
OIS.MouseListener.__init__(self)
OIS.KeyListener.__init__(self)
OIS.JoyStickListener.__init__(self)

self.app = app
self.renderWindow = renderWindow

# Init input system
import platform
int64 = False
for bit in platform.architecture():
if '64' in bit:
int64 = True
# Create the inputManager using the supplied renderWindow
if int64:
windowHnd = self.renderWindow.getCustomAttributeUnsignedLong("WINDOW")
else:
windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
t = self._inputSystemParameters()
params = [("WINDOW",str(windowHnd))]
params.extend(t)
self.inputManager = OIS.createPythonInputSystem(params)

try:
if bufferedMouse:
self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, bufferedMouse)
self.mouse.setEventCallback(self)

if bufferedKeys:
self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, bufferedKeys)
self.keyboard.setEventCallback(self)

if bufferedJoy:
self.joy = self.inputManager.createInputObjectJoyStick(OIS.OISJoyStick, bufferedJoy)
self.joy.setEventCallback(self)

except Exception, e: # Unable to obtain mouse/keyboard/joy input
raise e


self.windowResized(self.renderWindow)

# Listen for any events directed to the window manager's close button
ogre.WindowEventUtilities.addWindowEventListener(self.renderWindow, self)

self.quitApplication = False
self.lastMouseState = MouseState()
self.lastKeyState = KeyState()

self.bindsMouseMoved = []
self.bindsMousePressed = []
self.bindsMouseReleased = []
self.bindsKeyPressed = []
self.bindsKeyReleased = []
self.bindsOnTick = []
self.bindsAppClosed = []

self.bindsMouseMovedReturn = None
self.bindsMousePressedReturn = None
self.bindsMouseReleasedReturn = None



def __del__ (self ):
# Clean up OIS
self.delInputObjects()

OIS.InputManager.destroyInputSystem(self.inputManager)
self.inputManager = None

ogre.WindowEventUtilities.removeWindowEventListener(self.renderWindow, self)
self.windowClosed(self.renderWindow)

def delInputObjects(self):
# Clean up the initialized input objects
if self.keyboard:
self.inputManager.destroyInputObjectKeyboard(self.keyboard)
if self.mouse:
self.inputManager.destroyInputObjectMouse(self.mouse)
if self.joy:
self.inputManager.destroyInputObjectJoy(self.joy)


### Window Event Listener callbacks ###

def windowResized(self, rw):
dummyint = 0
width, height, depth, left, top= rw.getMetrics(dummyint,dummyint,dummyint, dummyint, dummyint)
# Note the wrapped function as default needs unsigned int's
ms = self.mouse.getMouseState()
ms.width = width
ms.height = height

def windowClosed(self, renderWindow):
# Only close for window that created OIS
for func in self.bindsAppClosed:
func()
if(renderWindow == self.renderWindow):
del self

import sys
sys.exit()

### Mouse Listener callbacks ###
def mouseMoved(self,arg):
state = arg.get_state()
self.lastMouseState.OnMouseMoved(state.X.abs, state.Y.abs, state.width, state.height, state.X.rel, state.Y.rel, state.Z.rel)
for func in self.bindsMouseMoved:
func(self.lastMouseState)

return True

def mousePressed(self, arg, id):
state = arg.get_state()
self.lastMouseState.OnMousePressed(state.X.abs, state.Y.abs, state.width, state.height, id)
for func in self.bindsMousePressed:
func(self.lastMouseState, id)

return True

def mouseReleased(self, arg, id):
state = arg.get_state()
self.lastMouseState.OnMouseReleased(state.X.abs, state.Y.abs, state.width, state.height, id)

for func in self.bindsMouseReleased:
func(self.lastMouseState, id)
return True

### Key Listener callbacks ###
def keyPressed(self, evt):
self.lastKeyState.OnKeyPressed(evt)

for func in self.bindsKeyPressed:
func(evt)
return True

def keyReleased(self, evt):
self.lastKeyState.OnKeyReleased()

for func in self.bindsKeyReleased:
func(evt)
return True

### Joystick Listener callbacks ###
def buttonPressed(self, evt, id):
return True

def buttonReleased(self, evt, id):
return True

def axisMoved(self, evt, id):
return True

### For mouse pointer ###
def _inputSystemParameters (self ):
if os.name == 'nt':
return [("w32_mouse","DISCL_FOREGROUND"), ("w32_mouse", "DISCL_NONEXCLUSIVE")]

### Tick ###
def frameStarted(self, frameEvent):
if self.keyboard:
self.keyboard.capture()
if self.mouse:
self.mouse.capture()
if self.joy:
self.joy.capture()
# joystick test
axes_int = self.joy.getJoyStickState().mAxes
axes = []
for i in axes_int:
axes.append(i.abs)

self.lastMouseState.OnTick(frameEvent.timeSinceLastFrame)
self.lastKeyState.OnTick(frameEvent.timeSinceLastFrame)

for func in self.bindsOnTick:
func(frameEvent, self.lastMouseState, self.lastKeyState)

stats = self.renderWindow.getStatistics()
curFPS = str(int(stats.lastFPS))
#print curFPS

return True

def BindMouseMoved(self, func):
self.bindsMouseMoved += [func]
def BindMousePressed(self, func):
self.bindsMousePressed += [func]
def BindMouseReleased(self, func):
self.bindsMouseReleased += [func]

def BindMouseMovedReturn(self, func):
self.bindsMouseMovedReturn = func
def BindMousePressedReturn(self, func):
self.bindsMousePressedReturn = func
def BindMouseReleasedReturn(self, func):
self.bindsMouseReleasedReturn = func

def BindKeyPressed(self, func):
self.bindsKeyPressed += [func]
def BindKeyReleased(self, func):
self.bindsKeyReleased += [func]

def BindTick(self, func):
self.bindsOnTick += [func]

def BindAppClosed(self, func):
self.bindsAppClosed += [func]



class DummyPageProvider(ogrepaging.PageProvider):
def prepareProceduralPage(self, page, section):
return True
def loadProceduralPage(self, page, section):
return True
def unloadProceduralPage(self, page, section):
return True
def unprepareProceduralPage(self, page, section):
return True

class NewTerrain(object):
MODE_NORMAL = 0
MODE_EDIT_HEIGHT = 1
MODE_EDIT_BLEND = 2

SHADOWS_NONE = 0
SHADOWS_COLOUR = 1
SHADOWS_DEPTH = 2


TERRAIN_PAGE_MIN_X = 0
TERRAIN_PAGE_MIN_Y = 0
TERRAIN_PAGE_MAX_X = 0
TERRAIN_PAGE_MAX_Y = 0

TERRAIN_FILE_PREFIX = "testTerrain"
TERRAIN_FILE_SUFFIX = "dat"
TERRAIN_WORLD_SIZE = 12000.0
TERRAIN_SIZE = 513

def __init__(self, sceneManager, scene):
self.sceneMgr = sceneManager
self.scene = scene
self.camera = scene.GetCamera().camera
self.root = scene.gameRoot.GetOgreRoot()
self.ray = ogre.Ray()

self.paging = True
self.terrainGroup = None
self.terrainPaging = None
self.pageManager = None
self.fly = False
self.fallVelocity = 0
self.dummyPageProvider = DummyPageProvider()
self.mode = NewTerrain.MODE_NORMAL
self.shadowMode = NewTerrain.SHADOWS_NONE
self.layerEdit = 1
self.brushSizeTerrainSpace = 0.02
self.editNode = None
self.editMarker = None
self.updateCountDown = 0
self.updateRate = 1.0 / 20.0
self.terrainPos = ogre.Vector3(1000, 0, 5000)
self.terrainsImported = False
self.pssmSetup = None
#XXX: I don't know what to do here. pssmSetup's supposed to be ShadowCameraSetupPtr
self.houseList = []



self.pressingKey = None
listener = scene.gameRoot.GetEventListener()
listener.BindMouseMoved(self._OnMouseMoved)
listener.BindKeyPressed(self._OnKeyPressed)
listener.BindKeyReleased(self._OnKeyReleased)
listener.BindTick(self._OnTick)


self.setupView()
self.setupContent()

def _OnTick(self, frameEvent, lastMouseState, lastKeyState):
if self.mode != NewTerrain.MODE_NORMAL:
ray = self.GetMouseRay(*lastMouseState.GetValues())
rayResult = self.terrainGroup.rayIntersects(ray)
if rayResult.hit:
self.editMarker.setVisible(True)
self.editNode.setPosition(rayResult.position)

# figure out which terrains this affects
brushSizeWorldSpace = NewTerrain.TERRAIN_WORLD_SIZE * self.brushSizeTerrainSpace
sphere = ogre.Sphere(rayResult.position, brushSizeWorldSpace)
terrainList = self.terrainGroup.sphereIntersects(sphere)

for ti in terrainList:
doTerrainModify(ti, rayResult.position, frameEvent.timeSinzeLastFrame)
else:
self.editMarker.setVisible(False)

# no need to do this
"""
if (!mFly)
{
// clamp to terrain
Vector3 camPos = mCamera->getPosition();
Ray ray;
ray.setOrigin(Vector3(camPos.x, 10000, camPos.z));
ray.setDirection(Vector3::NEGATIVE_UNIT_Y);

TerrainGroup::RayResult rayResult = mTerrainGroup->rayIntersects(ray);
Real distanceAboveTerrain = 50;
Real fallSpeed = 300;
Real newy = camPos.y;
if (rayResult.hit)
{
if (camPos.y > rayResult.position.y + distanceAboveTerrain)
{
mFallVelocity += evt.timeSinceLastFrame * 20;
mFallVelocity = std::min(mFallVelocity, fallSpeed);
newy = camPos.y - mFallVelocity * evt.timeSinceLastFrame;

}
newy = std::max(rayResult.position.y + distanceAboveTerrain, newy);
mCamera->setPosition(camPos.x, newy, camPos.z);

}

}
"""


if self.updateCountDown > 0:
self.updateCountDown -= frameEvent.timeSinceLastFrame
if self.updateCountDown <= 0:
self.terrainGroup.update()
self.updateCountDown = 0

if terrainGroup.isDerivedDataUpdateInProgress():
if self.terrainsImported:
print "Building terrain, please wait..."
else:
print "Updating textures, patience..."
else:
if self.terrainsImported:
self.saveTerrains(True)
self.terrainsImported = False

def _OnKeyReleased(self, evt):
self.pressingKey = None
def _OnKeyPressed(self, evt):
if evt.key == OIS.KC_S:
if self.pressingKey == OIS.KC_LCONTROL or self.pressingKey == OIS.KC_RCONTROL:
self.saveTerrains(True)


if evt.key == OIS.KC_F10:
ti = self.terrainGroup.getTerrainIterator()
while ti.hasMoreElements():
tkey = ti.peekNextKey()
ts = ti.getNext()
if ts.instance and ts.instance.isLoaded():
ts.instance._dumpTextures("terrain_" + str(tkey), ".png")

if evt.key == OIS.KC_1:
self.mode = NewTerrain.MODE_NORMAL
if evt.key == OIS.KC_2:
self.mode = NewTerrain.MODE_EDIT_HEIGHT
if evt.key == OIS.KC_3:
self.mode = NewTerrain.MODE_EDIT_BLEND
if evt.key == OIS.KC_4:
self.shadowMode = NewTerrain.SHADOWS_NONE
self.changeShadows()
if evt.key == OIS.KC_5:
self.shadowMode = NewTerrain.SHADOWS_COLOUR
self.changeShadows()
if evt.key == OIS.KC_6:
self.shadowMode = NewTerrain.SHADOWS_DEPTH
self.changeShadows()


self.pressingKey = evt.key
def _OnMouseMoved(self, lastMouseState):
self.RotateCamera(-lastMouseState.relX*self.rotationSpeed, -lastMouseState.relY*self.rotationSpeed)




def GetMouseRay(self, x, y, w, h):
pos_w = float(x) / float(w)
pos_h = float(y) / float(h)
mouseRay = self.scene.GetCameraToViewportRay(pos_w, pos_h)
return mouseRay


def doTerrainModify(self, terrain, centrepos, timeElepsed):
tsPos = terrain.getTerrainPosition(centrepos)

if self.pressingKey == OIS.KC_EQUALS or self.pressingKey == OIS.KC_MINUS:
if self.mode == NewTerrain.MODE_EDIT_HEIGHT:
terrainSize = terrain.getSize() - 1
startx = (tsPos.x - self.brushSizeTerrainSpace) * terrainSize
starty = (tsPos.y - self.brushSizeTerrainSpace) * terrainSize
endx = (tsPos.x + self.brushSizeTerrainSpace) * terrainSize
endy = (tsPos.y + self.brushSizeTerrainSpace) * terrainSize
startx = max(startx, 0)
starty = max(starty, 0)
endx = min(endx, terrainSize)
endy = min(endy, terrainSize)

x = startx
y = starty
while y <= endy:
while x <= endx:
tsXdist = (x / terrainSize) - tsPos.x
tsYdist = (y / terrainSize) - tsPos.y
weight = min(1.0, math.sqrt(tsYdist ** 2 + tsXdist ** 2) / (0.5* self.brushSizeTerrainSpace))
weight = 1.0 - weight**2

addedHeight = weight * 250.0 * timeElepsed
if self.pressingKey == OIS.KC_EQUALS:
newheight = terrain.getHeightAtPoins(x, y) + addedHeight
else:
newheight = terrain.getHeightAtPoins(x, y) - addedHeight
terrain.setHeightAtPoint(x, y, newheight)
if self.updateCountDown == 0:
self.updateCountDown = self.updateRate

x += 1
y += 1

elif self.mode == NewTerrain.MODE_EDIT_BLEND:
layer = terrain.getLayerBlendMap(self.layerEdit)
# we need image coords
imgSize = terrain.getLayerBlendMapSize()
startx = (tsPos.x - self.brushSizeTerrainSpace) * imgSize
starty = (tsPos.y - self.brushSizeTerrainSpace) * imgSize
endx = (tsPos.x + self.brushSizeTerrainSpace) * imgSize
endy = (tsPos.y + self.brushSizeTerrainSpace) * imgSize
startx = max(startx, 0)
starty = max(starty, 0)
endx = min(endx, imgSize)
endy = min(endy, imgSize)
x = startx
y = starty
while y <= endy:
while x <= endx:
tsXdist = (x / imgSize) - tsPos.x
tsYdist = (y / imgSize) - tsPos.y
weight = min(1.0, math.sqrt(tsYdist ** 2 + tsXdist ** 2) / (0.5 * self.brushSizeTerrainSpace))
weight = 1.0 - weight**2

paint = weight * timeElapsed
imgY = imgSize - y
if self.pressingKey == OIS.KC_EQUALS:
val = layer.getBlendValue(x, imgY) + paint
else:
val = layer.getBlendValue(x, imgY) - paint

val = ogre.Math.Clamp(val, 0.0, 1.0)
layer.setBlendValue(x, imgY, val)
layer.update()


x += 1
y += 1

def saveTerrains(self, onlyIfModified):
self.terrainGroup.saveAllTerrains(onlyIfModified)

def defineTerrain(self, x, y, flat = False):
"""
// if a file is available, use it
// if not, generate file from import

// Usually in a real project you'll know whether the compact terrain data is
// available or not; I'm doing it this way to save distribution size
"""
if flat:
self.terrainGroup.defineTerrain(x, y, 0.0)
else:
filename = self.terrainGroup.generateFilename(x, y)
if ogre.ResourceGroupManager.getSingleton().resourceExists(self.terrainGroup.getResourceGroup(), filename):
self.terrainGroup.defineTerrain(x, y)
else:
img = self.getTerrainImage((x % 2) != 0, (y%2) != 0)
self.terrainGroup.defineTerrain(x, y, img)
self.terrainsImported = True

def getTerrainImage(self, flipX, flipY):
img = ogre.Image()
img.load("terrain.png", ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)
if flipX:
img.flipAroundY()
if flipY:
img.flipAroundX()

return img

def initBlendMaps(self, terrain):
# XXX: I don't know how it is gonna be done so I'll leave it be
blendMap0 = terrain.getLayerBlendMap(1)
blendMap1 = terrain.getLayerBlendMap(2)
minHeight0 = 70
fadeDist0 = 40
minHeight1 = 70
fadeDist1 = 15
float* pBlend0 = blendMap0.getBlendPointer()
float* pBlend1 = blendMap1.getBlendPointer()

for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y)
{
for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x)
{
Real tx, ty;

blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty);
Real height = terrain->getHeightAtTerrainPosition(tx, ty);
Real val = (height - minHeight0) / fadeDist0;
val = Math::Clamp(val, (Real)0, (Real)1);
//*pBlend0++ = val;

val = (height - minHeight1) / fadeDist1;
val = Math::Clamp(val, (Real)0, (Real)1);
*pBlend1++ = val;
}
}
blendMap0.dirty()
blendMap1.dirty()
#//blendMap0->loadImage("blendmap1.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
blendMap0.update()
blendMap1.update()

"""
// set up a colour map
/*
if (!terrain->getGlobalColourMapEnabled())
{
terrain->setGlobalColourMapEnabled(true);
Image colourMap;
colourMap.load("testcolourmap.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
terrain->getGlobalColourMap()->loadImage(colourMap);
}
*/
"""


def configureTerrainDefaults(self, l):
#// Configure global
ogreterrain.TerrainGlobalOptions.setMaxPixelError(8)
#// testing composite map
ogreterrain.TerrainGlobalOptions.setCompositeMapDistance(3000)
#//TerrainGlobalOptions::setUseRayBoxDistanceCalculation(true);
#//TerrainGlobalOptions::getDefaultMaterialGenerator()->setDebugLevel(1);
#//TerrainGlobalOptions::setLightMapSize(256);
# XXX: castAsSM2Profile?
"""
TerrainMaterialGeneratorA::SM2Profile* matProfile =
static_cast<TerrainMaterialGeneratorA::SM2Profile*>(TerrainGlobalOptions::getDefaultMaterialGenerator()->getActiveProfile());
"""
matProfile = ogreterrain.getDefaultMaterialGenerator().getActiveProfile()

#//matProfile->setLightmapEnabled(false);
#// Important to set these so that the terrain knows what to use for derived (non-realtime) data
ogreterrain.TerrainGlobalOptions.setLightMapDirection(l.getDerivedDirection())
ogreterrain.TerrainGlobalOptions.setCompositeMapAmbient(self.sceneMgr.getAmbientLight())
#//TerrainGlobalOptions::setCompositeMapAmbient(ColourValue::Red);
ogreterrain.TerrainGlobalOptions.setCompositeMapDiffuse(l.getDiffuseColour())

#// Configure default import settings for if we use imported image
defaultimp = self.terrainGroup.getDefaultImportSettings()
defaultimp.terrainSize = NewTerrain.TERRAIN_SIZE
defaultimp.worldSize = NewTerrain.TERRAIN_WORLD_SIZE
defaultimp.inputScale = 600
defaultimp.minBatchSize = 33
defaultimp.maxBatchSize = 65
#// textures
defaultimp.layerList.resize(3)
defaultimp.layerList[0].worldSize = 100
defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");
defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");
defaultimp.layerList[1].worldSize = 30
defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");
defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");
defaultimp.layerList[2].worldSize = 200
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");


"""
void addTextureDebugOverlay(TrayLocation loc, TexturePtr tex, size_t i)
{
addTextureDebugOverlay(loc, tex->getName(), i);
}
void addTextureDebugOverlay(TrayLocation loc, const String& texname, size_t i)
{
// Create material
String matName = "Ogre/DebugTexture" + StringConverter::toString(i);
MaterialPtr debugMat = MaterialManager::getSingleton().getByName(matName);
if (debugMat.isNull())
{
debugMat = MaterialManager::getSingleton().create(matName,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
}
Pass* p = debugMat->getTechnique(0)->getPass(0);
p->removeAllTextureUnitStates();
p->setLightingEnabled(false);
TextureUnitState *t = p->createTextureUnitState(texname);
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);

// create template
if (!OverlayManager::getSingleton().hasOverlayElement("Ogre/DebugTexOverlay", true))
{
OverlayElement* e = OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexOverlay", true);
e->setMetricsMode(GMM_PIXELS);
e->setWidth(128);
e->setHeight(128);
}

// add widget
String widgetName = "DebugTex"+ StringConverter::toString(i);
Widget* w = mTrayMgr->getWidget(widgetName);
if (!w)
{
w = mTrayMgr->createDecorWidget(
loc, widgetName, "Panel", "Ogre/DebugTexOverlay");
}
w->getOverlayElement()->setMaterialName(matName);

}

void addTextureShadowDebugOverlay(TrayLocation loc, size_t num)
{
for (size_t i = 0; i < num; ++i)
{
TexturePtr shadowTex = mSceneMgr->getShadowTexture(i);
addTextureDebugOverlay(loc, shadowTex, i);

}

}
"""

def buildDepthShadowMaterial(self, textureName):
matName = "DepthShadows/" + textureName

ret = ogre.MaterialManager.getSingleton().getByName(matName)
if ret.isNull():
baseMat = ogre.MaterialManager.getSingleton().getByName("Ogre/shadow/depth/integrated/pssm")
ret = baseMat.clone(matName)
p = ret.getTechnique(0).getPass(0)
p.getTextureUnitState("diffuse").setTextureName(textureName)

splitPoints = ogre.Vector4()
# XXX: castAsPSSMShadowCameraSetup?
#const PSSMShadowCameraSetup::SplitPointList& splitPointList =
# static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get())->getSplitPoints();
splitPointList = mPSSMSetup.get().getSplitPoints()
for i in range(3):
splitPoints[i] = splitPointList[i]
p.getFragmentProgramParameters().setNamedConstant("pssmSplitPoints", splitPoints)

return ret;

def changeShadows(self):
self.configureShadows(self.shadowMode != NewTerrain.SHADOWS_NONE, self.shadowMode == NewTerrain.SHADOWS_DEPTH)

def configureShadows(self, enabled, depthShadows):
# XXX: castAsSM2Profile?
"""
TerrainMaterialGeneratorA::SM2Profile* matProfile =
static_cast<TerrainMaterialGeneratorA::SM2Profile*>(TerrainGlobalOptions::getDefaultMaterialGenerator()->getActiveProfile());
"""
matProfile = ogreterrain.TerrainGlobalOptions.getDefaultMaterialGenerator().getActiveProfile()
matProfile.setReceiveDynamicShadowsEnabled(enabled);
SHADOWS_IN_LOW_LOD_MATERIAL = True
if SHADOWS_IN_LOW_LOD_MATERIAL:
matProfile.setReceiveDynamicShadowsLowLod(True)
else:
matProfile.setReceiveDynamicShadowsLowLod(False)

for i in self.houseList:
i.setMaterialName("Examples/TudorHouse")

if enabled:
#// General scene setup
self.sceneMgr.setShadowTechnique(ogre.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED)
self.sceneMgr.setShadowFarDistance(3000)

#// 3 textures per directional light (PSSM)
self.sceneMgr.setShadowTextureCountPerLightType(ogre.Light.LT_DIRECTIONAL, 3)

if self.pssmSetup.isNull():
#// shadow camera setup
pssmSetup = ogre.PSSMShadowCameraSetup()
pssmSetup.setSplitPadding(self.camera.getNearClipDistance())
pssmSetup.calculateSplitPoints(3, self.camera.getNearClipDistance(), self.sceneMgr.getShadowFarDistance())
pssmSetup.setOptimalAdjustFactor(0, 2)
pssmSetup.setOptimalAdjustFactor(1, 1)
pssmSetup.setOptimalAdjustFactor(2, 0.5)
self.pssmSetup.bind(pssmSetup);

self.sceneMgr.setShadowCameraSetup(self.pssmSetup)

if depthShadows:
self.sceneMgr.setShadowTextureCount(3)
self.sceneMgr.setShadowTextureConfig(0, 2048, 2048, ogre.PF_FLOAT32_R)
self.sceneMgr.setShadowTextureConfig(1, 1024, 1024, ogre.PF_FLOAT32_R)
self.sceneMgr.setShadowTextureConfig(2, 1024, 1024, ogre.PF_FLOAT32_R)
self.sceneMgr.setShadowTextureSelfShadow(True)
self.sceneMgr.setShadowCasterRenderBackFaces(True)
self.sceneMgr.setShadowTextureCasterMaterial("PSSM/shadow_caster")

houseMat = buildDepthShadowMaterial("fw12b.jpg")
for i in self.houseList:
i.setMaterial(houseMat)

else:
self.sceneMgr.setShadowTextureCount(3)
self.sceneMgr.setShadowTextureConfig(0, 2048, 2048, PF_X8B8G8R8)
self.sceneMgr.setShadowTextureConfig(1, 1024, 1024, PF_X8B8G8R8)
self.sceneMgr.setShadowTextureConfig(2, 1024, 1024, PF_X8B8G8R8)
self.sceneMgr.setShadowTextureSelfShadow(False)
self.sceneMgr.setShadowCasterRenderBackFaces(False)
self.sceneMgr.setShadowTextureCasterMaterial("") # XXX: I'm not sure if it's done right. it was StringUtil::BLANK originally.

matProfile.setReceiveDynamicShadowsDepth(depthShadows)
#matProfile.setReceiveDynamicShadowsPSSM(static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get()))
matProfile.setReceiveDynamicShadowsPSSM(self.pssmSetup.get())

#//addTextureShadowDebugOverlay(TL_RIGHT, 3);

else:
self.sceneMgr.setShadowTechnique(ogre.SHADOWTYPE_NONE)


"""
/*-----------------------------------------------------------------------------
| Extends setupView to change some initial camera settings for this sample.
-----------------------------------------------------------------------------*/
"""
def setupView(self):
self.camera.setPosition(self.terrainPos + ogre.Vector3(1683, 50, 2116))
self.camera.lookAt(ogre.Vector3(1963, 50, 1660))
self.camera.setNearClipDistance(0.1)
self.camera.setFarClipDistance(50000)

if self.root.getRenderSystem().getCapabilities().hasCapability(ogre.RSC_INFINITE_FAR_PLANE):
self.camera.setFarClipDistance(0)# // enable infinite far clip distance if we can

def setupContent(self):
blankTerrain = False
#//blankTerrain = true;

self.editMarker = self.sceneMgr.createEntity("editMarker", "sphere.mesh")
self.editNode = self.sceneMgr.getRootSceneNode().createChildSceneNode()
self.editNode.attachObject(self.editMarker)
self.editNode.setScale(0.05, 0.05, 0.05)

ogre.MaterialManager.getSingleton().setDefaultTextureFiltering(ogre.TFO_ANISOTROPIC)
ogre.MaterialManager.getSingleton().setDefaultAnisotropy(7)

self.sceneMgr.setFog(ogre.FOG_LINEAR, ogre.ColourValue(0.7, 0.7, 0.8), 0, 10000, 25000)

lightdir = ogre.Vector3(0.55, -0.3, 0.75)
lightdir.normalise()


l = self.sceneMgr.createLight("tstLight")
l.setType(ogre.Light.LT_DIRECTIONAL)
l.setDirection(lightdir)
l.setDiffuseColour(ogre.ColourValue(1.0, 1.0, 1.0))
l.setSpecularColour(ogre.ColourValue(0.4, 0.4, 0.4))

self.sceneMgr.setAmbientLight(ogre.ColourValue(0.2, 0.2, 0.2))


self.terrainGroup = ogreterrain.TerrainGroup(self.sceneMgr, ogreterrain.Terrain.ALIGN_X_Z, NewTerrain.TERRAIN_SIZE, NewTerrain.TERRAIN_WORLD_SIZE)
self.terrainGroup.setFilenameConvention(NewTerrain.TERRAIN_FILE_PREFIX, NewTerrain.TERRAIN_FILE_SUFFIX)
self.terrainGroup.setOrigin(self.terrainPos)

self.configureTerrainDefaults(l)
if self.paging:
#// Paging setup
self.pageManager = ogrepaging.PageManager()
#// Since we're not loading any pages from .page files, we need a way just
#// to say we've loaded them without them actually being loaded
self.pageManager.setPageProvider(self.dummyPageProvider)
self.pageManager.addCamera(self.camera)
self.terrainPaging = ogrepaging.TerrainPaging(self.pageManager)
world = self.pageManager.createWorld()
self.terrainPaging.createWorldSection(world, self.terrainGroup, 2000, 3000,
NewTerrain.TERRAIN_PAGE_MIN_X, NewTerrain.TERRAIN_PAGE_MIN_Y,
NewTerrain.TERRAIN_PAGE_MAX_X, NewTerrain.TERRAIN_PAGE_MAX_Y)
else:
x = NewTerrain.TERRAIN_PAGE_MIN_X
while x <= NewTerrain.TERRAIN_PAGE_MAX_X:
while y <= NewTerrain.TERRAIN_PAGE_MAX_Y:
self.defineTerrain(x, y, blankTerrain)
y += 1
x += 1
#// sync load since we want everything in place when we start
self.terrainGroup.loadAllTerrains(True)

if self.terrainsImported:
ti = self.terrainGroup.getTerrainIterator()
while ti.hasMoreElements():
t = ti.getNext().instance
self.initBlendMaps(t)

self.terrainGroup.freeTemporaryResources()



#// create a few entities on the terrain
e = self.sceneMgr.createEntity("tudorhouse.mesh")
entPos = ogre.Vector3(self.terrainPos.x + 2043, 0, self.terrainPos.z + 1715)
rot = ogre.Quaternion()
entPos.y = self.terrainGroup.getHeightAtWorldPosition(entPos) + 65.5
rot.FromAngleAxis(ogre.Degree(random.randrange(-180.0, 180.0, int=float)), ogre.Vector3().UNIT_Y)
sn = self.sceneMgr.getRootSceneNode().createChildSceneNode(entPos, rot)
sn.setScale(Vector3(0.12, 0.12, 0.12))
sn.attachObject(e)
self.houseList += [e]

e = self.sceneMgr.createEntity("tudorhouse.mesh")
entPos = ogre.Vector3(self.terrainPos.x + 1850, 0, self.terrainPos.z + 1478)
rot = ogre.Quaternion()
entPos.y = self.terrainGroup.getHeightAtWorldPosition(entPos) + 65.5
rot.FromAngleAxis(ogre.Degree(random.randrange(-180.0, 180.0, int=float)), ogre.Vector3().UNIT_Y)
sn = self.sceneMgr.getRootSceneNode().createChildSceneNode(entPos, rot)
sn.setScale(Vector3(0.12, 0.12, 0.12))
sn.attachObject(e)
self.houseList += [e]

e = self.sceneMgr.createEntity("tudorhouse.mesh")
entPos = ogre.Vector3(self.terrainPos.x + 1970, 0, self.terrainPos.z + 2180)
rot = ogre.Quaternion()
entPos.y = self.terrainGroup.getHeightAtWorldPosition(entPos) + 65.5
rot.FromAngleAxis(ogre.Degree(random.randrange(-180.0, 180.0, int=float)), ogre.Vector3().UNIT_Y)
sn = self.sceneMgr.getRootSceneNode().createChildSceneNode(entPos, rot)
sn.setScale(Vector3(0.12, 0.12, 0.12))
sn.attachObject(e)
self.houseList += [e]

self.sceneMgr.setSkyBox(True, "Examples/CloudyNoonSkyBox")


class Scene(object):
def __init__(self, gameRoot):
self.gameRoot = gameRoot

def GetOgreSceneManager(self):
return self.sceneManager
def OnGameRootInit(self):
self.ogreRoot = self.gameRoot.GetOgreRoot()
self.sceneManager = self.ogreRoot.createSceneManager(ogre.ST_GENERIC)
#self.sceneManager = self.ogreRoot.createSceneManager(ogre.ST_EXTERIOR_CLOSE)

def CreateCamera():
camera = self.sceneManager.createCamera("PlayerCam")
cameraNode = self.sceneManager.getRootSceneNode().createChildSceneNode("PlayerCamNode")
cameraNode.attachObject(camera)
cameraNode.setFixedYawAxis(True)
camera.setNearClipDistance(2)
camera.setFarClipDistance(1000)

defNodeOrient = cameraNode.getOrientation()
return camera, cameraNode, defNodeOrient


self.gameCamera = GameCamera(self, *CreateCamera())

self.rn = self.sceneManager.getRootSceneNode()

# Set ambient light
self.sceneManager.setAmbientLight(ogre.ColourValue(0.8, 0.8, 0.8))

# Fog
# NB it's VERY important to set this before calling setWorldGeometry
# because the vertex program picked will be different
fadeColour = ogre.ColourValue(0.101, 0.125, 0.1836)
#self.sceneManager.setFog(ogre.FOG_LINEAR, fadeColour, 0.001, 500, 1000)
renderWindow = self.ogreRoot.getAutoCreatedWindow()
renderWindow.getViewport(0).setBackgroundColour(fadeColour)

#terrain_cfg = "terrain.cfg"
#self.sceneManager.setWorldGeometry(terrain_cfg)

self.terrain = NewTerrain(self.sceneManager, self)



def GetTerrain(self):
return self.terrain
def GetCamera(self):
return self.gameCamera
def GetGameRoot(self):
return self.gameRoot
def GetCameraToViewportRay(self, pos_w, pos_h):
return self.gameCamera.camera.getCameraToViewportRay(pos_w, pos_h)
def GetOgreSceneManager(self):
return self.sceneManager


class OgreApplication(object):
app_title = "New Terrain"
def Init(self):
def _InitOgre():
# create root
self.ogreRoot = ogre.Root()

# Read the resources.cfg file and add all resource locations in it
cf = ogre.ConfigFile()
cf.load("resources.cfg")
seci = cf.getSectionIterator()
while seci.hasMoreElements():
secName = seci.peekNextKey()
settings = seci.getNext()

for item in settings:
typeName = item.key
archName = item.value
ogre.ResourceGroupManager.getSingleton().addResourceLocation(archName, typeName, secName)

# Show the config dialog if we don't yet have an ogre.cfg file
if not self.ogreRoot.restoreConfig() and not self.ogreRoot.showConfigDialog():
raise Exception("User canceled config dialog! (setupRenderSystem)")

# createRenderWindow
self.ogreRoot.initialise(True, self.app_title)

# initializeResourceGroups
ogre.TextureManager.getSingleton().setDefaultNumMipmaps(3)
ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()

# initialise event listener
self.eventListener = OgreEventListener(self, self.ogreRoot.getAutoCreatedWindow(), True, True, False)
self.ogreRoot.addFrameListener(self.eventListener)

_InitOgre()
self.gameRoot = GameRoot(self.ogreRoot, self.eventListener)

def Launch(self):
self.Init()
self.ogreRoot.startRendering()

def GetGameRoot(self):
return self.gameRoot

def main():
try:
app = OgreApplication()
app.Launch()
except ogre.OgreException, e:
print e

if __name__ == '__main__':
main()



yubgipenguin

08-01-2010 21:50:43

Oh and other than that, you should be able to subclass TerrainMaterialGenerator and provide it to terrain engine to replace default terrain material..

Is it possible?