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);
|
cam->NodeUpdateGS(0.f);
|
||||||
|
|
||||||
scene->CalculateVisibleMeshes(m_rasterizer,cam);
|
scene->CalculateVisibleMeshes(m_rasterizer,cam);
|
||||||
|
scene->UpdateAnimations(m_engine->GetFrameTime());
|
||||||
scene->RenderBuckets(camtrans, m_rasterizer);
|
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)
|
static void setOccluder_recursive(SG_Node* node, bool v)
|
||||||
{
|
{
|
||||||
NodeList& children = node->GetSGChildren();
|
NodeList& children = node->GetSGChildren();
|
||||||
|
@ -852,10 +852,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Was this object culled?
|
* Was this object culled?
|
||||||
*/
|
*/
|
||||||
inline bool
|
bool
|
||||||
GetCulled(
|
GetCulled(
|
||||||
void
|
void
|
||||||
) { return m_bCulled; }
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set culled flag of this object
|
* Set culled flag of this object
|
||||||
|
@ -140,7 +140,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
|
|||||||
m_frameTime(0.f),
|
m_frameTime(0.f),
|
||||||
m_clockTime(0.f),
|
m_clockTime(0.f),
|
||||||
m_previousClockTime(0.f),
|
m_previousClockTime(0.f),
|
||||||
m_previousAnimTime(0.f),
|
|
||||||
|
|
||||||
|
|
||||||
m_exitcode(KX_EXIT_REQUEST_NO_REQUEST),
|
m_exitcode(KX_EXIT_REQUEST_NO_REQUEST),
|
||||||
@ -686,16 +685,6 @@ bool KX_KetsjiEngine::NextFrame()
|
|||||||
SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE);
|
SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE);
|
||||||
scene->UpdateParents(m_frameTime);
|
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);
|
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
|
||||||
SG_SetActiveStage(SG_STAGE_PHYSICS2);
|
SG_SetActiveStage(SG_STAGE_PHYSICS2);
|
||||||
scene->GetPhysicsEnvironment()->BeginFrame();
|
scene->GetPhysicsEnvironment()->BeginFrame();
|
||||||
@ -798,27 +787,6 @@ bool KX_KetsjiEngine::NextFrame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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
|
// Start logging time spend outside main loop
|
||||||
m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true);
|
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);
|
raslight->BindShadowBuffer(m_canvas, cam, camtrans);
|
||||||
|
|
||||||
/* update scene */
|
/* update scene */
|
||||||
|
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
|
||||||
scene->CalculateVisibleMeshes(m_rasterizer, cam, raslight->GetShadowLayer());
|
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 */
|
/* render */
|
||||||
m_rasterizer->ClearDepthBuffer();
|
m_rasterizer->ClearDepthBuffer();
|
||||||
m_rasterizer->ClearColorBuffer();
|
m_rasterizer->ClearColorBuffer();
|
||||||
@ -1319,6 +1294,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
|
|||||||
|
|
||||||
scene->CalculateVisibleMeshes(m_rasterizer,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);
|
m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
|
||||||
SG_SetActiveStage(SG_STAGE_RENDER);
|
SG_SetActiveStage(SG_STAGE_RENDER);
|
||||||
|
|
||||||
|
@ -111,7 +111,6 @@ private:
|
|||||||
double m_frameTime;//discrete timestamp of the 'game logic frame'
|
double m_frameTime;//discrete timestamp of the 'game logic frame'
|
||||||
double m_clockTime;//current time
|
double m_clockTime;//current time
|
||||||
double m_previousClockTime;//previous clock time
|
double m_previousClockTime;//previous clock time
|
||||||
double m_previousAnimTime; //the last time animations were updated
|
|
||||||
double m_remainingTime;
|
double m_remainingTime;
|
||||||
|
|
||||||
static int m_maxLogicFrame; /* maximum number of consecutive logic frame */
|
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);
|
MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now that we know visible meshes, update LoDs
|
||||||
|
UpdateObjectLods();
|
||||||
}
|
}
|
||||||
|
|
||||||
// logic stuff
|
// 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)
|
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);
|
TaskPool *pool = BLI_task_pool_create(KX_GetActiveEngine()->GetTaskScheduler(), &curtime);
|
||||||
|
|
||||||
for (int i=0; i<m_animatedlist->GetCount(); ++i) {
|
for (int i=0; i<m_animatedlist->GetCount(); ++i) {
|
||||||
|
@ -289,6 +289,8 @@ protected:
|
|||||||
double m_suspendedtime;
|
double m_suspendedtime;
|
||||||
double m_suspendeddelta;
|
double m_suspendeddelta;
|
||||||
|
|
||||||
|
double m_previousAnimTime; //the last time animations were updated
|
||||||
|
|
||||||
struct Scene* m_blenderScene;
|
struct Scene* m_blenderScene;
|
||||||
|
|
||||||
RAS_2DFilterManager m_filtermanager;
|
RAS_2DFilterManager m_filtermanager;
|
||||||
|
@ -274,6 +274,8 @@ void ImageRender::Render()
|
|||||||
|
|
||||||
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
|
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
|
||||||
|
|
||||||
|
m_scene->UpdateAnimations(m_engine->GetFrameTime());
|
||||||
|
|
||||||
m_scene->RenderBuckets(camtrans, m_rasterizer);
|
m_scene->RenderBuckets(camtrans, m_rasterizer);
|
||||||
|
|
||||||
m_scene->RenderFonts();
|
m_scene->RenderFonts();
|
||||||
|
Loading…
Reference in New Issue
Block a user