Collision detection

Started by
4 comments, last by tom76 22 years, 6 months ago
I have a flat terrain with walls, and a cyclinder in the middle. I use the following code to make sure the player doesn''t go through them. // Keep ship in bounds if( g_pShip->vPos.x < -5.0f || g_pShip->vPos.x > +5.0f || // this applies to the ship ONLY g_pShip->vPos.y < -5.0f || g_pShip->vPos.y > +5.0f ) { D3DXVec3Normalize( &g_pShip->vVel, &g_pShip->vPos ); // set ship back g_pShip->vVel.x *= -1.0f; // the bouncing g_pShip->vVel.y *= -1.0f; // depends on velocity g_pShip->vVel.z *= -1.0f; } Very crude as you can see, simply stopping the player going so far away from the centre of the play area. How would I stop the player going THROUGH the cyclinder in the middle? "I envy you, who has seen it all" "And I, young sir, envy you, who have yet to see it for the first time..." - Daniel Glenfield 1st October 2001
if (witisism == !witty) return to_hole
Advertisement
If you have cylinder that is hole-up oriented, you can compute distance between center of it and player point (point that is closer to center of cyclinder that others). Let it be d.
and compare d with cylinder radius. if if >= than point is inside.
(f) Fisher
In a 3D game it would be more than that, the ship could then pass through the top or bottom of the cylinder because the radius of a cylinder such as a 10'' pipe sticking out of the ground may only have a radius in a half inch. You also have to somehow take the lenght of the cylinder into consideration.

~Vendayan
"Never have a battle of wits with an unarmed man. He will surely attempt to disarm you as well"~Vendayan
Like fisher, I say that you''ll need to check the distance from the center of the cylinder and, if it''s near enought to have a collision, check if the ship is higher or lower than the cylinder to be sure it will not go over or below the cylinder. For the walls, I suggest you to do axis-align bounding box detection if all your walls are aligned to the axis. If not, then do oriented bounding box.
François DagenaisDagenais.f@videotron.ca
I agree with fisher as far as using distance goes- let me take that just one more step-

First off, I couldn''t help but see your code example reads just like line 1474 of UpdateDisplayList() in donuts.cpp- gawd, I love that source! I''m just going to go on the premise that''s the codebase we''re looking at. And, BTW if your interested, I implemented some neat things with Donuts (bullets exploding/indestructable/heatseeking) that you might be able to make use of. More on that at the bottom of this rant.

Welp, to business. In your IF we''re checking what? Any possibility the ship is somewhere it''s not supposed to be. To implement the obstruction in the middle you simply have to throw another ''or'' in there and check to see if the ship is within the cylinder.

If you scroll down a couple hundred lines to the CheckForHits() function, you''ll see about half a screen of code down is the line

// Check if bullet is in radius of objectFLOAT fDistance = D3DXVec3Length( &(pBullet->vPos - pObject->vPos) ); 


That''s a really easy way to handle the "distance" thing. The main problem here is that we''re not exactly working in 3 dimensions. As I understand it, the level looks from above like a small circle inside a big square. Our z-coordinate (if that''s the up/down of the game) should be ignored in the calculation of the distance from the center of the cylinder, else your collision detection will treat the cylinder like a sphere. Although we *could* use the D3DXVec2Length (I belive that''s the two-dimensional equivelant to the above function) and some fancy reassignments with the coords of the ship, it would be a much easier method to just set the z of the cylinder to the z of the ship before calculating length.

Of course, this means we''ll need a D3DXVECTOR3 variable (same type as your ship''s vpos, and I suggest global for this) set to the basic "whereabouts" of your cylinder. Have another value for the radius (point from center) of the cylinder. Mix''em all together, and you get...

  // Cylinder Data// (put at the top of the file with all the other globals)D3DXVECTOR3 g_cylPos;FLOAT       g_cylRad;// Initialize Data for the cylinder (center point IS 0, right?)// (Throw this around line 500 in CreateGameObjects)g_cylPos.x = 0.0f;g_cylPos.y = 0.0f;g_cylPos.z = 0.0f;g_cylRad = 0.5f;    // Make this anything you want.// Keep ship in bounds// (You know where this is)g_cylPos.z = g_pShip->vPos.z; // Put them on the "same level"if( g_pShip->vPos.x < -5.0f || g_pShip->vPos.x > +5.0f ||    g_pShip->vPos.y < -5.0f || g_pShip->vPos.y > +5.0f ||    D3DXVec3Length(&(g_pShip->vPos - g_cylPos)) <= g_cylRad ){     D3DXVec3Normalize( &g_pShip->vVel, &g_pShip->vPos );     g_pShip->vVel.x *= -1.0f;     g_pShip->vVel.y *= -1.0f;     g_pShip->vVel.z *= -1.0f;}  


I haven''t tested this, but it looks to me like it should work. Lemme know if this helps, and... if you want, see what fun I had with Donuts3D, you may try clicking here. Well, Have fun, and good luck!

-Tok.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
"Hey, I was''t joking... You really /could/ be "boinked" by some irate looney wielding a rubber malet." -Baldor the Bold
--------------------------~The Feature Creep of the Family~
Yep it''s from good old Donuts3D. I''ve not checked your own version yet but am eager to do so.

Thanks very much!

Daniel

"I envy you, who has seen it all"
"And I, young sir, envy you, who have yet to see it for the first time..."
- Daniel Glenfield
1st October 2001
if (witisism == !witty) return to_hole

This topic is closed to new replies.

Advertisement