|
@@ -1548,256 +1548,6 @@ BoundingBox CalculateBoundingBox(Mesh mesh)
|
|
|
return box;
|
|
|
}
|
|
|
|
|
|
-// Detect and resolve cubicmap collisions
|
|
|
-// NOTE: player position (or camera) is modified inside this function
|
|
|
-// TODO: This functions needs to be completely reviewed!
|
|
|
-Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius)
|
|
|
-{
|
|
|
- #define CUBIC_MAP_HALF_BLOCK_SIZE 0.5
|
|
|
-
|
|
|
- Color *cubicmapPixels = GetImageData(cubicmap);
|
|
|
-
|
|
|
- // Detect the cell where the player is located
|
|
|
- Vector3 impactDirection = { 0.0f, 0.0f, 0.0f };
|
|
|
-
|
|
|
- int locationCellX = 0;
|
|
|
- int locationCellY = 0;
|
|
|
-
|
|
|
- locationCellX = floor(playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE);
|
|
|
- locationCellY = floor(playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE);
|
|
|
-
|
|
|
- if ((locationCellX >= 0) && (locationCellY >= 0) && (locationCellX < cubicmap.width) && (locationCellY < cubicmap.height))
|
|
|
- {
|
|
|
- // Multiple Axis --------------------------------------------------------------------------------------------
|
|
|
-
|
|
|
- // Axis x-, y-
|
|
|
- if ((locationCellX > 0) && (locationCellY > 0))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) &&
|
|
|
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
|
|
- {
|
|
|
- playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Axis x-, y+
|
|
|
- if ((locationCellX > 0) && (locationCellY < cubicmap.height - 1))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) &&
|
|
|
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
|
|
- {
|
|
|
- playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Axis x+, y-
|
|
|
- if ((locationCellX < cubicmap.width - 1) && (locationCellY > 0))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) &&
|
|
|
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
|
|
- {
|
|
|
- playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Axis x+, y+
|
|
|
- if ((locationCellX < cubicmap.width - 1) && (locationCellY < cubicmap.height - 1))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) &&
|
|
|
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
|
|
- {
|
|
|
- playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Single Axis ---------------------------------------------------------------------------------------------------
|
|
|
-
|
|
|
- // Axis x-
|
|
|
- if (locationCellX > 0)
|
|
|
- {
|
|
|
- if (cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0)
|
|
|
- {
|
|
|
- if ((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius)
|
|
|
- {
|
|
|
- playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 0.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // Axis x+
|
|
|
- if (locationCellX < cubicmap.width - 1)
|
|
|
- {
|
|
|
- if (cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0)
|
|
|
- {
|
|
|
- if ((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius)
|
|
|
- {
|
|
|
- playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 0.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // Axis y-
|
|
|
- if (locationCellY > 0)
|
|
|
- {
|
|
|
- if (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0)
|
|
|
- {
|
|
|
- if ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)
|
|
|
- {
|
|
|
- playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 0.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // Axis y+
|
|
|
- if (locationCellY < cubicmap.height - 1)
|
|
|
- {
|
|
|
- if (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0)
|
|
|
- {
|
|
|
- if ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)
|
|
|
- {
|
|
|
- playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- impactDirection = (Vector3){ 0.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Diagonals -------------------------------------------------------------------------------------------------------
|
|
|
-
|
|
|
- // Axis x-, y-
|
|
|
- if ((locationCellX > 0) && (locationCellY > 0))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX - 1)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- else playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
-
|
|
|
- // Return ricochet
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius/3) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius/3))
|
|
|
- {
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Axis x-, y+
|
|
|
- if ((locationCellX > 0) && (locationCellY < cubicmap.height - 1))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX - 1)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- else playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
-
|
|
|
- // Return ricochet
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius/3) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius/3))
|
|
|
- {
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Axis x+, y-
|
|
|
- if ((locationCellX < cubicmap.width - 1) && (locationCellY > 0))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX + 1)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- else playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
-
|
|
|
- // Return ricochet
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius/3) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius/3))
|
|
|
- {
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Axis x+, y+
|
|
|
- if ((locationCellX < cubicmap.width - 1) && (locationCellY < cubicmap.height - 1))
|
|
|
- {
|
|
|
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) &&
|
|
|
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX + 1)].r != 0))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
|
|
- {
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
- else playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
|
|
-
|
|
|
- // Return ricochet
|
|
|
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius/3) &&
|
|
|
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius/3))
|
|
|
- {
|
|
|
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Floor collision
|
|
|
- if (playerPosition->y <= radius)
|
|
|
- {
|
|
|
- playerPosition->y = radius + 0.01f;
|
|
|
- impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z};
|
|
|
- }
|
|
|
- // Roof collision
|
|
|
- else if (playerPosition->y >= (1.5f - radius))
|
|
|
- {
|
|
|
- playerPosition->y = (1.5f - radius) - 0.01f;
|
|
|
- impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z};
|
|
|
- }
|
|
|
-
|
|
|
- free(cubicmapPixels);
|
|
|
-
|
|
|
- return impactDirection;
|
|
|
-}
|
|
|
-
|
|
|
//----------------------------------------------------------------------------------
|
|
|
// Module specific Functions Definition
|
|
|
//----------------------------------------------------------------------------------
|