Jump to content
  • Advertisement
Sign in to follow this  
_WeirdCat_

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

This topic is 1481 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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:

 

 

Edited by WiredCat

Share this post


Link to post
Share on other sites
Advertisement

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...

Edited by WiredCat

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!