using System.Collections.Generic; using System.Linq; using System.Numerics; using ACE.DatLoader.Entity; using ACE.Server.Physics.Animation; using ACE.Server.Physics.Entity; namespace ACE.Server.Physics.Collision { public class GfxObj { public uint ID; public CVertexArray VertexArray; /// /// Only populated if !PhysicsEngine.Instance.Server /// public Dictionary Polygons; /// /// Only populated if !PhysicsEngine.Instance.Server /// public Dictionary PhysicsPolygons; public Sphere PhysicsSphere; public BSP.BSPTree PhysicsBSP; /// /// Only populated if !PhysicsEngine.Instance.Server /// public Vector3 SortCenter; public Sphere DrawingSphere; public BSP.BSPTree DrawingBSP; public BBox GfxBoundBox; //public Material Material; // unused //public List Surfaces; // unused //public List SurfaceIDs; // unused public GfxObj() { } public GfxObj(DatLoader.FileTypes.GfxObj gfxObj) { if (gfxObj == null) return; ID = gfxObj.Id; VertexArray = gfxObj.VertexArray; if (!PhysicsEngine.Instance.Server) { Polygons = new Dictionary(); foreach (var kvp in gfxObj.Polygons) Polygons.Add(kvp.Key, PolygonCache.Get(kvp.Value, gfxObj.VertexArray)); } if (gfxObj.PhysicsPolygons.Count > 0) { if (!PhysicsEngine.Instance.Server) { PhysicsPolygons = new Dictionary(); foreach (var kvp in gfxObj.PhysicsPolygons) PhysicsPolygons.Add(kvp.Key, PolygonCache.Get(kvp.Value, gfxObj.VertexArray)); } PhysicsBSP = BSPCache.Get(gfxObj.PhysicsBSP, gfxObj.PhysicsPolygons, gfxObj.VertexArray); PhysicsSphere = PhysicsBSP.GetSphere(); } if (!PhysicsEngine.Instance.Server) SortCenter = gfxObj.SortCenter; DrawingBSP = BSPCache.Get(gfxObj.DrawingBSP, gfxObj.Polygons, gfxObj.VertexArray); DrawingSphere = DrawingBSP.GetSphere(); Init(); } public TransitionState FindObjCollisions(Transition transition, float scaleZ) { var path = transition.SpherePath; foreach (var localSpaceSphere in path.LocalSpaceSphere) { var offset = PhysicsSphere.Center - localSpaceSphere.Center; var radsum = PhysicsSphere.Radius + localSpaceSphere.Radius; if (offset.LengthSquared() - radsum * radsum < PhysicsGlobals.EPSILON) { if (path.InsertType == InsertType.InitialPlacement) return PhysicsBSP.placement_insert(transition); else return PhysicsBSP.find_collisions(transition, scaleZ); } } return TransitionState.OK; } public void Init() { GfxBoundBox = new BBox(); if (VertexArray.Vertices != null && VertexArray.Vertices.Count > 0) { var v = VertexArray.Vertices.Values.First(); GfxBoundBox.Min = v.Origin; // ref? GfxBoundBox.Max = v.Origin; foreach (var vertex in VertexArray.Vertices.Values) GfxBoundBox.AdjustBBox(vertex.Origin); } else { GfxBoundBox.Min = Vector3.Zero; GfxBoundBox.Max = Vector3.Zero; } } } }