• Advertisement
Sign in to follow this  

Collision sliding

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

Hello, I've been trying to create a collision sliding effect for a loooong time now, and it is always bugged. I looked everywhere and can't figure it out. I have ray->polygon collision and it works fine, but the characters just stops when he hits the wall, instead of sliding along it. I tried fixing this by extracting and calculating mesh face normals, and using them to push the user back. This works (in most cases) fine if I slide along a straight wall, but if I hit a spehere or cylinder it doesn't work so well, I assume it's a problem with either my way of caluculating the face normals, or the way I use them to push the user back. When I hit spehere or cylinder or any other non-straight surface it will either not slide at all, or it will push me back too much creating this ugly bouncy effect, and also I can always come close enough to cylinders to see through them(which I can't with walls). Here's my collision code:
if( checkCollision( mesh, &cCamera, xMove, yMove, zMove, &length, &FaceIndex, &u, &v ) )
	{
		//xMove, zMove ARE SIMPLY HOW MUCH TO MOVE EACH FRAME, DEPENDING ON BUTTON PRESSED
		// THE SIMPLE COLLISION, NO SLIDING, BUT WORKS
		float diff;
		diff = length - 5.00;
		D3DXVECTOR2 vecDir;
		D3DXVec2Normalize(&vecDir, &D3DXVECTOR2(xMove, zMove));
		vecDir *= diff;
		xMove = vecDir.x;
		zMove = vecDir.y;
		// END SIMPLE

		// MY ATTEMPT ON SLIDING
		vertex		*vert;
		WORD*		indices = 0;
		D3DXVECTOR3 indNormal, vec1, vec2, vec3, vNormal;
		
		// CODE TO CALCULATE THE FACE NORMALS
		// clonedMesh is an empty mesh containing ONLY vertex normals
			// GET THE LOCATION OF NORMALS FROM INDEX BUFFER, USING faceIndex RETURNED BY THE D3DXIntersect
		clonedMesh->LockIndexBuffer(0, ( LPVOID* )&indices);

			indNormal.x = indices[FaceIndex*3];
			indNormal.y = indices[FaceIndex*3+1];
			indNormal.z = indices[FaceIndex*3+2];

		clonedMesh->UnlockIndexBuffer();
			// get the normals
		clonedMesh->LockVertexBuffer( 0, ( LPVOID* )&vert );

			vec1 = D3DXVECTOR3( vert[( int )indNormal.x]._nx, 
								vert[( int )indNormal.x]._ny, 
								vert[( int )indNormal.x]._nz );

			vec2 = D3DXVECTOR3( vert[( int )indNormal.y]._nx, 
								vert[( int )indNormal.y]._ny, 
								vert[( int )indNormal.y]._nz );

			vec3 = D3DXVECTOR3( vert[( int )indNormal.z]._nx, 
								vert[( int )indNormal.z]._ny, 
								vert[( int )indNormal.z]._nz );


		clonedMesh->UnlockVertexBuffer( );

		vNormal = vec1 + u*(vec3-vec2) + v*(vec3-vec1);	 // calculate the final face normal using 3 vertex normals
								 //and barycentric coordinates returned by D3DXIntersect
		D3DXVec3Normalize(&vNormal, &vNormal);
		
		float xMoveTemp = 0.0f;
		float yMoveTemp = 0.0f;
		float zMoveTemp = 0.0f;
		
		// ATTEMPT TO SLIDE....
		xMoveTemp	+=  vNormal.x * diff;
		xMove		 =  xMove + xMoveTemp;

		zMoveTemp	+=  vNormal.z	* diff;
		zMove		 =  zMove + zMoveTemp;

	}


// COLLISION FUNCTION, I DOUBT THE PROBLEM IS HERE

BOOL checkCollision(ID3DXMesh *mesh, cCamera* cCamera, float xMove, float yMove,
					float zMove, float *length, DWORD *FaceIndex, float *u, float *v)
{

	float sX, sY, sZ;
	float eX, eY, eZ;
	float fSize = 0.0f;
	float diffX, diffY, diffZ;
	BOOL hit;
	float dist;
	DWORD faceHit;
	
	sX = cCamera->getXLoc();
	sY = cCamera->getYLoc();
	sZ = cCamera->getZLoc();

	eX = cCamera->getXLoc() + xMove;
	eY = cCamera->getYLoc() + yMove;
	eZ = cCamera->getZLoc() + zMove;

	eX = ( eX != 0 ) ? eX - eX/fabs(eX) * 4.0f : 0;		// ADD 4.0f TO VEL. VECTOR SO WE DON'T COME TOO CLOSE TO 
								//THE OTHER MESH, COZ THEN WE CAN SEE THROUGH IT
	//eY = ( eY != 0 ) ? eY - eY/fabs(eY) * 4.5f : 0;
	eZ = ( eZ != 0 ) ? eZ - eZ/fabs(eZ) * 4.0f : 0;

	diffX = eX - sX;
	diffY = eY - sY;
	diffZ = eZ - sZ;
	D3DXVECTOR3 vDir;

	D3DXVec3Normalize(&vDir, &D3DXVECTOR3(diffX, diffY, diffZ));

	D3DXIntersect(mesh, &D3DXVECTOR3(sX, sY, sZ), &vDir, &hit,
				FaceIndex, u, v, &dist, 0, 0);

	if(hit == TRUE)
	{
		fSize = (float)sqrt(diffX*diffX+diffY*diffY+diffZ*diffZ);
		if(dist > fSize)
		{
			hit = FALSE;
		}
		else
		{
			*length = dist;
		}
	}
	return hit;
}



So to summarize, I need someone to show me how to create a working sliding effect. Please help, I'm desperate! Thank you!

Share this post


Link to post
Share on other sites
Advertisement
From what I can see in your code you are trying to slide along the normal
of the trinagle you are intersecting with, instead you should slide along its tangent.

Also i would recommend to represent you "character" using some kind of bounding volume maybe a sphere.

Hope this helps.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement