Nav mesh progress

This commit is contained in:
dexyfex 2018-05-01 22:34:52 +10:00
parent 4c46a850f4
commit bab6668021
2 changed files with 120 additions and 96 deletions

View File

@ -14,7 +14,7 @@ namespace CodeWalker.GameFiles
public List<Vector3> Vertices { get; set; } public List<Vector3> Vertices { get; set; }
public List<ushort> Indices { get; set; } public List<ushort> Indices { get; set; }
public List<NavMeshAdjPoly> AdjPolys { get; set; } public List<NavMeshEdge> Edges { get; set; }
public List<YnvPoly> Polys { get; set; } public List<YnvPoly> Polys { get; set; }
public List<YnvPortal> Portals { get; set; } public List<YnvPortal> Portals { get; set; }
public List<YnvPoint> Points { get; set; } public List<YnvPoint> Points { get; set; }
@ -101,9 +101,9 @@ namespace CodeWalker.GameFiles
{ {
Indices = Nav.Indices.GetFullList(); Indices = Nav.Indices.GetFullList();
} }
if (Nav.AdjPolys != null) if (Nav.Edges != null)
{ {
AdjPolys = Nav.AdjPolys.GetFullList(); Edges = Nav.Edges.GetFullList();
} }
if (Nav.Polys != null) if (Nav.Polys != null)
{ {
@ -114,7 +114,6 @@ namespace CodeWalker.GameFiles
YnvPoly poly = new YnvPoly(); YnvPoly poly = new YnvPoly();
poly.Init(this, polys[i]); poly.Init(this, polys[i]);
poly.Index = i; poly.Index = i;
poly.CalculatePosition(); //calc poly center for display purposes..
Polys.Add(poly); Polys.Add(poly);
if (poly.PortalType > 0) if (poly.PortalType > 0)
@ -209,23 +208,46 @@ namespace CodeWalker.GameFiles
Vector3 aabbsizeinv = 1.0f / aabbsize; Vector3 aabbsizeinv = 1.0f / aabbsize;
var vertlist = new List<NavMeshVertex>(); var vertlist = new List<NavMeshVertex>();
if (Vertices != null) var indslist = new List<ushort>();
{ var edgelist = new List<NavMeshEdge>();
for (int i = 0; i < Vertices.Count; i++)
{
vertlist.Add(NavMeshVertex.Create((Vertices[i] - posoffset) * aabbsizeinv));
}
}
var polylist = new List<NavMeshPoly>(); var polylist = new List<NavMeshPoly>();
if (Polys != null) var portallist = new List<NavMeshPortal>();
var vertdict = new Dictionary<Vector3, ushort>();
var blankedgepart1 = new NavMeshEdgePart() { Value = 0x0FFFE1 };//1, -, 1, 0
var blankedgepart2 = new NavMeshEdgePart() { Value = 0x2FFFE1 };//1, -, 1, 1
var blankedge = new NavMeshEdge() { Unknown_0h = blankedgepart1, Unknown_4h = blankedgepart2 };
if (Polys != null) //rebuild vertices, indices, edges and polys lists from poly data.
{ {
for (int i = 0; i < Polys.Count; i++) for (int i = 0; i < Polys.Count; i++)
{ {
Polys[i].Index = i; var poly = Polys[i];
polylist.Add(Polys[i].RawData); var vc = poly.Vertices?.Length ?? 0;
for (int n = 0; n < vc; n++)
{
Vector3 v = poly.Vertices[n];
NavMeshEdge e = ((poly.Edges != null) && (n < poly.Edges.Length)) ? poly.Edges[n] : blankedge;
ushort ind;
if (!vertdict.TryGetValue(v, out ind))
{
ind = (ushort)vertlist.Count;
vertdict[v] = ind;
vertlist.Add(NavMeshVertex.Create((v - posoffset) * aabbsizeinv));
}
if ((poly.Indices != null) && (n < poly.Indices.Length))
{
poly.Indices[n] = ind;
}
indslist.Add(ind);
edgelist.Add(e);
}
poly._RawData.IndexCount = vc;
poly.Index = i;//this should be redundant...
polylist.Add(poly.RawData);
} }
} }
var portallist = new List<NavMeshPortal>();
if (Portals != null) if (Portals != null)
{ {
for (int i = 0; i < Portals.Count; i++) for (int i = 0; i < Portals.Count; i++)
@ -238,7 +260,7 @@ namespace CodeWalker.GameFiles
} }
} }
if (Points != null) if (Points != null) //points will be built into the sector tree
{ {
for (int i = 0; i < Points.Count; i++) for (int i = 0; i < Points.Count; i++)
{ {
@ -259,10 +281,10 @@ namespace CodeWalker.GameFiles
Nav.Indices = new NavMeshList<ushort>(); Nav.Indices = new NavMeshList<ushort>();
Nav.Indices.VFT = 1080158424; Nav.Indices.VFT = 1080158424;
} }
if (Nav.AdjPolys == null) if (Nav.Edges == null)
{ {
Nav.AdjPolys = new NavMeshList<NavMeshAdjPoly>(); Nav.Edges = new NavMeshList<NavMeshEdge>();
Nav.AdjPolys.VFT = 1080158440; Nav.Edges.VFT = 1080158440;
} }
if (Nav.Polys == null) if (Nav.Polys == null)
{ {
@ -273,9 +295,9 @@ namespace CodeWalker.GameFiles
Nav.Vertices.RebuildList(vertlist); Nav.Vertices.RebuildList(vertlist);
Nav.Indices.RebuildList(Indices); Nav.Indices.RebuildList(indslist);
Nav.AdjPolys.RebuildList(AdjPolys); Nav.Edges.RebuildList(edgelist);
Nav.Polys.RebuildList(polylist); Nav.Polys.RebuildList(polylist);
@ -474,67 +496,39 @@ namespace CodeWalker.GameFiles
//go through the nav mesh polys and generate verts to render... //go through the nav mesh polys and generate verts to render...
if ((Vertices == null) || (Vertices.Count == 0)) return;
if ((Indices == null) || (Indices.Count == 0)) return;
if ((Polys == null) || (Polys.Count == 0)) return; if ((Polys == null) || (Polys.Count == 0)) return;
int vc = Vertices.Count; int vc = Vertices.Count;
List<EditorVertex> rverts = new List<EditorVertex>(); List<EditorVertex> rverts = new List<EditorVertex>();
foreach (var ypoly in Polys)
{
var poly = ypoly.RawData;
var colour = ypoly.GetColour();
var colourval = (uint)colour.ToRgba();
var ic = poly.IndexCount;
var startid = poly.IndexID;
var endid = startid + ic;
if (startid >= Indices.Count)
{ continue; }
if (endid > Indices.Count)
{ continue; }
if(ic<3)
{ continue; }//not enough verts to make a triangle...
if (ic > 15)
{ }
EditorVertex p0 = new EditorVertex(); EditorVertex p0 = new EditorVertex();
EditorVertex p1 = new EditorVertex(); EditorVertex p1 = new EditorVertex();
EditorVertex p2 = new EditorVertex(); EditorVertex p2 = new EditorVertex();
foreach (var ypoly in Polys)
{
if ((ypoly.Vertices == null) || (ypoly.Vertices.Length < 3))
{ continue; }
var colour = ypoly.GetColour();
var colourval = (uint)colour.ToRgba();
p0.Colour = colourval; p0.Colour = colourval;
p1.Colour = colourval; p1.Colour = colourval;
p2.Colour = colourval; p2.Colour = colourval;
var startind = Indices[startid]; p0.Position = ypoly.Vertices[0];
if (startind >= vc)
{ continue; }
p0.Position = Vertices[startind];
//build triangles for the poly. //build triangles for the poly.
int tricount = ic - 2; int tricount = ypoly.Vertices.Length - 2;
for (int t = 0; t < tricount; t++) for (int t = 0; t < tricount; t++)
{ {
int tid = startid + t; p1.Position = ypoly.Vertices[t + 1];
int ind1 = Indices[tid + 1]; p2.Position = ypoly.Vertices[t + 2];
int ind2 = Indices[tid + 2];
if ((ind1 >= vc) || (ind2 >= vc))
{ continue; }
p1.Position = Vertices[ind1];
p2.Position = Vertices[ind2];
rverts.Add(p0); rverts.Add(p0);
rverts.Add(p1); rverts.Add(p1);
rverts.Add(p2); rverts.Add(p2);
} }
} }
TriangleVerts = rverts.ToArray(); TriangleVerts = rverts.ToArray();
@ -624,14 +618,58 @@ namespace CodeWalker.GameFiles
public Vector3 Position { get; set; } public Vector3 Position { get; set; }
public int Index { get; set; } public int Index { get; set; }
public ushort[] Indices { get; set; }
public Vector3[] Vertices { get; set; }
public NavMeshEdge[] Edges { get; set; }
public void Init(YnvFile ynv, NavMeshPoly poly) public void Init(YnvFile ynv, NavMeshPoly poly)
{ {
Ynv = ynv; Ynv = ynv;
RawData = poly; RawData = poly;
LoadIndices();
CalculatePosition(); //calc poly center for display purposes..
} }
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 NavMeshEdge[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++;
}
}
public void SetPosition(Vector3 pos) public void SetPosition(Vector3 pos)
{ {
Vector3 delta = pos - Position; Vector3 delta = pos - Position;
@ -709,30 +747,15 @@ namespace CodeWalker.GameFiles
public void CalculatePosition() public void CalculatePosition()
{ {
//calc poly center for display purposes. //calc poly center for display purposes.
var indices = Ynv.Indices;
var vertices = Ynv.Vertices;
if ((indices == null) || (vertices == 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; }
Vector3 pcenter = Vector3.Zero; Vector3 pcenter = Vector3.Zero;
float pcount = 0.0f; if (Vertices != null)
for (int id = startid; id < endid; id++)
{ {
var ind = indices[id]; for (int i = 0; i < Vertices.Length; i++)
if (ind >= vc) {
{ continue; } pcenter += Vertices[i];
pcenter += vertices[ind];
pcount += 1.0f;
} }
Position = pcenter * (1.0f / pcount); }
Position = pcenter * (1.0f / ((float)Vertices?.Length));
} }

View File

@ -54,8 +54,8 @@ namespace CodeWalker.GameFiles
public uint Unused_078h { get; set; } // 0x00000000 public uint Unused_078h { get; set; } // 0x00000000
public uint Unused_07Ch { get; set; } // 0x00000000 public uint Unused_07Ch { get; set; } // 0x00000000
public ulong IndicesPointer { get; set; } public ulong IndicesPointer { get; set; }
public ulong AdjPolysPointer { get; set; } public ulong EdgesPointer { get; set; }
public uint AdjPolysIndicesCount { get; set; } public uint EdgesIndicesCount { get; set; }
public NavMeshUintArray AdjAreaIDs { get; set; } public NavMeshUintArray AdjAreaIDs { get; set; }
public ulong PolysPointer { get; set; } public ulong PolysPointer { get; set; }
public ulong SectorTreePointer { get; set; } public ulong SectorTreePointer { get; set; }
@ -79,7 +79,7 @@ namespace CodeWalker.GameFiles
public NavMeshList<NavMeshVertex> Vertices { get; set; } public NavMeshList<NavMeshVertex> Vertices { get; set; }
public NavMeshList<ushort> Indices { get; set; } public NavMeshList<ushort> Indices { get; set; }
public NavMeshList<NavMeshAdjPoly> AdjPolys { get; set; } public NavMeshList<NavMeshEdge> Edges { get; set; }
public NavMeshList<NavMeshPoly> Polys { get; set; } public NavMeshList<NavMeshPoly> Polys { get; set; }
public NavMeshSector SectorTree { get; set; } public NavMeshSector SectorTree { get; set; }
public NavMeshPortal[] Portals { get; set; } public NavMeshPortal[] Portals { get; set; }
@ -109,8 +109,8 @@ namespace CodeWalker.GameFiles
Unused_078h = reader.ReadUInt32(); Unused_078h = reader.ReadUInt32();
Unused_07Ch = reader.ReadUInt32(); Unused_07Ch = reader.ReadUInt32();
IndicesPointer = reader.ReadUInt64(); IndicesPointer = reader.ReadUInt64();
AdjPolysPointer = reader.ReadUInt64(); EdgesPointer = reader.ReadUInt64();
AdjPolysIndicesCount = reader.ReadUInt32(); EdgesIndicesCount = reader.ReadUInt32();
AdjAreaIDs = reader.ReadStruct<NavMeshUintArray>(); AdjAreaIDs = reader.ReadStruct<NavMeshUintArray>();
PolysPointer = reader.ReadUInt64(); PolysPointer = reader.ReadUInt64();
SectorTreePointer = reader.ReadUInt64(); SectorTreePointer = reader.ReadUInt64();
@ -135,7 +135,7 @@ namespace CodeWalker.GameFiles
Vertices = reader.ReadBlockAt<NavMeshList<NavMeshVertex>>(VerticesPointer); Vertices = reader.ReadBlockAt<NavMeshList<NavMeshVertex>>(VerticesPointer);
Indices = reader.ReadBlockAt<NavMeshList<ushort>>(IndicesPointer); Indices = reader.ReadBlockAt<NavMeshList<ushort>>(IndicesPointer);
AdjPolys = reader.ReadBlockAt<NavMeshList<NavMeshAdjPoly>>(AdjPolysPointer); Edges = reader.ReadBlockAt<NavMeshList<NavMeshEdge>>(EdgesPointer);
Polys = reader.ReadBlockAt<NavMeshList<NavMeshPoly>>(PolysPointer); Polys = reader.ReadBlockAt<NavMeshList<NavMeshPoly>>(PolysPointer);
SectorTree = reader.ReadBlockAt<NavMeshSector>(SectorTreePointer); SectorTree = reader.ReadBlockAt<NavMeshSector>(SectorTreePointer);
Portals = reader.ReadStructsAt<NavMeshPortal>(PortalsPointer, PortalsCount); Portals = reader.ReadStructsAt<NavMeshPortal>(PortalsPointer, PortalsCount);
@ -150,7 +150,7 @@ namespace CodeWalker.GameFiles
VerticesPointer = (ulong)(Vertices != null ? Vertices.FilePosition : 0); VerticesPointer = (ulong)(Vertices != null ? Vertices.FilePosition : 0);
IndicesPointer = (ulong)(Indices != null ? Indices.FilePosition : 0); IndicesPointer = (ulong)(Indices != null ? Indices.FilePosition : 0);
AdjPolysPointer = (ulong)(AdjPolys != null ? AdjPolys.FilePosition : 0); EdgesPointer = (ulong)(Edges != null ? Edges.FilePosition : 0);
PolysPointer = (ulong)(Polys != null ? Polys.FilePosition : 0); PolysPointer = (ulong)(Polys != null ? Polys.FilePosition : 0);
SectorTreePointer = (ulong)(SectorTree != null ? SectorTree.FilePosition : 0); SectorTreePointer = (ulong)(SectorTree != null ? SectorTree.FilePosition : 0);
PortalsPointer = (ulong)(PortalsBlock?.FilePosition ?? 0); PortalsPointer = (ulong)(PortalsBlock?.FilePosition ?? 0);
@ -169,8 +169,8 @@ namespace CodeWalker.GameFiles
writer.Write(Unused_078h); writer.Write(Unused_078h);
writer.Write(Unused_07Ch); writer.Write(Unused_07Ch);
writer.Write(IndicesPointer); writer.Write(IndicesPointer);
writer.Write(AdjPolysPointer); writer.Write(EdgesPointer);
writer.Write(AdjPolysIndicesCount); writer.Write(EdgesIndicesCount);
writer.WriteStruct(AdjAreaIDs); writer.WriteStruct(AdjAreaIDs);
writer.Write(PolysPointer); writer.Write(PolysPointer);
writer.Write(SectorTreePointer); writer.Write(SectorTreePointer);
@ -198,7 +198,7 @@ namespace CodeWalker.GameFiles
var list = new List<IResourceBlock>(base.GetReferences()); var list = new List<IResourceBlock>(base.GetReferences());
if (Vertices != null) list.Add(Vertices); if (Vertices != null) list.Add(Vertices);
if (Indices != null) list.Add(Indices); if (Indices != null) list.Add(Indices);
if (AdjPolys != null) list.Add(AdjPolys); if (Edges != null) list.Add(Edges);
if (Polys != null) list.Add(Polys); if (Polys != null) list.Add(Polys);
if (SectorTree != null) list.Add(SectorTree); if (SectorTree != null) list.Add(SectorTree);
@ -592,10 +592,10 @@ namespace CodeWalker.GameFiles
[TypeConverter(typeof(ExpandableObjectConverter))] public struct NavMeshAdjPoly [TypeConverter(typeof(ExpandableObjectConverter))] public struct NavMeshEdge
{ {
public NavMeshAdjPolyPart Unknown_0h { get; set; } public NavMeshEdgePart Unknown_0h { get; set; }
public NavMeshAdjPolyPart Unknown_4h { get; set; } public NavMeshEdgePart Unknown_4h { get; set; }
public override string ToString() public override string ToString()
{ {
@ -604,7 +604,7 @@ namespace CodeWalker.GameFiles
} }
} }
[TypeConverter(typeof(ExpandableObjectConverter))] public struct NavMeshAdjPolyPart [TypeConverter(typeof(ExpandableObjectConverter))] public struct NavMeshEdgePart
{ {
public uint Value { get; set; } public uint Value { get; set; }
@ -623,7 +623,8 @@ namespace CodeWalker.GameFiles
public override string ToString() public override string ToString()
{ {
return AreaIDInd.ToString() + ", " + PolyID.ToString() + ", " + Unk2.ToString() + ", " + Unk3.ToString(); string pid = (PolyID == 0x3FFF) ? "-" : PolyID.ToString();
return AreaIDInd.ToString() + ", " + pid + ", " + Unk2.ToString() + ", " + Unk3.ToString();
} }
} }
@ -647,7 +648,7 @@ namespace CodeWalker.GameFiles
//public int IndexUnk { get { return (IndexFlags >> 0) & 31; } } //always 0 //public int IndexUnk { get { return (IndexFlags >> 0) & 31; } } //always 0
public int IndexCount { get { return (IndexFlags >> 5); } } public int IndexCount { get { return (IndexFlags >> 5); } set { IndexFlags = (ushort)((IndexFlags & 31) | ((value & 0x7FF) << 5)); } }
//public int PartUnk1 { get { return (PartFlags >> 0) & 0xF; } } //always 0 //public int PartUnk1 { get { return (PartFlags >> 0) & 0xF; } } //always 0
public ushort PartID { get { return (ushort)((PartFlags >> 4) & 0xFF); } set { PartFlags = (ushort)((PartFlags & 0xF00F) | ((value & 0xFF) << 4)); } } public ushort PartID { get { return (ushort)((PartFlags >> 4) & 0xFF); } set { PartFlags = (ushort)((PartFlags & 0xF00F) | ((value & 0xFF) << 4)); } }