forked from MagicBane/Server
FatBoy-DOTC
10 months ago
10 changed files with 275 additions and 5 deletions
@ -0,0 +1,10 @@ |
|||||||
|
package engine.collisionEngine; |
||||||
|
|
||||||
|
import java.awt.geom.Point2D; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
|
||||||
|
public class CollisionManager { |
||||||
|
public static HashMap<Integer, ArrayList<MeshTriangle>> mesh_triangles; |
||||||
|
public static HashMap<Integer, ArrayList<MeshData>> structure_meshes; |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
package engine.collisionEngine; |
||||||
|
|
||||||
|
import engine.gameManager.BuildingManager; |
||||||
|
import engine.math.Vector3f; |
||||||
|
import engine.math.Vector3fImmutable; |
||||||
|
import engine.objects.AbstractCharacter; |
||||||
|
import engine.objects.Building; |
||||||
|
|
||||||
|
import java.awt.geom.Line2D; |
||||||
|
import java.awt.geom.Point2D; |
||||||
|
import java.awt.geom.Rectangle2D; |
||||||
|
import java.util.ArrayList; |
||||||
|
|
||||||
|
public class Mesh { |
||||||
|
public int parentUUID; |
||||||
|
public MeshData meshData; |
||||||
|
private int meshID; |
||||||
|
private Rectangle2D.Float bounds; |
||||||
|
private ArrayList<MeshTriangle> triangles; |
||||||
|
private Vector3f mesh_loc; |
||||||
|
private Vector3f mesh_ref; |
||||||
|
private Vector3f mesh_end; |
||||||
|
private float mesh_maxY; |
||||||
|
private float mesh_minY; |
||||||
|
|
||||||
|
public Mesh(MeshData data, int parentUUID){ |
||||||
|
this.meshData = data; |
||||||
|
this.parentUUID = parentUUID; |
||||||
|
this.meshID = data.meshID; |
||||||
|
this.BakeTriangles(); |
||||||
|
this.BakeBounds(); |
||||||
|
} |
||||||
|
|
||||||
|
public void BakeTriangles(){ |
||||||
|
|
||||||
|
if(CollisionManager.mesh_triangles.containsKey(this.meshID) == false) |
||||||
|
return; // no triangle data to bake
|
||||||
|
|
||||||
|
this.triangles = new ArrayList<>(); |
||||||
|
|
||||||
|
Building building = BuildingManager.getBuilding(this.parentUUID); |
||||||
|
if(building == null) |
||||||
|
return; // can't continue without a building to base location offsets from
|
||||||
|
|
||||||
|
Vector3f adjustedBuildingLoc = new Vector3f(building.loc.x,building.loc.y, building.loc.z * -1); |
||||||
|
int rotDegrees = (int)Math.toDegrees(building.getBounds().getQuaternion().angleY); |
||||||
|
this.mesh_loc = Vector3f.rotateAroundPoint(adjustedBuildingLoc.add(meshData.mesh_loc),adjustedBuildingLoc,rotDegrees); |
||||||
|
this.mesh_ref = Vector3f.rotateAroundPoint(adjustedBuildingLoc.add(meshData.mesh_ref),adjustedBuildingLoc,rotDegrees); |
||||||
|
this.mesh_end = Vector3f.rotateAroundPoint(adjustedBuildingLoc.add(meshData.mesh_end),adjustedBuildingLoc,rotDegrees); |
||||||
|
this.mesh_minY = adjustedBuildingLoc.y + this.meshData.mesh_minY; |
||||||
|
this.mesh_maxY = adjustedBuildingLoc.y + this.meshData.mesh_maxY; |
||||||
|
|
||||||
|
for(MeshTriangle tri : CollisionManager.mesh_triangles.get(this.meshID)){ |
||||||
|
|
||||||
|
Vector3f point1 = this.mesh_loc.add(new Vector3f(tri.point1.x,this.mesh_loc.y,tri.point1.y)); |
||||||
|
Vector3f point2 = this.mesh_loc.add(new Vector3f(tri.point2.x,this.mesh_loc.y,tri.point2.y)); |
||||||
|
Vector3f point3 = this.mesh_loc.add(new Vector3f(tri.point3.x,this.mesh_loc.y,tri.point3.y)); |
||||||
|
|
||||||
|
Vector3f rotatedPoint1 = Vector3f.rotateAroundPoint(point1,this.mesh_loc,rotDegrees); |
||||||
|
Vector3f rotatedPoint2 = Vector3f.rotateAroundPoint(point2,this.mesh_loc,rotDegrees); |
||||||
|
Vector3f rotatedPoint3 = Vector3f.rotateAroundPoint(point3,this.mesh_loc,rotDegrees); |
||||||
|
|
||||||
|
MeshTriangle newTri = new MeshTriangle(); |
||||||
|
|
||||||
|
newTri.point1 = new Point2D.Float(rotatedPoint1.x,rotatedPoint1.z); |
||||||
|
newTri.point2 = new Point2D.Float(rotatedPoint2.x,rotatedPoint2.z); |
||||||
|
newTri.point3 = new Point2D.Float(rotatedPoint3.x,rotatedPoint3.z); |
||||||
|
|
||||||
|
newTri.sides = new ArrayList<>(); |
||||||
|
|
||||||
|
newTri.sides.add(new Line2D.Float(newTri.point1,newTri.point2)); |
||||||
|
newTri.sides.add(new Line2D.Float(newTri.point2,newTri.point3)); |
||||||
|
newTri.sides.add(new Line2D.Float(newTri.point3,newTri.point1)); |
||||||
|
|
||||||
|
this.triangles.add(newTri); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void BakeBounds(){ |
||||||
|
float width = this.mesh_ref.x - this.mesh_end.x; |
||||||
|
float height = this.mesh_ref.z - this.mesh_end.z; |
||||||
|
this.bounds = new Rectangle2D.Float(this.mesh_ref.x,this.mesh_ref.z,width,height); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean collides(AbstractCharacter mover, Vector3fImmutable destination){ |
||||||
|
|
||||||
|
if(mover == null) |
||||||
|
return false; |
||||||
|
|
||||||
|
Line2D.Float line = new Line2D.Float(new Point2D.Float(mover.loc.x,mover.loc.z * -1),new Point2D.Float(destination.x,destination.z * -1)); |
||||||
|
float footHeight = mover.loc.y; |
||||||
|
float headHeight = mover.loc.y + mover.characterHeight; |
||||||
|
|
||||||
|
if(line.intersects(this.bounds) == false) |
||||||
|
return false; // character path doesn't cross over this mesh
|
||||||
|
|
||||||
|
if(footHeight > this.mesh_maxY || headHeight < this.mesh_minY) |
||||||
|
return false; //character is either above or below the bounds of this mesh
|
||||||
|
|
||||||
|
for(MeshTriangle tri : this.triangles) |
||||||
|
if(tri.collides(line)) |
||||||
|
return true; //character's path directly hits part of this mesh
|
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean losBlocked(AbstractCharacter looker, Vector3fImmutable target){ |
||||||
|
|
||||||
|
float headHeight = looker.loc.y + looker.characterHeight; |
||||||
|
float targetAlt = target.y; |
||||||
|
|
||||||
|
Line2D.Float eyeLine = new Line2D.Float(new Point2D.Float(looker.loc.x,looker.loc.z * -1),new Point2D.Float(target.x,target.z * -1)); |
||||||
|
|
||||||
|
if(eyeLine.intersects(this.bounds) == false) |
||||||
|
return false; // character eye-line doesn't cross over this mesh
|
||||||
|
|
||||||
|
if(targetAlt > this.mesh_maxY && headHeight > this.mesh_maxY) |
||||||
|
return false; // both characters are above this mesh
|
||||||
|
|
||||||
|
if(targetAlt < this.mesh_maxY && headHeight < this.mesh_maxY) |
||||||
|
return false; // both characters are below this mesh
|
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package engine.collisionEngine; |
||||||
|
|
||||||
|
import engine.math.Vector3f; |
||||||
|
|
||||||
|
public class MeshData { |
||||||
|
public int propID; |
||||||
|
public int meshID; |
||||||
|
public Vector3f mesh_loc; |
||||||
|
public Vector3f mesh_ref; |
||||||
|
public Vector3f mesh_end; |
||||||
|
public float mesh_maxY; |
||||||
|
public float mesh_minY; |
||||||
|
|
||||||
|
public MeshData(int propID,int meshID, Vector3f meshLoc, Vector3f meshRef, Vector3f meshEnd, float maxY, float minY){ |
||||||
|
this.propID = propID; |
||||||
|
this.meshID = meshID; |
||||||
|
this.mesh_loc = meshLoc; |
||||||
|
this.mesh_ref = meshRef; |
||||||
|
this.mesh_end = meshEnd; |
||||||
|
this.mesh_maxY = maxY; |
||||||
|
this.mesh_minY = minY; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package engine.collisionEngine; |
||||||
|
|
||||||
|
import java.awt.geom.Line2D; |
||||||
|
import java.awt.geom.Point2D; |
||||||
|
import java.util.ArrayList; |
||||||
|
|
||||||
|
public class MeshTriangle { |
||||||
|
public Point2D.Float point1; |
||||||
|
public Point2D.Float point2; |
||||||
|
public Point2D.Float point3; |
||||||
|
public ArrayList<Line2D.Float> sides; |
||||||
|
|
||||||
|
public boolean collides(Line2D.Float line){ |
||||||
|
for(Line2D.Float side : sides) |
||||||
|
if(line.intersectsLine(side)) |
||||||
|
return true; |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue