Injecting Culling Algorithm

Jun 3, 2013 at 9:52 PM
My question is how can i implement culling. I have a Dynamic Quad Tree that holds my Actors that should be drawn.

So i can ask the Dynamic Quad Tree which Actors are inside the view that fits the screen size (for 2D in my case).

What is the best way to inject Culling like this into the engine? Idea? The Draw Calls have to be controlled by the result of the Dynamic Quad Tree Query.
Coordinator
Jun 3, 2013 at 10:10 PM
Sure, I can give some advice here. In the old days I did frustum culling from within the SceneRenderTask (formerly RenderView). There are methods in the Entity3D class for getting a list of entities in the subtree. These work for both Entity3D and Node3D, so you can efficiently build a list of the entities that would be visited by a recursive traversal using the Render methods. You can then directly call the render methods of the entities.

This works since preserving the scene graph order isn't important - it shows the logical connections between objects, but not necessarily the rendering order connections. You can also use this same technique when doing something with alpha transparency and you need to sort the entities.

I believe the paraboloid environment map scene render task shows an example of how to implement this. Note that you could just as easily delegate the render calls to the quad tree object if you want to - just make sure you update the scene graph once per frame, and then you can just have a SceneRenderTask that operates on the quad tree object.

I would be really interested to hear how it turns out and what experience you get from it!
Jun 3, 2013 at 10:14 PM
Thanks for you answer. I give you notice about my success in that.
Jul 17, 2013 at 4:47 PM
Edited Jul 17, 2013 at 4:49 PM
Ive made it over the Views ExecuteTask.

Instead of using:
std::vector<Entity3D*> set;
m_pScene->GetRoot()->GetEntities( set );

for ( auto pEntity : set ) {
    pEntity->Render( pPipelineManager, pParamManager, VT_GBUFFER );
        }
}
or
m_pScene->GetRoot()->Render( pPipelineManager, pParamManager, VT_GBUFFER );
i inject my dynamic quad tree in this way with my own code.
GameScene* gameScene = static_cast<GameScene*>(m_pScene);

float x, y, x2, y2;
gameScene->GetWorldBounds(x, y, x2, y2);

std::vector<GameObject*> set = gameScene->_getObjectsInsideArea(x, y, x2, y2);

for ( auto pGameObject : set ) {
    pGameObject->GetNode()->Render( pPipelineManager, pParamManager, VT_GBUFFER );
}
Coordinator
Jul 19, 2013 at 11:50 AM
So your GameObject is a descendent of Actor, right? If that is the case, how do you do the bounds checking - on the Node or the Body (or both) of the actor?

In either case, it is great to see you doing a variation on what I had originally done. I look forward to seeing a screenshot!
Jul 19, 2013 at 3:45 PM
Edited Jul 19, 2013 at 3:49 PM
You know i build a component system. My GameObject gets a MeshRendererComponent that holds the data for the bounds of the GameObject and the logic for recalculating the bounds.
The calculating is like your calculating/recalculation of the localMatrix and worldMatrix.
void MeshRendererComponent::UpdateBoundingBox() {
    UpdateLocalBoundingBox();
    UpdateGlobalBoundingBox();
}
My MeshRendererComponent knows when he should update the bounds. Over Messages the Components have the ability to communicate with other components. So over them the MeshRendererComponent knows when the Position, Rotation or Scalation has changed, so it can update the bounds.

Next there is the DynamicQuadTreeComponent Component that is added to the GameObject. It uses the globalBoundingBox information of the MeshRendererComponent to handle the quad tree entries.