Sign in to follow this  

Sliding collision, lil help

This topic is 3106 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

Alright, so here's the environment. C# XNA. The First colliding object is a BoundingSphere around my camera the second is a simple AABB(BoundingBox). Here's what I have so far:

                    BoundingBox AABB = worldCollision[i];
                    if (cameraSphere.Contains(AABB) != ContainmentType.Disjoint){
                        //The Sphere and the AABB collide

                        //1.Get closest coord from sphere
                        Vector3 collisionOrigin = ClosestPointOnAABB(fpCam.Position, AABB);
                        //2.Calculate sliding plane normal
                        Vector3 planeNormal = fpCam.Position - collisionOrigin;
                        planeNormal.Normalize();
                        //3.Get last Vector transformation done on the Camera
                        float Velocity = fpCam.lastMovementVector().Length();
                        //Calculate new location to move
                        Vector3 pushVelocity = planeNormal * Velocity;
                        //Set new location
                        fpCam.Position += pushVelocity;
 
                    }
I'm not sure exactly what I'm doing wrong. It works, and it works, but it is really bouncy and jumpy. Any ideas why? [Edited by - Cakey on June 10, 2009 4:59:02 PM]

Share this post


Link to post
Share on other sites
newer code less jittery but still has some error or something. Any ideas?

BoundingBox AABB = worldCollision[i];
if (cameraSphere.Contains(AABB) != ContainmentType.Disjoint){
//The Sphere and the AABB collide

//1.Get closest coord from sphere
Vector3 collisionOrigin = ClosestPointOnAABB(fpCam.Position, AABB);
//2. Get the overlapping value of the intersection
Vector3 getOverLap = collisionOrigin - fpCam.Position;
float penetrationDepth = (float)Math.Sqrt((getOverLap.X * getOverLap.X +
getOverLap.Y * getOverLap.Y +
getOverLap.Z * getOverLap.Z));

//3. Subtract Overlap from Colliding sphere size
penetrationDepth = minimumDistance + penetrationDepth;

//4. Calculate sliding plane normal
Vector3 planeNormal = fpCam.Position - collisionOrigin;
planeNormal.Normalize();

//5.Get last Vector transformation done on the Camera
float Velocity = fpCam.lastMovementVector().Length() * penetrationDepth;

//6. Calculate new location to move
Vector3 pushVelocity = planeNormal * Velocity;

//Set new location
fpCam.Position += pushVelocity;
}

Share this post


Link to post
Share on other sites
There are a couple of things about the code that are a bit inaccurate and/or confusing. Here's the code with a few comments added to point to some of the problem areas:

BoundingBox AABB = worldCollision[i];
if (cameraSphere.Contains(AABB) != ContainmentType.Disjoint){

// Some of your variable names are a little unclear, which makes
// the code hard to follow. I'll point them out as I go, starting
// with 'collisionOrigin' (I kind of see what you're getting at,
// but I would just call it 'closestPoint').
Vector3 collisionOrigin = ClosestPointOnAABB(fpCam.Position, AABB);

// There's some redundancy here in that you compute the vector from the
// closest point to the sphere center twice (reversed the second time).
// You also compute its length twice. These computations can be combined,
// which will tighten up the code and make it a bit more efficient.

// 'getOverlap' is another confusing variable name (it's an object, but
// the name includes a verb). Also, it's not the overlap, but rather the
// 'inverse' of the overlap (sort of). Maybe 'difference' instead?
Vector3 getOverLap = collisionOrigin - fpCam.Position;

// You should never code common operations such as computing the length
// of a vector manually like this; make a 'length' function instead. In
// addition to making the code easier to debug, it'll make it easier
// to read as well; this statement, for example, will become:

// float penetrationDepth = getOverlap.Length();

float penetrationDepth = (float)Math.Sqrt((getOverLap.X * getOverLap.X +
getOverLap.Y * getOverLap.Y +
getOverLap.Z * getOverLap.Z));

/// What's 'minimumDistance'? Is that the sphere's radius?
penetrationDepth = minimumDistance + penetrationDepth;

// This is the duplication I was talking about (you've already
// computed the negative of this vector, and its length, so you
// don't need to do it again here).
Vector3 planeNormal = fpCam.Position - collisionOrigin;
planeNormal.Normalize();

// The name 'Velocity' is incorrect (also, the capitilization is
// inconsistent, which is confusing). A velocity has a speed and direction;
// this variable should just be called 'speed'.
float Velocity = fpCam.lastMovementVector().Length() * penetrationDepth;

// I would have to spend a little time with this to
// understand what it is you're doing exactly, but I have a
// feeling (which could be wrong) that it's incorrect. Cleaning
// up the code will make it much easier to tell what's going
// on though.
Vector3 pushVelocity = planeNormal * Velocity;
fpCam.Position += pushVelocity;
}

Share this post


Link to post
Share on other sites
Yes the minimumDistance is the boundingSpheres radius.


here's the fixes you suggested:
//The Sphere and the AABB collide
//1.Get closest coord from sphere
Vector3 closestPoint = ClosestPointOnAABB(fpCam.Position, AABB);

//2. Get the overlapping value of the intersection
Vector3 difference = closestPoint - fpCam.Position;
float penetrationDepth = minimumDistance - difference.Length();

//4. Calculate sliding plane normal
Vector3 planeNormal = fpCam.Position - closestPoint;
planeNormal.Normalize();
//5.Get last Vector transformation done on the Camera
float speed = fpCam.lastMovementVector().Length() * penetrationDepth;

//6. Calculate new location to move
Vector3 pushVelocity = planeNormal * speed;

//Set new location
fpCam.Position += pushVelocity;


For some reason this code is NOT jittery. and appears to work but is the equation wrong? What if I collided on the y-axis?

[Edited by - Cakey on June 10, 2009 5:06:16 PM]

Share this post


Link to post
Share on other sites
To be honest I can't quite figure out what your code is supposed to do (maybe I'm just missing something).

The following code is similar to yours, but instead resolves the intersection by displacing the sphere using the minimum translational vector (not compiled or tested). Note also that I removed a few calculations that were redundant:

Vector3 closestPoint = ClosestPointOnAABB(fpCam.Position, AABB);

Vector3 difference = fpCam.Position - closestPoint;
float length = difference.Length();
float penetrationDepth = minimumDistance - length;

Vector3 planeNormal = difference / length;

// Resolve intersection:
fpCam.Position += planeNormal * penetrationDepth;

Share this post


Link to post
Share on other sites

This topic is 3106 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this