forked from MagicBane/Server
				
			
				 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