🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Tips on 3D level collision

Started by
7 comments, last by Hashbrown 6 years, 1 month ago

I'm wondering what is the right way to create level collision for a very basic level like the following image (click on it for a larger version):

question.png

I'm not  what to search, so I'm a little confused. What I'm thinking is AABB collision tests for the cubes and walls, maybe keeping them all in arrays, and checking the array for collisions every frame. Again, not sure if that's the correct way of doing this.  

I'm also not sure about the platform in the middle since the character would have to go up a slope like this one: 

slope.png

...and stand on the platform. The floor is set at y:0 at the moment, but it might be higher or lower in different parts of the map. If anybody has links I can read to learn, or even just keywords I can use to search. I'd really appreciate it. I just don't know where to start in terms of searching. Thanks!  

Edit: I don't plan on using collider shapes outside of cubes and that slope in green. Making sure to keep the collision very simple. I don't think any of these level colliders are going to rotate either, so it's going to be axis aligned. 

Edit 2:  I just found this old post from 2002 and from what I understand in one of the answers:  divide the world in different cubes and each one holds a list of all the aabb colliders within that particular cube. I'm guessing in order to avoid having to walk and test so many colliders. Not sure if I'm on the right track though. Also need to figure out how to go up the slope, obb perhaps?

Advertisement

I think it's a good idea to flag the objects as dynamic or not, that way you only have to check collisions for colliders which are dynamic (against the other objects). OBB shouldn't be necessary as you concluded, if the objects (cubes/walls) don't rotate (all axis aligned).

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

For going up the slope, the simplest way would be casting a ray from your character downwards, performing triangle- ray intersection with the scene and just don't allow the character fall under the closest collision point.

I love this forum. Thanks Cozzie and turanszkij, I appreciate the tips. Once I finish, I'll share what I did so other can use. Thanks again!

My collision code might intrest you : i posted this in another topic also :

 

Here is the collision code to get the ground level ( y position )

You have to make 4 lists of weedfields :

Normal weedfield is totally flat, all vertices has the same Y position.

WeedfieldX is exactly the same Y position for all left vertices, also for all right vertices.

WeedfieldY is exactly the same Y position for all front vertices and same for all back vertices.

WeedfieldZ has 3 or 4 vertices with different Y positions.

Once you have this sorted you can use this code :

 

 


	
//-----------------------------------------------------------------------------------------
float LevelMesh::getGroundLevel( float x , float z )
{
// WeedField ground level
sWeedField*nextwf = firstwf;
while( nextwf )
     {
     if( x >= nextwf->l && x <= nextwf->r &&
         z >= nextwf->f && z <= nextwf->b )
       {
       return nextwf->y;
       }
     
     nextwf = nextwf->next;
     }
	// WeedFieldX ground level
sWeedFieldX*nextwfx = firstwfx;
while( nextwfx )
     {
     if( x >= nextwfx->l && x <= nextwfx->r &&
         z >= nextwfx->f && z <= nextwfx->b )
       {
       float fTempBalance = ( ( x - nextwfx->r ) - ( nextwfx->l - nextwfx->r ) ) * nextwfx->fAbsRScale;
       return XFade( nextwfx->y1 , nextwfx->y2 , fTempBalance );
       }
     
     nextwfx = nextwfx->next;
     }
	// WeedFieldY ground level
sWeedFieldY*nextwfy = firstwfy;
while( nextwfy )
     {
     if( x >= nextwfy->l && x <= nextwfy->r &&
         z >= nextwfy->f && z <= nextwfy->b )
       {
       float fTempBalance = ( ( z - nextwfy->b ) - ( nextwfy->f - nextwfy->b ) ) * nextwfy->fAbsBScale;
       return XFade( nextwfy->y1 , nextwfy->y2 , fTempBalance );
       }
     
     nextwfy = nextwfy->next;
     }
	// WeedFieldZ ground level
sWeedFieldZ*nextwfz = firstwfz;
while( nextwfz )
     {
     if( x >= nextwfz->l && x <= nextwfz->r &&
         z >= nextwfz->f && z <= nextwfz->b )
       {
       float fTempBalanceFB = ( ( z - nextwfz->b ) - ( nextwfz->f - nextwfz->b ) ) * nextwfz->fAbsBScale;
       float fTempBalanceLR = ( ( x - nextwfz->r ) - ( nextwfz->l - nextwfz->r ) ) * nextwfz->fAbsRScale;
       
       if( fTempBalanceFB > fTempBalanceLR ) // Driehoek 1
         {
         float y1 = nextwfz->y3 - ( nextwfz->y4 - nextwfz->y2 );
         
         float fXFadeLFB = XFade( nextwfz->y2 , nextwfz->y4 , fTempBalanceFB );
         float fXFadeRFB = XFade( y1 , nextwfz->y3 , fTempBalanceFB );
         
         return XFade( fXFadeLFB , fXFadeRFB , fTempBalanceLR );
         }else // Driehoek 2
         {
         float y4 = nextwfz->y2 - ( nextwfz->y1 - nextwfz->y3 );
         
         float fXFadeFLR = XFade( nextwfz->y2 , nextwfz->y1 , fTempBalanceLR );
         float fXFadeBLR = XFade( y4 , nextwfz->y3 , fTempBalanceLR );
         
         return XFade( fXFadeFLR, fXFadeBLR , fTempBalanceFB );
         }
       
       }
     
     nextwfz = nextwfz->next;
     }
	return fEndOfLevel; // end of level
}
	 
	

Xfade is something like a + fade * ( b - a );

Driehoek = dutch for triangle.

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

On 6/5/2018 at 9:45 AM, the incredible smoker said:

My collision code might intrest you : i posted this in another topic also :

 

Here is the collision code to get the ground level ( y position )

You have to make 4 lists of weedfields :

Normal weedfield is totally flat, all vertices has the same Y position.

WeedfieldX is exactly the same Y position for all left vertices, also for all right vertices.

WeedfieldY is exactly the same Y position for all front vertices and same for all back vertices.

WeedfieldZ has 3 or 4 vertices with different Y positions.

Once you have this sorted you can use this code :

 

 



	
//-----------------------------------------------------------------------------------------
float LevelMesh::getGroundLevel( float x , float z )
{
// WeedField ground level
sWeedField*nextwf = firstwf;
while( nextwf )
     {
     if( x >= nextwf->l && x <= nextwf->r &&
         z >= nextwf->f && z <= nextwf->b )
       {
       return nextwf->y;
       }
     
     nextwf = nextwf->next;
     }
	// WeedFieldX ground level
sWeedFieldX*nextwfx = firstwfx;
while( nextwfx )
     {
     if( x >= nextwfx->l && x <= nextwfx->r &&
         z >= nextwfx->f && z <= nextwfx->b )
       {
       float fTempBalance = ( ( x - nextwfx->r ) - ( nextwfx->l - nextwfx->r ) ) * nextwfx->fAbsRScale;
       return XFade( nextwfx->y1 , nextwfx->y2 , fTempBalance );
       }
     
     nextwfx = nextwfx->next;
     }
	// WeedFieldY ground level
sWeedFieldY*nextwfy = firstwfy;
while( nextwfy )
     {
     if( x >= nextwfy->l && x <= nextwfy->r &&
         z >= nextwfy->f && z <= nextwfy->b )
       {
       float fTempBalance = ( ( z - nextwfy->b ) - ( nextwfy->f - nextwfy->b ) ) * nextwfy->fAbsBScale;
       return XFade( nextwfy->y1 , nextwfy->y2 , fTempBalance );
       }
     
     nextwfy = nextwfy->next;
     }
	// WeedFieldZ ground level
sWeedFieldZ*nextwfz = firstwfz;
while( nextwfz )
     {
     if( x >= nextwfz->l && x <= nextwfz->r &&
         z >= nextwfz->f && z <= nextwfz->b )
       {
       float fTempBalanceFB = ( ( z - nextwfz->b ) - ( nextwfz->f - nextwfz->b ) ) * nextwfz->fAbsBScale;
       float fTempBalanceLR = ( ( x - nextwfz->r ) - ( nextwfz->l - nextwfz->r ) ) * nextwfz->fAbsRScale;
       
       if( fTempBalanceFB > fTempBalanceLR ) // Driehoek 1
         {
         float y1 = nextwfz->y3 - ( nextwfz->y4 - nextwfz->y2 );
         
         float fXFadeLFB = XFade( nextwfz->y2 , nextwfz->y4 , fTempBalanceFB );
         float fXFadeRFB = XFade( y1 , nextwfz->y3 , fTempBalanceFB );
         
         return XFade( fXFadeLFB , fXFadeRFB , fTempBalanceLR );
         }else // Driehoek 2
         {
         float y4 = nextwfz->y2 - ( nextwfz->y1 - nextwfz->y3 );
         
         float fXFadeFLR = XFade( nextwfz->y2 , nextwfz->y1 , fTempBalanceLR );
         float fXFadeBLR = XFade( y4 , nextwfz->y3 , fTempBalanceLR );
         
         return XFade( fXFadeFLR, fXFadeBLR , fTempBalanceFB );
         }
       
       }
     
     nextwfz = nextwfz->next;
     }
	return fEndOfLevel; // end of level
}
	 
	

Xfade is something like a + fade * ( b - a );

Driehoek = dutch for triangle.

Smoker sorry about the slightly late response. This was very useful, as I mentioned earlier it's a lot easier looking at other examples, so thanks again :)

I hope you understand all else just aks.

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

Thanks smoker,  I plan on implementing your code once I get home. I'm definitely going to have questions. I'm just now learning about level collision. Won't give up until understanding these concepts. 

This topic is closed to new replies.

Advertisement