Skip to main content
gamedev.net
🔒 Locked

Problems with collision!!

Started by Madi Nov 19, 2008 at 9:25 AM 2 replies 1k views
Original Post
Madi
Madi
Hi everyone First of all, I am using Visual Studio C++ 2008 with DirectX 9.0c SDK (June 2008). I have developed a tumor trying to figure out how to make my player mesh collide with a building mesh I've created. It should be noted, that I have no trouble when making my enemy meshes collide with another building mesh. Anyways, the code is as follows:

void EnemyUpdate(float elapsedTimeSec)
{
...
//The enemy mesh colliding with a building mesh
for (int i = 0; i < NUM_ENEMIES; i++)
    {
		// Figure out the center of each bounding sphere in world space
		g_aBuilding.position = g_building.getPosition();
		D3DXVECTOR3 vBuildingBoundingCenterWS = g_aBuilding.buildingCenter + g_aBuilding.position;
		D3DXVECTOR3 vEnemyBoundingCenterWS = g_anEnemy.enemyCenter + g_anEnemy.position;

// Figure out how far apart the spheres are
		FLOAT eDistance = D3DXVec3Length( &(vEnemyBoundingCenterWS - vBuildingBoundingCenterWS) );

if (eDistance < g_enemyRadius + g_buildingRadius)
		{
			g_aBuilding.buildingCollision = true;
			g_anEnemy.velocity *= -1.0f;
		}
...

The g_anEnemy.velocity *= -1.0f; part of the above code, was taken from another part of my project - the part were the enemy collides with the terrain's boundries:

...
//-----------------------------------------------------------------------------
// Name: EnemyBoundriesAtEdges()
// Desc: This function performs simple collision detection to prevent the
//       enemy from moving beyond the edges of the floor.
//-----------------------------------------------------------------------------
void EnemyBoundriesAtEdges(Enemy &enemy, float elapsedTimeSec)
{
	float floorBoundary = GROUND_PLANE_SIZE * 0.5f - g_enemyRadius;
	D3DXVECTOR3 enemyVelocity = enemy.velocity * elapsedTimeSec;
	D3DXVECTOR3 newEnemyPos = enemy.position + enemyVelocity;
		
	// First test to see if the enemy is still within the floor's bounds.
	if (newEnemyPos.z > -floorBoundary && newEnemyPos.z < floorBoundary)
	{
		if (newEnemyPos.x > -floorBoundary && newEnemyPos.x < floorBoundary)
			return; // enemy is still within the floor's bounds
	}
		
	// If we reach here then the enemy has crossed the floor's edges.
	// What we'll do here is reverse the enemy's velocity so that it will
	// move in the opposite direction that the enemy is currently moving.
   	enemy.velocity *= -1.0f;
}
...

The enemy does bounce back whenever collided with a building mesh. Now to my problem. I created a separate building mesh and here's the code for it:

void UpdatePlayer(float elapsedTimeSec)
{
	g_aPlayer.position = g_player.getPosition();
	g_aBuilding2.position = g_building2.getPosition();
	D3DXVECTOR3 vPlayerBoundingCenterWS2 = g_aPlayer.playerCenter + g_aPlayer.position;
	D3DXVECTOR3 vBuildingBoundingCenterWS2 = g_aBuilding2.buildingCenter + g_aBuilding2.position;
	
	// Figure out how far apart the spheres are
	FLOAT gDistance = D3DXVec3Length( &(vPlayerBoundingCenterWS2 - vBuildingBoundingCenterWS2) );
...
float velocity = forwardSpeed * elapsedTimeSec;

	if (gDistance < g_playerRadius + g_buildingRadius2)
		{
			g_aBuilding2.buildingCollision = true;
			velocity = 0.0f;
		}
...

The last bit of code from above is taken from when the player reaches the edges of the terrain:

//-----------------------------------------------------------------------------
// Name: PlayerBoundriesAtEdges()
// Desc: This function performs simple collision detection to prevent the
//       player from moving beyond the edges of the floor.
//-----------------------------------------------------------------------------
float PlayerBoundriesAtEdges(const Object3D &player, float forwardSpeed, float elapsedTimeSec)
{
	/* Predict whether the player will move beyond the edges of the
	   floor based on the player's current forward velocity and the
	   amount of time that has elapsed */
	float floorBoundary = GROUND_PLANE_SIZE * 0.5f - g_playerRadius;
    float velocity = forwardSpeed * elapsedTimeSec;
    D3DXVECTOR3 newPlayerPos = player.getPosition() + player.getForwardVector() * velocity;

    if (newPlayerPos.z > -floorBoundary && newPlayerPos.z < floorBoundary)
    {
        if (newPlayerPos.x > -floorBoundary && newPlayerPos.x < floorBoundary)
            return forwardSpeed; /* The player will still be within floor's bounds */
    }

    return 0.0f; /* The player will have crossed the floor's edges, so the player is
				    stopped */
}

So my question is - what the F am I doing wrong?? My code seems correct, and the player should be able to stop when colliding with the building mesh. Any help is highly appreciative. Thanks in advance.
gabe83
gabe83
I don't see any differences between the two approaches, so if enemies correctly bounce when hitting building bounding spheres, the player should stop.

Are you sure that the problem is here? How are you using variable "velocity" after the player collision check?

And what happens if you put a breakpoint on this line
velocity = 0.0f;

If it breaks when the player hits the building bs then you can be sure that the problem is elsewhere.
Madi
Madi
The program doesn't break when a collision is occured :(

But it seems as if I am getting close.

The function mentioned before:

//-----------------------------------------------------------------------------// Name: PlayerBoundriesAtEdges()// Desc: This function performs simple collision detection to prevent the//       player from moving beyond the edges of the floor.//-----------------------------------------------------------------------------float PlayerBoundriesAtEdges(const Object3D &player, float forwardSpeed, float elapsedTimeSec){	/* Predict whether the player will move beyond the edges of the	   floor based on the player's current forward velocity and the	   amount of time that has elapsed */	float floorBoundary = GROUND_PLANE_SIZE * 0.5f - g_playerRadius;    float velocity = forwardSpeed * elapsedTimeSec;    D3DXVECTOR3 newPlayerPos = player.getPosition() + player.getForwardVector() * velocity;    if (newPlayerPos.z > -floorBoundary && newPlayerPos.z < floorBoundary)    {        if (newPlayerPos.x > -floorBoundary && newPlayerPos.x < floorBoundary)            return forwardSpeed; /* The player will still be within floor's bounds */    }    return 0.0f; /* The player will have crossed the floor's edges, so the player is				    stopped */}


..is declared in the following function as:
void UpdatePlayer(float elapsedTimeSec){.../* Prevent the player from walking off the edge of the floor */	forwardSpeed = PlayerBoundriesAtEdges(g_player, forwardSpeed, elapsedTimeSec);...


So what I did was remove the float velocity from the function and do this instead:
...if (gDistance < g_playerRadius + g_buildingRadius2)		{			g_aBuilding2.buildingCollision = true;			forwardSpeed = 0.0f;		}...


The result is that the player mesh collides and stops with the building mesh, but how do I make the player mesh move again? can't seem to figure out how to implement whenever the player isn't facing the building mesh.

Thanks for the help so far.

[Edited by - Madi on November 20, 2008 3:42:03 PM]
Madi
Madi
Problem solved!! FINALLY!! What a relief.
I just had to rewrite the whole boundry function:

//-----------------------------------------------------------------------------// Name: PlayerBoundriesAtEdges()// Desc: This function performs simple collision detection to prevent the//       player from moving beyond the edges of the floor.//-----------------------------------------------------------------------------float PlayerBoundriesAtEdges(const Object3D &player, float forwardSpeed, float elapsedTimeSec){	/* Predict whether the player will move beyond the edges of the	   floor based on the player's current forward velocity and the	   amount of time that has elapsed */	float floorBoundary = GROUND_PLANE_SIZE * 0.5f - g_playerRadius;    float velocity = forwardSpeed * elapsedTimeSec;		g_aPlayer.position = g_player.getPosition();	g_aBuilding2.position = g_building2.getPosition();    D3DXVECTOR3 newPlayerPos = player.getPosition() + player.getForwardVector() * velocity;	D3DXVECTOR3 vBuildingBoundingCenterWS2 = g_aBuilding2.buildingCenter + g_aBuilding2.position;	// Figure out how far apart the spheres are	FLOAT gDistance = D3DXVec3Length( &(newPlayerPos - vBuildingBoundingCenterWS2) );    if (newPlayerPos.z > -floorBoundary && newPlayerPos.z < floorBoundary)    {        if (newPlayerPos.x > -floorBoundary && newPlayerPos.x < floorBoundary)		{			if (gDistance > (g_playerRadius - 0.5) + g_buildingRadius2)			{				g_aBuilding2.buildingCollision = true;				return forwardSpeed; /* The player will still be within floor's bounds */			}		}    }    return 0.0f; /* The player will have crossed the floor's edges, so the player is				    stopped */}


Again, thanks for anyone trying to solve this f***er. Pardon my language.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.