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>(); if (Vertices != null) { for (int i = 0; i < Vertices.Count; i++) { vertlist.Add(NavMeshVertex.Create((Vertices[i] - posoffset) * aabbsizeinv)); } } var polylist = new List <NavMeshPoly>(); if (Polys != null) { for (int i = 0; i < Polys.Count; i++) { Polys[i].Index = i; polylist.Add(Polys[i].RawData); } } var portallist = new List <NavMeshPortal>(); 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) { 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.AdjPolys == null) { Nav.AdjPolys = new NavMeshList <NavMeshAdjPoly>(); Nav.AdjPolys.VFT = 1080158440; } if (Nav.Polys == null) { Nav.Polys = new NavMeshList <NavMeshPoly>(); Nav.Polys.VFT = 1080158408; } Nav.Vertices.RebuildList(vertlist); Nav.Indices.RebuildList(Indices); Nav.AdjPolys.RebuildList(AdjPolys); Nav.Polys.RebuildList(polylist); Nav.Portals = (portallist.Count > 0) ? portallist.ToArray() : null; Nav.PortalsCount = (uint)(Nav.Portals?.Length ?? 0); //TODO: update portal links data..... 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; }
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; }