/** \file SceneContentGenerator.cpp \brief Creates content for a scene. */ #include "OgreSceneContentGenerator.h" // limit for failed attempts to create objects (to avoids infinite loop) #define MAX_FAILED_ATTEMPTS 500000 namespace Ogre { /*************************************************************/ /* SceneContentGenerator implementation */ /*************************************************************/ //----------------------------------------------------------------------- SceneContentGenerator::SceneContentGenerator(SceneManager *sm): mSceneMgr(sm), mMinPos(Vector3(-70.0f, -70.0f, 0.0f)), mMaxPos(Vector3(70.0f, 70.0f, 600.0f)), mMinAngle(Vector3(0.0f, 0.0f, 0.0f)), mMaxAngle(Vector3(360, 360, 360)), mScale(0.1, 0.1, 0.1)//, mObjectCount(0) { } //----------------------------------------------------------------------- void SceneContentGenerator::GenerateScene(int numObjects, const String &objName) { int new_size = GetObjectCount() + numObjects; int failed_attempts = 0; // counter used to avoid invinite loop //-- create random values between zero and one while ((GetObjectCount() < new_size) && (failed_attempts < MAX_FAILED_ATTEMPTS)) { // Setup the ray scene query Vector3 rotation = Vector3(Math::RangeRandom(mMinAngle.x, mMaxAngle.x), Math::RangeRandom(mMinAngle.y, mMaxAngle.y), Math::RangeRandom(mMinAngle.z, mMaxAngle.z)); Vector3 position = Vector3(Math::RangeRandom(mMinPos.x, mMaxPos.x), Math::RangeRandom(mMinPos.y, mMaxPos.y), Math::RangeRandom(mMinPos.z, mMaxPos.z)); // failed to generate new object if (!GenerateSceneObject(position, rotation, objName)) ++ failed_attempts; } } //----------------------------------------------------------------------- SceneNode *SceneContentGenerator::GenerateSceneObject(const Vector3 &position, const Quaternion &orientation, const String& objName) { char name[25]; sprintf(name, "%s Entity%d", objName.c_str(), GetObjectCount()); Entity *ent = mSceneMgr->createEntity(name, objName + ".mesh"); ent->setCastShadows(true); SceneNode *node = mSceneMgr->getRootSceneNode()-> createChildSceneNode(String(name) + "Node", position); //ent->setCastShadows(false); node->attachObject(ent); node->setScale(mScale); node->setOrientation(orientation); // store pointer to node and object mSceneNodes.push_back(node); mEntities.push_back(ent); return node; } //----------------------------------------------------------------------- SceneNode *SceneContentGenerator::GenerateSceneObject(const Vector3 &position, const Vector3 &rotation, const String& objName) { Matrix3 mat; mat.FromEulerAnglesYXZ(Degree(rotation.x), Degree(rotation.y), Degree(rotation.z)); return GenerateSceneObject(position, Quaternion(mat), objName); } //----------------------------------------------------------------------- void SceneContentGenerator::SetMinAngle(Vector3 minAngle) { mMinAngle = minAngle; } //----------------------------------------------------------------------- void SceneContentGenerator::SetMaxAngle(Vector3 maxAngle) { mMaxAngle = maxAngle; } //----------------------------------------------------------------------- void SceneContentGenerator::SetMinPos(Vector3 minPos) { mMinPos = minPos; } //----------------------------------------------------------------------- void SceneContentGenerator::SetMaxPos(Vector3 maxPos) { mMaxPos = maxPos; } //----------------------------------------------------------------------- int SceneContentGenerator::GetObjectCount() { return (int)mSceneNodes.size(); } //----------------------------------------------------------------------- void SceneContentGenerator::SetScale(Vector3 scale) { mScale = scale; } //----------------------------------------------------------------------- bool SceneContentGenerator::WriteObjects(const std::string &filename) { std::ofstream ofstr(filename.c_str()); std::vector::const_iterator it, it_end; it_end = mSceneNodes.end(); if(!ofstr.is_open()) return false; char str[100]; for(it = mSceneNodes.begin(); it < it_end; ++it) { SceneNode *node = (*it); sscanf(node->getName().c_str(), "%s ", str); // write name of mesh ofstr << str << " " << StringConverter::toString(node->getPosition()) << " " << StringConverter::toString(node->getOrientation()) << " " << StringConverter::toString(node->getScale()) << "\n"; } ofstr.close(); return true; } //----------------------------------------------------------------------- bool SceneContentGenerator::LoadObjects(const std::string &filename) { std::ifstream ifstr(filename.c_str()); char line[256]; Vector3 position; Quaternion orientation; char objName[100]; if (!ifstr.is_open()) return false; //mSceneNodes.clear(); // reset list of objects while (!ifstr.eof()) { ifstr.getline(line, 256); sscanf(line, "%s %f %f %f %f %f %f %f %f %f %f", objName, &position.x, &position.y, &position.z, &orientation.w, &orientation.x, &orientation.y, &orientation.z, &mScale.x, &mScale.y, &mScale.z); GenerateSceneObject(position, orientation, objName); //std::stringstream d; d << StringConverter::toString(position) << " " << StringConverter::toString(orientation); //LogManager::getSingleton().logMessage(d.str()); } ifstr.close(); return true; } //----------------------------------------------------------------------- SceneNodeList *SceneContentGenerator::GetGeneratedSceneNodes() { return &mSceneNodes; } //----------------------------------------------------------------------- EntityList *SceneContentGenerator::GetGeneratedEntities() { return &mEntities; } //----------------------------------------------------------------------- void SceneContentGenerator::RemoveGeneratedObjects() { //-- destroy scene nodes and detach entities while (!mSceneNodes.empty()) { SceneNode *node = mSceneNodes.back(); mSceneNodes.pop_back(); //node->detachAllObjects(); mSceneMgr->destroySceneNode(node->getName()); } //-- remove and destroy entities while (!mEntities.empty()) { Entity *ent = mEntities.back(); mEntities.pop_back(); mSceneMgr->destroyEntity(ent); } } } // namespace Ogre