diff --git a/ngengine_public.jar b/ngengine_public.jar index 3842feae..bc8fc39d 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index b0da63bf..6aa351d7 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -42,6 +42,8 @@ import engine.clientdata.visitors.MeshVisitor; import engine.clientdata.visitors.PortalVisitor; import engine.clientdata.visitors.PortalVisitor.Cell; import engine.clients.Client; +import engine.resources.common.Mesh3DTriangle; +import engine.resources.common.Ray; import engine.resources.objects.SWGObject; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -63,13 +65,21 @@ import protocol.swg.objectControllerObjects.TargetUpdate; import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; import resources.common.*; +import toxi.geom.Ray3D; +import toxi.geom.Vec3D; +import toxi.geom.mesh.TriangleMesh; import wblut.geom.WB_AABBNode; import wblut.geom.WB_AABBTree; +import wblut.geom.WB_Distance; import wblut.geom.WB_Intersection; import wblut.geom.WB_Point3d; import wblut.geom.WB_Ray; import wblut.geom.WB_Transform; +import wblut.geom.WB_Vector3d; import wblut.hemesh.HE_Mesh; +import wblut.hemesh.HE_Vertex; +import wblut.math.WB_Epsilon; +import wblut.math.WB_M44; @SuppressWarnings("unused") @@ -77,7 +87,8 @@ public class SimulationService implements INetworkDispatch { Map> quadTrees; private NGECore core; - + private Map cellMeshes = new ConcurrentHashMap(); + public SimulationService(NGECore core) { this.core = core; TerrainService terrainService = core.terrainService; @@ -342,7 +353,7 @@ public class SimulationService implements INetworkDispatch { } - public WB_AABBTree getAABBTree(SWGObject object, int collisionBlockFlag) { + /*public WB_AABBTree getAABBTree(SWGObject object, int collisionBlockFlag) { if(object.getMeshVisitor() == null || object.getTemplateData() == null) { System.out.println("NULL Mesh Visitor for: " + object.getTemplate()); @@ -351,9 +362,8 @@ public class SimulationService implements INetworkDispatch { if(object.getTemplateData().getAttribute("collisionActionBlockFlags") != null) { int bit = (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags") & collisionBlockFlag; - - if(bit == (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags")) - return null; + //if(bit == (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags")) + // return null; } Point3D position = object.getPosition(); @@ -361,29 +371,57 @@ public class SimulationService implements INetworkDispatch { if(mesh == null) return null; - System.out.println(object.getHeading()); + float angle = (float) (object.getRadians() * (180 / Math.PI)); System.out.println("Angle: " + angle); Quaternion quat = object.getOrientation(); - WB_Transform transform = new WB_Transform().addRotateZ(object.getRadians()); - mesh = mesh.move(position.x, position.z, position.y).transform(transform); - mesh.clean(); - mesh.cleanUnusedElementsByFace(); + //WB_Transform transform = new WB_Transform(); + //transform.addRotateZ(object.getRadians()); + + //mesh = mesh.transform(transform); + + //mesh = mesh.move(position.x, position.z, position.y); + + WB_AABBTree aabbTree = new WB_AABBTree(mesh, mesh.numberOfFaces()); return aabbTree; - } + }*/ + + public Ray convertRayToModelSpace(Point3D origin, Point3D end, SWGObject object) { - public WB_Ray convertRayToModelSpace(WB_Ray ray, SWGObject object) { + Point3D position = object.getPosition(); + + WB_M44 translateMatrix = new WB_M44(1, 0, 0, position.x, 0, 1, 0, position.y, 0, 0, 1, position.z, 0, 0, 0, 1); - WB_Transform transform = new WB_Transform().addTranslate(new WB_Point3d(-object.getPosition().x, -object.getPosition().z , -object.getPosition().y)).addRotateZ(object.getRadians()); - ray = transform.apply(ray); + float radians = object.getRadians(); + float sin = (float) Math.sin(radians); + float cos = (float) Math.cos(radians); + + WB_M44 rotationMatrix = new WB_M44(cos, 0, sin, 0, 0, 1, 0, 0, -sin, 0, cos, 0, 0, 0, 0, 1); + + WB_M44 modelSpace = translateMatrix.mult(rotationMatrix).inverse(); + + float originX = (float) (modelSpace.m11 * origin.x + modelSpace.m12 * origin.y + modelSpace.m13 * origin.z + modelSpace.m14); + float originY = (float) (modelSpace.m21 * origin.x + modelSpace.m22 * origin.y + modelSpace.m23 * origin.z + modelSpace.m24); + float originZ = (float) (modelSpace.m31 * origin.x + modelSpace.m32 * origin.y + modelSpace.m33 * origin.z + modelSpace.m34); + + origin = new Point3D(originX, originY, originZ); + + float endX = (float) (modelSpace.m11 * end.x + modelSpace.m12 * end.y + modelSpace.m13 * end.z + modelSpace.m14); + float endY = (float) (modelSpace.m21 * end.x + modelSpace.m22 * end.y + modelSpace.m23 * end.z + modelSpace.m24); + float endZ = (float) (modelSpace.m31 * end.x + modelSpace.m32 * end.y + modelSpace.m33 * end.z + modelSpace.m34); + + end = new Point3D(endX, endY, endZ); + + Vector3D direction = new Vector3D(end.x - origin.x, end.y - origin.y, end.z - origin.z).normalize(); - return ray; + return new Ray(origin, direction); } + public void handleDisconnect(IoSession session) { Client client = core.getClient((Integer) session.getAttribute("connectionId")); @@ -416,6 +454,7 @@ public class SimulationService implements INetworkDispatch { session.suspendWrite(); core.objectService.destroyObject(object); core.getActiveConnectionsMap().remove((Integer) session.getAttribute("connectionId")); + } public void handleZoneIn(Client client) { @@ -522,21 +561,18 @@ public class SimulationService implements INetworkDispatch { } - // not fully working yet(rotation of meshes wrong) public boolean checkLineOfSight(SWGObject obj1, SWGObject obj2) { if(obj1.getPlanet() != obj2.getPlanet()) return false; - if((obj1.getContainer() != null && obj2.getContainer() != null) && (obj1.getContainer() == obj2.getContainer())) // if both are in same cell they should always be in sight of each other - return true; - - if(obj1.getGrandparent() != null && obj2.getGrandparent() != null) { + if(obj1.getGrandparent() != null || obj2.getGrandparent() != null) { if(obj1.getGrandparent() == obj2.getGrandparent()) return checkLineOfSightInBuilding(obj1, obj2, obj1.getGrandparent()); - else + else if(obj1.getGrandparent() != null && obj2.getGrandparent() != null) return false; + } float heightOrigin = 1.f; @@ -551,46 +587,49 @@ public class SimulationService implements INetworkDispatch { Point3D position1 = obj1.getWorldPosition(); Point3D position2 = obj2.getWorldPosition(); - Vector3D origin = new Vector3D(position1.x, position1.z, position1.y + heightOrigin); - Vector3D end = new Vector3D(position2.x, position2.z, position2.y + heightDirection); - + Point3D origin = new Point3D(position1.x, position1.y + heightOrigin, position1.z); + Point3D end = new Point3D(position2.x, position2.y + heightDirection, position2.z); float distance = position1.getDistance2D(position2); - List inRangeObjects = get(obj1.getPlanet(), position1.x, position1.z, (int) distance + 1); + List inRangeObjects = get(obj1.getPlanet(), position1.x, position1.z, 150); - WB_Ray ray = new WB_Ray(origin.getX(), origin.getY() , origin.getZ(), end.getX(), end.getY(), end.getZ()); - for(SWGObject object : inRangeObjects) { if(object == obj1 || object == obj2) continue; - Point3D position = object.getWorldPosition(); - float otherDistance = position.getDistance2D(position1); - System.out.println("Distance from origin to target: " + distance + " Distance from origin to current obj: " + otherDistance); - if(!obj1.inRange(position, distance)) - continue; - - WB_AABBTree aabbTree = getAABBTree(object, 255); - - if(aabbTree == null) - continue; - - //System.out.println(object.getTemplate()); - - //ray = convertRayToModelSpace(ray, object); - - ArrayList collisions = WB_Intersection.getIntersection(ray, aabbTree); - if(!collisions.isEmpty()) { - System.out.println("Collided with " + object.getTemplate() + " X: " + object.getPosition().x + " Y: " + object.getPosition().y + " Z: " + object.getPosition().z); - return false; + if(object.getTemplateData().getAttribute("collisionActionBlockFlags") != null) { + int bit = (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags") & 255; + if(bit == (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags")) + continue; } + + Ray ray = convertRayToModelSpace(origin, end, object); + + MeshVisitor visitor = object.getMeshVisitor(); + if(visitor == null) + continue; + + List tris = visitor.getTriangles(); + + if(tris.isEmpty()) + continue; + + for(Mesh3DTriangle tri : tris) { + + if(ray.intersectsTriangle(tri, distance) != null) { + System.out.println("Collided with " + object.getTemplate() + " X: " + object.getPosition().x + " Y: " + object.getPosition().y + " Z: " + object.getPosition().z); + return false; + } + + } + } - /*if(obj1.getContainer() != null || obj2.getContainer() != null) { + if(obj1.getContainer() != null || obj2.getContainer() != null) { CellObject cell = null; @@ -601,13 +640,12 @@ public class SimulationService implements INetworkDispatch { if(cell != null) return checkLineOfSightWorldToCell(obj1, obj2, cell); - }*/ - + } + return true; } - // not fully working yet(rotation of meshes wrong) public boolean checkLineOfSightInBuilding(SWGObject obj1, SWGObject obj2, SWGObject building) { PortalVisitor portalVisitor = building.getPortalVisitor(); @@ -617,34 +655,45 @@ public class SimulationService implements INetworkDispatch { Point3D position1 = obj1.getPosition(); Point3D position2 = obj2.getPosition(); - - Vector3D origin = new Vector3D(position1.x, position1.z, position1.y + 1); - Vector3D end = new Vector3D(position2.x, position2.z, position2.y + 1); + Point3D origin = new Point3D(position1.x, position1.y + 1, position1.z); + Point3D end = new Point3D(position2.x, position2.y + 1, position2.z); - //Vector3D direction = end.subtract(origin).normalize(); - - WB_Ray ray = new WB_Ray(origin.getX(), origin.getY(), origin.getZ(), end.getX(), end.getY(), end.getZ()); + Vector3D direction = new Vector3D(end.x - origin.x, end.y - origin.y, end.z - origin.z).normalize(); + float distance = position1.getDistance2D(position2); + Ray ray = new Ray(origin, direction); for(int i = 1; i < portalVisitor.cells.size(); i++) { Cell cell = portalVisitor.cells.get(i); - System.out.println(cell.name); try { - System.out.println(cell.mesh); - MeshVisitor meshVisitor = ClientFileManager.loadFile(cell.mesh, MeshVisitor.class); - WB_AABBTree aabbTree = meshVisitor.getAABBTree(meshVisitor.createMesh()); - if(aabbTree == null) + MeshVisitor meshVisitor; + if(!cellMeshes.containsKey(cell.mesh)) { + meshVisitor = ClientFileManager.loadFile(cell.mesh, MeshVisitor.class); + cellMeshes.put(cell.mesh, meshVisitor); + } else { + meshVisitor = cellMeshes.get(cell.mesh); + } + + if(meshVisitor == null) continue; - ArrayList collisions = WB_Intersection.getIntersection(ray, aabbTree); + List tris = meshVisitor.getTriangles(); + + if(tris.isEmpty()) + continue; - if(!collisions.isEmpty()) { - System.out.println("Collision with: " + cell.name); - return false; + for(Mesh3DTriangle tri : tris) { + + if(ray.intersectsTriangle(tri, distance) != null) { + System.out.println("Collision with: " + cell.name); + return false; + } + } + } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } @@ -655,7 +704,6 @@ public class SimulationService implements INetworkDispatch { } - // not fully working yet(rotation of meshes wrong) public boolean checkLineOfSightWorldToCell(SWGObject obj1, SWGObject obj2, CellObject cell) { SWGObject building = cell.getContainer(); @@ -680,22 +728,33 @@ public class SimulationService implements INetworkDispatch { Point3D position1 = obj1.getWorldPosition(); Point3D position2 = obj2.getWorldPosition(); - Point3D origin = new Point3D(position1.x, position1.z, position1.y + heightOrigin); - Point3D direction = new Point3D(position2.x, position2.z, position2.y + heightDirection); + Point3D origin = new Point3D(position1.x, position1.y + heightOrigin, position1.z); + Point3D end = new Point3D(position2.x, position2.y + heightDirection, position2.z); - WB_Ray ray = new WB_Ray(origin.x, origin.y , origin.z, direction.x, direction.y, direction.z); - ray = convertRayToModelSpace(ray, building); + Ray ray = convertRayToModelSpace(origin, end, building); if(cell.getCellNumber() >= portalVisitor.cellCount) return true; try { + MeshVisitor meshVisitor = ClientFileManager.loadFile(portalVisitor.cells.get(cell.getCellNumber()).mesh, MeshVisitor.class); - WB_AABBTree aabbTree = meshVisitor.getAABBTree(meshVisitor.createMesh()); - ArrayList collisions = WB_Intersection.getIntersection(ray, aabbTree); + + if(meshVisitor == null) + return true; + + List tris = meshVisitor.getTriangles(); + + if(tris.isEmpty()) + return true; - if(!collisions.isEmpty()) - return false; + for(Mesh3DTriangle tri : tris) { + + if(ray.intersectsTriangle(tri) != null) { + return false; + } + + } } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 79ac9bee..fd77e6ee 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -423,13 +423,15 @@ public class ObjectService implements INetworkDispatch { if(obj != null) { obj.setisInSnapshot(true); obj.setParentId(chunk.parentId); + if(obj instanceof CellObject) { + ((CellObject) obj).setCellNumber(chunk.cellNumber); + } } //System.out.print("\rLoading Object [" + counter + "/" + visitor.getChunks().size() + "] : " + visitor.getName(chunk.nameId)); } visitor.dispose(); synchronized(objectList) { for(SWGObject obj : objectList) { - obj.getTemplateData().dispose(); if(obj.getParentId() != 0 && getObject(obj.getParentId()) != null) { SWGObject parent = getObject(obj.getParentId()); parent.add(obj);