diff --git a/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs index b1ed748..1fd6ea1 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs @@ -16,6 +16,8 @@ namespace CodeWalker.GameFiles public List Indices { get; set; } public List AdjPolys { get; set; } public List Polys { get; set; } + public List Portals { get; set; } + public List Points { get; set; } public EditorVertex[] PathVertices { get; set; } @@ -27,6 +29,7 @@ namespace CodeWalker.GameFiles public bool HasChanged { get; set; } = false; public List SaveWarnings = null; + public PathBVH BVH { get; set; } public int AreaID @@ -79,13 +82,13 @@ namespace CodeWalker.GameFiles Nav = rd.ReadBlock(); - if ((Nav != null) && (Nav.SectorTree != null)) + if (Nav != null) { + Vector3 posoffset = Nav.SectorTree?.AABBMin.XYZ() ?? Vector3.Zero; + Vector3 aabbsize = Nav.AABBSize; + if (Nav.Vertices != null) { - Vector3 posoffset = Nav.SectorTree.AABBMin.XYZ(); - Vector3 aabbsize = Nav.AABBSize; - var verts = Nav.Vertices.GetFullList(); Vertices = new List(verts.Count); for (int i = 0; i < verts.Count; i++) @@ -111,36 +114,60 @@ namespace CodeWalker.GameFiles YnvPoly poly = new YnvPoly(); poly.Init(this, polys[i]); poly.Index = i; + poly.CalculatePosition(); //calc poly center for display purposes.. Polys.Add(poly); - - - //calc poly center. - if ((Indices == null) || (Vertices == null)) - { continue; } - var vc = Vertices.Count; - var ic = poly._RawData.IndexCount; - var startid = poly._RawData.IndexID; - var endid = startid + ic; - if (startid >= Indices.Count) - { continue; } - if (endid > Indices.Count) - { continue; } - Vector3 pcenter = Vector3.Zero; - float pcount = 0.0f; - for (int id = startid; id < endid; id++) - { - var ind = Indices[id]; - if(ind>=vc) - { continue; } - - pcenter += Vertices[ind]; - pcount += 1.0f; - } - poly.Position = pcenter * (1.0f / pcount); - - } } + if (Nav.Portals != null) + { + var portals = Nav.Portals; + Portals = new List(portals.Length); + for (int i = 0; i < portals.Length; i++) + { + YnvPortal portal = new YnvPortal(); + portal.Init(this, portals[i]); + portal.Index = i; + portal.Position1 = posoffset + portal._RawData.Position1.ToVector3() * aabbsize; + portal.Position2 = posoffset + portal._RawData.Position2.ToVector3() * aabbsize; + Portals.Add(portal); + } + } + + + ////### add points to the list and calculate positions... + var treestack = new Stack(); + 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(); + } + 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); + } } @@ -150,6 +177,8 @@ namespace CodeWalker.GameFiles UpdateTriangleVertices(); + BuildBVH(); + Loaded = true; LoadQueued = true; @@ -251,91 +280,51 @@ namespace CodeWalker.GameFiles public void UpdateAllNodePositions() { if (Nav == null) return; - if (Nav.Portals == null) return; - int cnt = Nav.Portals?.Length ?? 0; - if (cnt <= 0) - { - NodePositions = null; - return; - } Vector3 posoffset = Nav.SectorTree.AABBMin.XYZ(); Vector3 aabbsize = Nav.AABBSize; - var np = new Vector4[cnt]; - for (int i = 0; i < cnt; i++) - { - var portal = Nav.Portals[i]; - var pv = portal.Position1.ToVector3(); - //var pv = portal.Position2.ToVector3(); - np[i] = new Vector4(posoffset + pv * aabbsize, 1.0f); - } - NodePositions = np; - - - - int lcnt = Nav.PortalLinks?.Length ?? 0; - if (lcnt <= 0) - { - PathVertices = null; - return; - } - - //var lv = new EditorVertex[lcnt]; - //for (int i = 0; i < lcnt; i++) - //{ - // var pl = Nav.PortalLinks[i]; - // if (pl >= np.Length) lv[i] = new EditorVertex(); - // else - // { - // lv[i].Position = np[pl].XYZ(); - // lv[i].Colour = 0xFF0000FF; - // } - //} - //PathVertices = lv; - EditorVertex v = new EditorVertex(); v.Colour = 0xFF0000FF; var lv = new List(); - //int cind = 0; - var plinks = Nav.PortalLinks; - for (int i = 0; i < cnt; i++) + var nv = new List(); + + + ////### add portal positions to the node list, also add links to the link vertex array + int cnt = Portals?.Count ?? 0; + if (cnt > 0) { - var portal = Nav.Portals[i]; - - //var plcnt = 2; - - v.Position = posoffset + portal.Position1.ToVector3() * aabbsize; - lv.Add(v); - v.Position = posoffset + portal.Position2.ToVector3() * aabbsize; - lv.Add(v); - - - //var plcnt = portal.LinkCount; - //if (plcnt < 2) continue; - //var plink = (cind < plinks.Length) ? plinks[cind] : 0xFFFF; - //var ppos = (plink < np.Length) ? np[plink].XYZ() : Vector3.Zero; - //for (int pl = 1; pl < plcnt; pl++) - //{ - // var ind2 = cind + pl; - // var plink2 = (ind2 < plinks.Length) ? plinks[ind2] : 0xFFFF; - // var ppos2 = (plink2 < np.Length) ? np[plink2].XYZ() : Vector3.Zero; - // v.Position = ppos; lv.Add(v); - // v.Position = ppos2; lv.Add(v); - //} - //cind += plcnt; + for (int i = 0; i < cnt; i++) + { + var portal = Portals[i]; + nv.Add(new Vector4(portal.Position1, 1.0f)); + v.Position = portal.Position1; lv.Add(v); + v.Position = portal.Position2; lv.Add(v); + } } - PathVertices = lv.ToArray(); + + + ////### add point positions to the node list + cnt = Points?.Count ?? 0; + if (cnt >= 0) + { + for (int i = 0; i < cnt; i++) + { + var point = Points[i]; + nv.Add(new Vector4(point.Position, 1.0f)); + } + } + + + NodePositions = (nv.Count > 0) ? nv.ToArray() : null; + PathVertices = (lv.Count > 0) ? lv.ToArray() : null; + } public void UpdateTriangleVertices() { - if (Nav == null) return; - if (Nav.Polys == null) return; - if (Nav.Vertices == null) return; - //need position and colour for each vertex. //render as a triangle list... (no indices needed) @@ -410,6 +399,16 @@ namespace CodeWalker.GameFiles + public void BuildBVH() + { + var nodes = new List(); + if (Portals != null) nodes.AddRange(Portals); + if (Points != null) nodes.AddRange(Points); + BVH = new PathBVH(nodes, 10, 10); + } + + + public EditorVertex[] GetPathVertices() { return PathVertices; @@ -493,6 +492,12 @@ namespace CodeWalker.GameFiles } + public void SetPosition(Vector3 pos) + { + Vector3 delta = pos - Position; + Position = pos; + //TODO: update vertex positions!!! + } public Color4 GetColour() { @@ -556,11 +561,129 @@ namespace CodeWalker.GameFiles } + + public void CalculatePosition() + { + //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; + float pcount = 0.0f; + for (int id = startid; id < endid; id++) + { + var ind = indices[id]; + if (ind >= vc) + { continue; } + + pcenter += vertices[ind]; + pcount += 1.0f; + } + Position = pcenter * (1.0f / pcount); + } + + + public override string ToString() { return AreaID.ToString() + ", " + Index.ToString(); } } + [TypeConverter(typeof(ExpandableObjectConverter))] public class YnvPortal : BasePathNode + { + public NavMeshPortal _RawData; + + public YnvFile Ynv { get; set; } + public NavMeshPortal RawData { get { return _RawData; } set { _RawData = value; } } + + public Vector3 Position { get { return Position1; } set { Position1 = value; } } + public Vector3 Position1 { get; set; } + public Vector3 Position2 { get; set; } + public int Index { get; set; } + + + public void Init(YnvFile ynv, NavMeshPortal portal) + { + Ynv = ynv; + RawData = portal; + } + + public void SetPosition(Vector3 pos) + { + Position = pos; + //TODO: update _RawData positions! + } + + public override string ToString() + { + return Index.ToString(); + } + } + + [TypeConverter(typeof(ExpandableObjectConverter))] public class YnvPoint : BasePathNode + { + public NavMeshPoint _RawData; + + public YnvFile Ynv { get; set; } + public NavMeshPoint RawData { get { return _RawData; } set { _RawData = value; } } + + public Vector3 Position { get; set; } + public float Direction + { + get + { + return (float)Math.PI * 2.0f * _RawData.Angle / 255.0f; + } + set + { + _RawData.Angle = (byte)(value * 255.0f / ((float)Math.PI * 2.0f)); + } + } + public Quaternion Orientation + { + get { return Quaternion.RotationAxis(Vector3.UnitZ, Direction); } + set + { + Vector3 dir = value.Multiply(Vector3.UnitX); + float dira = (float)Math.Atan2(dir.Y, dir.X); + Direction = dira; + } + } + + public int Index { get; set; } + public byte Flags { get { return _RawData.Flags; } set { _RawData.Flags = value; } } + + public void Init(YnvFile ynv, NavMeshPoint point) + { + Ynv = ynv; + RawData = point; + } + + public void SetPosition(Vector3 pos) + { + Position = pos; + //TODO! update _RawData.Position!!! + } + public void SetOrientation(Quaternion orientation) + { + Orientation = orientation; + } + + public override string ToString() + { + return Index.ToString() + ": " + Flags.ToString(); + } + + } } diff --git a/CodeWalker.Core/GameFiles/Resources/Nav.cs b/CodeWalker.Core/GameFiles/Resources/Nav.cs index 848ef57..59777c9 100644 --- a/CodeWalker.Core/GameFiles/Resources/Nav.cs +++ b/CodeWalker.Core/GameFiles/Resources/Nav.cs @@ -608,14 +608,14 @@ namespace CodeWalker.GameFiles } } - public uint AdjAreaIDInd { get { return (Value >> 0) & 0x1F; } } + public uint AreaIDInd { get { return (Value >> 0) & 0x1F; } } public uint PolyID { get { return (Value >> 5) & 0x3FFF; } } public uint Unk2 { get { return (Value >> 19) & 0x3; } } - public uint Unk3 { get { return (Value >> 21); } } + public uint Unk3 { get { return (Value >> 21) & 0x7FF; } } public override string ToString() { - return AdjAreaIDInd.ToString() + ", " + PolyID.ToString() + ", " + Unk2.ToString() + ", " + Unk3.ToString(); + return AreaIDInd.ToString() + ", " + PolyID.ToString() + ", " + Unk2.ToString() + ", " + Unk3.ToString(); } } @@ -766,29 +766,29 @@ namespace CodeWalker.GameFiles public uint UnkDataStartID { get; set; } public uint Unused_04h { get; set; } // 0x00000000 public ulong PolyIDsPointer { get; set; } - public ulong UnkDataPointer { get; set; } + public ulong PointsPointer { get; set; } public ushort PolyIDsCount { get; set; } - public ushort UnkDataCount { get; set; } + public ushort PointsCount { get; set; } public uint Unused_1Ch { get; set; } // 0x00000000 public ushort[] PolyIDs { get; set; } - public NavMeshSectorDataUnk[] UnkData { get; set; } + public NavMeshPoint[] Points { get; set; } private ResourceSystemStructBlock PolyIDsBlock = null; - private ResourceSystemStructBlock UnkDataBlock = null; + private ResourceSystemStructBlock PointsBlock = null; public override void Read(ResourceDataReader reader, params object[] parameters) { UnkDataStartID = reader.ReadUInt32(); Unused_04h = reader.ReadUInt32(); PolyIDsPointer = reader.ReadUInt64(); - UnkDataPointer = reader.ReadUInt64(); + PointsPointer = reader.ReadUInt64(); PolyIDsCount = reader.ReadUInt16(); - UnkDataCount = reader.ReadUInt16(); + PointsCount = reader.ReadUInt16(); Unused_1Ch = reader.ReadUInt32(); PolyIDs = reader.ReadUshortsAt(PolyIDsPointer, PolyIDsCount); - UnkData = reader.ReadStructsAt(UnkDataPointer, UnkDataCount); + Points = reader.ReadStructsAt(PointsPointer, PointsCount); } @@ -796,16 +796,16 @@ namespace CodeWalker.GameFiles { PolyIDsPointer = (ulong)(PolyIDsBlock?.FilePosition ?? 0); PolyIDsCount = (ushort)(PolyIDs?.Length ?? 0); - UnkDataPointer = (ulong)(UnkDataBlock?.FilePosition ?? 0); - UnkDataCount = (ushort)(UnkData?.Length ?? 0); + PointsPointer = (ulong)(PointsBlock?.FilePosition ?? 0); + PointsCount = (ushort)(Points?.Length ?? 0); writer.Write(UnkDataStartID); writer.Write(Unused_04h); writer.Write(PolyIDsPointer); - writer.Write(UnkDataPointer); + writer.Write(PointsPointer); writer.Write(PolyIDsCount); - writer.Write(UnkDataCount); + writer.Write(PointsCount); writer.Write(Unused_1Ch); } @@ -818,10 +818,10 @@ namespace CodeWalker.GameFiles PolyIDsBlock = new ResourceSystemStructBlock(PolyIDs); list.Add(PolyIDsBlock); } - if ((UnkData != null) && (UnkData.Length > 0)) + if ((Points != null) && (Points.Length > 0)) { - UnkDataBlock = new ResourceSystemStructBlock(UnkData); - list.Add(UnkDataBlock); + PointsBlock = new ResourceSystemStructBlock(Points); + list.Add(PointsBlock); } @@ -830,21 +830,33 @@ namespace CodeWalker.GameFiles public override string ToString() { - return "(Polys: " + PolyIDsCount.ToString() + ", UnkOffset: " + UnkDataStartID.ToString() + ", UnkCount: " + UnkDataCount.ToString() + ")"; + return "(Polys: " + PolyIDsCount.ToString() + ", UnkOffset: " + UnkDataStartID.ToString() + ", UnkCount: " + PointsCount.ToString() + ")"; } } - [TypeConverter(typeof(ExpandableObjectConverter))] public struct NavMeshSectorDataUnk + [TypeConverter(typeof(ExpandableObjectConverter))] public struct NavMeshPoint { - public ushort Unknown_0h { get; set; } - public ushort Unknown_2h { get; set; } - public ushort Unknown_4h { get; set; } - public ushort Unknown_6h { get; set; } + public ushort X { get; set; } + public ushort Y { get; set; } + public ushort Z { get; set; } + public byte Angle { get; set; } + public byte Flags { get; set; } + + + public Vector3 Position { get { return ToVector3(); } } + + public Vector3 ToVector3() + { + const float usmax = ushort.MaxValue; + return new Vector3(X / usmax, Y / usmax, Z / usmax); + } public override string ToString() { - return Unknown_0h.ToString() + ", " + Unknown_2h.ToString() + ", " + Unknown_4h.ToString() + ", " + Unknown_6h.ToString(); + return Flags.ToString() + ": " + Angle.ToString() + ", " + Position.ToString(); } + + } diff --git a/CodeWalker.Core/World/Space.cs b/CodeWalker.Core/World/Space.cs index 7657d0b..b1f962d 100644 --- a/CodeWalker.Core/World/Space.cs +++ b/CodeWalker.Core/World/Space.cs @@ -1164,7 +1164,7 @@ namespace CodeWalker.World } - public void GetVisibleYnvs(Camera cam, List ynvs) + public void GetVisibleYnvs(Camera cam, int gridrange, List ynvs) { if (!Inited) return; if (Grid == null) return; @@ -1173,7 +1173,6 @@ namespace CodeWalker.World ynvs.Clear(); - int gridrange = 30; var pos = NavGrid.GetCellPos(cam.Position); int minx = Math.Min(Math.Max(pos.X - gridrange, 0), NavGrid.CellCountX-1); int maxx = Math.Min(Math.Max(pos.X + gridrange, 0), NavGrid.CellCountX-1); diff --git a/Forms/ModelForm.cs b/Forms/ModelForm.cs index 96230f1..27929df 100644 --- a/Forms/ModelForm.cs +++ b/Forms/ModelForm.cs @@ -573,7 +573,7 @@ namespace CodeWalker.Forms FileName = ybn.Name; Ybn = ybn; - UpdateBoundsUI(ybn.Bounds); + UpdateBoundsUI(ybn); } public void LoadParticles(YptFile ypt) { @@ -825,7 +825,7 @@ namespace CodeWalker.Forms ToolsPanel.Visible = true; //show the panel by default for dictionaries... } - private void UpdateBoundsUI(Bounds bounds) + private void UpdateBoundsUI(YbnFile bounds) { DetailsPropertyGrid.SelectedObject = bounds; } diff --git a/Rendering/ShaderManager.cs b/Rendering/ShaderManager.cs index 56139dd..96056f7 100644 --- a/Rendering/ShaderManager.cs +++ b/Rendering/ShaderManager.cs @@ -83,7 +83,7 @@ namespace CodeWalker.Rendering private Camera Camera; public ShaderGlobalLights GlobalLights = new ShaderGlobalLights(); - public bool PathsDepthClip = false;//true;// + public bool PathsDepthClip = true;//false;// private GameFileCache GameFileCache; private RenderableCache RenderableCache; diff --git a/Shaders/PathBoxVS.cso b/Shaders/PathBoxVS.cso index 17aef3c..8bfb231 100644 Binary files a/Shaders/PathBoxVS.cso and b/Shaders/PathBoxVS.cso differ diff --git a/Shaders/PathBoxVS.hlsl b/Shaders/PathBoxVS.hlsl index 7ab7db5..f00dd8d 100644 --- a/Shaders/PathBoxVS.hlsl +++ b/Shaders/PathBoxVS.hlsl @@ -35,6 +35,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID) float3 ipos = input.Position.xyz * 0.25f; float3 opos = ipos + npos - CameraPos.xyz; float4 cpos = mul(float4(opos, 1), ViewProj); + cpos.z -= 0.01; //bias paths depth slightly to bring it in front of normal geometry... output.Position = cpos; output.Colour = ((float4)1) * LightColour.a; //apply intensity diff --git a/Shaders/PathDynVS.cso b/Shaders/PathDynVS.cso index f1122fb..79dfb5f 100644 Binary files a/Shaders/PathDynVS.cso and b/Shaders/PathDynVS.cso differ diff --git a/Shaders/PathDynVS.hlsl b/Shaders/PathDynVS.hlsl index 99304d1..c424ad6 100644 --- a/Shaders/PathDynVS.hlsl +++ b/Shaders/PathDynVS.hlsl @@ -36,6 +36,7 @@ VS_OUTPUT main(uint id : SV_VertexID) float3 opos = pos - CameraPos.xyz; float4 cpos = mul(float4(opos, 1), ViewProj); + cpos.z -= 0.01; //bias paths depth slightly to bring it in front of normal geometry... output.Position = cpos; output.Colour.rgb = col.rgb * LightColour.a; //apply intensity output.Colour.a = col.a; diff --git a/Shaders/PathVS.cso b/Shaders/PathVS.cso index 0508de7..63fb2a6 100644 Binary files a/Shaders/PathVS.cso and b/Shaders/PathVS.cso differ diff --git a/Shaders/PathVS.hlsl b/Shaders/PathVS.hlsl index 9df1950..232e3a6 100644 --- a/Shaders/PathVS.hlsl +++ b/Shaders/PathVS.hlsl @@ -28,6 +28,7 @@ VS_OUTPUT main(VS_INPUT input) float3 opos = pos - CameraPos.xyz; float4 cpos = mul(float4(opos, 1), ViewProj); + cpos.z -= 0.01; //bias paths depth slightly to bring it in front of normal geometry... output.Position = cpos; output.Colour.rgb = col.rgb * LightColour.a; //apply intensity output.Colour.a = col.a; diff --git a/Utils/MapUtils.cs b/Utils/MapUtils.cs index a987979..248bd90 100644 --- a/Utils/MapUtils.cs +++ b/Utils/MapUtils.cs @@ -185,6 +185,8 @@ namespace CodeWalker public WaterQuad WaterQuad { get; set; } public Bounds CollisionBounds { get; set; } public YnvPoly NavPoly { get; set; } + public YnvPoint NavPoint { get; set; } + public YnvPortal NavPortal { get; set; } public YndNode PathNode { get; set; } public YndLink PathLink { get; set; } public TrainTrackNode TrainTrackNode { get; set; } @@ -218,6 +220,8 @@ namespace CodeWalker (WaterQuad != null) || (CollisionBounds != null) || (NavPoly != null) || + (NavPoint != null) || + (NavPortal != null) || (PathNode != null) || (TrainTrackNode != null) || (DistantLodLights != null) || @@ -248,6 +252,8 @@ namespace CodeWalker || (WaterQuad != mhit.WaterQuad) || (CollisionBounds != mhit.CollisionBounds) || (NavPoly != mhit.NavPoly) + || (NavPoint != mhit.NavPoint) + || (NavPortal != mhit.NavPortal) || (PathNode != mhit.PathNode) || (TrainTrackNode != mhit.TrainTrackNode) || (ScenarioNode != mhit.ScenarioNode) @@ -268,6 +274,8 @@ namespace CodeWalker || (WaterQuad != null) || (CollisionBounds != null) || (NavPoly != null) + || (NavPoint != null) + || (NavPortal != null) || (PathNode != null) || (PathLink != null) || (TrainTrackNode != null) @@ -290,6 +298,8 @@ namespace CodeWalker WaterQuad = null; CollisionBounds = null; NavPoly = null; + NavPoint = null; + NavPortal = null; PathNode = null; PathLink = null; TrainTrackNode = null; @@ -352,6 +362,14 @@ namespace CodeWalker { name = "NavPoly " + NavPoly.ToString(); } + if (NavPoint != null) + { + name = "NavPoint " + NavPoint.ToString(); + } + if (NavPortal != null) + { + name = "NavPortal " + NavPortal.ToString(); + } if (PathNode != null) { name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString(); //+ FloatUtil.GetVector3String(PathNode.Position); @@ -418,6 +436,14 @@ namespace CodeWalker { name = "NavPoly " + NavPoly.ToString(); } + if (NavPoint != null) + { + name = "NavPoint " + NavPoint.ToString(); + } + if (NavPortal != null) + { + name = "NavPortal " + NavPortal.ToString(); + } if (PathNode != null) { name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString();// + FloatUtil.GetVector3String(PathNode.Position); @@ -461,6 +487,14 @@ namespace CodeWalker { res = true; } + else if (NavPoint != null) + { + res = true; + } + else if (NavPortal != null) + { + res = true; + } else if (PathNode != null) { res = true; @@ -500,6 +534,14 @@ namespace CodeWalker { return NavPoly.Position; } + else if (NavPoint != null) + { + return NavPoint.Position; + } + else if (NavPortal != null) + { + return NavPortal.Position; + } else if (PathNode != null) { return PathNode.Position; @@ -539,6 +581,14 @@ namespace CodeWalker { return Quaternion.Identity; } + else if (NavPoint != null) + { + return NavPoint.Orientation; + } + else if (NavPortal != null) + { + return Quaternion.Identity; + } else if (PathNode != null) { return Quaternion.Identity; @@ -578,6 +628,14 @@ namespace CodeWalker { return WidgetAxis.XYZ; } + else if (NavPoint != null) + { + return WidgetAxis.Z; + } + else if (NavPortal != null) + { + return WidgetAxis.None; + } else if (PathNode != null) { return WidgetAxis.None; @@ -617,6 +675,14 @@ namespace CodeWalker { return Vector3.One; } + else if (NavPoint != null) + { + return Vector3.One; + } + else if (NavPortal != null) + { + return Vector3.One; + } else if (PathNode != null) { return Vector3.One; @@ -667,13 +733,21 @@ namespace CodeWalker } else if (NavPoly != null) { - //NavPoly.SetPosition(newpos); + NavPoly.SetPosition(newpos); //if (projectForm != null) //{ // projectForm.OnWorldNavPolyModified(NavPoly); //} } + else if (NavPoint != null) + { + NavPoint.SetPosition(newpos); + } + else if (NavPortal != null) + { + NavPortal.SetPosition(newpos); + } else if (TrainTrackNode != null) { TrainTrackNode.SetPosition(newpos); @@ -709,6 +783,10 @@ namespace CodeWalker { ScenarioNode.SetOrientation(newrot); } + else if (NavPoint != null) + { + NavPoint.SetOrientation(newrot); + } else if (Audio != null) { Audio.SetOrientation(newrot); diff --git a/WorldForm.Designer.cs b/WorldForm.Designer.cs index b64100a..f50fd73 100644 --- a/WorldForm.Designer.cs +++ b/WorldForm.Designer.cs @@ -1540,9 +1540,9 @@ namespace CodeWalker this.label12.AutoSize = true; this.label12.Location = new System.Drawing.Point(4, 178); this.label12.Name = "label12"; - this.label12.Size = new System.Drawing.Size(106, 13); + this.label12.Size = new System.Drawing.Size(129, 13); this.label12.TabIndex = 51; - this.label12.Text = "Collision mesh range:"; + this.label12.Text = "Collision/nav mesh range:"; // // CollisionMeshRangeTrackBar // @@ -1551,6 +1551,7 @@ namespace CodeWalker this.CollisionMeshRangeTrackBar.BackColor = System.Drawing.SystemColors.ControlLightLight; this.CollisionMeshRangeTrackBar.LargeChange = 1; this.CollisionMeshRangeTrackBar.Location = new System.Drawing.Point(6, 194); + this.CollisionMeshRangeTrackBar.Maximum = 15; this.CollisionMeshRangeTrackBar.Minimum = 1; this.CollisionMeshRangeTrackBar.Name = "CollisionMeshRangeTrackBar"; this.CollisionMeshRangeTrackBar.Size = new System.Drawing.Size(188, 45); @@ -1878,6 +1879,8 @@ namespace CodeWalker // PathsDepthClipCheckBox // this.PathsDepthClipCheckBox.AutoSize = true; + this.PathsDepthClipCheckBox.Checked = true; + this.PathsDepthClipCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; this.PathsDepthClipCheckBox.Location = new System.Drawing.Point(10, 434); this.PathsDepthClipCheckBox.Name = "PathsDepthClipCheckBox"; this.PathsDepthClipCheckBox.Size = new System.Drawing.Size(102, 17); @@ -2674,7 +2677,7 @@ namespace CodeWalker this.ToolbarCameraModeButton}); this.Toolbar.Location = new System.Drawing.Point(1, 0); this.Toolbar.Name = "Toolbar"; - this.Toolbar.Size = new System.Drawing.Size(585, 25); + this.Toolbar.Size = new System.Drawing.Size(554, 25); this.Toolbar.TabIndex = 6; this.Toolbar.Text = "toolStrip1"; // diff --git a/WorldForm.cs b/WorldForm.cs index 4823d4a..0ffc6cf 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -792,7 +792,7 @@ namespace CodeWalker { rendernavmeshynvs.Clear(); - space.GetVisibleYnvs(camera, rendernavmeshynvs); + space.GetVisibleYnvs(camera, collisionmeshrange, rendernavmeshynvs); if (ProjectForm != null) { @@ -1117,7 +1117,9 @@ namespace CodeWalker change = change || (LastMouseHit.CollisionBounds != PrevMouseHit.CollisionBounds); break; case MapSelectionMode.NavMesh: - change = change || (LastMouseHit.NavPoly != PrevMouseHit.NavPoly); + change = change || (LastMouseHit.NavPoly != PrevMouseHit.NavPoly) + || (LastMouseHit.NavPoint != PrevMouseHit.NavPoint) + || (LastMouseHit.NavPortal != PrevMouseHit.NavPortal); break; case MapSelectionMode.Path: change = change || (LastMouseHit.PathNode != PrevMouseHit.PathNode); @@ -1144,9 +1146,9 @@ namespace CodeWalker { return; } - if (SelectionMode == MapSelectionMode.NavMesh) + if ((SelectionMode == MapSelectionMode.NavMesh) && (CurMouseHit.NavPoly != null)) { - return;//navmesh mode isn't needing a selection box.. + return;//navmesh poly isn't needing a selection box.. } @@ -1197,6 +1199,10 @@ namespace CodeWalker ori = sp.Orientation; } } + if (CurMouseHit.NavPoint != null) + { + ori = CurMouseHit.NavPoint.Orientation; + } if (CurMouseHit.Audio != null) { ori = CurMouseHit.Audio.Orientation; @@ -1424,6 +1430,21 @@ namespace CodeWalker Renderer.RenderSelectionNavPoly(selectionItem.NavPoly); //return;//don't render a selection box for nav mesh? } + if (selectionItem.NavPoint != null) + { + var navp = selectionItem.NavPoint; + camrel = navp.Position - camera.Position; + + //render direction arrow for NavPoint + ori = navp.Orientation; + float arrowlen = 2.0f; + float arrowrad = 0.25f; + Renderer.RenderSelectionArrowOutline(navp.Position, -Vector3.UnitY, Vector3.UnitZ, ori, arrowlen, arrowrad, cgrn); + } + if (selectionItem.NavPortal != null) + { + camrel = selectionItem.NavPortal.Position - camera.Position; + } if (selectionItem.Audio != null) { @@ -1724,7 +1745,7 @@ namespace CodeWalker { ynv.UpdateTriangleVertices(); - //ynv.BuildBVH();//TODO! + ynv.BuildBVH(); lock (Renderer.RenderSyncRoot) { @@ -2658,6 +2679,11 @@ namespace CodeWalker Renderer.BoundingBoxes.Add(mb); } + if (ynv.BVH != null) + { + UpdateMouseHits(ynv.BVH, ref mray); + } + //if ((CurMouseHit.NavPoint != null) || (CurMouseHit.NavPortal != null)) continue; if ((ynv.Nav != null) && (ynv.Vertices != null) && (ynv.Indices != null) && (ynv.Polys != null)) { UpdateMouseHits(ynv, ynv.Nav.SectorTree, ynv.Nav.SectorTree, ref mray); @@ -2825,6 +2851,8 @@ namespace CodeWalker { var cellaabb = poly._RawData.CellAABB; CurMouseHit.NavPoly = poly; + CurMouseHit.NavPoint = null; + CurMouseHit.NavPortal = null; CurMouseHit.HitDist = hitdist; CurMouseHit.AABB = new BoundingBox(cellaabb.Min, cellaabb.Max); break;//no need to test further tris in this poly @@ -3119,6 +3147,9 @@ namespace CodeWalker CurMouseHit.PathNode = n as YndNode; CurMouseHit.TrainTrackNode = n as TrainTrackNode; CurMouseHit.ScenarioNode = n as ScenarioNode; + CurMouseHit.NavPoint = n as YnvPoint; + CurMouseHit.NavPortal = n as YnvPortal; + CurMouseHit.NavPoly = null; CurMouseHit.HitDist = hitdist; CurMouseHit.CamRel = (n.Position - camera.Position); CurMouseHit.AABB = nbox; @@ -3364,6 +3395,38 @@ namespace CodeWalker SelectItem(ms); } } + public void SelectNavPoint(YnvPoint point) + { + if (point == null) + { + SelectItem(null); + } + else + { + float nrad = 0.5f; + + MapSelection ms = new MapSelection(); + ms.NavPoint = point; + ms.AABB = new BoundingBox(new Vector3(-nrad), new Vector3(nrad)); + SelectItem(ms); + } + } + public void SelectNavPortal(YnvPortal portal) + { + if (portal == null) + { + SelectItem(null); + } + else + { + float nrad = 0.5f; + + MapSelection ms = new MapSelection(); + ms.NavPortal = portal; + ms.AABB = new BoundingBox(new Vector3(-nrad), new Vector3(nrad)); + SelectItem(ms); + } + } public void SelectPathNode(YndNode node) { if (node == null) @@ -3580,6 +3643,24 @@ namespace CodeWalker //ToolbarDeleteItemButton.Enabled = true; //ToolbarDeleteItemButton.Text = "Delete nav poly"; } + else if (item.NavPoint != null) + { + SelectionEntityTabPage.Text = "NavPoint"; + SelEntityPropertyGrid.SelectedObject = item.NavPoint; + ynv = item.NavPoint.Ynv; + //ToolbarCopyButton.Enabled = true; + //ToolbarDeleteItemButton.Enabled = true; + //ToolbarDeleteItemButton.Text = "Delete nav point"; + } + else if (item.NavPortal != null) + { + SelectionEntityTabPage.Text = "NavPortal"; + SelEntityPropertyGrid.SelectedObject = item.NavPortal; + ynv = item.NavPortal.Ynv; + //ToolbarCopyButton.Enabled = true; + //ToolbarDeleteItemButton.Enabled = true; + //ToolbarDeleteItemButton.Text = "Delete nav portal"; + } else if (item.TrainTrackNode != null) { SelectionEntityTabPage.Text = "TrainNode"; diff --git a/WorldInfoForm.cs b/WorldInfoForm.cs index 42cf591..0c5a47a 100644 --- a/WorldInfoForm.cs +++ b/WorldInfoForm.cs @@ -124,6 +124,16 @@ namespace CodeWalker SelectionEntityTabPage.Text = "Nav Poly"; SelEntityPropertyGrid.SelectedObject = item.NavPoly; } + else if (item.NavPoint != null) + { + SelectionEntityTabPage.Text = "Nav Point"; + SelEntityPropertyGrid.SelectedObject = item.NavPoint; + } + else if (item.NavPortal != null) + { + SelectionEntityTabPage.Text = "Nav Portal"; + SelEntityPropertyGrid.SelectedObject = item.NavPortal; + } else if (item.PathNode != null) { SelectionEntityTabPage.Text = "Path Node";