Beispiel #1
0
 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;
 }
Beispiel #2
0
        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++;
            }
        }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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;
        }