public YnvEdge(YnvEdge copy, YnvPoly poly) { _RawData = copy._RawData; _RawData._Poly1.PolyID = 0x3FFF; _RawData._Poly2.PolyID = 0x3FFF; Poly1 = poly; Poly2 = poly; AreaID1 = 0x3FFF; AreaID2 = 0x3FFF; }
public void LoadIndices() { //load indices, vertices and edges var indices = Ynv.Indices; var vertices = Ynv.Vertices; var edges = Ynv.Edges; if ((indices == null) || (vertices == null) || (edges == null)) { return; } var vc = vertices.Count; var ic = _RawData.IndexCount; var startid = _RawData.IndexID; var endid = startid + ic; if (startid >= indices.Count) { return; } if (endid > indices.Count) { return; } if (endid > edges.Count) { return; } Indices = new ushort[ic]; Vertices = new Vector3[ic]; Edges = new YnvEdge[ic]; int i = 0; for (int id = startid; id < endid; id++) { var ind = indices[id]; Indices[i] = ind; Vertices[i] = (ind < vc) ? vertices[ind] : Vector3.Zero; Edges[i] = edges[id]; i++; } }
private void BuildStructs() { Vector3 posoffset = Nav.SectorTree?.AABBMin.XYZ() ?? Vector3.Zero; Vector3 aabbsize = Nav.AABBSize; Vector3 aabbsizeinv = 1.0f / aabbsize; var vertlist = new List <NavMeshVertex>(); var indslist = new List <ushort>(); var edgelist = new List <NavMeshEdge>(); var polylist = new List <NavMeshPoly>(); var portallist = new List <NavMeshPortal>(); var portallinks = new List <ushort>(); var vertdict = new Dictionary <Vector3, ushort>(); var areadict = new Dictionary <uint, uint>(); var arealist = new List <uint>(); var areaid = Nav.AreaID; EnsureEdgeAreaID(areaid, areadict, arealist); EnsureEdgeAreaID(0x3FFF, areadict, arealist); EnsureEdgeAreaID(areaid - 100, areadict, arealist); EnsureEdgeAreaID(areaid - 1, areadict, arealist); EnsureEdgeAreaID(areaid + 1, areadict, arealist); EnsureEdgeAreaID(areaid + 100, areadict, arealist); if (Polys != null) //rebuild vertices, indices, edges and polys lists from poly data. { for (int i = 0; i < Polys.Count; i++) { var poly = Polys[i]; var vc = poly.Vertices?.Length ?? 0; //poly.AreaID = (ushort)Nav.AreaID; poly._RawData.IndexID = (ushort)indslist.Count; for (int n = 0; n < vc; n++) { Vector3 v = poly.Vertices[n]; YnvEdge e = ((poly.Edges != null) && (n < poly.Edges.Length)) ? poly.Edges[n] : null; ushort ind; if (!vertdict.TryGetValue(v, out ind)) { ind = (ushort)vertlist.Count; vertdict[v] = ind; vertlist.Add(NavMeshVertex.Create(Vector3.Clamp((v - posoffset) * aabbsizeinv, Vector3.Zero, Vector3.One))); } if ((poly.Indices != null) && (n < poly.Indices.Length)) { poly.Indices[n] = ind; } indslist.Add(ind); NavMeshEdge edge; if (e != null) { if (e.Poly1 != null) { e.PolyID1 = (uint)e.Poly1.Index; e.AreaID1 = e.Poly1.AreaID; if (e.AreaID1 == 0x3FFF) { } //debug } if (e.Poly2 != null) { e.PolyID2 = (uint)e.Poly2.Index; e.AreaID2 = e.Poly2.AreaID; if (e.AreaID2 == 0x3FFF) { } //debug } if ((e.AreaID1 == 0) || (e.AreaID2 == 0)) { } //debug e._RawData._Poly1.AreaIDInd = EnsureEdgeAreaID(e.AreaID1, areadict, arealist); e._RawData._Poly2.AreaIDInd = EnsureEdgeAreaID(e.AreaID2, areadict, arealist); edge = e.RawData; } else { var areaind = EnsureEdgeAreaID(0x3FFF, areadict, arealist); edge = new NavMeshEdge();//create an empty edge edge._Poly1.PolyID = 0x3FFF; edge._Poly2.PolyID = 0x3FFF; edge._Poly1.AreaIDInd = areaind; edge._Poly2.AreaIDInd = areaind; } edgelist.Add(edge); } poly._RawData.IndexCount = vc; poly._RawData.PortalLinkID = (uint)portallinks.Count;//these shouldn't be directly editable! poly._RawData.PortalLinkCount = (byte)(poly.PortalLinks?.Length ?? 0); if (poly.PortalLinks != null) { portallinks.AddRange(poly.PortalLinks); } poly.Index = i; //this should be redundant... poly.CalculateAABB(); //make sure this is up to date! polylist.Add(poly.RawData); } } if (Portals != null) { for (int i = 0; i < Portals.Count; i++) { var portal = Portals[i]; var pdata = portal.RawData; pdata.PositionFrom = NavMeshVertex.Create((portal.PositionFrom - posoffset) * aabbsizeinv); pdata.PositionTo = NavMeshVertex.Create((portal.PositionTo - posoffset) * aabbsizeinv); portallist.Add(pdata); } } if (Points != null) //points will be built into the sector tree { for (int i = 0; i < Points.Count; i++) { var point = Points[i]; var pdata = point.RawData; pdata.Position = point.Position; } } if (Nav.Vertices == null) { Nav.Vertices = new NavMeshList <NavMeshVertex>(); Nav.Vertices.VFT = 1080158456; } if (Nav.Indices == null) { Nav.Indices = new NavMeshList <ushort>(); Nav.Indices.VFT = 1080158424; } if (Nav.Edges == null) { Nav.Edges = new NavMeshList <NavMeshEdge>(); Nav.Edges.VFT = 1080158440; } if (Nav.Polys == null) { Nav.Polys = new NavMeshList <NavMeshPoly>(); Nav.Polys.VFT = 1080158408; } Nav.Vertices.RebuildList(vertlist); Nav.VerticesCount = Nav.Vertices.ItemCount; Nav.Indices.RebuildList(indslist); Nav.Edges.RebuildList(edgelist); Nav.EdgesIndicesCount = Nav.Indices.ItemCount; Nav.Polys.RebuildList(polylist); Nav.PolysCount = Nav.Polys.ItemCount; Nav.Portals = (portallist.Count > 0) ? portallist.ToArray() : null; Nav.PortalsCount = (uint)(Nav.Portals?.Length ?? 0); Nav.PortalLinks = (portallinks.Count > 0) ? portallinks.ToArray() : null; Nav.PortalLinksCount = (uint)(Nav.PortalLinks?.Length ?? 0); var adjAreaIds = new NavMeshUintArray(); adjAreaIds.Set(arealist.ToArray()); Nav.AdjAreaIDs = adjAreaIds; for (int i = 0; i < Nav.Polys.ListParts.Count; i++) //reassign part id's on all the polys... { var listpart = Nav.Polys.ListParts[i]; var partitems = listpart?.Items; if (partitems == null) { continue; } ushort iu = (ushort)i; for (int j = 0; j < partitems.Length; j++) { partitems[j].PartID = iu; } } //Build Sector Tree int depth = 0; if ((Nav.ContentFlags & NavMeshFlags.Vehicle) == 0) { depth = 2; } //vehicle navmesh has a single level, static has 3.. NavMeshSector orig = Nav.SectorTree; NavMeshSector root = new NavMeshSector(); root.SetAABBs(orig.AABBMin.XYZ(), orig.AABBMax.XYZ()); uint pointindex = 0; BuildSectorTree(root, depth, ref pointindex); Nav.SectorTree = root; }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { throw new Exception("File entry wasn't a resource! (is it binary data?)"); } ResourceDataReader rd = new ResourceDataReader(resentry, data); Nav = rd.ReadBlock <NavMesh>(); if (Nav != null) { Vector3 posoffset = Nav.SectorTree?.AABBMin.XYZ() ?? Vector3.Zero; Vector3 aabbsize = Nav.AABBSize; if (Nav.Vertices != null) { var verts = Nav.Vertices.GetFullList(); Vertices = new List <Vector3>(verts.Count); for (int i = 0; i < verts.Count; i++) { var ov = verts[i].ToVector3(); Vertices.Add(posoffset + ov * aabbsize); } } if (Nav.Indices != null) { Indices = Nav.Indices.GetFullList(); } if (Nav.Edges != null) { var edges = Nav.Edges.GetFullList(); Edges = new List <YnvEdge>(edges.Count); for (int i = 0; i < edges.Count; i++) { YnvEdge edge = new YnvEdge(); edge.Init(this, edges[i]); Edges.Add(edge); } } if (Nav.Polys != null) { var polys = Nav.Polys.GetFullList(); Polys = new List <YnvPoly>(polys.Count); for (int i = 0; i < polys.Count; i++) { YnvPoly poly = new YnvPoly(); poly.Init(this, polys[i]); poly.Index = i; Polys.Add(poly); } } if (Nav.Portals != null) { var portals = Nav.Portals; Portals = new List <YnvPortal>(portals.Length); for (int i = 0; i < portals.Length; i++) { YnvPortal portal = new YnvPortal(); portal.Init(this, portals[i]); portal.Index = i; portal.PositionFrom = posoffset + portal._RawData.PositionFrom.ToVector3() * aabbsize; portal.PositionTo = posoffset + portal._RawData.PositionTo.ToVector3() * aabbsize; Portals.Add(portal); } } ////### add points to the list and calculate positions... var treestack = new Stack <NavMeshSector>(); var pointi = 0; if (Nav.SectorTree != null) { treestack.Push(Nav.SectorTree); } while (treestack.Count > 0) { var sector = treestack.Pop(); if (sector.Data != null) { var points = sector.Data.Points; if (points != null) { if (Points == null) { Points = new List <YnvPoint>(); } for (int i = 0; i < points.Length; i++) { YnvPoint point = new YnvPoint(); point.Init(this, points[i]); point.Index = pointi; pointi++; point.Position = posoffset + point._RawData.Position * aabbsize; Points.Add(point); } } } if (sector.SubTree1 != null) { treestack.Push(sector.SubTree1); } if (sector.SubTree2 != null) { treestack.Push(sector.SubTree2); } if (sector.SubTree3 != null) { treestack.Push(sector.SubTree3); } if (sector.SubTree4 != null) { treestack.Push(sector.SubTree4); } } } UpdateAllNodePositions(); UpdateTriangleVertices(); BuildBVH(); Loaded = true; LoadQueued = true; }