forked from bartvdbraak/blender
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:
parent
d419e2e90c
commit
315609ec0c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -852,10 +852,10 @@ public:
|
||||
/**
|
||||
* Was this object culled?
|
||||
*/
|
||||
inline bool
|
||||
bool
|
||||
GetCulled(
|
||||
void
|
||||
) { return m_bCulled; }
|
||||
);
|
||||
|
||||
/**
|
||||
* Set culled flag of this object
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user