Hello all. I'm currently working on a soft body physics library for XNA called "JelloPhysics". the library is to the point that it can be used now, and is available from my
homepage.
Anyway, as usual I got the library working on Windows, and it seemed to run quite well, and then I ported over to 360, and the performance was not exactly stellar. So I did a lot of research, and thanks to information on the blogs and this forum, I've been able to increase the performance on the 360 quite a bit. This was mostly through avoiding allocating heap objects in my code, and reducing operator overloading / inlining inner loop math for all of the Vector2's (the engine is all in 2D).
I have a project I'm working on to test the library, and according to StopWatch, currently my physics.update() function is taking about 0.34ms on Windows, and 1.51ms on X360. That puts the 360 at about 4.4x slower than the windows code.
using Nprof I've found where most of the time is spent in the update() function, and I'm trying to optimize those functions as much as I can... however I don't see much left that I can do.
in my code, I use a lot of List<> containers for keeping track of everything. I iterate through the List<> with a simple for loop, accessing members with the [] operator.
I am wondering if anyone has done any profiling to see if accessing members of a List<> is slower than, say accesing an array, on the 360?
currently I am trying to optimize the following function, and I'm not sure where to go from here.
The only things I can think is that the = operator on Vector2 might be a function call, so inlining that might give a slight gain, and possibly changing from a List<> to some other container that is faster to access on the 360, if such a thing exists.
of course, I also probably need to try and come up with an algorithm that doesn't require calling this function as much as I currently am, but the 4.4x difference in speed between my Windows laptop and the 360 seems a bit excessive, so I'm inclined to believe I still have some code in here somewhere that is particularly slow on the 360.
here is the function.
public bool contains(ref Vector2 pt)
{
// basic idea: draw a line from the point to a point known to be outside the body. count the number of
// lines in the polygon it intersects. if that number is odd, we are inside. if it's even, we are outside.
// in this implementation we will always use a line that moves off in the positive X direction from the point
// to simplify things.
Vector2 endPt = new Vector2();
endPt.X = mAABB.Max.X + 0.1f;
endPt.Y = pt.Y;
// line we are testing against goes from pt -> endPt.
bool inside = false;
Vector2 edgeSt = mPointMasses[0].Position;
Vector2 edgeEnd = new Vector2();
int c = mPointMasses.Count;
for (int i = 0; i < c; i++)
{
// the current edge is defined as the line from edgeSt -> edgeEnd.
if (i < (c - 1))
edgeEnd = mPointMasses[i + 1].Position;
else
edgeEnd = mPointMasses[0].Position;
// perform check now...
if (((edgeSt.Y <= pt.Y) && (edgeEnd.Y > pt.Y)) ||
((edgeSt.Y > pt.Y) && (edgeEnd.Y <= pt.Y)))
{
// this line crosses the test line at some point... does it do so within our test range?
float slope = (edgeEnd.X - edgeSt.X) /
(edgeEnd.Y - edgeSt.Y);
float hitX = edgeSt.X + ((pt.Y - edgeSt.Y) * slope);
if ((hitX >= pt.X) && (hitX <= endPt.X))
inside = !inside;
}
edgeSt = edgeEnd;
}
return inside;
}