Advertisement

Problem with positioning an object after no collision :) sounds strange?:P

Started by September 30, 2014 07:44 PM
0 comments, last by _WeirdCat_ 10 years, 4 months ago

Hi, i have a problem with calculating position of a tank that its position is calculated from 4 points (see image below there are 4 spheres on the corners of tank hull - red green white and blue)

tankf.jpg

So i do following steps:

First i calculate forces that are acting on the tank (in this example tank is dropped from 20 meters above the surface), i simplified the formula so force acting on the tank is gravity (weight) only. It should fall to the point on the surface this big red sphere ;]

Then after setting new position of a tank i check whenever there was a collision with the surface[ from tank old position to the new one) and if there was i set the tank to the proper position. BUT problem occurs when theres no collision at all

let me start from begin:

calculate forces acting on tank

for each collision sphere (white,red,green,blue):

check collision (from old position to the new position - new pos, is a pos where we want to go with the tank) if there was no collision return that point where we want to go (new pos)










fl = col->SPHERE_INTERSECT_POLYGON(col_front_left,col_front_left + movement_ray,2.0f,sector,facei,rfl); <-- last value is the returned point
fr = col->SPHERE_INTERSECT_POLYGON(col_front_right,col_front_right + movement_ray,2.0f,sector,facei,rfr);

rl = col->SPHERE_INTERSECT_POLYGON(col_rear_left,col_rear_left + movement_ray,2.0f,sector,facei,rrl);
rr = col->SPHERE_INTERSECT_POLYGON(col_rear_right,col_rear_right + movement_ray,2.0f,sector,facei,rrr);

col_front_left, col_front_right, col_rear_left, col_rear_right are positions of these collision spheres. the return point of collision or no collision is

rfl for front left , rfr for front right, rrl for rear left, rrr for rear right

fl,fr,rl,rr are bools to help me determinate where collision occured.

then i calculate the actual pitch and roll of the tank, and the new roll and pitch after collision(or no collision)

then i subtract them to see the difference (and then i can rotate tank by this angle)

a(anglename) stands for actual(anglename) n(anglename) stands for new(anglename)










t3dpoint aroll  = ( (col_front_left - col_front_right) + (col_rear_left - col_rear_right) ) /2.0f;

t3dpoint apitch = ( (col_front_left - col_rear_left) + (col_front_right - col_rear_right) ) /2.0f;

t3dpoint nroll 	= ( (rfl - rfr) + (rrl - rrr) ) / 2.0f;

t3dpoint npitch = ( (rfl - rrl) + (rfr - rrr) ) / 2.0f;

so now we are here since tank position and rotation is represented by 4 points (these collision spheres)

i calculate the position like

pos = (rfl+rfr+rrl+rrr) / 4.0f; (add all sphere positions and then divide it by the amount of spheres) and this is the main line causing problems, whenever i want to go down it goes infront...

heres the full code:












void __fastcall CheckForCollision()
{
int facei = ReturnFaceIndex(oldc);

t3dpoint movement_ray = vectorAB(oldc,pos); //oldc is a point before movement, pos is a point where we want to go (after movement).

t3dpoint rfl, rfr, rrl, rrr;
bool fl,fr,rl,rr;

rfl = col_front_left;
rfr = col_front_right;

rrl = col_rear_left;
rrr = col_rear_right;

     // &PS, //
fl = col->SPHERE_INTERSECT_POLYGON(col_front_left,col_front_left + movement_ray,2.0f,sector,facei,rfl);
fr = col->SPHERE_INTERSECT_POLYGON(col_front_right,col_front_right + movement_ray,2.0f,sector,facei,rfr);

rl = col->SPHERE_INTERSECT_POLYGON(col_rear_left,col_rear_left + movement_ray,2.0f,sector,facei,rrl);
rr = col->SPHERE_INTERSECT_POLYGON(col_rear_right,col_rear_right + movement_ray,2.0f,sector,facei,rrr);



t3dpoint aroll  = ( (col_front_left - col_front_right) + (col_rear_left - col_rear_right) ) /2.0f;

t3dpoint apitch = ( (col_front_left - col_rear_left) + (col_front_right - col_rear_right) ) /2.0f;

t3dpoint nroll 	= ( (rfl - rfr) + (rrl - rrr) ) / 2.0f;

t3dpoint npitch = ( (rfl - rrl) + (rfr - rrr) ) / 2.0f;


//. u = v - n * dot(n, v)
//
// cross(n, cross(v, n))

t3dpoint A,B, n;

A =  vectorAB(sector->VBO_V[sector->VBO_BE[facei].INDEX_START],sector->VBO_V[sector->VBO_BE[facei].INDEX_START+1]);

B =  vectorAB(sector->VBO_V[sector->VBO_BE[facei].INDEX_START],
sector->VBO_V[sector->VBO_BE[facei].INDEX_START+3]);
n = vectorcross(A,B);

t3dpoint proj_surfacev_apitch = n * (apitch*n);
t3dpoint proj_surfacev_npitch = vectorcross(n, vectorcross(npitch,n));

t3dpoint proj_surfacev_aroll = vectorcross(n, vectorcross(aroll,n));
t3dpoint proj_surfacev_nroll = vectorcross(n, vectorcross(nroll,n));

float pitcha = AngleBetweenVectors(proj_surfacev_apitch, apitch);
float rolla = AngleBetweenVectors(proj_surfacev_aroll, aroll);
float pitchn = AngleBetweenVectors(proj_surfacev_npitch, npitch);
float rolln = AngleBetweenVectors(proj_surfacev_nroll, nroll);

float res_pitch = pitchn - pitcha;
float res_roll = rolln - rolla;


hull.rotation.pitch( cos(res_pitch), sin(res_pitch) );
hull.rotation.DoRotation();

hull.rotation.roll( cos(res_roll), sin(res_roll) );
hull.rotation.DoRotation();



pos = (rfl+rfr+rrl+rrr) / 4.0f;

}


any suggestions? i think the code is fine, maybe someone else will tell me that, it should work but somehow it isn'teverything btween las sphere_intersect_polygon and pos = (xx) / 4.0f is irrevelant to the topic.

so the code that is responsible for this is like:




void __fastcall CheckForCollision()
{
int facei = ReturnFaceIndex(oldc);

t3dpoint movement_ray = vectorAB(oldc,pos); //oldc is a point before movement, pos is a point where we want to go (after movement).

t3dpoint rfl, rfr, rrl, rrr;
bool fl,fr,rl,rr;

rfl = col_front_left;
rfr = col_front_right;

rrl = col_rear_left;
rrr = col_rear_right;

     // &PS, //
fl = col->SPHERE_INTERSECT_POLYGON(col_front_left,col_front_left + movement_ray,2.0f,sector,facei,rfl);
fr = col->SPHERE_INTERSECT_POLYGON(col_front_right,col_front_right + movement_ray,2.0f,sector,facei,rfr);

rl = col->SPHERE_INTERSECT_POLYGON(col_rear_left,col_rear_left + movement_ray,2.0f,sector,facei,rrl);
rr = col->SPHERE_INTERSECT_POLYGON(col_rear_right,col_rear_right + movement_ray,2.0f,sector,facei,rrr);



pos = (rfl+rfr+rrl+rrr) / 4.0f;

}

maybe il post a vid what i get:

i found what is causing the problem. Its the gravity vector itself:

original code:








t3dpoint gravity_vec = -pos;

t3dpoint Q = Normalize(gravity_vec);

Q = Q * (eGForce * mass);

whenever i write gravity_vec = t3dpoint(0,-1,0); tank begins to fall at once, so this is obvious that normalization isn't precise or maybe it needs to be truncated.

Since normalization of a vector is given by

{

x = x/veclen;

y = y/veclen;

z = z/veclen;

}

i did something liek this:








t3dpoint gravity_vec = -pos;

t3dpoint Q = Normalize(gravity_vec);

Q.x =  float( int(Q.x*100.0f) ) / 100.0f;
Q.y =  float( int(Q.y*100.0f) ) / 100.0f;
Q.z =  float( int(Q.z*100.0f) ) / 100.0f;

Q = Q * (eGForce * mass);

Now it seems to work, but it lacks the precision

another thing is that i used a fixed time: dt = 0.033; //1/3 of second when i switched it to the time between frames everything started to working fine (with the old code)

i do translation like this










t3dpoint result_force = Q;

t3dpoint Acceleration = result_force / mass;

pos = pos + (vel * dt);
vel = vel + (Acceleration * dt);

so what was the problem why it couldnt work with 0.033 even if gravity normalize vector was ok (from the beggining i have checked it ), worst thing is that now dt is smaller than 0.033 and it works...

somehow multiplication was screwing everything..

now it works....

well i forgot to ad dthat i changed the positioning forumla

there wasnt average of 4 spheres, if i do old one forumla tank still goes front and then changes to go down like in old vid...

This topic is closed to new replies.

Advertisement