diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs index f826cb9..55124a9 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs @@ -1321,6 +1321,8 @@ namespace CodeWalker.GameFiles public uint EntityHash { get; set; } = 0; //used by CW as a unique position+name identifier + public LinkedList LodManagerChildren = null; + public string Name { @@ -1695,6 +1697,21 @@ namespace CodeWalker.GameFiles ChildList = null; } + + public void LodManagerAddChild(YmapEntityDef child) + { + if (LodManagerChildren == null) + { + LodManagerChildren = new LinkedList(); + } + LodManagerChildren.AddLast(child); + } + public void LodManagerRemoveChild(YmapEntityDef child) + { + LodManagerChildren?.Remove(child);//could improve this by caching the list node.... + } + + public override string ToString() { return _CEntityDef.ToString() + ((ChildList != null) ? (" (" + ChildList.Count.ToString() + " children) ") : " ") + _CEntityDef.lodLevel.ToString(); diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index f94b178..fb4e460 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -1521,6 +1521,13 @@ namespace CodeWalker.Rendering renderworldrenderables.Clear(); VisibleYmaps.Clear(); + foreach (var ymap in renderworldVisibleYmapDict.Values) + { + if (!RenderWorldYmapIsVisible(ymap)) continue; + VisibleYmaps.Add(ymap); + } + RenderWorldAdjustMapViewCamera(); + LodManager.MaxLOD = renderworldMaxLOD; LodManager.LodDistMult = renderworldDetailDistMult; @@ -1529,43 +1536,38 @@ namespace CodeWalker.Rendering LodManager.ShowScriptedYmaps = ShowScriptedYmaps; LodManager.Update(renderworldVisibleYmapDict, ref camera.Position, currentElapsedTime); - if (MapViewEnabled) - { - - foreach (var ymap in renderworldVisibleYmapDict.Values) - { - if (!RenderWorldYmapIsVisible(ymap)) continue; - VisibleYmaps.Add(ymap); - } - RenderWorldAdjustMapViewCamera(); - } - else - { - foreach (var ymap in LodManager.CurrentYmaps.Values) - { - if (!RenderWorldYmapIsVisible(ymap)) continue; - VisibleYmaps.Add(ymap); - } - } - var ents = LodManager.VisibleLeaves;// LodManager.GetVisibleEntities(camera); + var ents = LodManager.GetVisibleLeaves(camera); + + + //foreach (var ent in ents) + //{ + // if (!RenderIsEntityFinalRender(ent)) + // { continue; } + // var arch = ent.Archetype; + // var drawable = gameFileCache.TryGetDrawable(arch); + // var rndbl = TryGetRenderable(arch, drawable); + // var ready = ((rndbl != null) && rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload)); + //} foreach (var ent in ents) { if (!RenderIsEntityFinalRender(ent)) { continue; } - if (MapViewEnabled) - { - if (!camera.ViewFrustum.ContainsAABBNoFrontClipNoOpt(ref ent.BBMin, ref ent.BBMax)) - { continue; } - } - else - { - if (!camera.ViewFrustum.ContainsAABBNoClip(ref ent.BBCenter, ref ent.BBExtent)) - { continue; } - } + //if (MapViewEnabled) + //{ + // if (!camera.ViewFrustum.ContainsAABBNoFrontClipNoOpt(ref ent.BBMin, ref ent.BBMax)) + // { continue; } + //} + //else + //{ + // if (!camera.ViewFrustum.ContainsAABBNoClip(ref ent.BBCenter, ref ent.BBExtent)) + // { continue; } + //} + + renderworldentities.Add(ent); @@ -1597,12 +1599,11 @@ namespace CodeWalker.Rendering { var ent = renderworldentities[i]; var arch = ent.Archetype; - var pent = ent.Parent; var drawable = gameFileCache.TryGetDrawable(arch); - Renderable rndbl = TryGetRenderable(arch, drawable); + var rndbl = TryGetRenderable(arch, drawable); if ((rndbl != null) && rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload)) { - RenderableEntity rent = new RenderableEntity(); + var rent = new RenderableEntity(); rent.Entity = ent; rent.Renderable = rndbl; @@ -3483,15 +3484,16 @@ namespace CodeWalker.Rendering public float MapViewDist = 1.0f; public bool ShowScriptedYmaps = true; + public Vector3 Position = Vector3.Zero; + public Dictionary CurrentYmaps = new Dictionary(); private List RemoveYmaps = new List(); - public Dictionary> EntityTree = new Dictionary>(); - private Dictionary> RootEntities = new Dictionary>(); - public Dictionary> VisibleRoots = new Dictionary>(); + public Dictionary RootEntities = new Dictionary(); public List VisibleLeaves = new List(); public void Update(Dictionary ymaps, ref Vector3 position, float elapsed) { + Position = position; foreach (var kvp in ymaps) { @@ -3530,7 +3532,6 @@ namespace CodeWalker.Rendering } } - RemoveYmaps.Clear(); foreach (var kvp in CurrentYmaps) { @@ -3549,15 +3550,11 @@ namespace CodeWalker.Rendering for (int i = 0; i < ymap.AllEntities.Length; i++) { var ent = ymap.AllEntities[i]; - EntityTree.Remove(ent); RootEntities.Remove(ent); + ent.LodManagerChildren?.Clear(); if ((ent.Parent != null) && (ent.Parent.Ymap != ymap)) { - LinkedList clist = null; - if (EntityTree.TryGetValue(ent.Parent, out clist)) - { - clist.Remove(ent); - } + ent.Parent.LodManagerRemoveChild(ent); } } } @@ -3577,26 +3574,11 @@ namespace CodeWalker.Rendering var ent = ymap.AllEntities[i]; if (ent.Parent != null) { - LinkedList clist = null; - if (!EntityTree.TryGetValue(ent.Parent, out clist)) - { - clist = new LinkedList(); - EntityTree[ent.Parent] = clist; - } - clist.AddLast(ent); + ent.Parent.LodManagerAddChild(ent); } else { - LinkedList clist = null; - if ((ent._CEntityDef.lodLevel != rage__eLodType.LODTYPES_DEPTH_ORPHANHD) && (ent._CEntityDef.lodLevel != rage__eLodType.LODTYPES_DEPTH_HD)) - { - if (!EntityTree.TryGetValue(ent, out clist)) - { - clist = new LinkedList(); - EntityTree[ent] = clist; - } - } - RootEntities[ent] = clist; + RootEntities[ent] = ent; } } } @@ -3604,35 +3586,73 @@ namespace CodeWalker.Rendering } - VisibleRoots.Clear(); + } + + public List GetVisibleLeaves() + { VisibleLeaves.Clear(); foreach (var kvp in RootEntities) { var ent = kvp.Key; if (EntityVisibleAtMaxLodLevel(ent)) { - ent.Distance = MapViewEnabled ? MapViewDist : (ent.Position - position).Length(); - if(ent.Distance <= (ent.LodDist * LodDistMult)) + ent.Distance = MapViewEnabled ? MapViewDist : (ent.Position - Position).Length(); + if (ent.Distance <= (ent.LodDist * LodDistMult)) { - VisibleRoots[ent] = kvp.Value; - RecurseAddVisibleLeaves(ent, ref position); + RecurseAddVisibleLeaves(ent); } } } - - - - + return VisibleLeaves; } - - private void RecurseAddVisibleLeaves(YmapEntityDef ent, ref Vector3 position) + private void RecurseAddVisibleLeaves(YmapEntityDef ent) { - var clist = GetEntityChildren(ent, ref position); + var clist = GetEntityChildren(ent); if (clist != null) { - foreach (var child in clist) + var cnode = clist.First; + while (cnode != null) { - RecurseAddVisibleLeaves(child, ref position); + RecurseAddVisibleLeaves(cnode.Value); + cnode = cnode.Next; + } + } + else + { + VisibleLeaves.Add(ent); + } + } + + public List GetVisibleLeaves(Camera cam) + { + VisibleLeaves.Clear(); + foreach (var kvp in RootEntities) + { + var ent = kvp.Key; + if (EntityVisibleAtMaxLodLevel(ent) && EntityVisible(ent, cam)) + { + ent.Distance = MapViewEnabled ? MapViewDist : (ent.Position - Position).Length(); + if (ent.Distance <= (ent.LodDist * LodDistMult)) + { + RecurseAddVisibleLeaves(ent, cam); + } + } + } + return VisibleLeaves; + } + private void RecurseAddVisibleLeaves(YmapEntityDef ent, Camera cam) + { + var clist = GetEntityChildren(ent); + if (clist != null) + { + var cnode = clist.First; + while (cnode != null) + { + if (EntityVisible(cnode.Value, cam)) + { + RecurseAddVisibleLeaves(cnode.Value, cam); + } + cnode = cnode.Next; } } else @@ -3642,35 +3662,51 @@ namespace CodeWalker.Rendering } - private LinkedList GetEntityChildren(YmapEntityDef ent, ref Vector3 position) + + private LinkedList GetEntityChildren(YmapEntityDef ent) { //get the children list for this entity, if all the hcildren are available, and they are within range if (!EntityChildrenVisibleAtMaxLodLevel(ent)) return null; - LinkedList clist = null; - EntityTree.TryGetValue(ent, out clist); + var clist = ent.LodManagerChildren; if ((clist != null) && (clist.Count >= ent._CEntityDef.numChildren)) { - ent.Distance = MapViewEnabled ? MapViewDist : (ent.Position - position).Length(); + if (ent.Parent != null)//already calculated root entities distance + { + ent.Distance = MapViewEnabled ? MapViewDist : (ent.Position - Position).Length(); + } if (ent.Distance <= (ent.ChildLodDist * LodDistMult)) { return clist; } else { - foreach (var child in clist) + var cnode = clist.First; + while (cnode != null) { - child.Distance = MapViewEnabled ? MapViewDist : (child.Position - position).Length(); + var child = cnode.Value; + child.Distance = MapViewEnabled ? MapViewDist : (child.Position - Position).Length(); if (child.Distance <= (child.LodDist * LodDistMult)) { return clist; } + cnode = cnode.Next; } } } return null; } - + private bool EntityVisible(YmapEntityDef ent, Camera cam) + { + if (MapViewEnabled) + { + return cam.ViewFrustum.ContainsAABBNoFrontClipNoOpt(ref ent.BBMin, ref ent.BBMax); + } + else + { + return cam.ViewFrustum.ContainsAABBNoClip(ref ent.BBCenter, ref ent.BBExtent); + } + } private bool EntityVisibleAtMaxLodLevel(YmapEntityDef ent) { if (MaxLOD != rage__eLodType.LODTYPES_DEPTH_ORPHANHD) diff --git a/Rendering/ShaderManager.cs b/Rendering/ShaderManager.cs index 3af5b5d..32b7391 100644 --- a/Rendering/ShaderManager.cs +++ b/Rendering/ShaderManager.cs @@ -688,7 +688,7 @@ namespace CodeWalker.Rendering context.OutputMerger.DepthStencilState = dsEnabled; context.Rasterizer.State = rsSolid; - float maxdist = 3000.0f;// cascade.IntervalFar * 5.0f; + float maxdist = Shadowmap.maxShadowDistance;// 3000.0f;// cascade.IntervalFar * 5.0f; //find the casters within range shadowcasters.Clear(); diff --git a/Rendering/Utils/Shadowmap.cs b/Rendering/Utils/Shadowmap.cs index 4c2471c..7962338 100644 --- a/Rendering/Utils/Shadowmap.cs +++ b/Rendering/Utils/Shadowmap.cs @@ -46,7 +46,7 @@ namespace CodeWalker.Rendering Vector3 SceneExtent; float[] fCascadeIntervals = { 7.0f, 20.0f, 65.0f, 160.0f, 600.0f, 3000.0f, 5000.0f, 10000.0f }; - float maxShadowDistance = 3000.0f; + public float maxShadowDistance = 3000.0f; long graphicsMemoryUsage = 0;