- Home /
optimizing Gravitacional object-to-object calculations
i are making a simulator of bodies being atracted to each others based in gravitacional force, so F = G* (M*m/D*D) and this force is applyied to each two objects, if you have four in the scene, will have 16 diferent forces, with one thousand, one milion diferent forces to calculate. this is the code that make all the job ( commemted)
all the position and velocity data is calculated by me, in the scene have no gameObjects, all is represented in a particle system, and each particle is asigned to the objects position every frame.
class Memorized
{
var M : float; // the object mass
var P : Vector3; // the object position
var R : float; // the object radius
var V : Vector3;// the object velocity
}
function atract () {
updateall();// update the objects position and velocity.
for(var k=0;k<numero;k++) // loops trought all objects. sometimes with 1000 objects have 11.8 fps.
{
// caching the main object values for computing performance
var M : float = mem[k].M;
var F : Vector3;
var P : Vector3 = mem[k].P;
var R2 : float = (mem[k].R*2)*(mem[k].R*2);// here is the diameter of the object squared.
for(var i = 0; i<numero; i++) // loops again trought all objects to sum all resulting forces.
{
if(i!=k) // detect if the two objects is the same
{
var D : Vector3 = P - mem[i].P; // distance between the two objects
var Dm : float = D.sqrMagnitude; // sqrmagnitude because is less computing espensive. ( magnitude*magnitude = sqrMagnitude)
if(Dm < R2) // check if the other obj is inside the radius of this.
colidir(k,i); // destroy less mass object and sum this mass, also make a resulting velocity after impact.
else // without this else the force of the destroyed overlaping object is applyied, resulting in total chaos
F -= ((D.normalized)*((M*mem[i].M)/Dm)); // the gravitacional force calculation, this make the all object be atracted to all others.
//( ForceDirection * majormass*minormass/squareddistance)
}
}
if(k<numero)// prevent a index error if the object has colided and do not exist more.
mem[k].V += (F*G)/M; // applying the force to object. ( Acceleration = Force/Mass)
}
}
all works perfectly, but, how i can improve the speed that this works? now, with 900 objects, I've got 11.7-12.0 fps. logicaly, after some colided the fps stay at 80's. how internal unity physics collision detection make which matematic calculation to detect a few of thowsands of objects if are or not coliding? by detecting if the distance between then is smaller tan the colider radius right? (D < R)?
so why my distance calculations between all objects is too more computing espensive than the internal physics system?
even if I comment the part of the code that add force, still getting lower fps than with the same number of rigidbodies and sphere colliders. Can I use GPU support to make this kind of mathematic? how?
thanks in advance.
Answer by ItsAzai · Aug 06, 2014 at 10:56 PM
You can half the computation time of the distance calculations by changing
for(var i = 0; i<**numero**; i++)
into
for(var i = 0; i<**k**; i++)
and then applying the found force to both the k and i object.
If you want it to go even faster, you're probably going to have to give up on some precision. You could try implementing the Barnes-Hut algorithm, which uses spatial octrees to give the most precise calculations to the objects that are closest to the object of which we're trying to find the resulting force.
i did your suggestion to half the calculations, really nice results! now with one thousand objects i achieve 20 fps, and is very promissing the idea of octree optmization.
I read a lot of octree and also quadtree, this make the total tests of distance much less based in the density of the points. But this have good results with much and much objects, with few ones the brute-force method can be less cpu-intensive... also with octrees the area of the game is limited to the size of the box, and with a greater box will need more subdivisions, with more subdivisions the calculations will be expensive...
however... thanks for helping me! ( I will mark you asnwer as correct before some days... waiting some other people ideas)
Your answer
Follow this Question
Related Questions
Why are gravity rigidbodies so performance costly? 1 Answer
Gravity within range 1 Answer
What's a good draw call count? 2 Answers
Android Best performance 1 Answer
make projectiles always hit target 1 Answer