#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #include "TestKdTree.h" #include "WinCmdLineParser.h" #include #ifdef __cplusplus extern "C" { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char *argv[]) #endif { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 // parse windows-style command line WinCmdLineParser cmdparser(strCmdLine); KdTreeAppListener::Options options; try { cmdparser .addOpt("i","infile", ARGUMENT_REQUIRED) .addOpt("o","outfile", ARGUMENT_REQUIRED) .addOpt("l","logfile", ARGUMENT_REQUIRED) .addOpt("d","demomode", ARGUMENT_NONE) .addOpt("","buildmode", ARGUMENT_REQUIRED) .addOpt("","maxdepth", ARGUMENT_REQUIRED) .addOpt("","kt", ARGUMENT_REQUIRED) .addOpt("","ki", ARGUMENT_REQUIRED) .addOpt("r","rendermode", ARGUMENT_REQUIRED) .addOpt("s","scenemgr", ARGUMENT_REQUIRED) .addOpt("","comment", ARGUMENT_REQUIRED) .addOpt("e","enhancevis", ARGUMENT_NONE) .addOpt("","savesceneto", ARGUMENT_REQUIRED) .addOpt("f","faststart", ARGUMENT_NONE) .addOpt("b","burnin", ARGUMENT_NONE) .addOpt("v","viewcells", ARGUMENT_OPTIONAL) .addOpt("","nodelrq", ARGUMENT_NONE); cmdparser.getOpt("i", options.mDemoInfileName); cmdparser.getOpt("o", options.mDemoOutfileName); cmdparser.getOpt("l", options.mDemoLogfileName); cmdparser.getOpt("comment", options.mComment); options.mDelRenderQueue = !cmdparser.getOpt("nodelrq"); options.mFastStart = cmdparser.getOpt("f"); options.mBurnIn = cmdparser.getOpt("b"); options.mDemoMode = cmdparser.getOpt("d"); options.mEnhancedVisibility = cmdparser.getOpt("e"); cmdparser.getOpt("savesceneto", options.mSceneOutfileName); std::string tmp; std::stringstream s; if (cmdparser.getOpt("buildmode", tmp)) { int bm = KdTree::KDBM_NOTSET; for (int i = 0; i < KdTree::KDBM_SIZE; i ++) { if (tmp == KdTreeAppListener::BUILDMETHOD[i]) bm = i; } if (bm != KdTree::KDBM_NOTSET) { options.mBuildMethod = bm; } else { MessageBox(NULL, ("Invalid argument for option --buildmode: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR ); return -1; } } if (cmdparser.getOpt("maxdepth", tmp)) { s << tmp; s >> options.mMaxDepth; s.clear(); } if (cmdparser.getOpt("kt", tmp)) { s << tmp; s >> options.mKT; s.clear(); } if (cmdparser.getOpt("ki", tmp)) { s << tmp; s >> options.mKI; s.clear(); } if (cmdparser.getOpt("r",tmp)) { int rm = KdTree::KDRM_NOTSET; for (int i = 0; i < KdTree::KDRM_SIZE; i ++) { if (tmp == KdTreeAppListener::RENDERMETHOD[i]) rm = i; } if (rm != KdTree::KDRM_NOTSET) { options.mRenderMethod = rm; } else { MessageBox(NULL, ("Invalid argument for option --rendermode: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR ); return -1; } } if (cmdparser.getOpt("s",tmp)) { int sm = KdTreeAppListener::SM_NOTSET; for (int i = 0; i < KdTreeAppListener::SM_SIZE; i ++) { if (tmp == KdTreeAppListener::SCENEMANAGER[i]) sm = i; } if (sm != KdTreeAppListener::SM_NOTSET) { options.mSceneManager = sm; } else { MessageBox(NULL, ("Invalid argument for option --scenemgr: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR ); return -1; } } if (cmdparser.getOpt("v",tmp)) { if (tmp == "0") options.mViewCells = KdTreeAppListener::VCM_OFF; else if (tmp == "" || tmp == "1") options.mViewCells = KdTreeAppListener::VCM_ON; else if (tmp == "2") options.mViewCells = KdTreeAppListener::VCM_FILTER; else { MessageBox(NULL, ("Invalid argument for option --viewcells: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR ); return -1; } } } catch (std::string s) { MessageBox(NULL, s.c_str(), "Error", MB_OK | MB_ICONERROR ); return -1; } // Create application object KdTreeApp app(options); #else // TODO: unix-style getopt // Create application object KdTreeApp app; #endif SET_TERM_HANDLER; // init random number generator // srand(time(0)); try { app.go(); } catch( Ogre::Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl; #endif } return 0; } #ifdef __cplusplus } #endif #define ENT_GRID 0x01 #define ENT_RND 0x02 #define ENT_SPC 0x04 #define ENT_MOV 0x08 #define ENT_PLN 0x10 void KdTreeApp::setupResources(void) { String tmp; ConfigFile cfDeath; char *errptr; int base = 10; cfDeath.load("testKdTree.cfg"); mSceneFiles = cfDeath.getSetting("scene"); mViewCells = cfDeath.getSetting("viewcells"); tmp = cfDeath.getSetting("shadows"); StringUtil::toLowerCase(tmp); if (tmp == "on") mShadowsEnabled = true; else mShadowsEnabled = false; tmp = cfDeath.getSetting("planedim"); mPlaneDim = static_cast(strtod(tmp.c_str(), &errptr)); tmp = cfDeath.getSetting("randomcount"); mRandomCount = static_cast(strtol(tmp.c_str(), &errptr, base)); tmp = cfDeath.getSetting("selectentities"); mSelectEntities = static_cast(strtol(tmp.c_str(), &errptr, base)); tmp = cfDeath.getSetting("count"); mModelCount = static_cast(strtol(tmp.c_str(), &errptr, base)); tmp = cfDeath.getSetting("spacing"); mModelSpacing = static_cast(strtol(tmp.c_str(), &errptr, base)); tmp = cfDeath.getSetting("radius"); mRotationRadius = static_cast(strtod(tmp.c_str(), &errptr)); tmp = cfDeath.getSetting("period"); mOptions.mRotationPeriod = static_cast(strtod(tmp.c_str(), &errptr)); tmp = cfDeath.getSetting("movespeed"); mOptions.mMoveSpeed = static_cast(strtod(tmp.c_str(), &errptr)); tmp = cfDeath.getSetting("rotatespeed"); mOptions.mRotateSpeed = static_cast(strtod(tmp.c_str(), &errptr)); // command line has preference over config file if (mOptions.mDemoInfileName.empty()) mOptions.mDemoInfileName = cfDeath.getSetting("demoinfile"); if (mOptions.mDemoOutfileName.empty()) mOptions.mDemoOutfileName = cfDeath.getSetting("demooutfile"); if (mOptions.mDemoLogfileName.empty()) mOptions.mDemoLogfileName = cfDeath.getSetting("demologfile"); ExampleApplication::setupResources(); } void KdTreeApp::createScene(void) { createMaterials(); // load simple scene (planes & robots) if (mSceneFiles == "") { createSimpleScene(); mOptions.mSceneType = KdTreeAppListener::ST_SIMPLE; mCamNode->setPosition(Vector3(1280,600,1666)); mCamNode->setOrientation(Quaternion(0.936893, -0.124586, 0.323813, 0.04306)); } //// load terrain, but only if terrainscenemanager selected //else if (mSceneFiles == TERRAIN_SCENE) //{ // Plane waterPlane; // // Set ambient light // mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // // Create a light // Light* l = mSceneMgr->createLight("MainLight"); // // Accept default settings: point light, white diffuse, just set position // // NB I could attach the light to a SceneNode if I wanted it to move automatically with // // other objects, but I don't // l->setPosition(20,80,50); // // Fog // // NB it's VERY important to set this before calling setWorldGeometry // // because the vertex program picked will be different // //ColourValue fadeColour(0.93, 0.86, 0.76); // //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000); // //mWindow->getViewport(0)->setBackgroundColour(fadeColour); // mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue); // std::string terrain_cfg("terrain.cfg"); // mSceneMgr -> setWorldGeometry( terrain_cfg ); // // Define the required skyplane // Plane plane; // // 5000 world units from the camera // plane.d = 5000; // // Above the camera, facing down // plane.normal = -Vector3::UNIT_Y; // // read interesting params from config file // ConfigFile terrainconf; // std::stringstream s; // Real x,y,z; // // terrainconf.load(terrain_cfg); // s << terrainconf.getSetting("PageWorldX"); // s >> x; // s.clear(); // s << terrainconf.getSetting("MaxHeight"); // s >> y; // s.clear(); // s << terrainconf.getSetting("PageWorldZ"); // s >> z; // s.clear(); // // add stuff minus gound plane // createTerrainScene(x, y + 1500, z); // // Set a nice viewpoint // mCamNode->setPosition(707,2500,528); // mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329)); // //mCamNode->setPosition(1056.59, 467.412, 783.502); // //mCamNode->setOrientation(Quaternion(-0.281354, 0.0204027, 0.956747, 0.0695345)); //} // load scene from file else { // don't load the other stuff loadScene(mSceneFiles); if (mOptions.mSceneType == KdTreeAppListener::ST_GEOMETRY) { // initial position mCamNode->setPosition(Vector3(827.885, 184.435, -524.984)); mCamNode->setOrientation(Quaternion(0.98935, 0.0348082, -0.141246, 0.00496945)); // initial position for vis camera mTopCam->setPosition(Vector3(1232, 3990, -1477)); //// try loading view cells if specified and if scene manager supports it //if (!mViewCells.empty()) // mSceneMgr->setOption("LoadViewCells", mViewCells.c_str()); // sky box mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true); } else if (mOptions.mSceneType == KdTreeAppListener::ST_TERRAIN) { // initial position mCamNode->setPosition(707,2500,528); mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329)); // sky box mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", mPlaneDim * 2); } } } // fill terrain with robots, spaceships & whatever void KdTreeApp::createTerrainScene(Real max_x, Real max_y, Real max_z) { Vector3 scale(0.3, 0.3, 0.3); Entity *deaths; SceneNode *nodes, *anchor; std::string entName; std::string nodeName; int i; Real min_x = 100, min_y = 0, min_z = 100; max_x -= 100; max_z -= 100; try { anchor = mSceneMgr->getSceneNode("AnchorNode"); } catch (Exception) { anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode"); } if (mSelectEntities & ENT_RND) { entName = "randomdeath"; nodeName = "RandomDeathNode"; for (i = 0; i < mRandomCount; i++) { Vector3 pos = clampToGround(Vector3( Math::RangeRandom(min_x, max_x), max_y, Math::RangeRandom(min_z, max_z)), 0, max_y); // hack to fill valleys if (pos == Vector3::ZERO) { -- i; continue; } deaths = mSceneMgr->createEntity(cat(entName,666,i),"robot.mesh"); if (mShadowsEnabled) deaths->setCastShadows(true); nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos, Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y)); nodes->attachObject(deaths); nodes->setScale(scale); } } // added by matt //mSceneMgr->setOption("RebuildBiHierarchy", NULL); if (mSelectEntities & ENT_SPC) { entName = "randomspaceship"; nodeName = "RandomSpaceshipNode"; for (i = 0; i < mRandomCount; i++) { Vector3 pos = clampToGround(Vector3( Math::RangeRandom(min_x, max_x), max_y, Math::RangeRandom(min_z, max_z)), Math::RangeRandom(20, 500), max_y); // hack to fill valleys if (pos == Vector3::ZERO) { -- i; continue; } deaths = mSceneMgr->createEntity(cat(entName,666,i),"razor.mesh"); if (mShadowsEnabled) deaths->setCastShadows(true); nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos, Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y)); nodes->attachObject(deaths); nodes->setScale(scale); } } if (mSelectEntities & ENT_MOV) { Entity *movingDeath = mSceneMgr->createEntity("movingDeath","robot.mesh"); if (mShadowsEnabled) movingDeath->setCastShadows( true ); SceneNode *deathPivotNode = mSceneMgr->getRootSceneNode()-> createChildSceneNode("deathPivotNode", Vector3((min_x + max_x)/2,0,(min_z + max_z)/2)); mMoveNode = deathPivotNode->createChildSceneNode("movingNode", Vector3(0, 0, mRotationRadius) /*,Quaternion(Radian(Math::HALF_PI), Vector3::UNIT_Y)*/); mMoveNode->attachObject(movingDeath); mMoveNode->setScale(scale); Entity *ent_ball = mSceneMgr->createEntity("ball","sphere.mesh"); SceneNode *node_pivot = mMoveNode->createChildSceneNode("pivotNode"); SceneNode *node_ball = node_pivot->createChildSceneNode("orbitNode", Vector3(120, 40, 0)); node_ball->attachObject(ent_ball); node_ball->setScale(scale/10); } } void KdTreeApp::createSimpleScene() { Entity *deaths; SceneNode *nodes; std::string entName = "death"; std::string nodeName = "DeathNode"; int i, j, x, z; Real planeHalf = mPlaneDim / 2; Real planeThreeEights = mPlaneDim * 3 / 8; Real planeSixth = mPlaneDim / 6; SceneNode *anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode"); //SceneNode *grndan = anchor->createChildSceneNode("GroundAnchor"); SceneNode *grndan = mSceneMgr->getRootSceneNode(); if (mSelectEntities & ENT_GRID) { for (j = 0, z = -(mModelCount / 2 * mModelSpacing); j < mModelCount; j++, z += mModelSpacing) { for (i = 0, x = -(mModelCount / 2 * mModelSpacing); i < mModelCount; i++, x += mModelSpacing) { deaths = mSceneMgr->createEntity(cat(entName, i, j).c_str(),"robot.mesh"); //deaths = mSceneMgr->createEntity(cat(entName, i, j).c_str(),"cube.mesh"); if (mShadowsEnabled) deaths->setCastShadows(true); nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName, i, j).c_str(), Vector3(x, 0 , z)); nodes->attachObject(deaths); } } } if (mSelectEntities & ENT_RND) { entName = "randomdeath"; nodeName = "RandomDeathNode"; for (i = 0; i < mRandomCount; i++) { Vector3 pos( Math::RangeRandom(-planeHalf,-planeSixth), 0, Math::RangeRandom(-planeThreeEights, planeThreeEights)); deaths = mSceneMgr->createEntity(cat(entName,666,i),"robot.mesh"); //deaths = mSceneMgr->createEntity(cat(entName,666,i),"cube.mesh"); if (mShadowsEnabled) deaths->setCastShadows(true); nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos, Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y)); nodes->attachObject(deaths); } } if (mSelectEntities & ENT_SPC) { entName = "randomspaceship"; nodeName = "RandomSpaceshipNode"; for (i = 0; i < mRandomCount; i++) { Vector3 pos( //Math::RangeRandom(-planeHalf,-planeSixth), Math::RangeRandom(planeSixth,planeHalf), Math::RangeRandom(planeHalf * 0.1, planeHalf), Math::RangeRandom(-planeThreeEights, planeThreeEights)); deaths = mSceneMgr->createEntity(cat(entName,666,i),"razor.mesh"); //deaths = mSceneMgr->createEntity(cat(entName,666,i),"cube.mesh"); if (mShadowsEnabled) deaths->setCastShadows(true); nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos, Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y)); nodes->attachObject(deaths); } } if (mSelectEntities & ENT_MOV) { Entity *movingDeath = mSceneMgr->createEntity("movingDeath","robot.mesh"); if (mShadowsEnabled) movingDeath->setCastShadows( true ); SceneNode *deathPivotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("deathPivotNode"); mMoveNode = deathPivotNode->createChildSceneNode("movingNode", Vector3(0, 0, mRotationRadius)/*, Quaternion(Radian(Math::HALF_PI), Vector3::UNIT_Y)*/); mMoveNode->attachObject(movingDeath); Entity *ent_ball = mSceneMgr->createEntity("ball","sphere.mesh"); SceneNode *node_pivot = mMoveNode->createChildSceneNode("pivotNode"); SceneNode *node_ball = node_pivot->createChildSceneNode("orbitNode", Vector3(120, 40, 0)); node_ball->attachObject(ent_ball); node_ball->scale(0.1, 0.1, 0.1); //mFollowCam->setAutoTracking(true, mMoveNode); } if (mSelectEntities & ENT_PLN) { Plane ground(Vector3::UNIT_Y, 0); MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, ground, mPlaneDim * 4 / 3, mPlaneDim, 20, 20, true, 1, 20, 20, Vector3::UNIT_Z); Entity *ent_ground = mSceneMgr->createEntity("GroundEntity", "ground"); ent_ground->setCastShadows(false); ent_ground->setMaterialName("Examples/RustySteel");//("Examples/Rockwall"); SceneNode *node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode", Vector3(0, 0, 0)); node_ground->attachObject(ent_ground); //MeshManager::getSingleton().createPlane("ground2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, // ground, mPlaneDim/2, mPlaneDim, 10, 20, true, 1, 10, 20, Vector3::UNIT_Z); //ent_ground = mSceneMgr->createEntity("GroundEntity2", "ground2"); //ent_ground->setCastShadows(false); //ent_ground->setMaterialName("Examples/RustySteel"); //node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode2", Vector3(-mPlaneDim/4, 0, 0)); //node_ground->attachObject(ent_ground); } // Lights mSceneMgr->setAmbientLight(ColourValue(0.1,0.1,0.1)); Light *light = mSceneMgr->createLight("light"); if (mShadowsEnabled) { mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); light->setType(Light::LT_POINT); light->setPosition(Vector3(x, 300, z + 200)); } else { light->setType(Light::LT_DIRECTIONAL); light->setDirection(-1,-1,-1); } light->setDiffuseColour(ColourValue::White); light->setSpecularColour(ColourValue(1, 1, 0.2)); // Skybox mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", mPlaneDim * 2); } void KdTreeApp::createFrameListener(void) { // set pointer to self in options mOptions.myApp = this; mFrameListener = new KdTreeAppListener(mWindow, mSceneMgr, mOptions); //mFrameListener->showDebugOverlay( true ); mRoot->addFrameListener(mFrameListener); mRenderTargerListener = new KdTreeAppRenderTargetListener(mSceneMgr); mWindow->addListener(mRenderTargerListener); } void KdTreeApp::chooseSceneManager(void) { // Get the SceneManager mOptions.mSceneManager=3; //changed cse mSceneMgr = mRoot->createSceneManager( KdTreeAppListener::SCENEMANAGERNAME[mOptions.mSceneManager], "MySceneManager"); // set params for kdtree scene manager if (mOptions.mSceneManager == KdTreeAppListener::SM_KDT || mOptions.mSceneManager == KdTreeAppListener::SM_KTE || mOptions.mSceneManager == KdTreeAppListener::SM_BVH || mOptions.mSceneManager == KdTreeAppListener::SM_BIH ) { mSceneMgr->setOption("BuildMethod", &mOptions.mBuildMethod); mSceneMgr->setOption("KdTreeMaxDepth", &mOptions.mMaxDepth); mSceneMgr->setOption("KT", &mOptions.mKT); mOptions.mKI=20; mSceneMgr->setOption("KI", &mOptions.mKI); mSceneMgr->setOption("RenderMethod", &mOptions.mRenderMethod); mSceneMgr->setOption("EnhancedVisibility", &mOptions.mEnhancedVisibility); bool show=true; mSceneMgr->setOption("ShowBiHierarchy", &show); mSceneMgr->setOption("ShowAllBoxes", &show); } // set algorithm when scene manager is OCM - numbering is different though else if (mOptions.mSceneManager == KdTreeAppListener::SM_OCM) { int alg = CONV_KDT_TO_OCM_ALG(mOptions.mRenderMethod); mSceneMgr->setOption("Algorithm", &alg); } bool vizcullnodes = true; mSceneMgr->setOption("VisualizeCulledNodes", &vizcullnodes); mSceneMgr->setOption("DeleteRenderQueue", &mOptions.mDelRenderQueue); // fix //bool depthpass = true; //mSceneMgr->setOption("UseDepthPass", &depthpass); // create ray query for ground intersection mRaySceneQuery = mSceneMgr->createRayQuery( Ray(Vector3::ZERO, Vector3::NEGATIVE_UNIT_Y)); } void KdTreeApp::createCamera(void) { // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); mCamera->setNearClipDistance(1); SceneNode *TempNode=mSceneMgr->getRootSceneNode();//->createChildSceneNode("PlayerCamNode", Vector3(0,0,0)); printf("TempNode: %d\n",TempNode); mCamNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("PlayerCamNode", Vector3(0,0,0)); mCamNode->attachObject(mCamera); // Position it at 500 in Z direction mTopCam = mSceneMgr->createCamera("TopCam"); mTopCam->setPosition(Vector3(0,mPlaneDim * 1.25,0)); mTopCam->setDirection(0,0,-1); mTopCam->pitch(Radian(-Math::HALF_PI)); mTopCam->setCullingFrustum(mCamera); mTopCam->setNearClipDistance(1); // infinite far plane? if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) { mTopCam->setFarClipDistance(0); mCamera->setFarClipDistance(0); } else { mTopCam->setFarClipDistance(20000); mCamera->setFarClipDistance(20000); } } void KdTreeApp::createViewports(void) { // Create one viewport, entire window Viewport* vp = mWindow->addViewport(mCamera); vp->setBackgroundColour(ColourValue(0,0,100)); // Alter the camera aspect ratio to match the viewport mCamera->setAspectRatio( Real(vp->getActualWidth()) / Real(vp->getActualHeight())); /* Viewport* fvp = mWindow->addViewport(mFollowCam,2,0.75,0.75,0.25,0.25); fvp->setBackgroundColour(ColourValue(100,0,0)); fvp->setOverlaysEnabled( false ); mFollowCam->setAspectRatio( Real(fvp->getActualWidth()) / Real(fvp->getActualHeight())); */ } bool KdTreeApp::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 bool cont = false; if (mOptions.mFastStart) cont = mRoot->restoreConfig(); else cont = mRoot->showConfigDialog(); if (cont) { // 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; } } void KdTreeApp::createMaterials() { MaterialPtr mat; Technique * tech; Pass * pass; TextureUnitState * tex; // create play button mat = MaterialManager::getSingleton().getByName("KdTree/DemoPlayButton"); if (mat.isNull()) mat = MaterialManager::getSingleton().create("KdTree/DemoPlayButton", "General"); mat->setLightingEnabled(false); tech = mat->getTechnique(0); tech->setSceneBlending(SBT_TRANSPARENT_ALPHA); tech->setDepthCheckEnabled(false); pass = tech->getPass(0); tex = pass->createTextureUnitState(); tex->setTextureName("DemoPlayButton.png"); // create record button mat = MaterialManager::getSingleton().getByName("KdTree/DemoRecordButton"); if (mat.isNull()) mat = MaterialManager::getSingleton().create("KdTree/DemoRecordButton", "General"); mat->setLightingEnabled(false); tech = mat->getTechnique(0); tech->setSceneBlending(SBT_TRANSPARENT_ALPHA); tech->setDepthCheckEnabled(false); pass = tech->getPass(0); tex = pass->createTextureUnitState(); tex->setTextureName("DemoRecordButton.png"); } Vector3 KdTreeApp::clampToGround(const Vector3& vect, Real offset, Real cap) { static Ray updateRay; static Vector3 result; result = vect; if (mOptions.mSceneType == KdTreeAppListener::ST_TERRAIN) { updateRay.setOrigin(vect); updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y); mRaySceneQuery->setRay(updateRay); RaySceneQueryResult& qryResult = mRaySceneQuery->execute(); RaySceneQueryResult::iterator i = qryResult.begin(); if (i != qryResult.end() && i->worldFragment) { SceneQuery::WorldFragment* wf = i->worldFragment; result.y = wf->singleIntersection.y; } } else { updateRay.setOrigin(vect); updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y); mRaySceneQuery->setRay(updateRay); RaySceneQueryResult& qryResult = mRaySceneQuery->execute(); RaySceneQueryResult::iterator i = qryResult.begin(); while (i != qryResult.end() && i->movable) { if (i->movable->getName() != "PlayerCam") { MovableObject *mov = i->movable; result.y = mov->getWorldBoundingBox().getCenter().y; break; } i++; } } // hack to fill the valleys only - make cap lower than max height if (result.y >= cap) return Vector3::ZERO; result.y = result.y + offset > cap ? cap : result.y + offset; return result; } //----------------------------------------------------------------------- // splits strings containing multiple file names static int splitFilenames(const std::string str, std::vector &filenames) { int pos = 0; while(1) { int npos = (int)str.find(';', pos); if (npos < 0 || npos - pos < 1) break; filenames.push_back(std::string(str, pos, npos - pos)); pos = npos + 1; } filenames.push_back(std::string(str, pos, str.size() - pos)); return (int)filenames.size(); } bool KdTreeApp::loadScene(const String &filename) { // use leaf nodes of the original spatial hierarchy as occludees std::vector filenames; int files = splitFilenames(filename, filenames); std::stringstream d; d << "number of input files: " << files << "\n"; LogManager::getSingleton().logMessage(d.str()); bool loadres = false; bool result = filenames.empty() ? false : true; std::vector::const_iterator fit, fit_end = filenames.end(); int i = 0; // root for different files for (fit = filenames.begin(); fit != fit_end; ++ fit, ++ i) { const std::string fn = *fit; if (strstr(fn.c_str(), ".iv") || strstr(fn.c_str(), ".wrl")) { // load iv files loadres = loadSceneIV(fn, mSceneMgr->getRootSceneNode(), i); mOptions.mSceneType = KdTreeAppListener::ST_GEOMETRY; } else if (strstr(fn.c_str(), ".cfg")) { // load terrain from cfg loadres = loadSceneCfg(fn, mSceneMgr->getRootSceneNode(), i); mOptions.mSceneType = KdTreeAppListener::ST_TERRAIN; } else if (strstr(fn.c_str(), ".txt")) { // load entities form text file loadres = loadSceneASCII(fn, mSceneMgr->getRootSceneNode(), i); } else { loadres = false; } // result is true only if all files have been succesfully loaded result = result ? loadres : false; } return result; } //----------------------------------------------------------------------- bool KdTreeApp::loadSceneIV(const String &filename, SceneNode *root, const int index) { IVReader * mIVReader = new IVReader(); if (0) { String logFilename = "IVLog" + Ogre::StringConverter().toString(index) + ".log"; Log *log = LogManager::getSingleton().createLog(logFilename); mIVReader->setLog(log); } //viennaNode->translate(Vector3(-300, -300, 0)); if (mIVReader->loadFile(filename.c_str())) { SceneNode *node = root->createChildSceneNode("IVSceneNode" + index); mIVReader->buildTree(mSceneMgr, node); mIVReader->collapse(); OGRE_DELETE(mIVReader); return true; } else { OGRE_DELETE(mIVReader); return false; } } //----------------------------------------------------------------------- bool KdTreeApp::loadSceneCfg(const String &filename, SceneNode *root, const int index) { // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // Create a light Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50); // try to load world geometry defined in the cfg file mSceneMgr -> setWorldGeometry( filename ); // return true since we have no feedback from setWorldGeometry return true; } #define MAX_BUF_SIZE 1024 //----------------------------------------------------------------------- bool KdTreeApp::loadSceneASCII(const String &filename, SceneNode *root, const int index) { typedef std::map EntMeshMap; typedef std::vector Line; std::ifstream read; read.open(filename.c_str()); if (read.is_open()) { char buf[MAX_BUF_SIZE]; Line line; std::stringstream s; std::string node, ent, mesh; Vector3 pos; Quaternion or; Vector3 scale; int count; EntMeshMap emm; // the node which is parent to all entities SceneNode *anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode"); while (!read.eof()) { line.clear(); memset(buf, 0, MAX_BUF_SIZE); read.getline(buf, MAX_BUF_SIZE); splitFilenames(std::string(buf), line); if (line.size() < 5) continue; // see if node not empty s << line[4]; s >> count; s.clear(); if (count > 0) { // read info node = line[0]; s << line[1]; s >> pos.x >> pos.y >> pos.z; s.clear(); s << line[2]; s >> or.w >> or.x >> or.y >> or.z; s.clear(); s << line[3]; s >> scale.x >> scale.y >> scale.z; s.clear(); for (int i = 5; i < 5 + count; i ++) { s << line[i]; s >> ent >> mesh; s.clear(); emm[ent] = mesh; } // build node //SceneNode *newnode = anchor->createChildSceneNode(node, pos, or); SceneNode *newnode = anchor->createChildSceneNode(node); for (EntMeshMap::iterator emmit = emm.begin(); emmit != emm.end(); emmit ++) { Entity * entity = mSceneMgr->createEntity(emmit->first, emmit->second); newnode->attachObject(entity); } newnode->setPosition(pos); newnode->setOrientation(or); newnode->setScale(scale); emm.clear(); } } return true; } else { return false; } } //----------------------------------------------------------------------- bool KdTreeApp::saveSceneASCII(const String& filename, SceneNode *entityroot) { // find all entities under node entityroot and store their name, position //and orientation to a test file std::ofstream write; write.open(filename.c_str()); if (write.is_open()) { NodeList list; addNodesToList(entityroot, list); std::string fs = ";", rs = "\n"; std::string entnames; int entcount; for (NodeList::iterator it = list.begin(); it != list.end(); it ++) { // fist dump info about node (name, position, orientation, scale) SceneNode * node = *it; write << node->getName() << fs << StringConverter::toString(node->getPosition()) << fs << StringConverter::toString(node->getOrientation()) << fs << StringConverter::toString(node->getScale()) << fs; entcount = 0; entnames = ""; SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator(); while (objIt.hasMoreElements()) { MovableObject *movable = objIt.getNext(); if (movable->getMovableType() == "Entity") { Entity *ent = static_cast(movable); entcount++; entnames += fs + ent->getName() + " " + ent->getMesh()->getName(); } } // now dump entity count and names write << entcount << entnames << rs; } write.close(); return true; } else { return false; } } void KdTreeApp::addNodesToList(SceneNode* node, NodeList& list) { //// check if node has entities //bool entfound = false; //SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator(); //while (objIt.hasMoreElements()) //{ // MovableObject *movable = objIt.getNext(); // if (movable->getMovableType() == "Entity") // entfound = true; //} //// if yes, add to list //if (entfound) list.push_back(node); // check if node has children and add them to list SceneNode::ChildNodeIterator childIt = node->getChildIterator(); while (childIt.hasMoreElements()) { SceneNode *child = static_cast(childIt.getNext()); addNodesToList(child, list); } } /**********************************************************************/ /* VisualizationRenderTargetListener implementation */ /**********************************************************************/ //----------------------------------------------------------------------- KdTreeAppRenderTargetListener::KdTreeAppRenderTargetListener(SceneManager *sceneMgr) :RenderTargetListener(), mSceneMgr(sceneMgr) { } //----------------------------------------------------------------------- void KdTreeAppRenderTargetListener::preViewportUpdate(const RenderTargetViewportEvent &evt) { // visualization viewport const bool showViz = evt.source->getZOrder() == VIZ_VIEWPORT_Z_ORDER; const bool nShowViz = !showViz; mSavedShadowTechnique = mSceneMgr->getShadowTechnique(); mSavedAmbientLight = mSceneMgr->getAmbientLight(); // -- ambient light must be full for visualization, shadows disabled if (showViz) { mSceneMgr->setAmbientLight(ColourValue(1, 1, 1)); mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); } mSceneMgr->setOption("PrepareVisualization", &showViz); SceneNode * skybox = mSceneMgr->getSkyBoxNode(); if (skybox != 0) mSceneMgr->setOption("SkyBoxEnabled", &nShowViz); //if ((SceneNode * skyplane = mSceneMgr->getSkyPlaneNode()) != 0) // mSceneMgr->setOption("SkyPlaneEnabled", &showViz); RenderTargetListener::preViewportUpdate(evt); } //----------------------------------------------------------------------- void KdTreeAppRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt) { // reset values mSceneMgr->setShadowTechnique(mSavedShadowTechnique); mSceneMgr->setAmbientLight(mSavedAmbientLight); RenderTargetListener::postRenderTargetUpdate(evt); }