Sign in to follow this  
Spa8nky

[C#] Not happy with the following method, is there a better alternative?

Recommended Posts

I would like to do a test between any two classes that inherit from the same shape class. I can only think of the following method to differentiate between each shape type automatically, but I'm not entirely happy with it. What methods would you guys recommend?

    public enum Shape_Type : int
    {
        AABB = 0, 
        CIRCLE = 1,
        OBB = 2,
        POLYGON = 3,        
        Count = 4                               // Total number of shape types
    }

        static CollisionFunction2D[] function = new CollisionFunction2D[]
        {
            TestAABBAABB,
            TestCircleCircle,
            TestOBBOBB,
            TestPolygonPolygon,
            TestSweptAABBAABB,
            TestSweptCircleCircle,
            TestSweptOBBOBB,
            TestSweptPolygonPolygon,
        };

        public static bool TestShapeShape(Shape s1, Shape s2, ref Contact2D contact)
        {
            // Cast enum type to int so the type can be used in calculations
            int a_Value = (int)s1.Type;
            int b_Value = (int)s2.Type;

            // All tests are covered in ascending numberical order
            // There is no need to test (a vs b) if we have (b vs a) implemented
            if (a_Value > b_Value)
            {
                // [Swap a and b]
                // • This method should return a boolean
                // • Otherwise the original DetectCollision method will still be performed with the objects the wrong way around     
                return TestShapeShape(s2, s1, ref contact);
            }

            // Find the correct collision test function based on both bodies' shape type (set to 3 for time being)
            int index = 3;      
            CollisionFunction2D function_Current = function[index];

            return function_Current(s1, s2, ref contact);
        }

Thank you.

Share this post


Link to post
Share on other sites
I usually use run-time type checking since C# offers it. What you are doing is what I would usually do in C++.

If you have a BaseClass and ChildClass1 and ChildClass2, you can for example do the following tests:

BaseClass var1 = new ChildClass1();
BaseClass var2 = new ChildClass2();

if (var1 is ChildClass2)... // FALSE!
if (var2 is ChildClass2)... // TRUE!
if (var1 is BaseClass && var2 is BaseClass)... // TRUE!

Share this post


Link to post
Share on other sites
I thought about the "is" keyword but what if I add another shape type? In this case it won't automatically assign a new function based on the shape type unless I code it in.

I was thinking of something more automated, or perhaps a formula for the index that can adapt to the number of shape types and delegate accordingly?

Share this post


Link to post
Share on other sites
Method overloading?

class Collision
{
public static bool Test(Circle, Circle)
{

}

public static bool Test(Circle, Polygon)
{

}

public static bool Test(Circle, Box)
{

}
}



You'll have to add new collision methods for every new shape you introduce (but you'd have to do that anyway I imagine), but at least you won't have to maintain a list and explicitly tie the collision functions to the various types of shapes.

Share this post


Link to post
Share on other sites
That method doesn't work:


private static bool Test(CD_Rectangle a, CD_Rectangle b, ref Contact2D contact)
{
Console.WriteLine("AABBAABB");
return false;
}

private static bool Test(CD_Circle a, CD_Circle b, ref Contact2D contact)
{
Console.WriteLine("CircleCircle");
return false;
}

public static bool TestShapeShape(Shape s1, Shape s2, ref Contact2D contact)
{
Test(s1, s2, ref contact);
}



The best overloaded method match for 'Cthonian.Detection2D.Test(Cthonian.CD_Rectangle, Cthonian.CD_Rectangle, ref Cthonian.Contact2D)' has some invalid arguments

Argument '1': cannot convert from 'Cthonian.Shape' to 'Cthonian.CD_Rectangle'
Argument '2': cannot convert from 'Cthonian.Shape' to 'Cthonian.CD_Rectangle'

Share this post


Link to post
Share on other sites
For a relatively small, closed set of types, especially being used in a typically performance sensitive area like collision, your original method would be pretty good I think.

You could have a complete table for testing each type against each other (so you would have a 4x4 array). You can then calculate the index with:
"a_Value * COUNT + b_Value".

Share this post


Link to post
Share on other sites
Are you going to call this method frequently (as in a physics engine)?
In that case you might want to test the overload versus delegate invokation for performance.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
For a relatively small, closed set of types, especially being used in a typically performance sensitive area like collision, your original method would be pretty good I think.

You could have a complete table for testing each type against each other (so you would have a 4x4 array). You can then calculate the index with:
"a_Value * COUNT + b_Value".


This is what I initially thought, but then what of swept collisions? How could I factor them into that array?

Also, wouldn't that equation mean that I would have to have dummy functions in the function array, just so the index is correct?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this