ok as far as i understand this now
//calculate new position based on velocity and time
D3DXVECTOR3 new_pos1 = e1p + velocity1 * Timer;
D3DXVECTOR3 new_pos2 = e2p + velocity2 * Timer;
//find the distance between the 2 spheres centres
D3DXVECTOR3 newPos = new_pos1 - new_pos2;
float new_dist_sq = (newPos.x * newPos.x + newPos.y * newPos.y + newPos.z * newPos.z);
//A-B plus the size of the bounds combined
float AB = new_dist + (minDist * minDist);
// this is where i could be going wrong,calculating the normal
D3DXVECTOR3 normal;
normal.x = new_pos2.x /new_dist ;
normal.y = new_pos2.y /new_dist;
normal.z = new_pos2.z /new_dist;
//calculate d based on velocity and the normal value
float d = (velocity1.x*normal.x) + (velocity1.y*normal.y) + velocity1.z*normal.z);
///and from d calculate the new velocity
velocity1.x = velocity1.x - (2 * d) * normal.x;
velocity1.y = velocity1.y - (2 * d) * normal.y;
velocity1.z = velocity1.z - (2 * d) * normal.z;
//then
new_pos1 -= velocity1
Now this gives a very accurate collision, no overlapping or anything else, but the change is very sudden, i.e if you walk straight into a sphere holding forward, it will keep jumping back rather than a smooth non movement if that makes sense?
accurate ball-to-ball collision?
Epilef:
Once you found a collision point and surface, for a position based velocity you would want to reflect the old position to the other side of the surface. This way, the next step will compare the "corrected" old position to position, and will get a vector pointing in the reflected direction.
In a Verlet integrated system, just doing this would cause you to lose velocity: the distance between the reflected old_position and the "stopped" collision position is shorter than what was originally calculated. To fix this you can either:
- Push old_position backwards along the reflected vector until it is the right distance away. This is a hacky way of fixing it, but it simplifies things.
- Push position forwards along the reflected vector for whatever distance was left after the collision bounced it. In this case, you would need to repeat your collision process.
It's hard to give more details without having any code.
Stowelly:
The change is probably sudden because:
Velocity is units per second, and you're adding a whole second of velocity to the position. Hopefully you're not running at 1FPS :D You have to calculate how much "time" is left over after your collision happened, and scale the velocity accordingly.
Every frame you're processing movement over a period of time. e.g. the time since the last frame was 33ms (0.033s) and your velocity is 100 units per second. So, the movement for this frame is going to be 100 * 0.033 == 3.3 units. If you move 2 units before colliding, the reflected velocity should be scaled so that you only move 1.3 additional units in the reflected direction.
It also appears that you have TWO moving objects. The process as I described it is intended for one moving object and a static, world object that doesn't really react to collisions. If you have two moving objects and you want the second to get pushed around, you have to apply some velocity to the object you collide with as well.
[Edited by - SantaClaws on February 1, 2007 5:51:24 PM]
Once you found a collision point and surface, for a position based velocity you would want to reflect the old position to the other side of the surface. This way, the next step will compare the "corrected" old position to position, and will get a vector pointing in the reflected direction.
In a Verlet integrated system, just doing this would cause you to lose velocity: the distance between the reflected old_position and the "stopped" collision position is shorter than what was originally calculated. To fix this you can either:
- Push old_position backwards along the reflected vector until it is the right distance away. This is a hacky way of fixing it, but it simplifies things.
- Push position forwards along the reflected vector for whatever distance was left after the collision bounced it. In this case, you would need to repeat your collision process.
It's hard to give more details without having any code.
Stowelly:
The change is probably sudden because:
new_pos1 -= velocity1
Velocity is units per second, and you're adding a whole second of velocity to the position. Hopefully you're not running at 1FPS :D You have to calculate how much "time" is left over after your collision happened, and scale the velocity accordingly.
Every frame you're processing movement over a period of time. e.g. the time since the last frame was 33ms (0.033s) and your velocity is 100 units per second. So, the movement for this frame is going to be 100 * 0.033 == 3.3 units. If you move 2 units before colliding, the reflected velocity should be scaled so that you only move 1.3 additional units in the reflected direction.
It also appears that you have TWO moving objects. The process as I described it is intended for one moving object and a static, world object that doesn't really react to collisions. If you have two moving objects and you want the second to get pushed around, you have to apply some velocity to the object you collide with as well.
[Edited by - SantaClaws on February 1, 2007 5:51:24 PM]
thanks for being so patient, im in the process of studying maths and physics on my games degree and shouldnt have much more problems with this soon
i really dont think its the time causing this issue, ive tried multiplying the velocity by the current frame timer and although it does seem a little bit better it still has alot of issues, basically if i stand next to the sphere its fine, just edge towards it until its just within the collision area then it bounces back probably about the distance of the entire boundary
i just cant visualise where in the algorithm is causing this, again thanks alot
EDIT: it appears to do it on one side of the objects more than the other
ive also uploaded the release version of this to demonstrate what i mean
http://download.yousendit.com/050CCB60712EF5EA
also oli's collision and response tutorial has a broken link unfortunately
[Edited by - Stowelly on February 2, 2007 4:02:53 AM]
i really dont think its the time causing this issue, ive tried multiplying the velocity by the current frame timer and although it does seem a little bit better it still has alot of issues, basically if i stand next to the sphere its fine, just edge towards it until its just within the collision area then it bounces back probably about the distance of the entire boundary
i just cant visualise where in the algorithm is causing this, again thanks alot
EDIT: it appears to do it on one side of the objects more than the other
ive also uploaded the release version of this to demonstrate what i mean
http://download.yousendit.com/050CCB60712EF5EA
also oli's collision and response tutorial has a broken link unfortunately
[Edited by - Stowelly on February 2, 2007 4:02:53 AM]
what does the 2 represent in this operation?
velocity.z = velocity.z - (2 * d) * normal.z
if i make it smaller my refections on the smaller spheres are very accurate, if i make it larger the reflections for the bigger spheres is better
velocity.z = velocity.z - (2 * d) * normal.z
if i make it smaller my refections on the smaller spheres are very accurate, if i make it larger the reflections for the bigger spheres is better
ive solved this now, thanks alot for all your help
while(new_dist_sq <= minDist * minDist )
{
D3DXVECTOR3 normal;
float moveApart = 0.002f;
normal = e2p - e1p;
new_pos1 -= normal * moveApart * time;
newPos = new_pos1 - new_pos2 ;
new_dist_sq = (newPos.x * newPos.x + newPos.y * newPos.y + newPos.z * newPos.z);
}
while(new_dist_sq <= minDist * minDist )
{
D3DXVECTOR3 normal;
float moveApart = 0.002f;
normal = e2p - e1p;
new_pos1 -= normal * moveApart * time;
newPos = new_pos1 - new_pos2 ;
new_dist_sq = (newPos.x * newPos.x + newPos.y * newPos.y + newPos.z * newPos.z);
}
Damn you forums! My big explanation waiting to be posted goes to waste. :(
Haha, glad to hear you got it solved, though.
Haha, glad to hear you got it solved, though.
Hi again, I'm working on this problem again after a long time of putting it aside. I hadn't gotten it to work before, and now I've tried a lot more and I still can't figure it out.
Why is the Pythagorean theorem used, if that's only for right angles? It seems like that's the problem, because 'd' is almost always larger than it should be. Also, in this line:
A.position -= V*d
Doesn't V*d come out to be a very large vector?
It seems like i'm doing this all wrong, but i've checked over it and tried lots of other things, but it just doesn't work...
Why is the Pythagorean theorem used, if that's only for right angles? It seems like that's the problem, because 'd' is almost always larger than it should be. Also, in this line:
A.position -= V*d
Doesn't V*d come out to be a very large vector?
It seems like i'm doing this all wrong, but i've checked over it and tried lots of other things, but it just doesn't work...
You should really start using vector notation.
Spheres [PA, ra], [PB, rb].
Spheres [PA, ra], [PB, rb].
Vector Delta = PA - PB;float d2 = Delta.DotProduct(Delta);float r = ra + rb;float r2 = r * r;if(d2 < r2){ float d = sqrt(d2); Vector Push = Delta * (r - d) / d; PA += Push * 0.5f; PB -= Push * 0.5f;}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement