Performance & creating many objects at once

Jun 4, 2011 at 10:21 PM

Hi,

In the game I'm trying to create, when 2 (or more) moving objects collide with each other, they shatter into multiple smaller objects. Each smaller object being another physics-enabled object. Ofcourse I'm limiting the amount of objects that can exist at once in various ways, so the amount of objects isn't the problem. However, at the time the 2 objects are colliding and the smaller objects are created, some lag occurs for a small moment. I timed various bits of the proces and traced most of the lag to the physics update of the game. I'm not sure how to solve it.

I'm wondering what part of the phsyics update actually causes the lag? I'm considering caching rigidbodies and just leave them disabled while they're not needed. But I'm not sure it's a good solution, since the objects to be created have random sizes. You can't really cache random :-) Or perhaps you know of another good way I can add quite a few objects at once without too much overhead?

Thanks!

Jun 14, 2011 at 10:39 PM

I took an adventurous step and actually read your code to see what it does. I still don't understand it :P

I did found out, however, that Quadtree is a LOT faster then SweepAndPrune. Aparrently updating the sweeping indexes takes quite some time, time a quadtree doesn't need. Unfortunatly the quadtree didn't detect all collisions. I took the liberty of changing the quadtree a tiny bit so it does detect it all.

This is the code I changed:

/// <summary>
/// Detects collisions with the specified <see cref="CollisionGroup"/> in the <see cref="QuadtreeNode"/> and
/// it's children.
/// </summary>
/// <param name="collisionSystem">The associated<see cref="CollisionSystem"/>.</param>
/// <param name="collisionGroup">The source <see cref="CollisionGroup"/>/</param>
/// <param name="context">The <see cref="CollisionContext"/> to use for collision detection.</param>
internal void DetectCollisions(QuadtreeCollisionSystem collisionSystem, CollisionGroup collisionGroup, CollisionContext context)
{
    // Iterate through all of this node's associated collision groups.
    for (int i = 0; i < this.collisionGroups.Count; i++)
    {
        // Detect collisions.
        collisionSystem.DetectCollisions(collisionGroup, this.collisionGroups[i], context);
    }

    QuadtreeNode node;

    // Iterate through all child nodes.
    for (int i = 0; i < this.nodes.Length; i++)
    {
        // Get the current child node.
        node = this.nodes[i];

        // Check for a complete empty quadtree node hierarchy.
        if (node.totalCount == 0)
        {
            continue;
        }

        // Quadtree nodes with only one collision group can skip the containment check.
        if (!(node.totalCount == 1 && node.collisionGroups.Count > 0))
        {
            // Old
            //// Check for containment.
            //if (collisionGroup.AABB.Max.X > node.bounds.Max.X ||
            //    collisionGroup.AABB.Min.X < node.bounds.Min.X ||
            //    collisionGroup.AABB.Max.Z > node.bounds.Max.Z ||
            //    collisionGroup.AABB.Min.Z < node.bounds.Min.Z)
            //{
            //    continue;
            //}

            // New
            // Check for containment.
            if (collisionGroup.AABB.Min.X > node.bounds.Max.X ||
                collisionGroup.AABB.Max.X < node.bounds.Min.X ||
                collisionGroup.AABB.Min.Z > node.bounds.Max.Z ||
                collisionGroup.AABB.Max.Z < node.bounds.Min.Z)
            {
                continue;
            }
        }

        // Detect collisions with the current child quadtree node.
        node.DetectCollisions(collisionSystem, collisionGroup, context);
    }
}

As you can see, I only switched some min/max checks. I'm not sure if I killed some optimisation, but at least no collisions are forgotten this way. I believe I changed it from "Skip node if AABB does not fit in it completely" to "Skip node only if AABB doesn't overlap". I hope you can fix this the proper way (if it isn;t already) and make a new build, so I can skip my custom build again. Don't forget the Octree, it looks like it has the same issue.

Thanks,
Xcone