mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-12-03 20:32:53 +08:00
Added LOD manager, improved shadows performance
This commit is contained in:
parent
ea1fe3b077
commit
6c76726131
@ -42,6 +42,8 @@ namespace CodeWalker.GameFiles
|
||||
public YmapFile[] ChildYmaps = null;
|
||||
public bool MergedWithParent = false;
|
||||
|
||||
public bool IsScripted { get { return (_CMapData.flags & 1) > 0; } }
|
||||
|
||||
public YmapGrassInstanceBatch[] GrassInstanceBatches { get; set; }
|
||||
public YmapPropInstanceBatch[] PropInstanceBatches { get; set; }
|
||||
|
||||
@ -1283,6 +1285,8 @@ namespace CodeWalker.GameFiles
|
||||
public Vector3 BBExtent; //oriented archetype AABB extent
|
||||
public Vector3 BSCenter; //oriented archetype BS center
|
||||
public float BSRadius;//cached from archetype
|
||||
public float LodDist;
|
||||
public float ChildLodDist;
|
||||
|
||||
public CEntityDef _CEntityDef;
|
||||
public CEntityDef CEntityDef { get { return _CEntityDef; } set { _CEntityDef = value; } }
|
||||
@ -1402,7 +1406,7 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
if (BSRadius == 0.0f)
|
||||
{
|
||||
BSRadius = _CEntityDef.lodDist;//need something so it doesn't get culled...
|
||||
BSRadius = LodDist;//need something so it doesn't get culled...
|
||||
}
|
||||
if (BBMin == BBMax)
|
||||
{
|
||||
@ -1487,6 +1491,16 @@ namespace CodeWalker.GameFiles
|
||||
BBMin = ncenter - nextent;
|
||||
BBMax = ncenter + nextent;
|
||||
}
|
||||
LodDist = _CEntityDef.lodDist;
|
||||
if (LodDist <= 0)
|
||||
{
|
||||
LodDist = Archetype.LodDist;
|
||||
}
|
||||
ChildLodDist = _CEntityDef.childLodDist;
|
||||
if (ChildLodDist < 0)
|
||||
{
|
||||
ChildLodDist = LodDist * 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ cbuffer ShadowmapVars : register(b1)
|
||||
float CascadeCountInv;
|
||||
float TexelSize;
|
||||
float TexelSizeX;
|
||||
float Pad20;
|
||||
float ShadowMaxDistance; //2000 or so
|
||||
};
|
||||
|
||||
|
||||
@ -233,7 +233,7 @@ float3 FullLighting(float3 diff, float3 spec, float3 norm, float4 vc0, uniform S
|
||||
if (enableShadows == 1)
|
||||
{
|
||||
//float shadowdepth = input.Shadows.x;// *0.000001;
|
||||
if (abs(shadowdepth) < 2000)//2km
|
||||
if (abs(shadowdepth) < ShadowMaxDistance)//2km
|
||||
{
|
||||
//float4 shadowcoord = input.LightShadow;
|
||||
//float4 shadowcolour = (float4)1;
|
||||
|
@ -46,6 +46,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -66,6 +67,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -86,6 +88,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\CW.ico</ApplicationIcon>
|
||||
|
@ -1517,71 +1517,124 @@ namespace CodeWalker.Rendering
|
||||
|
||||
public void RenderWorld(Dictionary<MetaHash, YmapFile> renderworldVisibleYmapDict, IEnumerable<Entity> spaceEnts)
|
||||
{
|
||||
|
||||
renderworldentities.Clear();
|
||||
renderworldrenderables.Clear();
|
||||
|
||||
|
||||
//LodManager.Update(renderworldVisibleYmapDict, ref camera.Position, currentElapsedTime);
|
||||
|
||||
|
||||
|
||||
VisibleYmaps.Clear();
|
||||
foreach (var ymap in renderworldVisibleYmapDict.Values)
|
||||
|
||||
|
||||
LodManager.MaxLOD = renderworldMaxLOD;
|
||||
LodManager.LodDistMult = renderworldDetailDistMult;
|
||||
LodManager.MapViewEnabled = MapViewEnabled;
|
||||
LodManager.MapViewDist = camera.OrthographicSize / MapViewDetail;
|
||||
LodManager.ShowScriptedYmaps = ShowScriptedYmaps;
|
||||
LodManager.Update(renderworldVisibleYmapDict, ref camera.Position, currentElapsedTime);
|
||||
|
||||
if (MapViewEnabled)
|
||||
{
|
||||
if (!RenderWorldYmapIsVisible(ymap)) continue;
|
||||
VisibleYmaps.Add(ymap);
|
||||
|
||||
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);
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
renderworldentities.Add(ent);
|
||||
|
||||
if (renderinteriors && ent.IsMlo && (ent.MloInstance != null)) //render Mlo child entities...
|
||||
{
|
||||
RenderWorldAddInteriorEntities(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (spaceEnts != null)
|
||||
{
|
||||
foreach (var ae in spaceEnts) //used by active space entities (eg "bullets")
|
||||
{
|
||||
if (ae.EntityDef == null) continue; //nothing to render...
|
||||
RenderWorldCalcEntityVisibility(ae.EntityDef);
|
||||
ae.EntityDef.Distance = (ae.EntityDef.Position - camera.Position).Length();
|
||||
renderworldentities.Add(ae.EntityDef);
|
||||
}
|
||||
}
|
||||
|
||||
if (MapViewEnabled)
|
||||
{
|
||||
//find the max Z value for positioning camera in map view, to help shadows
|
||||
//float minZ = float.MaxValue;
|
||||
float maxZ = float.MinValue;
|
||||
float cvwidth = camera.OrthographicSize * camera.AspectRatio * 0.5f;
|
||||
float cvheight = camera.OrthographicSize * 0.5f;
|
||||
float cvwmin = camera.Position.X - cvwidth; //TODO:make all these vars global...
|
||||
float cvwmax = camera.Position.X + cvwidth;
|
||||
float cvhmin = camera.Position.Y - cvheight;
|
||||
float cvhmax = camera.Position.Y + cvheight;
|
||||
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
|
||||
if (renderentities)
|
||||
{
|
||||
for (int i = 0; i < renderworldentities.Count; i++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.AllEntities != null)
|
||||
var ent = renderworldentities[i];
|
||||
var arch = ent.Archetype;
|
||||
var pent = ent.Parent;
|
||||
var drawable = gameFileCache.TryGetDrawable(arch);
|
||||
Renderable rndbl = TryGetRenderable(arch, drawable);
|
||||
if ((rndbl != null) && rndbl.IsLoaded && (rndbl.AllTexturesLoaded || !waitforchildrentoload))
|
||||
{
|
||||
for (int i = 0; i < ymap.AllEntities.Length; i++)
|
||||
{
|
||||
var ent = ymap.AllEntities[i];
|
||||
if ((ent.Position.Z < 1000.0f) && (ent.BSRadius < 500.0f))
|
||||
{
|
||||
float r = ent.BSRadius;
|
||||
if (((ent.Position.X + r) > cvwmin) && ((ent.Position.X - r) < cvwmax) && ((ent.Position.Y + r) > cvhmin) && ((ent.Position.Y - r) < cvhmax))
|
||||
{
|
||||
//minZ = Math.Min(minZ, ent.BBMin.Z);
|
||||
maxZ = Math.Max(maxZ, ent.BBMax.Z + 50.0f);//add some bias to avoid clipping things...
|
||||
}
|
||||
}
|
||||
}
|
||||
RenderableEntity rent = new RenderableEntity();
|
||||
rent.Entity = ent;
|
||||
rent.Renderable = rndbl;
|
||||
|
||||
if (HideEntities.ContainsKey(ent.EntityHash)) continue; //don't render hidden entities!
|
||||
|
||||
RenderArchetype(arch, ent, rent.Renderable, false);
|
||||
}
|
||||
}
|
||||
|
||||
//move the camera closer to the geometry, to help shadows in map view.
|
||||
if (maxZ == float.MinValue) maxZ = 1000.0f;
|
||||
camera.Position.Z = Math.Min(maxZ, 1000.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RenderWorldYmapExtras();
|
||||
}
|
||||
|
||||
public void RenderWorld_Orig(Dictionary<MetaHash, YmapFile> renderworldVisibleYmapDict, IEnumerable<Entity> spaceEnts)
|
||||
{
|
||||
renderworldentities.Clear();
|
||||
renderworldrenderables.Clear();
|
||||
VisibleYmaps.Clear();
|
||||
|
||||
|
||||
foreach (var ymap in renderworldVisibleYmapDict.Values)
|
||||
{
|
||||
if (!RenderWorldYmapIsVisible(ymap)) continue;
|
||||
VisibleYmaps.Add(ymap);
|
||||
}
|
||||
|
||||
RenderWorldAdjustMapViewCamera();
|
||||
|
||||
|
||||
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
@ -1631,6 +1684,19 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (spaceEnts != null)
|
||||
{
|
||||
foreach (var ae in spaceEnts) //used by active space entities (eg "bullets")
|
||||
{
|
||||
if (ae.EntityDef == null) continue; //nothing to render...
|
||||
RenderWorldCalcEntityVisibility(ae.EntityDef);
|
||||
renderworldentities.Add(ae.EntityDef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (renderentities)
|
||||
{
|
||||
for (int i = 0; i < renderworldentities.Count; i++)
|
||||
@ -1664,95 +1730,7 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (renderinteriors && (rendercollisionmeshes || (SelectionMode == MapSelectionMode.Collision)))
|
||||
{
|
||||
for (int i = 0; i < renderworldentities.Count; i++)
|
||||
{
|
||||
var ent = renderworldentities[i];
|
||||
if (ent.IsMlo)
|
||||
{
|
||||
RenderInteriorCollisionMesh(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (rendercars)
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.CarGenerators != null)
|
||||
{
|
||||
RenderYmapCarGenerators(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rendergrass)
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.GrassInstanceBatches != null)
|
||||
{
|
||||
RenderYmapGrass(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renderdistlodlights && timecycle.IsNightTime)
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.DistantLODLights != null)
|
||||
{
|
||||
RenderYmapDistantLODLights(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renderlodlights && shaders.deferred)
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.LODLights != null)
|
||||
{
|
||||
RenderYmapLODLights(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool RenderWorldYmapIsVisible(YmapFile ymap)
|
||||
{
|
||||
if (!ShowScriptedYmaps)
|
||||
{
|
||||
if ((ymap._CMapData.flags & 1) > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ymap.HasChanged)//don't cull edited project ymaps, because extents may not have been updated!
|
||||
{
|
||||
var eemin = ymap._CMapData.entitiesExtentsMin;
|
||||
var eemax = ymap._CMapData.entitiesExtentsMax;
|
||||
bool visible = false;
|
||||
if (MapViewEnabled)//don't do front clipping in 2D mode
|
||||
{
|
||||
visible = camera.ViewFrustum.ContainsAABBNoFrontClipNoOpt(ref eemin, ref eemax);
|
||||
}
|
||||
else
|
||||
{
|
||||
visible = camera.ViewFrustum.ContainsAABBNoClipNoOpt(ref eemin, ref eemax);
|
||||
}
|
||||
if (!visible)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
RenderWorldYmapExtras();
|
||||
}
|
||||
private void RenderWorldCalcEntityVisibility(YmapEntityDef ent)
|
||||
{
|
||||
@ -1874,6 +1852,36 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool RenderWorldYmapIsVisible(YmapFile ymap)
|
||||
{
|
||||
if (!ShowScriptedYmaps)
|
||||
{
|
||||
if ((ymap._CMapData.flags & 1) > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ymap.HasChanged)//don't cull edited project ymaps, because extents may not have been updated!
|
||||
{
|
||||
var eemin = ymap._CMapData.entitiesExtentsMin;
|
||||
var eemax = ymap._CMapData.entitiesExtentsMax;
|
||||
bool visible = false;
|
||||
if (MapViewEnabled)//don't do front clipping in 2D mode
|
||||
{
|
||||
visible = camera.ViewFrustum.ContainsAABBNoFrontClipNoOpt(ref eemin, ref eemax);
|
||||
}
|
||||
else
|
||||
{
|
||||
visible = camera.ViewFrustum.ContainsAABBNoClipNoOpt(ref eemin, ref eemax);
|
||||
}
|
||||
if (!visible)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private void RenderWorldAddInteriorEntities(YmapEntityDef ent)
|
||||
{
|
||||
if (ent.MloInstance.Entities != null)
|
||||
@ -1886,9 +1894,7 @@ namespace CodeWalker.Rendering
|
||||
|
||||
intent.IsVisible = true;
|
||||
|
||||
var iebscent = intent.Position + intent.BSCenter - camera.Position;
|
||||
float iebsrad = intent.BSRadius;
|
||||
if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref iebscent, iebsrad))
|
||||
if (!camera.ViewFrustum.ContainsAABBNoClip(ref intent.BBCenter, ref intent.BBExtent))
|
||||
{
|
||||
continue; //frustum cull interior ents
|
||||
}
|
||||
@ -1912,9 +1918,7 @@ namespace CodeWalker.Rendering
|
||||
|
||||
intent.IsVisible = true;
|
||||
|
||||
var iebscent = intent.Position + intent.BSCenter - camera.Position;
|
||||
float iebsrad = intent.BSRadius;
|
||||
if (!camera.ViewFrustum.ContainsSphereNoClipNoOpt(ref iebscent, iebsrad))
|
||||
if (!camera.ViewFrustum.ContainsAABBNoClip(ref intent.BBCenter, ref intent.BBExtent))
|
||||
{
|
||||
continue; //frustum cull interior ents
|
||||
}
|
||||
@ -1925,7 +1929,104 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
}
|
||||
}
|
||||
private void RenderWorldAdjustMapViewCamera()
|
||||
{
|
||||
if (MapViewEnabled)
|
||||
{
|
||||
//find the max Z value for positioning camera in map view, to help shadows
|
||||
//float minZ = float.MaxValue;
|
||||
float maxZ = float.MinValue;
|
||||
float cvwidth = camera.OrthographicSize * camera.AspectRatio * 0.5f;
|
||||
float cvheight = camera.OrthographicSize * 0.5f;
|
||||
float cvwmin = camera.Position.X - cvwidth; //TODO:make all these vars global...
|
||||
float cvwmax = camera.Position.X + cvwidth;
|
||||
float cvhmin = camera.Position.Y - cvheight;
|
||||
float cvhmax = camera.Position.Y + cvheight;
|
||||
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.AllEntities != null)
|
||||
{
|
||||
for (int i = 0; i < ymap.AllEntities.Length; i++)//this is bad
|
||||
{
|
||||
var ent = ymap.AllEntities[i];
|
||||
if ((ent.Position.Z < 1000.0f) && (ent.BSRadius < 500.0f))
|
||||
{
|
||||
if ((ent.BBMax.X > cvwmin) && (ent.BBMin.X < cvwmax) && (ent.BBMax.Y > cvhmin) && (ent.BBMin.Y < cvhmax))
|
||||
{
|
||||
//minZ = Math.Min(minZ, ent.BBMin.Z);
|
||||
maxZ = Math.Max(maxZ, ent.BBMax.Z + 50.0f);//add some bias to avoid clipping things...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//move the camera closer to the geometry, to help shadows in map view.
|
||||
if (maxZ == float.MinValue) maxZ = 1000.0f;
|
||||
camera.Position.Z = Math.Min(maxZ, 1000.0f);
|
||||
camera.ViewFrustum.Position = camera.Position;
|
||||
}
|
||||
}
|
||||
private void RenderWorldYmapExtras()
|
||||
{
|
||||
if (renderinteriors && (rendercollisionmeshes || (SelectionMode == MapSelectionMode.Collision)))
|
||||
{
|
||||
for (int i = 0; i < renderworldentities.Count; i++)
|
||||
{
|
||||
var ent = renderworldentities[i];
|
||||
if (ent.IsMlo)
|
||||
{
|
||||
RenderInteriorCollisionMesh(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rendercars)
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.CarGenerators != null)
|
||||
{
|
||||
RenderYmapCarGenerators(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rendergrass && (renderworldMaxLOD == rage__eLodType.LODTYPES_DEPTH_ORPHANHD)) //hide grass with orphans
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.GrassInstanceBatches != null)
|
||||
{
|
||||
RenderYmapGrass(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renderdistlodlights && timecycle.IsNightTime)
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.DistantLODLights != null)
|
||||
{
|
||||
RenderYmapDistantLODLights(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renderlodlights && shaders.deferred)
|
||||
{
|
||||
for (int y = 0; y < VisibleYmaps.Count; y++)
|
||||
{
|
||||
var ymap = VisibleYmaps[y];
|
||||
if (ymap.LODLights != null)
|
||||
{
|
||||
RenderYmapLODLights(ymap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3376,18 +3477,26 @@ namespace CodeWalker.Rendering
|
||||
|
||||
public class RenderLodManager
|
||||
{
|
||||
public rage__eLodType MaxLOD = rage__eLodType.LODTYPES_DEPTH_ORPHANHD;
|
||||
public float LodDistMult = 1.0f;
|
||||
public bool MapViewEnabled = false;
|
||||
public float MapViewDist = 1.0f;
|
||||
public bool ShowScriptedYmaps = true;
|
||||
|
||||
|
||||
private Dictionary<YmapEntityDef, int> EntityDict = new Dictionary<YmapEntityDef, int>(); //visible entities and their current child counts
|
||||
|
||||
public Dictionary<MetaHash, YmapFile> CurrentYmaps = new Dictionary<MetaHash, YmapFile>();
|
||||
private List<MetaHash> RemoveYmaps = new List<MetaHash>();
|
||||
public Dictionary<YmapEntityDef, LinkedList<YmapEntityDef>> EntityTree = new Dictionary<YmapEntityDef, LinkedList<YmapEntityDef>>();
|
||||
private Dictionary<YmapEntityDef, LinkedList<YmapEntityDef>> RootEntities = new Dictionary<YmapEntityDef, LinkedList<YmapEntityDef>>();
|
||||
public Dictionary<YmapEntityDef, LinkedList<YmapEntityDef>> VisibleRoots = new Dictionary<YmapEntityDef, LinkedList<YmapEntityDef>>();
|
||||
public List<YmapEntityDef> VisibleLeaves = new List<YmapEntityDef>();
|
||||
|
||||
public void Update(Dictionary<MetaHash, YmapFile> ymaps, ref Vector3 position, float elapsed)
|
||||
{
|
||||
EntityDict.Clear();
|
||||
|
||||
foreach (var ymap in ymaps.Values)
|
||||
foreach (var kvp in ymaps)
|
||||
{
|
||||
YmapFile pymap = ymap.Parent;
|
||||
var ymap = kvp.Value;
|
||||
var pymap = ymap.Parent;
|
||||
if (ymap._CMapData.parent != 0) //ensure parent references on ymaps
|
||||
{
|
||||
ymaps.TryGetValue(ymap._CMapData.parent, out pymap);
|
||||
@ -3419,16 +3528,95 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ymap.AllEntities != null) //add visible entities to the dict, increment entity parent child counts
|
||||
}
|
||||
|
||||
|
||||
RemoveYmaps.Clear();
|
||||
foreach (var kvp in CurrentYmaps)
|
||||
{
|
||||
YmapFile ymap = null;
|
||||
if (!ymaps.TryGetValue(kvp.Key, out ymap) || (ymap != kvp.Value) || (ymap.IsScripted && !ShowScriptedYmaps))
|
||||
{
|
||||
RemoveYmaps.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
foreach (var remYmap in RemoveYmaps)
|
||||
{
|
||||
var ymap = CurrentYmaps[remYmap];
|
||||
CurrentYmaps.Remove(remYmap);
|
||||
if (ymap.AllEntities != null) // remove this ymap's entities from the tree.....
|
||||
{
|
||||
for (int i = 0; i < ymap.AllEntities.Length; i++)
|
||||
{
|
||||
var ent = ymap.AllEntities[i];
|
||||
//ent.BBMin
|
||||
|
||||
|
||||
EntityTree.Remove(ent);
|
||||
RootEntities.Remove(ent);
|
||||
if ((ent.Parent != null) && (ent.Parent.Ymap != ymap))
|
||||
{
|
||||
LinkedList<YmapEntityDef> clist = null;
|
||||
if (EntityTree.TryGetValue(ent.Parent, out clist))
|
||||
{
|
||||
clist.Remove(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var kvp in ymaps)
|
||||
{
|
||||
var ymap = kvp.Value;
|
||||
if (ymap.IsScripted && !ShowScriptedYmaps)
|
||||
{ continue; }
|
||||
if (!CurrentYmaps.ContainsKey(kvp.Key))
|
||||
{
|
||||
CurrentYmaps.Add(kvp.Key, kvp.Value);
|
||||
if (ymap.AllEntities != null) // add this ymap's entities to the tree...
|
||||
{
|
||||
for (int i = 0; i < ymap.AllEntities.Length; i++)
|
||||
{
|
||||
var ent = ymap.AllEntities[i];
|
||||
if (ent.Parent != null)
|
||||
{
|
||||
LinkedList<YmapEntityDef> clist = null;
|
||||
if (!EntityTree.TryGetValue(ent.Parent, out clist))
|
||||
{
|
||||
clist = new LinkedList<YmapEntityDef>();
|
||||
EntityTree[ent.Parent] = clist;
|
||||
}
|
||||
clist.AddLast(ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
LinkedList<YmapEntityDef> 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<YmapEntityDef>();
|
||||
EntityTree[ent] = clist;
|
||||
}
|
||||
}
|
||||
RootEntities[ent] = clist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VisibleRoots.Clear();
|
||||
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))
|
||||
{
|
||||
VisibleRoots[ent] = kvp.Value;
|
||||
RecurseAddVisibleLeaves(ent, ref position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3437,6 +3625,77 @@ namespace CodeWalker.Rendering
|
||||
|
||||
}
|
||||
|
||||
private void RecurseAddVisibleLeaves(YmapEntityDef ent, ref Vector3 position)
|
||||
{
|
||||
var clist = GetEntityChildren(ent, ref position);
|
||||
if (clist != null)
|
||||
{
|
||||
foreach (var child in clist)
|
||||
{
|
||||
RecurseAddVisibleLeaves(child, ref position);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VisibleLeaves.Add(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private LinkedList<YmapEntityDef> GetEntityChildren(YmapEntityDef ent, ref Vector3 position)
|
||||
{
|
||||
//get the children list for this entity, if all the hcildren are available, and they are within range
|
||||
if (!EntityChildrenVisibleAtMaxLodLevel(ent)) return null;
|
||||
LinkedList<YmapEntityDef> clist = null;
|
||||
EntityTree.TryGetValue(ent, out clist);
|
||||
if ((clist != null) && (clist.Count >= ent._CEntityDef.numChildren))
|
||||
{
|
||||
ent.Distance = MapViewEnabled ? MapViewDist : (ent.Position - position).Length();
|
||||
if (ent.Distance <= (ent.ChildLodDist * LodDistMult))
|
||||
{
|
||||
return clist;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var child in clist)
|
||||
{
|
||||
child.Distance = MapViewEnabled ? MapViewDist : (child.Position - position).Length();
|
||||
if (child.Distance <= (child.LodDist * LodDistMult))
|
||||
{
|
||||
return clist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private bool EntityVisibleAtMaxLodLevel(YmapEntityDef ent)
|
||||
{
|
||||
if (MaxLOD != rage__eLodType.LODTYPES_DEPTH_ORPHANHD)
|
||||
{
|
||||
if ((ent._CEntityDef.lodLevel == rage__eLodType.LODTYPES_DEPTH_ORPHANHD) ||
|
||||
(ent._CEntityDef.lodLevel < MaxLOD))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private bool EntityChildrenVisibleAtMaxLodLevel(YmapEntityDef ent)
|
||||
{
|
||||
if (MaxLOD != rage__eLodType.LODTYPES_DEPTH_ORPHANHD)
|
||||
{
|
||||
if ((ent._CEntityDef.lodLevel == rage__eLodType.LODTYPES_DEPTH_ORPHANHD) ||
|
||||
(ent._CEntityDef.lodLevel <= MaxLOD))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -720,7 +720,7 @@ namespace CodeWalker.Rendering
|
||||
Shadowmap.BeginDepthRender(context, i);
|
||||
|
||||
float worldtocascade = cascade.WorldUnitsToCascadeUnits * 2.0f;
|
||||
float minrad = cascade.WorldUnitsPerTexel * 3.0f;
|
||||
float minrad = cascade.WorldUnitsPerTexel * 5.0f;
|
||||
|
||||
shadowbatch.Clear();
|
||||
for (int c = 0; c < shadowcasters.Count; c++)
|
||||
|
@ -45,6 +45,10 @@ namespace CodeWalker.Rendering
|
||||
Vector3 SceneCenter;
|
||||
Vector3 SceneExtent;
|
||||
|
||||
float[] fCascadeIntervals = { 7.0f, 20.0f, 65.0f, 160.0f, 600.0f, 3000.0f, 5000.0f, 10000.0f };
|
||||
float maxShadowDistance = 3000.0f;
|
||||
|
||||
|
||||
long graphicsMemoryUsage = 0;
|
||||
public long VramUsage
|
||||
{
|
||||
@ -215,8 +219,8 @@ namespace CodeWalker.Rendering
|
||||
float fFrustumIntervalBegin, fFrustumIntervalEnd;
|
||||
Vector4 vLightCameraOrthographicMin; // light space frustrum aabb
|
||||
Vector4 vLightCameraOrthographicMax;
|
||||
float fCameraNearFarRange = 1000.0f; //(far - near) //1000m in planet space
|
||||
float[] fCascadeIntervals = { 0.0075f, 0.02f, 0.06f, 0.15f, 0.5f, 1.0f, 1.5f, 2.5f };
|
||||
//float[] fCascadeIntervals = { 7.5f, 20.0f, 60.0f, 150.0f, 500.0f, 1000.0f, 1500.0f, 2500.0f };
|
||||
//float[] fCascadeIntervals = { 7.0f, 20.0f, 65.0f, 160.0f, 650.0f, 2000.0f, 5000.0f, 10000.0f };
|
||||
|
||||
Vector4 vWorldUnitsPerTexel = Vector4.Zero;
|
||||
float fInvTexelCount = 1.0f / (float)TextureSize;
|
||||
@ -229,8 +233,8 @@ namespace CodeWalker.Rendering
|
||||
fFrustumIntervalBegin = 0.0f;
|
||||
// Scale the intervals between 0 and 1. They are now percentages that we can scale with.
|
||||
fFrustumIntervalEnd = fCascadeIntervals[iCascadeIndex];
|
||||
fFrustumIntervalBegin = fFrustumIntervalBegin * fCameraNearFarRange;
|
||||
fFrustumIntervalEnd = fFrustumIntervalEnd * fCameraNearFarRange;
|
||||
//fFrustumIntervalBegin = fFrustumIntervalBegin * fCameraNearFarRange;
|
||||
//fFrustumIntervalEnd = fFrustumIntervalEnd * fCameraNearFarRange;
|
||||
Vector4[] vFrustumPoints = new Vector4[8];
|
||||
|
||||
|
||||
@ -380,6 +384,7 @@ namespace CodeWalker.Rendering
|
||||
ShadowVars.Vars.CascadeCountInv = 1.0f / (float)CascadeCount;
|
||||
ShadowVars.Vars.TexelSize = 1.0f / txs;
|
||||
ShadowVars.Vars.TexelSizeX = ShadowVars.Vars.TexelSize / (float)CascadeCount;
|
||||
ShadowVars.Vars.ShadowMaxDistance = maxShadowDistance;
|
||||
|
||||
ShadowVars.Update(context);
|
||||
|
||||
@ -831,7 +836,7 @@ namespace CodeWalker.Rendering
|
||||
public float CascadeCountInv;
|
||||
public float TexelSize;
|
||||
public float TexelSizeX;
|
||||
public float Pad2;
|
||||
public float ShadowMaxDistance;
|
||||
}
|
||||
|
||||
public struct ShadowmapVarsCascadeData
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
30
WorldForm.Designer.cs
generated
30
WorldForm.Designer.cs
generated
@ -176,6 +176,7 @@ namespace CodeWalker
|
||||
this.BoundsStyleComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.tabPage10 = new System.Windows.Forms.TabPage();
|
||||
this.DeferredShadingCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.WeatherRegionComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.label29 = new System.Windows.Forms.Label();
|
||||
this.CloudParamTrackBar = new System.Windows.Forms.TrackBar();
|
||||
@ -295,7 +296,6 @@ namespace CodeWalker
|
||||
this.ToolbarPanel = new System.Windows.Forms.Panel();
|
||||
this.SubtitleLabel = new System.Windows.Forms.Label();
|
||||
this.SubtitleTimer = new System.Windows.Forms.Timer(this.components);
|
||||
this.DeferredShadingCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.StatusStrip.SuspendLayout();
|
||||
this.ToolsPanel.SuspendLayout();
|
||||
this.ToolsTabControl.SuspendLayout();
|
||||
@ -665,7 +665,7 @@ namespace CodeWalker
|
||||
this.WorldDetailDistTrackBar.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
this.WorldDetailDistTrackBar.LargeChange = 10;
|
||||
this.WorldDetailDistTrackBar.Location = new System.Drawing.Point(6, 110);
|
||||
this.WorldDetailDistTrackBar.Maximum = 30;
|
||||
this.WorldDetailDistTrackBar.Maximum = 50;
|
||||
this.WorldDetailDistTrackBar.Name = "WorldDetailDistTrackBar";
|
||||
this.WorldDetailDistTrackBar.Size = new System.Drawing.Size(182, 45);
|
||||
this.WorldDetailDistTrackBar.TabIndex = 62;
|
||||
@ -2233,6 +2233,19 @@ namespace CodeWalker
|
||||
this.tabPage10.Text = "Lighting";
|
||||
this.tabPage10.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// DeferredShadingCheckBox
|
||||
//
|
||||
this.DeferredShadingCheckBox.AutoSize = true;
|
||||
this.DeferredShadingCheckBox.Checked = true;
|
||||
this.DeferredShadingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.DeferredShadingCheckBox.Location = new System.Drawing.Point(10, 5);
|
||||
this.DeferredShadingCheckBox.Name = "DeferredShadingCheckBox";
|
||||
this.DeferredShadingCheckBox.Size = new System.Drawing.Size(107, 17);
|
||||
this.DeferredShadingCheckBox.TabIndex = 30;
|
||||
this.DeferredShadingCheckBox.Text = "Deferred shading";
|
||||
this.DeferredShadingCheckBox.UseVisualStyleBackColor = true;
|
||||
this.DeferredShadingCheckBox.CheckedChanged += new System.EventHandler(this.DeferredShadingCheckBox_CheckedChanged);
|
||||
//
|
||||
// WeatherRegionComboBox
|
||||
//
|
||||
this.WeatherRegionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
@ -3415,19 +3428,6 @@ namespace CodeWalker
|
||||
//
|
||||
this.SubtitleTimer.Tick += new System.EventHandler(this.SubtitleTimer_Tick);
|
||||
//
|
||||
// DeferredShadingCheckBox
|
||||
//
|
||||
this.DeferredShadingCheckBox.AutoSize = true;
|
||||
this.DeferredShadingCheckBox.Checked = true;
|
||||
this.DeferredShadingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.DeferredShadingCheckBox.Location = new System.Drawing.Point(10, 5);
|
||||
this.DeferredShadingCheckBox.Name = "DeferredShadingCheckBox";
|
||||
this.DeferredShadingCheckBox.Size = new System.Drawing.Size(107, 17);
|
||||
this.DeferredShadingCheckBox.TabIndex = 30;
|
||||
this.DeferredShadingCheckBox.Text = "Deferred shading";
|
||||
this.DeferredShadingCheckBox.UseVisualStyleBackColor = true;
|
||||
this.DeferredShadingCheckBox.CheckedChanged += new System.EventHandler(this.DeferredShadingCheckBox_CheckedChanged);
|
||||
//
|
||||
// WorldForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
Loading…
Reference in New Issue
Block a user