XNA Collision Gravity Problem

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
LeonBlade
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1314
Joined: Thu Jan 22, 2009 12:22 am
Current Project: Trying to make my first engine in C++ using OGL
Favorite Gaming Platforms: PS3
Programming Language of Choice: C++
Location: Blossvale, NY

XNA Collision Gravity Problem

Post by LeonBlade »

Hey everyone,

I have currently a player model setup in a GameObject class which stores velocity, position, collision sphere, rotation, etc.

Now, I have gravity kick in by saying...

Code: Select all

player.VelocityY += 0.4f;
player.PositionY = player.VelocityY;
Something like that...

Now, the collision spheres meet...

Code: Select all

if (player.CollisionSphere.Intersects(groundCollision))
{
     player.VelocityY = 0.0f;
}
Basically stopping all Y velocity... but then when I move off of a surface like a sphere, it needs to translate over on X and or Z axis and translate on the Y axis towards the ground and it keeps doing this over and over which slows it down basically giving away the fact that I'm using a sphere...

Someone suggested to limit the velocity (which makes sense) so that I don't keep increasing speed slowing down player.
How would I go about doing this?

I'm pretty sure I got some form of working collision for regular stuff not based on gravity... here is some psuedo code for it, if you can find a better solution or know one (which is most likely true) then tell me what you got.

Code: Select all

if (player.Collision.Intersects(object.Colisision))
{
     if (player.PositionX <= object.PositionX)
     {
          player.PositionX -= 0.1f;
          player.VelocityX = 0.0f;
     }

     // repeat for greater than and Z for less and greater than
}
Something like that... I'm sure that is HORRIBLE way to check for collision but... lol... I'm assuming it at least is functional which is all I care about for right now, unless someone has a better solution...

Thanks,
LeonBlade
There's no place like ~/
User avatar
LeonBlade
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1314
Joined: Thu Jan 22, 2009 12:22 am
Current Project: Trying to make my first engine in C++ using OGL
Favorite Gaming Platforms: PS3
Programming Language of Choice: C++
Location: Blossvale, NY

Re: XNA Collision Gravity Problem

Post by LeonBlade »

Nobody?
There's no place like ~/
User avatar
M_D_K
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1087
Joined: Tue Oct 28, 2008 10:33 am
Favorite Gaming Platforms: PC
Programming Language of Choice: C/++
Location: UK

Re: XNA Collision Gravity Problem

Post by M_D_K »

First I have a question. Does XNA update the position based on velocity or do you have to do it yourself?
Gyro Sheen wrote:you pour their inventory onto my life
IRC wrote: <sparda> The routine had a stack overflow, sorry.
<sparda> Apparently the stack was full of shit.
User avatar
LeonBlade
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1314
Joined: Thu Jan 22, 2009 12:22 am
Current Project: Trying to make my first engine in C++ using OGL
Favorite Gaming Platforms: PS3
Programming Language of Choice: C++
Location: Blossvale, NY

Re: XNA Collision Gravity Problem

Post by LeonBlade »

It's my own class I have to update it but it's one line position += velocity
There's no place like ~/
User avatar
M_D_K
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1087
Joined: Tue Oct 28, 2008 10:33 am
Favorite Gaming Platforms: PC
Programming Language of Choice: C/++
Location: UK

Re: XNA Collision Gravity Problem

Post by M_D_K »

OK well gravity isn't directly velocity it affects it but you don't mess with it directly.

Code: Select all

//timems = Delta time
m_velocity.x += m_acceleration.x * timems;
m_velocity.y += m_acceleration.y * timems;
m_velocity.z += m_acceleration.z * timems;
			
m_position.x += m_velocity.x * timems;
m_position.y += m_velocity.y * timems;
m_position.z += m_velocity.z * timems;
That is code I use for my game objects and such. Gravity would be set in acceleration.y in OpenGL I use -9.81(in 3D space). I don't know if its the same in DirectX but still its a starting point.

So what you want to do is add another Vector to your class and use that to manipulate gravity. The result is that when that code updates every frame, objects that a going up will come down again.
Gyro Sheen wrote:you pour their inventory onto my life
IRC wrote: <sparda> The routine had a stack overflow, sorry.
<sparda> Apparently the stack was full of shit.
User avatar
LeonBlade
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1314
Joined: Thu Jan 22, 2009 12:22 am
Current Project: Trying to make my first engine in C++ using OGL
Favorite Gaming Platforms: PS3
Programming Language of Choice: C++
Location: Blossvale, NY

Re: XNA Collision Gravity Problem

Post by LeonBlade »

Alright, cool I'll check this out tomorrow.
There's no place like ~/
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: XNA Collision Gravity Problem

Post by qpHalcy0n »

For a very rudimentary collision case (sphere to plane) which is what you're doing I gather, the simplest case would be to calculate a resultant velocity from the collision.

You can evaluate the collision based on a poll of a collision query at time0 (now), and time1 (interpolated for the next frame). The collision becomes a simple dot product of the center of the spheroid to the collider's plane normal. If the collider is a curved surface, the tangent at the nearest point would suffice. This yields the
distance of the sphere to the plane. If the distance > 0, you are on the front-facing side of the plane (guaranteed if your polygons are wound correctly), and < 0 if you are on the backside of the plane. So then obviously if distance at time0 is > 0 and distance at time1 < 0, then an interpolated collision has occured. By accounting for the sphere's radius, you can fine tune the collision time. So that: if distance < radius then a collision has occured. Accounting for high object velocity is why two samples are necessary, because its conceivable that the object may be moving so fast that simply accounting for the sphere's radius at a single time sample may never evaluate.

Since you've determined that a collision has happened you now need to determine a result. Well, in simplest terms, the result is a new velocity vector which is simplified as a reflection of the incoming velocity (before the collision) about the plane's normal. The amount of "deadness" or "absorbance" can be reflected by scaling the resultant vector by a value ranging 0-1. Finding the reflection vector is some basic geometry:

r = result
i = incoming vector
n = plane normal

r = i - 2 * n * dot_product(i, n);

Then the object's new velocity becomes r. You can deaden the "bounciness" by scaling r from 0-1.

This will eliminate that kind of effect you're describing. This is also an extremely fast routine. However, the object's reaction to a planar collision will be VERY simple and obvious (like a bouncy ball bouncing around walls, even though the object it encapsulates may be a cube). It would not take into account complex objects colliding with other complex objects, which can get rather hairy.


In sum:
determine collision at time0
determine collision at time1
if((distance at time0 > 0 && distance at time1 < 0) || distance at time0 < radius)
{
collision has occured...evaluate resultant velocity vector
m_player.velocity = resultant velocity vector
}

m_player->update
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: XNA Collision Gravity Problem

Post by MarauderIIC »

Now that was useful.
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
LeonBlade
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1314
Joined: Thu Jan 22, 2009 12:22 am
Current Project: Trying to make my first engine in C++ using OGL
Favorite Gaming Platforms: PS3
Programming Language of Choice: C++
Location: Blossvale, NY

Re: XNA Collision Gravity Problem

Post by LeonBlade »

The BoundingBox and sphere both have an intersect method.
For some reason, I can't stop my player...
There's no place like ~/
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: XNA Collision Gravity Problem

Post by qpHalcy0n »

Well then you need to be sure that they're behaving as they're expected to and you need to see what you get back. Either way, if then the collision has happened you may still need to go through the routine of obtaining a result velocity from the collision yourself.
User avatar
LeonBlade
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1314
Joined: Thu Jan 22, 2009 12:22 am
Current Project: Trying to make my first engine in C++ using OGL
Favorite Gaming Platforms: PS3
Programming Language of Choice: C++
Location: Blossvale, NY

Re: XNA Collision Gravity Problem

Post by LeonBlade »

What I'm doing is basically poor but...

Code: Select all

if (player.CollisionSphere.Intersects(groundCollision))
{
     player.VelocityY = 0.0f;
}
else
{
     player.Velocity = -1.0f;
}
Just to see if it works, and sometimes the player doesn't move down at all (which could mean my bounding sphere is HUGE, but I doubt it) and other times it just moves down and under the ground plane...

I don't have the project with me, it's at school, so there isn't really much I can do until Monday and then I can continue whenever I want when I get my new computer.

Like I said before, the position is updated every game frame with

Code: Select all

player.Postition += player.Velocity;
Which works fine, except for the collision stuff... so I'm not sure why I'm getting these problems...
All collision tutorials/sample are height maps... bleh... gay... not what I want...
There's no place like ~/
Post Reply