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);
}
[C#] Not happy with the following method, is there a better alternative?
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?
Thank you.
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!
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!
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?
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?
Method overloading?
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.
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.
That method doesn't work:
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'
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'
Oops, my bad. I hadn't realized how you would use it.
You may be able to implement a solution in terms of the visitor pattern though.
You may be able to implement a solution in terms of the visitor pattern though.
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".
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".
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.
In that case you might want to test the overload versus delegate invokation for performance.
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?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement