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.
This commit is contained in:
Mitchell Stokes 2014-07-10 22:11:25 -07:00
parent d419e2e90c
commit 315609ec0c
Notes: blender-bot 2023-02-14 10:37:44 +01:00
Referenced by commit 4fac29ca0e, Revert "Fix T40257: Frustum culling not working properly"
Referenced by issue #42122, vibrating animation bug in the game engine
Referenced by issue #41094, Ping pong action works wrong when GLSL mode and Sun buffer shadow are enabled in BGE.
Referenced by issue #40257, BGE: Frustrum culling not working properly
8 changed files with 57 additions and 35 deletions

View File

@ -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);
}

View File

@ -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<RAS_MeshSlot> 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();

View File

@ -852,10 +852,10 @@ public:
/**
* Was this object culled?
*/
inline bool
bool
GetCulled(
void
) { return m_bCulled; }
);
/**
* Set culled flag of this object

View File

@ -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);

View File

@ -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 */

View File

@ -1529,6 +1529,9 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int
MarkVisible(rasty, static_cast<KX_GameObject*>(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; i<m_animatedlist->GetCount(); ++i) {

View File

@ -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;

View File

@ -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();