Medals:  Joined: 8/20/2011(UTC) Posts: 1,421 Location: Hannover
Thanks: 18 times Was thanked: 97 time(s) in 92 post(s)
|
Originally Posted by: codesmith  One obvious optimization would be making the rotation table based, I mean to store Sin and Cos values in tables for e.g. angles in Degrees (table of 360 items for example). Of course this would make the rotation more unaccurate but would be an optimization to this if it's needed.
A few months ago one programmer did implement rotation lookup tables and after lots of work I told him that it is most likely not making a difference and he wrote some performance tests to prove his optimizations would be good. As it turns out it made no difference or was even slower than to call the math functions. You are right that calculating sin/cos is a overhead and there are some tricks that can be employed, especially for particle sprites, but overzealous optimizations can lead to ugly and hard to understand code. For this reason all of the optimizations have been removed. We even went the other way and made code slower, but more clean, e.g. if you look at the Matrix class. We tried instead to optimize the code in our build service, the Matrix class is easy, it can just be replaced with an uglier, but faster version. Something like sin/cos is harder, but there might be places where code like this is basically recalculating the same values thousands of times: Code:
foreach (var entity in entities) // lets say this is a huge number like 1000
entity.DrawRotated(90);
public void DrawRotated(float rotation)
{
//..
var vertices = new[]
foreach (var entity in entities) // lets say this is a huge number like 1000
entity.DrawRotated(90);
public void DrawRotated(float rotation)
{
//..
var vertices = new[]
{
GetVertex(drawArea.TopLeft.RotateAround(rotationCenter, rotation), Point.Zero, entity),
GetVertex(drawArea.TopRight.RotateAround(rotationCenter, rotation), Point.UnitX, entity),
GetVertex(drawArea.BottomRight.RotateAround(rotationCenter, rotation), Point.One, entity),
GetVertex(drawArea.BottomLeft.RotateAround(rotationCenter, rotation), Point.UnitY, entity)
};
entity.Get<Image>().Draw(vertices);
}
public Point RotateAround(Point center, float angleInDegrees)
{
RotateAround(center, MathExtensions.Sin(angleInDegrees), MathExtensions.Cos(angleInDegrees));
return this;
}
public void RotateAround(Point center, float rotationSin, float rotationCos)
{
var translatedPoint = this - center;
X = center.X + translatedPoint.X * rotationCos - translatedPoint.Y * rotationSin;
Y = center.Y + translatedPoint.X * rotationSin + translatedPoint.Y * rotationCos;
}
It could be replaced with: Code:
foreach (var entity in entities) // lets say this is a huge number like 1000
entity.DrawRotated(MathExtensions.Sin(90), MathExtensions.Cos(90));
public void DrawRotated(float rotationSin, float rotationCos)
{
//..
var vertices = new[]
foreach (var entity in entities) // lets say this is a huge number like 1000
entity.DrawRotated(MathExtensions.Sin(90), MathExtensions.Cos(90));
public void DrawRotated(float rotationSin, float rotationCos)
{
//..
var vertices = new[]
{
GetVertex(drawArea.TopLeft.RotateAround(rotationCenter, rotationSin, rotationCos), Point.Zero, entity),
GetVertex(drawArea.TopRight.RotateAround(rotationCenter, rotationSin, rotationCos), Point.UnitX, entity),
GetVertex(drawArea.BottomRight.RotateAround(rotationCenter, rotationSin, rotationCos), Point.One, entity),
GetVertex(drawArea.BottomLeft.RotateAround(rotationCenter, rotationSin, rotationCos), Point.UnitY, entity)
};
entity.Get<Image>().Draw(vertices);
}
public void RotateAround(Point center, float rotationSin, float rotationCos)
{
var translatedPoint = this - center;
X = center.X + translatedPoint.X * rotationCos - translatedPoint.Y * rotationSin;
Y = center.Y + translatedPoint.X * rotationSin + translatedPoint.Y * rotationCos;
}
Now just one call to sin and cos was done. It is obviously hard to detect such optimizations, but luckily computers are good at detecting patterns :) This is ongoing work and will take a long time, but certain patterns seem to repeat themselves in game programming (e.g. use of vertex buffers instead of using higher level classes like in this thread). Edited by user Wednesday, May 1, 2013 5:02:03 PM(UTC)
| Reason: fixed code, stupid syntax highlighter
|