Sign in to follow this  
Madi

Problems with collision!!

Recommended Posts

Madi    114
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[i].enemyCenter + g_anEnemy[i].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[i].velocity *= -1.0f;
		}
...

The g_anEnemy[i].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.

Share this post


Link to post
Share on other sites
gabe83    122
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.

Share this post


Link to post
Share on other sites
Madi    114
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]

Share this post


Link to post
Share on other sites
Madi    114
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.

Share this post


Link to post
Share on other sites

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