![JAR search and dependency download from the Maven repository](/logo.png)
ca.blarg.gdx.tilemap3d.TileMapSweptSphereCollisionChecker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gdx-tilemap3d Show documentation
Show all versions of gdx-tilemap3d Show documentation
Library to handle management and rendering of a game world composed of 3D "tiles" arranged in a uniform 3D grid, via libGDX.
The newest version!
package ca.blarg.gdx.tilemap3d;
import ca.blarg.gdx.math.SweptSphere;
import ca.blarg.gdx.math.SweptSphereCollisionTester;
import ca.blarg.gdx.math.SweptSphereWorldCollisionChecker;
import ca.blarg.gdx.tilemap3d.tilemesh.TileMesh;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.badlogic.gdx.utils.ObjectSet;
public class TileMapSweptSphereCollisionChecker implements SweptSphereWorldCollisionChecker {
static final TileCoord min = new TileCoord();
static final TileCoord max = new TileCoord();
static final Vector3 tileWorldPosition = new Vector3();
static final Vector3 a = new Vector3();
static final Vector3 b = new Vector3();
static final Vector3 c = new Vector3();
public TileMap tileMap;
public final TileCoord lastCollisionTilePosition = new TileCoord();
final ObjectSet checkedLargeTiles = new ObjectSet(32);
@Override
public boolean checkForCollisions(SweptSphere sphere, BoundingBox possibleCollisionArea) {
if (tileMap == null)
throw new UnsupportedOperationException("No TileMap object is set.");
min.set(0, 0, 0);
max.set(0, 0, 0);
float lastCollisionDistance = Float.MAX_VALUE;
boolean foundCollision = false;
lastCollisionTilePosition.set(TileCoord.Zero);
// TODO: I don't think we even need to check if the area overlaps ... ?
// (it probably always will, right?)
boolean overlapping = tileMap.getOverlappedTiles(possibleCollisionArea, min, max);
if (overlapping) {
for (int y = min.y; y <= max.y; ++y) {
for (int z = min.z; z < max.z; ++z) {
for (int x = min.x; x < max.x; ++x) {
Tile tile = tileMap.get(x, y, z);
// only check solid tiles
if (tile.isCollideable()) {
int worldPosX = x - (int)tile.parentTileOffsetX;
int worldPosY = y - (int)tile.parentTileOffsetY;
int worldPosZ = z - (int)tile.parentTileOffsetZ;
// if this is a large tile, get the parent tile and make sure we haven't already checked
// for collisions against it
if (tile.isLargeTile()) {
Tile parentTile;
if (tile.isLargeTileRoot())
parentTile = tile;
else
parentTile = tileMap.get(worldPosX, worldPosY, worldPosZ);
boolean needToCheck = checkedLargeTiles.add(parentTile);
if (!needToCheck)
continue; // don't check it again!
}
// check each triangle in this tile's mesh
TileMesh mesh = tileMap.tileMeshes.get(tile);
Vector3[] vertices = mesh.getCollisionVertices();
// world position of this tile, will be used to move each
// mesh triangle into world space
tileWorldPosition.set(worldPosX, worldPosY, worldPosZ);
// also add the global TileMesh offset so the mesh is within
// 0,0,0 to 1,1,1 and not -0.5,-0.5,-0.5 to 0.5,0.5,0.5
tileWorldPosition.add(TileMesh.OFFSET);
Matrix4 transform = Tile.getTransformationFor(tile);
for (int i = 0; i < vertices.length; i += 3) {
// get the vertices making up this triangle
a.set(vertices[i]);
b.set(vertices[i + 1]);
c.set(vertices[i + 2]);
if (transform != null) {
a.mul(transform);
b.mul(transform);
c.mul(transform);
}
// move these vertices into world space
a.add(tileWorldPosition);
b.add(tileWorldPosition);
c.add(tileWorldPosition);
// test against it. we don't actually care about the
// return value, but just want the CollisionPacket
// to be updated. at the end of all these tests, it
// will contain info for the closest intersection
// found
boolean collided = SweptSphereCollisionTester.test(sphere, a, b, c);
if (collided && sphere.nearestCollisionDistance < lastCollisionDistance) {
foundCollision = true;
lastCollisionDistance = sphere.nearestCollisionDistance;
// this is the closest collision found so far
// record the grid position ...
lastCollisionTilePosition.set(x, y, z);
}
}
}
}
}
}
}
checkedLargeTiles.clear();
return foundCollision;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy