void App::UpdThr() { Ogre::Timer gtim; //#ifdef _WIN32 //DWORD af = 2; //gtim.setOption("QueryAffinityMask", &af); //#endif gtim.reset(); while (!mShutDown) { /// step Game ** double dt = double(gtim.getMicroseconds()) * 0.000001; gtim.reset(); if (pSet->multi_thr == 1 && !bLoading) { bSimulating = true; bool ret = pGame->OneLoop(dt); if (!ret) mShutDown = true; DoNetworking(); bSimulating = false; } boost::this_thread::sleep(boost::posix_time::milliseconds(pSet->thread_sleep)); } }
void Application::initializeCEGUI() { Ogre::Timer timer; timer.reset(); CEGUI::OgreRenderer::bootstrapSystem(*mOgreWindow); mUIRoot = static_cast<CEGUI::GUISheet*>(CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "Root")); mUIRoot->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0), CEGUI::UDim(0, 0))); mUIRoot->setSize(CEGUI::UVector2(CEGUI::UDim(1, 0), CEGUI::UDim(1, 0))); mUIRoot->setVisible(true); CEGUI::System::getSingleton().setGUISheet(mUIRoot); CEGUI::SchemeManager::getSingleton().create("OISBDemo.scheme"); CEGUI::System::getSingleton().setDefaultMouseCursor("OgreTrayImages", "MouseArrow"); CEGUI::MouseCursor::getSingleton().hide(); //mUIRoot->addChildWindow(CEGUI::WindowManager::getSingleton().loadWindowLayout("Introduction.layout")); mUIRoot->addChildWindow(CEGUI::WindowManager::getSingleton().loadWindowLayout("HUD.layout")); mUIHUDThrottle = static_cast<CEGUI::ProgressBar*>(CEGUI::WindowManager::getSingleton().getWindow("HUD/Throttle")); mUIHUDVelocity = CEGUI::WindowManager::getSingleton().getWindow("HUD/Velocity"); mUIHUDAltitude = CEGUI::WindowManager::getSingleton().getWindow("HUD/Altitude"); std::stringstream sstr; sstr << timer.getMicroseconds(); CEGUI::Logger::getSingleton().logEvent("Time to start CEGUI: " + sstr.str()); }
void Application::go() { Ogre::Timer loopTimer; bool continueRunning = true; while ( continueRunning ) { Ogre::WindowEventUtilities::messagePump(); SimpleInputManager::capture(); // Update logic stuff float elapsedSeconds = loopTimer.getMicroseconds() * 1.0 / 1000000; updateLogic( elapsedSeconds ); // Update graphics stuff updateAnimations( elapsedSeconds ); bool windowClosed = m_window->isClosed(); continueRunning &= ! windowClosed; updateStats(); loopTimer.reset(); bool renderFrameSuccess = m_root->renderOneFrame(); continueRunning &= renderFrameSuccess; continueRunning &= ! m_exitRequested; } }
// Run //------------------------------------------------------------------------------------- void BaseApp::Run( bool showDialog ) { mShowDialog = showDialog; if (!setup()) return; if (!pSet->limit_fps) mRoot->startRendering(); // default else { Ogre::Timer tim; while (1) { Ogre::WindowEventUtilities::messagePump(); if (tim.getMicroseconds() > 1000000.0 / pSet->limit_fps_val) { tim.reset(); if (!mRoot->renderOneFrame()) break; }else if (pSet->limit_sleep >= 0) boost::this_thread::sleep(boost::posix_time::milliseconds(pSet->limit_sleep)); } } destroyScene(); }
void Application::go() { Ogre::Timer loopTimer; bool continueRunning = true; while ( continueRunning ) { Ogre::WindowEventUtilities::messagePump(); SimpleInputManager::capture(); // Update logic stuff // Update graphics stuff bool windowClosed = m_window->isClosed(); continueRunning &= ! windowClosed; loopTimer.reset(); bool renderFrameSuccess = m_root->renderOneFrame(); continueRunning &= renderFrameSuccess; continueRunning &= ! m_exitRequested; } }
//--------------------------------------------------------------------------- void HeatVisionListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) { if(pass_id == 0xDEADBABE) { // "random_fractions" parameter fpParams->setNamedConstant("random_fractions", Ogre::Vector4(Ogre::Math::RangeRandom(0.0, 1.0), Ogre::Math::RangeRandom(0, 1.0), 0, 0)); // "depth_modulator" parameter float inc = ((float)timer->getMilliseconds())/1000.0f; if ( (fabs(curr-end) <= 0.001) ) { // take a new value to reach end = Ogre::Math::RangeRandom(0.95, 1.0); start = curr; } else { if (curr > end) curr -= inc; else curr += inc; } timer->reset(); fpParams->setNamedConstant("depth_modulator", Ogre::Vector4(curr, 0, 0, 0)); } }
/** * Releases the object's resources */ void MediaPlayerOCV::end() { // Check if already released if ( !isValid() ) return; // Release thread if ( m_multithreaded && m_captureThread ) { // Signal the thread and wait for it to be done m_captureThread->signal(); Ogre::Timer timerLimit; timerLimit.reset(); while( (m_captureThread->get_finished() == false) && (timerLimit.getMilliseconds() < 250) ) ; if ( m_captureThread->get_finished() ) { delete m_captureThread; } else LOG_CRITICAL( "MediaPlayerOCV: capture thread timer expired, and the thread did not finish. Something is wrong, there will be a memory leak" ); m_captureThread = NULL; } // Clear resources m_capture.release(); m_frameImg.end(); // Clear flags m_bIsValid = false; m_newBufferReady = false; m_loopPending = false; }
void Application::update() { Ogre::Timer loopTimer; bool continueRunning = true; while (continueRunning) { Ogre::WindowEventUtilities::messagePump(); SimpleInputManager::capture(); float elapsedSeconds = loopTimer.getMicroseconds() * 1.0 / 1000000; m_NXOgreTimeController->advance(elapsedSeconds); loopTimer.reset(); updateOverlayInfo(); bool renderFrameSuccess = m_root->renderOneFrame(); if (!renderFrameSuccess || m_exitRequested) { continueRunning = false; } } }
void OMW::Engine::go() { assert (!mContentFiles.empty()); assert (!mOgre); Settings::Manager settings; std::string settingspath; settingspath = loadSettings (settings); // Create encoder ToUTF8::Utf8Encoder encoder (mEncoding); mEncoder = &encoder; prepareEngine (settings); // Play some good 'ol tunes MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); if (!mSaveGameFile.empty()) { MWBase::Environment::get().getStateManager()->loadGame(mSaveGameFile); } else if (!mSkipMenu) { // start in main menu MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); try { // Is there an ini setting for this filename or something? MWBase::Environment::get().getSoundManager()->streamMusic("Special/morrowind title.mp3"); std::string logo = mFallbackMap["Movies_Morrowind_Logo"]; if (!logo.empty()) MWBase::Environment::get().getWindowManager()->playVideo(logo, true); } catch (...) {} } else { MWBase::Environment::get().getStateManager()->newGame (!mNewGame); } // Start the main rendering loop Ogre::Timer timer; while (!MWBase::Environment::get().getStateManager()->hasQuitRequest()) { float dt = timer.getMilliseconds()/1000.f; dt = std::min(dt, 0.2f); timer.reset(); Ogre::Root::getSingleton().renderOneFrame(dt); } // Save user settings settings.saveUser(settingspath); std::cout << "Quitting peacefully." << std::endl; }
//--------------------------------------------------------------------------- void HeatVisionListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) { if(pass_id == 0xDEADBABE) { timer->reset(); fpParams = mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); } }
void Application::run() { initialize(); setupScene(); Ogre::Timer timer; timer.reset(); mRunning = true; while (mRunning) { const Ogre::Real delta= timer.getMicroseconds() * static_cast<Ogre::Real>(0.000001f); timer.reset(); runOneFrame(delta); } finalize(); }
::FreeConsole(); } void Game::Run() { InitializeGame(); ConnectToPVD(); InitializeKinect(); kinectController = BodyController(); InputManager* inputManager = InputManager::GetInstance(); inputManager->RegisterSensorListener(&kinectController); inputManager->BeginAllCapture(); sceneManager = new SceneManager(); sceneManager->Initialize(mWindow, mRoot); AllocConsole(); freopen("conin$","r",stdin); freopen("conout$","w",stdout); freopen("conout$","w",stderr); printf("Debugging Window:\n"); /*std::shared_ptr<GameScene> gameScene(new GameScene(sceneManager, mRoot, "Probending Arena", contestantData)); sceneManager->FlagSceneSwitch(gameScene, true); gameScene.reset();*/ std::shared_ptr<MenusScene> menuScene = std::make_shared<MenusScene>(sceneManager, mRoot, MenusScene::Screens::MainMenu); sceneManager->FlagSceneSwitch(menuScene, true); menuScene.reset(); bool rendering = true; Ogre::Timer gameTimer = Ogre::Timer(); float currentTime = 0; float previousTime = 0; while (rendering) { gameTimer.reset(); if(!Update(currentTime / 1000.0f)) rendering = false; //Ogre::WindowEventUtilities::messagePump(); #if(!MEMORY_LEAK_DETECT) mRoot->renderOneFrame(); #endif currentTime = (float)gameTimer.getMilliseconds();
bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) { if (evt.state.buttonDown(OIS::MB_Left) == false) SdkSample::mouseReleased(evt, id); Ogre::Ray ray = mTrayMgr->getCursorRay(mCamera); beastie::ray_query result; Ogre::Timer timer; unsigned long rayTime = 0; timer.reset(); bool ret = mTree->intersect(ray, 10000, result); rayTime = timer.getMicroseconds(); mResultObject->beginUpdate(0); if (ret) { // Hit something. mResultObject->position(result.hitTriangle.a + (result.hitTriangle.n * 3.f)); mResultObject->position(result.hitTriangle.b + (result.hitTriangle.n * 3.f)); mResultObject->position(result.hitTriangle.c + (result.hitTriangle.n * 3.f)); mHitPosLabelX->setCaption(Ogre::StringConverter::toString(result.globalPosition.x)); mHitPosLabelY->setCaption(Ogre::StringConverter::toString(result.globalPosition.y)); mHitPosLabelZ->setCaption(Ogre::StringConverter::toString(result.globalPosition.z)); } else { // Didn't hit anything. // Try raycasting the ground plane. Ogre::Vector3 globalPosition; if (beastie::intersections::line( beastie::line(ray, 100000) , mPlane, globalPosition )) { mHitPosLabelX->setCaption(Ogre::StringConverter::toString(globalPosition.x)); mHitPosLabelY->setCaption(Ogre::StringConverter::toString(globalPosition.y)); mHitPosLabelZ->setCaption(Ogre::StringConverter::toString(globalPosition.z)); float const radius = 50; // accuracy is the count of points (and lines). // Higher values make the circle smoother, but may slowdown the performance. // The performance also is related to the count of circles. float const accuracy = 15; for(float theta = 0; theta <= 2 * Math::PI; theta += Ogre::Math::PI / accuracy) { mResultObject->position(globalPosition.x + (radius * cos(theta)), 0, globalPosition.z + (radius * sin(theta))); mResultObject->position(globalPosition); } } else { // Really didn't click on anything at all. mHitPosLabelX->setCaption("-"); mHitPosLabelY->setCaption("-"); mHitPosLabelZ->setCaption("-"); mResultObject->position(0,0,0); mResultObject->position(0,0,0); mResultObject->position(0,0,0); } } mResultObject->end(); return true; }
bool NavMesher::Build() { // ******* Only for OBJ Loading **** cleanup(); const char * filepath = "../../media/models/"; if (!m_geom || !m_geom->loadMesh(filepath)) { delete m_geom; m_geom = 0; m_ctx->log(RC_LOG_ERROR, "Geom load log %s:"); } assert(m_geom); if (!m_geom || !m_geom->getMesh()) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified."); return false; } if(m_geom->getMesh()->getTriCount() <= 0 || m_geom->getMesh()->getVertCount()<=0) Ogre::Exception(0,Ogre::String("Bad verts or Triangle count. Verts: "+ StringConverter::toString( m_geom->getMesh()->getVertCount()) + "/n" + "Triangles :" +StringConverter::toString(m_geom->getMesh()->getTriCount())),"NavMesher::Build"); //reset timer Ogre::Timer tm; tm.reset(); unsigned long stime = tm.getMicroseconds(); //clear existing Clear(); // ******* Only for OBJ Loading **** const float* bmin = m_geom->getMeshBoundsMin(); const float* bmax = m_geom->getMeshBoundsMax(); const float* verts = m_geom->getMesh()->getVerts(); const int nverts = m_geom->getMesh()->getVertCount(); const int *tris = m_geom->getMesh()->getTris(); const int ntris = m_geom->getMesh()->getTriCount(); if(sizeof(tris) <= 0 || ntris <= 0) { return false; } // // Step 1. Initialize build config. // // Init build configuration from GUI memset(&m_cfg, 0, sizeof(m_cfg)); m_cfg.cs = m_cellSize; m_cfg.ch = m_cellHeight; m_cfg.walkableSlopeAngle = m_agentMaxSlope; m_cfg.walkableHeight = (int)ceilf(m_agentHeight / m_cfg.ch); m_cfg.walkableClimb = (int)floorf(m_agentMaxClimb / m_cfg.ch); m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs); m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize); m_cfg.maxSimplificationError = m_edgeMaxError; m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly; m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist; m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError; // Set the area where the navigation will be build. // Here the bounds of the input mesh are used, but the // area could be specified by an user defined box, etc. rcVcopy(m_cfg.bmin, bmin); rcVcopy(m_cfg.bmax, bmax); rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height); // Reset build times gathering. m_ctx->resetTimers(); // Start the build process. m_ctx->startTimer(RC_TIMER_TOTAL); m_ctx->log(RC_LOG_PROGRESS, "Building navigation:"); m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height); m_ctx->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f); // // Step 2. Rasterize input polygon soup. // // Allocate voxel heightfield where we rasterize our input data to. m_solid = rcAllocHeightfield(); if (!m_solid) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'."); return false; } if (!rcCreateHeightfield(m_ctx, *m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield."); return false; } // Allocate array that can hold triangle area types. // If you have multiple meshes you need to process, allocate // and array which can hold the max number of triangles you need to process. m_triareas = new unsigned char[ntris]; if (!m_triareas) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", ntris); return false; } // Find triangles which are walkable based on their slope and rasterize them. // If your input data is multiple meshes, you can transform them here, calculate // the are type for each of the meshes and rasterize them. memset(m_triareas, 0, ntris*sizeof(unsigned char)); rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triareas); rcRasterizeTriangles(m_ctx, verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb); if (!m_keepInterResults) { delete [] m_triareas; m_triareas = 0; } // // Step 3. Filter walkables surfaces. // // Once all geoemtry is rasterized, we do initial pass of filtering to // remove unwanted overhangs caused by the conservative rasterization // as well as filter spans where the character cannot possibly stand. rcFilterLowHangingWalkableObstacles(m_ctx, m_cfg.walkableClimb, *m_solid); rcFilterLedgeSpans(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid); rcFilterWalkableLowHeightSpans(m_ctx, m_cfg.walkableHeight, *m_solid); // // Step 4. Partition walkable surface to simple regions. // // Compact the heightfield so that it is faster to handle from now on. // This will result more cache coherent data as well as the neighbours // between walkable cells will be calculated. m_chf = rcAllocCompactHeightfield(); if (!m_chf) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'."); return false; } if (!rcBuildCompactHeightfield(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data."); return false; } if (!m_keepInterResults) { rcFreeHeightField(m_solid); m_solid = 0; } // Erode the walkable area by agent radius. if (!rcErodeWalkableArea(m_ctx, m_cfg.walkableRadius, *m_chf)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not erode."); return false; } // (Optional) Mark areas. const ConvexVolume* vols = m_geom->getConvexVolumes(); for (int i = 0; i < m_geom->getConvexVolumeCount(); ++i) rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *m_chf); if (m_monotonePartitioning) { // Partition the walkable surface into simple regions without holes. // Monotone partitioning does not need distancefield. if (!rcBuildRegionsMonotone(m_ctx, *m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build regions."); return false; } } else { // Prepare for region partitioning, by calculating distance field along the walkable surface. if (!rcBuildDistanceField(m_ctx, *m_chf)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build distance field."); return false; } // Partition the walkable surface into simple regions without holes. if (!rcBuildRegions(m_ctx, *m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build regions."); return false; } } // // Step 5. Trace and simplify region contours. // // Create contours. m_cset = rcAllocContourSet(); if (!m_cset) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'."); return false; } if (!rcBuildContours(m_ctx, *m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, *m_cset)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create contours."); return false; } // // Step 6. Build polygons mesh from contours. // // Build polygon navmesh from the contours. m_pmesh = rcAllocPolyMesh(); if (!m_pmesh) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'."); return false; } if (!rcBuildPolyMesh(m_ctx, *m_cset, m_cfg.maxVertsPerPoly, *m_pmesh)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours."); return false; } // // Step 7. Create detail mesh which allows to access approximate height on each polygon. // m_dmesh = rcAllocPolyMeshDetail(); if (!m_dmesh) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmdtl'."); return false; } if (!rcBuildPolyMeshDetail(m_ctx, *m_pmesh, *m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, *m_dmesh)) { m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build detail mesh."); return false; } if (!m_keepInterResults) { rcFreeCompactHeightfield(m_chf); m_chf = 0; rcFreeContourSet(m_cset); m_cset = 0; } // At this point the navigation mesh data is ready, you can access it from m_pmesh. // See rcDebugDrawPolyMesh or dtCreateNavMeshData as examples how to access the data. // // (Optional) Step 8. Create Detour data from Recast poly mesh. // // The GUI may allow more max points per polygon than Detour can handle. // Only build the detour navmesh if we do not exceed the limit. unsigned char* navData = 0; int navDataSize = 0; // Update poly flags from areas. for (int i = 0; i < m_pmesh->npolys; ++i) { if (m_pmesh->areas[i] == RC_WALKABLE_AREA) m_pmesh->areas[i] = SAMPLE_POLYAREA_GROUND; if (m_pmesh->areas[i] == SAMPLE_POLYAREA_GROUND || m_pmesh->areas[i] == SAMPLE_POLYAREA_GRASS || m_pmesh->areas[i] == SAMPLE_POLYAREA_ROAD) { m_pmesh->flags[i] = SAMPLE_POLYFLAGS_WALK; } else if (m_pmesh->areas[i] == SAMPLE_POLYAREA_WATER) { m_pmesh->flags[i] = SAMPLE_POLYFLAGS_SWIM; } else if (m_pmesh->areas[i] == SAMPLE_POLYAREA_DOOR) { m_pmesh->flags[i] = SAMPLE_POLYFLAGS_WALK | SAMPLE_POLYFLAGS_DOOR; } } memset(&m_params, 0, sizeof(m_params)); m_params.verts = m_pmesh->verts; m_params.vertCount = m_pmesh->nverts; m_params.polys = m_pmesh->polys; m_params.polyAreas = m_pmesh->areas; m_params.polyFlags = m_pmesh->flags; m_params.polyCount = m_pmesh->npolys; m_params.nvp = m_pmesh->nvp; m_params.detailMeshes = m_dmesh->meshes; m_params.detailVerts = m_dmesh->verts; m_params.detailVertsCount = m_dmesh->nverts; m_params.detailTris = m_dmesh->tris; m_params.detailTriCount = m_dmesh->ntris; m_params.walkableHeight = m_agentHeight; m_params.walkableRadius = m_agentRadius; m_params.walkableClimb = m_agentMaxClimb; rcVcopy(m_params.bmin, m_pmesh->bmin); rcVcopy(m_params.bmax, m_pmesh->bmax); m_params.cs = m_cfg.cs; m_params.ch = m_cfg.ch; m_params.buildBvTree = true; if (!dtCreateNavMeshData(&m_params, &navData, &navDataSize)) { m_ctx->log(RC_LOG_ERROR, "Could not build Detour navmesh."); return false; } m_navMesh = dtAllocNavMesh(); if (!m_navMesh) { delete [] navData; m_ctx->log(RC_LOG_ERROR, "Could not create Detour navmesh"); return false; } m_navQuery = dtAllocNavMeshQuery(); dtStatus status = m_navQuery->init(m_navMesh, 2048); if (dtStatusFailed(status)) { m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query"); return false; } if (!m_navMesh->init(navData, navDataSize, true)) { delete [] navData; m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh"); return false; } //take time stime = tm.getMicroseconds() - stime; DrawDebug(); return true; }
/// Image from road /// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . void App::SaveGrassDens() { Ogre::Timer ti; for (int i=0; i < RTs-1; ++i) //-1 preview camera manual { if (!rt[i].tex) return; rt[i].tex->update(); // all have to exist } int w = rt[1].tex->getWidth(), h = rt[1].tex->getHeight(); using Ogre::uint; uint *rd = new uint[w*h]; // road render uint *gd = new uint[w*h]; // grass dens PixelBox pb_rd(w,h,1, PF_BYTE_RGBA, rd); rt[1].tex->copyContentsToMemory(pb_rd, RenderTarget::FB_FRONT); const int f = std::max(0, scn->sc->grDensSmooth); float sum = 0.f; register int v,i,j,x,y, a,b,d,m; // gauss kernel for smoothing int *mask = new int[(f*2+1)*(f*2+1)]; m = 0; if (f==0) { mask[0] = 256.f; sum = 256.f; } else for (j = -f; j <= f; ++j) for (i = -f; i <= f; ++i, ++m) { v = std::max(0.f, (1.f - sqrtf((float)(i*i+j*j)) / float(f)) * 256.f); mask[m] = v; sum += v; } sum = 2.f / sum; //par normally would be 1.f - but road needs to stay black and be smooth outside // change smooth to distance from road with fade ?.. /// road - rotate, smooth ----------- for (y = f; y < h-f; ++y) { a = y*w +f; for (x = f; x < w-f; ++x, ++a) { b = x*w + (h-y); // rot 90 ccw b=a // sum kernel v = 0; m = 0; for (j = -f; j <= f; ++j) { d = b -f + j*w; for (i = -f; i <= f; ++i, ++d, ++m) v += ((rd[d] >> 16) & 0xFF) * mask[m] / 256; } v = std::max(0, (int)(255.f * (1.f - v * sum) )); // avg, inv, clamp gd[a] = 0xFF000000 + v; // write } } v = 0xFF0000FF; // frame f [] todo: get from rd[b] not clear.. for (y = 0; y <= f; ++y) for (x=0; x < w; ++x) gd[y*w+x] = v; // - up for (y=h-f-1; y < h; ++y) for (x=0; x < w; ++x) gd[y*w+x] = v; // - down for (x = 0; x <= f; ++x) for (y=0; y < h; ++y) gd[y*w+x] = v; // | left for (x=w-f-1; x < w; ++x) for (y=0; y < h; ++y) gd[y*w+x] = v; // | right LogO(String("::: Time road dens: ") + fToStr(ti.getMilliseconds(),0,3) + " ms"); ti.reset(); if (!IsVdrTrack()) // vdr trk no grass, only previews { Image im; // for trees, before grass angle and height im.loadDynamicImage((uchar*)gd, w,h,1, PF_BYTE_RGBA); im.save(gcom->TrkDir()+"objects/roadDensity.png"); } delete[] rd; delete[] gd; delete[] mask; // road, terrain ---------------- int u = pSet->allow_save ? pSet->gui.track_user : 1; rt[0].tex->writeContentsToFile(gcom->pathTrk[u] + pSet->gui.track + "/preview/road.png"); rt[2].tex->writeContentsToFile(gcom->pathTrk[u] + pSet->gui.track + "/preview/terrain.jpg"); LogO(String("::: Time save prv : ") + fToStr(ti.getMilliseconds(),0,3) + " ms"); }