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