#include "OgreTerrainContentGenerator.h" namespace Ogre { /*************************************************/ /* RayQueryExecutor implementation */ /*************************************************/ //----------------------------------------------------------------------- RayQueryExecutor::RayQueryExecutor(SceneManager *sm) { mRaySceneQuery = sm->createRayQuery(Ray()); } //----------------------------------------------------------------------- RayQueryExecutor::~RayQueryExecutor() { OGRE_DELETE(mRaySceneQuery); } //----------------------------------------------------------------------- bool RayQueryExecutor::executeRayQuery(Vector3 *result, const Vector3 &pos, const Vector3 &dir) { return executeRayQuery(result, Ray(pos, dir)); } //----------------------------------------------------------------------- bool RayQueryExecutor::executeRayQuery(Vector3 *result, const Ray &ray) { mRaySceneQuery->setRay(ray); // Perform the scene query RaySceneQueryResult &queryResult = mRaySceneQuery->execute(); RaySceneQueryResult::iterator it = queryResult.begin(); if (it != queryResult.end() && it->worldFragment) { SceneQuery::WorldFragment* wf = it->worldFragment; *result = wf->singleIntersection; return true; } return false; } /*******************************************************/ /* TerrainContentGenerator implementation */ /*******************************************************/ //----------------------------------------------------------------------- TerrainContentGenerator::TerrainContentGenerator(SceneManager *sm): SceneContentGenerator(sm), mOffset(0) { mMinPos = Vector3(0.0f, MAX_HEIGHT, 0.0f); mMaxPos = Vector3(3000.0f, MAX_HEIGHT, 3000.0f); mMinAngle = Vector3(0.0f, 0.0f, 0.0f); mMaxAngle = Vector3(360.0f, 0.0f, 0.0f); mRayQueryExecutor = new RayQueryExecutor(sm); } //----------------------------------------------------------------------- TerrainContentGenerator::~TerrainContentGenerator() { delete mRayQueryExecutor; } //----------------------------------------------------------------------- SceneNode *TerrainContentGenerator::GenerateSceneObject(const Vector3 &position, const Vector3 &rotation, const String& objName, const bool clampToTerrain) { if (clampToTerrain) return GenerateSceneObject(position, rotation, objName); return SceneContentGenerator::GenerateSceneObject(position, rotation, objName); } //----------------------------------------------------------------------- SceneNode *TerrainContentGenerator::GenerateSceneObject(const Vector3 &position, const Vector3 &rotation, const String& objName) { Vector3 queryResult; // set y to max height so we are sure to be over terrain Vector3 pos(position.x, MAX_HEIGHT, position.z); if (mRayQueryExecutor->executeRayQuery(&queryResult, position, Vector3::NEGATIVE_UNIT_Y)) { // reject if height is too high if (queryResult.y < mMaxPos.y) { // add offset so object is over terrain queryResult.y += mOffset; return SceneContentGenerator::GenerateSceneObject(queryResult, rotation, objName); } } return NULL; } //----------------------------------------------------------------------- void TerrainContentGenerator::SetOffset(Real offset) { mOffset = offset; } } // namespace Ogre