forked from MagicBane/Server
FatBoy-DOTC
10 months ago
10 changed files with 275 additions and 5 deletions
@ -0,0 +1,10 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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