Browse Source

database mesh data loaded into hashmaps

server-collision
FatBoy-DOTC 11 months ago
parent
commit
f1e41e47cf
  1. 37
      src/engine/collision/Mesh.java
  2. 17
      src/engine/collision/Triangle.java
  3. 95
      src/engine/db/handlers/dbBuildingHandler.java
  4. 75
      src/engine/gameManager/BuildingManager.java
  5. 5
      src/engine/objects/Building.java
  6. 5
      src/engine/server/world/WorldServer.java

37
src/engine/collision/Mesh.java

@ -0,0 +1,37 @@
package engine.collision;
import java.awt.geom.Line2D;
import java.util.ArrayList;
public class Mesh {
public ArrayList<Triangle> triangles;
public ArrayList<Line2D> BoundingLines;
public float meshHeight;
public boolean BoundsCollides(Line2D line){
for(Line2D side : BoundingLines)
if(side.intersectsLine(line))
return true;
return false;
}
public boolean MeshCollides(Line2D line, float charHeight){
//movement path does not intersect this mesh
if(!this.BoundsCollides(line))
return false;
//character moving is higher than the max Y of this mesh
if(charHeight < this.meshHeight)
return false;
for(Triangle tri : triangles)
if(tri.collides(line))
return true;
//characters movement path did not intersect this triangle
return false;
}
}

17
src/engine/collision/Triangle.java

@ -0,0 +1,17 @@
package engine.collision;
import java.awt.geom.Line2D;
import java.util.ArrayList;
public class Triangle {
public ArrayList<Line2D> sides;
public boolean collides(Line2D line)
{
for(Line2D side : sides)
if(side.intersectsLine(line))
return true;
return false;
}
}

95
src/engine/db/handlers/dbBuildingHandler.java

@ -15,11 +15,13 @@ import engine.Enum.ProtectionState;
import engine.Enum.TaxType; import engine.Enum.TaxType;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.objects.*; import engine.objects.*;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.awt.geom.Rectangle2D;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -27,6 +29,7 @@ import java.sql.SQLException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -849,4 +852,96 @@ public class dbBuildingHandler extends dbHandlerBase {
return false; return false;
} }
public void LOAD_PROP_MESHES() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_structure_meshes`")) {
ResultSet rs = preparedStatement.executeQuery();
BuildingManager.prop_meshes = new HashMap<>();
while (rs.next()) {
if(BuildingManager.prop_meshes.containsKey(rs.getInt("propId")) == false){
ArrayList<Integer> meshList = new ArrayList<>();
meshList.add(rs.getInt("meshID"));
BuildingManager.prop_meshes.put(rs.getInt("propId"),meshList);
}
else
{
BuildingManager.prop_meshes.get(rs.getInt("propId")).add(rs.getInt("meshID"));
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_MESH_DATA() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_mesh_triangles`")) {
ResultSet rs = preparedStatement.executeQuery();
BuildingManager.mesh_triangle_points = new HashMap<>();
BuildingManager.mesh_heights = new HashMap<>();
while (rs.next()) {
ArrayList<Float> floatPoints = new ArrayList<>();
for(String f : rs.getString("vertices").split(";"))
{
floatPoints.add(Float.parseFloat(f));
}
ArrayList<Vector3f> triPoints = new ArrayList<>();
for(int i = 0; i < floatPoints.size(); i += 3){
triPoints.add(new Vector3f(floatPoints.get(i),floatPoints.get(i+1),floatPoints.get(i+2)));
}
if(BuildingManager.mesh_triangle_points.containsKey(rs.getInt("meshID")) == false){
ArrayList<ArrayList<Vector3f>> newPoints = new ArrayList<>();
newPoints.add(triPoints);
BuildingManager.mesh_triangle_points.put(rs.getInt("meshID"),newPoints);
}
else
{
BuildingManager.mesh_triangle_points.get(rs.getInt("meshID")).add(triPoints);
}
if(BuildingManager.mesh_heights.containsKey(rs.getInt("meshID")) == false){
BuildingManager.mesh_heights.put(rs.getInt("meshID"),rs.getFloat("maxY"));
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_MESH_BOUNDING_BOXES() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_mesh_triangles`")) {
ResultSet rs = preparedStatement.executeQuery();
BuildingManager.mesh_bounding_boxes = new HashMap<>();
while (rs.next()) {
if(BuildingManager.mesh_bounding_boxes.containsKey(rs.getInt("meshId")) == false){
float centerX = Float.parseFloat(rs.getString("start").split(";")[0]);
float centerZ = Float.parseFloat(rs.getString("start").split(";")[1]);
float endX = Float.parseFloat(rs.getString("end").split(";")[0]);
float endZ = Float.parseFloat(rs.getString("end").split(";")[1]);
float refX = Float.parseFloat(rs.getString("ref").split(";")[0]);
float refZ = Float.parseFloat(rs.getString("ref").split(";")[1]);
Rectangle2D boundRect = new Rectangle2D.Float();
boundRect.setRect(centerX,centerZ,Math.abs(endX-refX),Math.abs(endZ-refZ));
BuildingManager.mesh_bounding_boxes.put(rs.getInt("meshId"),boundRect);
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
} }

75
src/engine/gameManager/BuildingManager.java

@ -14,10 +14,13 @@ import engine.Enum.BuildingGroup;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.collision.Mesh;
import engine.collision.Triangle;
import engine.job.JobContainer; import engine.job.JobContainer;
import engine.job.JobScheduler; import engine.job.JobScheduler;
import engine.jobs.UpgradeBuildingJob; import engine.jobs.UpgradeBuildingJob;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
@ -27,6 +30,10 @@ import engine.objects.*;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
@ -38,6 +45,12 @@ public enum BuildingManager {
BUILDINGMANAGER; BUILDINGMANAGER;
public static HashMap<Integer,ArrayList<Integer>> prop_meshes = new HashMap<>();
public static HashMap<Integer,Float> mesh_heights = new HashMap<>();
public static HashMap<Integer,ArrayList<ArrayList<Vector3f>>> mesh_triangle_points = new HashMap<>();
public static HashMap<Integer, Rectangle2D> mesh_bounding_boxes = new HashMap<>();
public static HashMap<Integer, ArrayList<BuildingLocation>> _stuckLocations = new HashMap<>(); public static HashMap<Integer, ArrayList<BuildingLocation>> _stuckLocations = new HashMap<>();
public static HashMap<Integer, ArrayList<BuildingLocation>> _slotLocations = new HashMap<>(); public static HashMap<Integer, ArrayList<BuildingLocation>> _slotLocations = new HashMap<>();
@ -942,6 +955,9 @@ public enum BuildingManager {
cleanupHirelings(building); cleanupHirelings(building);
//rebake colliders for change in rank
BuildingManager.BakeBuildingMeshes(building);
building.isDeranking.compareAndSet(true, false); building.isDeranking.compareAndSet(true, false);
} }
@ -960,4 +976,63 @@ public enum BuildingManager {
return null; return null;
} }
public static void BakeBuildingMeshes(Building building){
if(building == null)
return;
building.buildingMeshes = new ArrayList<>();
float rotation = building.getRot().getRotation();
Vector3f buildingLoc = new Vector3f(building.loc.x,building.loc.y,building.loc.z);
if(!prop_meshes.containsKey(building.getBlueprint().getMeshForRank(building.getRank())))
return; //no data for this prop ID
ArrayList<Integer> meshes = prop_meshes.get(building.getBlueprint().getMeshForRank(building.getRank()));
for(int mesh : meshes){
if(!mesh_heights.containsKey(mesh) || !mesh_triangle_points.containsKey(mesh))
return; //no data for this mesh
Mesh generatedMesh = new Mesh();
generatedMesh.meshHeight = mesh_heights.get(mesh);
ArrayList<ArrayList<Vector3f>> triPoints = mesh_triangle_points.get(mesh);
if(mesh_bounding_boxes.containsKey(mesh)){
Rectangle2D boundingBox = mesh_bounding_boxes.get(mesh);
generatedMesh.BoundingLines = new ArrayList<>();
float maxX = building.loc.x + (float)boundingBox.getMaxX();
float minX = building.loc.x + (float)boundingBox.getMinX();
float maxY = building.loc.z + (float)boundingBox.getMaxY();
float minY = building.loc.z + (float)boundingBox.getMinY();
Point2D.Float p1 = new Point2D.Float(minX,maxY);
Point2D.Float p2 = new Point2D.Float(maxX,maxY);
Point2D.Float p3 = new Point2D.Float(maxX,minY);
Point2D.Float p4 = new Point2D.Float(minX,minY);
generatedMesh.BoundingLines.add(new Line2D.Float(p1,p2));
generatedMesh.BoundingLines.add(new Line2D.Float(p2,p3));
generatedMesh.BoundingLines.add(new Line2D.Float(p3,p4));
generatedMesh.BoundingLines.add(new Line2D.Float(p4,p1));
}
for(ArrayList<Vector3f> pointList : triPoints){
ArrayList<Vector3f> rotatedPoints = new ArrayList<>();
for(Vector3f point : pointList)
rotatedPoints.add(Vector3f.rotateAroundPoint(buildingLoc,point,rotation));
Point2D.Float p1 = new Point2D.Float(rotatedPoints.get(0).x,rotatedPoints.get(0).z);
Point2D.Float p2 = new Point2D.Float(rotatedPoints.get(1).x,rotatedPoints.get(1).z);
Point2D.Float p3 = new Point2D.Float(rotatedPoints.get(2).x,rotatedPoints.get(2).z);
Triangle tri = new Triangle();
tri.sides = new ArrayList<>();
tri.sides.add(new Line2D.Float(p1,p2));
tri.sides.add(new Line2D.Float(p2,p3));
tri.sides.add(new Line2D.Float(p3,p1));
generatedMesh.triangles.add(tri);
}
building.buildingMeshes.add(generatedMesh);
}
}
} }

5
src/engine/objects/Building.java

@ -14,6 +14,7 @@ import engine.Enum.*;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.Terrain; import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.collision.Mesh;
import engine.db.archive.CityRecord; import engine.db.archive.CityRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
import engine.db.archive.MineRecord; import engine.db.archive.MineRecord;
@ -99,6 +100,8 @@ public class Building extends AbstractWorldObject {
private ConcurrentHashMap<Integer, Condemned> condemned; private ConcurrentHashMap<Integer, Condemned> condemned;
private ArrayList<Building> children = null; private ArrayList<Building> children = null;
public ArrayList<Mesh> buildingMeshes;
/** /**
* ResultSet Constructor * ResultSet Constructor
*/ */
@ -1003,6 +1006,8 @@ public class Building extends AbstractWorldObject {
if (this.upgradeDateTime != null) if (this.upgradeDateTime != null)
BuildingManager.submitUpgradeJob(this); BuildingManager.submitUpgradeJob(this);
BuildingManager.BakeBuildingMeshes(this);
} }
public synchronized boolean setOwner(AbstractCharacter newOwner) { public synchronized boolean setOwner(AbstractCharacter newOwner) {

5
src/engine/server/world/WorldServer.java

@ -309,6 +309,11 @@ public class WorldServer {
Logger.info("Initializing Errant Guild"); Logger.info("Initializing Errant Guild");
Guild.getErrantGuild(); Guild.getErrantGuild();
Logger.info("Loading Server Collision Meshes.");
DbManager.BuildingQueries.LOAD_PROP_MESHES();
DbManager.BuildingQueries.LOAD_MESH_DATA();
DbManager.BuildingQueries.LOAD_MESH_BOUNDING_BOXES();
Logger.info("Loading zone template data"); Logger.info("Loading zone template data");
DbManager.ZoneQueries.LOAD_ALL_ZONE_TEMPLATES(); DbManager.ZoneQueries.LOAD_ALL_ZONE_TEMPLATES();

Loading…
Cancel
Save