#include "TestKdTree.h" #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #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 { // Create application object KdTreeApp app; 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"); mSelectedSceneManager = cfDeath.getSetting("scenemanager"); mSceneFiles = cfDeath.getSetting("scene"); 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"); mRotationPeriod = static_cast(strtod(tmp.c_str(), &errptr)); tmp = cfDeath.getSetting("movespeed"); mMoveSpeed = static_cast(strtod(tmp.c_str(), &errptr)); tmp = cfDeath.getSetting("rotatespeed"); mRotateSpeed = static_cast(strtod(tmp.c_str(), &errptr)); ExampleApplication::setupResources(); } void KdTreeApp::createScene(void) { 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; // load scene from file if (mSceneFiles != "") { // don't load the other stuff loadScene(mSceneFiles); //mCamera->setPosition(Vector3(830, 300, -540)); //mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329)); // total view //mCamera->setPosition(Vector3(688, 866, 944)); //mCamera->setOrientation(Quaternion(-0.979419, 0.201128, 0.0165594, 0.00340038)); mTopCam->setPosition(Vector3(1232, 3990, -1477)); // walkthrough view mCamNode->setPosition(Vector3(1102.56, 181.845, -350.305)); //mCamNode->setOrientation(Quaternion(-0.977321, -0.117497, -0.174903, 0.0210273)); mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true); } else { mCamNode->setPosition(Vector3(1280,600,1666)); mCamNode->setOrientation(Quaternion(0.936893, -0.124586, 0.323813, 0.04306)); //mCamera->lookAt(Vector3(-20,30,10)); 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"); 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"); 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"); 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"); mDeathNode = deathPivotNode->createChildSceneNode("movingNode", Vector3(0, 0, mRotationRadius)/*, Quaternion(Radian(Math::HALF_PI), Vector3::UNIT_Y)*/); mDeathNode->attachObject(movingDeath); Entity *ent_ball = mSceneMgr->createEntity("ball","sphere.mesh"); SceneNode *node_pivot = mDeathNode->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, mDeathNode); } 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()); light->setSpecularColour(ColourValue(1, 1, 0.2)); // Skybox mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", mPlaneDim * 2); } /* Some math tests Plane planeX(Vector3::UNIT_X, Vector3(10,10,10)); Plane planeY(Vector3::UNIT_Y, Vector3(10,10,10)); Plane planeZ(Vector3::UNIT_Z, Vector3(10,10,10)); Vector3 vect(20,20,20); Vector3 interX = planeX.projectVector(vect); Vector3 interY = planeY.projectVector(vect); Vector3 interZ = planeZ.projectVector(vect); std::stringstream ssX, ssY, ssZ; ssX << "The intersection of " << planeX << " and " << vect << " is at: " << interX; ssY << "The intersection of " << planeY << " and " << vect << " is at: " << interY; ssZ << "The intersection of " << planeZ << " and " << vect << " is at: " << interZ; LogManager::getSingleton().logMessage(ssX.str()); LogManager::getSingleton().logMessage(ssY.str()); LogManager::getSingleton().logMessage(ssZ.str()); */ } void KdTreeApp::createFrameListener(void) { mFrameListener = new KdTreeAppListener(mWindow, mSceneMgr, mRotateSpeed, mMoveSpeed, mRotationPeriod); mFrameListener->showDebugOverlay( true ); mRoot->addFrameListener(mFrameListener); mWindow->addListener(new KdTreeAppRenderTargetListener(mSceneMgr)); } void KdTreeApp::chooseSceneManager(void) { // Get the SceneManager mSceneMgr = mRoot->createSceneManager(mSelectedSceneManager,"MySceneManager"); } void KdTreeApp::createCamera(void) { // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); mCamera->setNearClipDistance(1); mCamNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("PlayerCamNode", Vector3(0,0,0)); mCamNode->attachObject(mCamera); // Position it at 500 in Z direction //mCamera->setPosition(Vector3(0,50,500)); //mCamera->setPosition(Vector3(500,256,666)); //mCamera->setPosition(Vector3(1280,600,1666)); // Look back along -Z //mCamera->lookAt(Vector3(0,50,-300)); //mCamera->lookAt(Vector3(-20,30,10)); //mFollowCam = mSceneMgr->createCamera("FollowCam"); //mFollowCam->setPosition(Vector3(800,150,800)); //mFollowCam->setNearClipDistance(5); //mFollowCam->setFOVy(Angle(15)); 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 #ifdef KDTREE_FASTSTART if(mRoot->restoreConfig()) #else if(mRoot->showConfigDialog()) #endif { // 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; } } //----------------------------------------------------------------------- // 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 result = false; 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")) { // hack: set postion manually for vienna //mCamNode->setPosition(Vector3(830, 300, -540)); //mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329)); // load iv files loadSceneIV(fn, mSceneMgr->getRootSceneNode(), i); } result = true; } /* if (result) { int intersectables, faces; std::stringstream d; d << filename << " parsed successfully.\n" << "#NUM_OBJECTS (Total numner of objects)\n" << intersectables << "\n" << "#NUM_FACES (Total numner of faces)\n" << faces << "\n"; } */ return result; } //----------------------------------------------------------------------- bool KdTreeApp::loadSceneIV(const String &filename, SceneNode *root, const int index) { IVReader * mIVReader = new IVReader(); if (1) { 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; } return false; } /**********************************************************************/ /* 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); mSceneMgr->setOption("SkyBoxEnabled", &nShowViz); //mSceneMgr->setOption("SkyPlaneEnabled", &showViz); RenderTargetListener::preViewportUpdate(evt); } //----------------------------------------------------------------------- void KdTreeAppRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt) { // reset values mSceneMgr->setShadowTechnique(mSavedShadowTechnique); mSceneMgr->setAmbientLight(mSavedAmbientLight); RenderTargetListener::postRenderTargetUpdate(evt); }