From 315609ec0c1e28eb12bde3e8bbd2a5b03672b1a9 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Thu, 10 Jul 2014 22:11:25 -0700 Subject: Fix T40257: Frustum culling not working properly This is mostly the same fix as before, but now code depending on culling checks is executed after KX_Scene->CalculateVisibleMeshes(). As a side-effect, LoD checks and animation culling now use the current frame's culling information rather than the previous frame's. --- source/gameengine/Ketsji/KX_Dome.cpp | 1 + source/gameengine/Ketsji/KX_GameObject.cpp | 21 ++++++++++++ source/gameengine/Ketsji/KX_GameObject.h | 4 +-- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 44 +++++++------------------- source/gameengine/Ketsji/KX_KetsjiEngine.h | 1 - source/gameengine/Ketsji/KX_Scene.cpp | 17 ++++++++++ source/gameengine/Ketsji/KX_Scene.h | 2 ++ source/gameengine/VideoTexture/ImageRender.cpp | 2 ++ 8 files changed, 57 insertions(+), 35 deletions(-) (limited to 'source') diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 657eaef72b7..c7f7f586865 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -2044,6 +2044,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) cam->NodeUpdateGS(0.f); scene->CalculateVisibleMeshes(m_rasterizer,cam); + scene->UpdateAnimations(m_engine->GetFrameTime()); scene->RenderBuckets(camtrans, m_rasterizer); } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index de528aeac63..f61d08e7f71 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -928,6 +928,27 @@ KX_GameObject::SetVisible( } } +bool KX_GameObject::GetCulled() +{ + // If we're set to not cull, double-check with + // the mesh slots first. This is kind of nasty, but + // it allows us to get proper culling information. + if (!m_bCulled) + { + SG_QList::iterator mit(m_meshSlots); + for (mit.begin(); !mit.end(); ++mit) + { + if ((*mit)->m_bCulled) + { + m_bCulled = true; + break; + } + } + } + + return m_bCulled; +} + static void setOccluder_recursive(SG_Node* node, bool v) { NodeList& children = node->GetSGChildren(); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 7450be4fdef..f7f40acb8f1 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -852,10 +852,10 @@ public: /** * Was this object culled? */ - inline bool + bool GetCulled( void - ) { return m_bCulled; } + ); /** * Set culled flag of this object diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 7d7e15a5141..dde9e0c194d 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -140,7 +140,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system) m_frameTime(0.f), m_clockTime(0.f), m_previousClockTime(0.f), - m_previousAnimTime(0.f), m_exitcode(KX_EXIT_REQUEST_NO_REQUEST), @@ -686,16 +685,6 @@ bool KX_KetsjiEngine::NextFrame() SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE); scene->UpdateParents(m_frameTime); - // update levels of detail - scene->UpdateObjectLods(); - - if (!GetRestrictAnimationFPS()) - { - m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true); - SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); - scene->UpdateAnimations(m_frameTime); - } - m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); SG_SetActiveStage(SG_STAGE_PHYSICS2); scene->GetPhysicsEnvironment()->BeginFrame(); @@ -797,27 +786,6 @@ bool KX_KetsjiEngine::NextFrame() m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true); } } - - - // Handle the animations independently of the logic time step - if (GetRestrictAnimationFPS()) - { - double clocktime = m_kxsystem->GetTimeInSeconds(); - m_logger->StartLog(tc_animations, clocktime, true); - SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); - - double anim_timestep = 1.0/KX_GetActiveScene()->GetAnimationFPS(); - if (clocktime - m_previousAnimTime > anim_timestep) - { - // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep) - // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime)); - m_previousAnimTime = clocktime; - for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit) - { - (*sceneit)->UpdateAnimations(clocktime); - } - } - } // Start logging time spend outside main loop m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true); @@ -1186,8 +1154,15 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) raslight->BindShadowBuffer(m_canvas, cam, camtrans); /* update scene */ + m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); scene->CalculateVisibleMeshes(m_rasterizer, cam, raslight->GetShadowLayer()); + m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true); + scene->UpdateAnimations(GetFrameTime()); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + + /* render */ m_rasterizer->ClearDepthBuffer(); m_rasterizer->ClearColorBuffer(); @@ -1319,6 +1294,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) scene->CalculateVisibleMeshes(m_rasterizer,cam); + m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true); + SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); + + scene->UpdateAnimations(GetFrameTime()); + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); SG_SetActiveStage(SG_STAGE_RENDER); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 9e5d1893320..b1ac952731e 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -111,7 +111,6 @@ private: double m_frameTime;//discrete timestamp of the 'game logic frame' double m_clockTime;//current time double m_previousClockTime;//previous clock time - double m_previousAnimTime; //the last time animations were updated double m_remainingTime; static int m_maxLogicFrame; /* maximum number of consecutive logic frame */ diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 3d71327828e..d57c9b78587 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1529,6 +1529,9 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int MarkVisible(rasty, static_cast(m_objectlist->GetValue(i)), cam, layer); } } + + // Now that we know visible meshes, update LoDs + UpdateObjectLods(); } // logic stuff @@ -1634,6 +1637,20 @@ static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(t void KX_Scene::UpdateAnimations(double curtime) { + KX_KetsjiEngine *engine = KX_GetActiveEngine(); + + if (engine->GetRestrictAnimationFPS()) + { + // Handle the animations independently of the logic time step + double anim_timestep = 1.0 / GetAnimationFPS(); + if (curtime - m_previousAnimTime < anim_timestep) + return; + + // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep) + // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime)); + m_previousAnimTime = curtime; + } + TaskPool *pool = BLI_task_pool_create(KX_GetActiveEngine()->GetTaskScheduler(), &curtime); for (int i=0; iGetCount(); ++i) { diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 2e1ee9f101d..c5840c28041 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -289,6 +289,8 @@ protected: double m_suspendedtime; double m_suspendeddelta; + double m_previousAnimTime; //the last time animations were updated + struct Scene* m_blenderScene; RAS_2DFilterManager m_filtermanager; diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 18474932879..8c6dcf45d6f 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -274,6 +274,8 @@ void ImageRender::Render() m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + m_scene->UpdateAnimations(m_engine->GetFrameTime()); + m_scene->RenderBuckets(camtrans, m_rasterizer); m_scene->RenderFonts(); -- cgit v1.2.3