Page 1 of 1

How to re-use ConvexHullShape

Posted: Thu May 05, 2011 9:04 am
by Bonus
I'm using Toolbox.GetConvexHull to create a list of ConvexHulls with the same list of vertices. But ConvexHull recalculate it again and creates new ConvexHullShape. How to re-use ConvexHullShape?

Re: How to re-use ConvexHullShape

Posted: Thu May 05, 2011 8:34 pm
by Norbo
First, create a shape directly:

Code: Select all

            Vector3[] vertices = new Vector3[] 
            {
                new Vector3(-1,0,-1),
                new Vector3(-1,0,1),
                new Vector3(1,0,-1),
                new Vector3(1,0,1),
                new Vector3(0,2,0)             
            };
            var convexHullShape = new ConvexHullShape(vertices);
Now, create entities using that shape. In the latest stable release, there's two main ways of doing this: creating a 'typed' entity, and creating a morphable entity. The generic typed entity is the superclass of all the prefabs, and it lets you access the CollisionInformation property of the entity using the most derived available type. The morphable entity is a little simpler to make, but after you make the entity, the CollisionInformation property is just an EntityCollidable (but it is settable!)

In both of these examples, the shape is shared and passed into new collidable objects, which are in turn given to an entity constructor (alongside a mass).

Code: Select all

            var entity1 = new Entity<ConvexCollidable<ConvexHullShape>>(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);
            var entity2 = new Entity<ConvexCollidable<ConvexHullShape>>(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);
            var entity3 = new Entity<ConvexCollidable<ConvexHullShape>>(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);
            var entity4 = new Entity<ConvexCollidable<ConvexHullShape>>(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);

Code: Select all

            var mEntity1 = new MorphableEntity(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);
            var mEntity2 = new MorphableEntity(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);
            var mEntity3 = new MorphableEntity(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);
            var mEntity4 = new MorphableEntity(new ConvexCollidable<ConvexHullShape>(convexHullShape), 2);
In the latest development version (http://bepuphysics.codeplex.com/SourceC ... evelopment), MorphableEntities can also be constructed by simply passing a shape in as well (shortening the constructor a bit):

Code: Select all

            var msEntity1 = new MorphableEntity(convexHullShape, 2);
            var msEntity2 = new MorphableEntity(convexHullShape, 2);
            var msEntity3 = new MorphableEntity(convexHullShape, 2);
            var msEntity4 = new MorphableEntity(convexHullShape, 2);
For maximum initialization sharing, you could re-use other data like the inertia tensor. This can be done with both types of entities, but this example shows the last morphable entity setup:

Code: Select all

            var msiEntity1 = new MorphableEntity(convexHullShape, 2);
            var msiEntity2 = new MorphableEntity(convexHullShape, 2, msiEntity1.LocalInertiaTensor, msiEntity1.Volume);
            var msiEntity3 = new MorphableEntity(convexHullShape, 2, msiEntity1.LocalInertiaTensor, msiEntity1.Volume);
            var msiEntity4 = new MorphableEntity(convexHullShape, 2, msiEntity1.LocalInertiaTensor, msiEntity1.Volume);
Also, all of these entity constructors will center the entity body on the origin. You can assign their Position property to anything after being created. If you need to know the offset from the 'configuration space' origin of the original vertices and the shape's center, you can use the other ConvexHullShape constructor which outputs a center.

Code: Select all

            Vector3 hullCenter;
            var convexHullShape = new ConvexHullShape(vertices, out hullCenter);

Re: How to re-use ConvexHullShape

Posted: Fri May 06, 2011 4:45 am
by Bonus
Thanks Norbo. Now it runs amazingly fast!
It would be nice to have a demo ready for this stuff.

Re: How to re-use ConvexHullShape

Posted: Fri May 06, 2011 4:47 am
by Norbo
It would be nice to have a demo ready for this stuff.
Noted :)

Re: How to re-use ConvexHullShape

Posted: Tue May 17, 2011 7:45 pm
by BabaJustin
I've changed my code to reuse a ConvexHullShape creating a 'typed' entity. I am still seeing the creation of each Entity taking quite a bit of time however on a Windows Phone (around 2 seconds each). Is there a way to improve this further?

I'm assuming the number of vertices in the ConvexHullShape makes a big difference? Perhaps I will get the most gain trying to optimize my shape further.

Re: How to re-use ConvexHullShape

Posted: Tue May 17, 2011 8:06 pm
by Norbo
If you re-use the shape and it's still taking a long time, it's probably related to the inertia tensor calculation. As shown above, that can be shared as well by passing a tensor into the constructor. Providing a volume will also prevent additional calculations.

2 seconds is a lot longer than I'd expect, though. It is indeed a good idea to keep convex hulls at the lowest possible point count. Their startup (inertia tensor) and runtime (collision detection) cost increases proportionally with the vertex count.

Re: How to re-use ConvexHullShape

Posted: Tue May 17, 2011 9:01 pm
by BabaJustin
It's starting look like it's mostly the number of points now. Reusing the inertia tensor helped too, but it's still pretty slow.

Re: How to re-use ConvexHullShape

Posted: Tue May 17, 2011 9:39 pm
by Norbo
Did you reuse both the inertia and volume? The convex hull volume calculation is fairly expensive too.

Re: How to re-use ConvexHullShape

Posted: Thu May 19, 2011 9:06 pm
by BabaJustin
I had missed the volume. Makes a huge difference apparently. I was also changing the Mass after creation which caused a hiccup too.
It's much much quicker now, thanks!