Stopped HD ytd's getting loaded when HD texture not enabled, changed cache stacks to queues, added distance property to entity

This commit is contained in:
dexy 2019-01-08 18:57:24 +11:00
parent 2d8305c7a1
commit 1af436b403
4 changed files with 105 additions and 58 deletions

View File

@ -1248,6 +1248,7 @@ namespace CodeWalker.GameFiles
public MetaWrapper[] Extensions { get; set; } public MetaWrapper[] Extensions { get; set; }
public int Index { get; set; } public int Index { get; set; }
public float Distance { get; set; } //used for rendering
public bool IsVisible; //used for rendering public bool IsVisible; //used for rendering
public bool ChildrenVisible; //used for rendering public bool ChildrenVisible; //used for rendering
public bool ChildrenRendered; //used when rendering ymap mode to reduce LOD flashing... public bool ChildrenRendered; //used when rendering ymap mode to reduce LOD flashing...

View File

@ -18,7 +18,7 @@ namespace CodeWalker.GameFiles
private Action<string> ErrorLog; private Action<string> ErrorLog;
public int MaxItemsPerLoop = 1; //to keep things flowing... public int MaxItemsPerLoop = 1; //to keep things flowing...
private ConcurrentStack<GameFile> requestQueue = new ConcurrentStack<GameFile>(); private ConcurrentQueue<GameFile> requestQueue = new ConcurrentQueue<GameFile>();
////dynamic cache ////dynamic cache
private Cache<GameFileCacheKey, GameFile> mainCache; private Cache<GameFileCacheKey, GameFile> mainCache;
@ -135,7 +135,7 @@ namespace CodeWalker.GameFiles
textureLookup.Clear(); textureLookup.Clear();
GameFile queueclear; GameFile queueclear;
while (requestQueue.TryPop(out queueclear)) while (requestQueue.TryDequeue(out queueclear))
{ } //empty the old queue out... { } //empty the old queue out...
} }
@ -1486,9 +1486,9 @@ namespace CodeWalker.GameFiles
private void TryLoadEnqueue(GameFile gf) private void TryLoadEnqueue(GameFile gf)
{ {
if (((!gf.Loaded)) && (requestQueue.Count < 5))//(!gf.LoadQueued) && if (((!gf.Loaded)) && (requestQueue.Count < 10))// && (!gf.LoadQueued)
{ {
requestQueue.Push(gf); requestQueue.Enqueue(gf);
gf.LoadQueued = true; gf.LoadQueued = true;
} }
} }
@ -1870,7 +1870,7 @@ namespace CodeWalker.GameFiles
int itemcount = 0; int itemcount = 0;
while (requestQueue.TryPop(out req) && (itemcount < MaxItemsPerLoop)) while (requestQueue.TryDequeue(out req) && (itemcount < MaxItemsPerLoop))
{ {
//process content requests. //process content requests.
if (req.Loaded) if (req.Loaded)

View File

@ -253,10 +253,10 @@ namespace CodeWalker.Rendering
public class RenderableCacheLookup<TKey, TVal> where TVal: RenderableCacheItem<TKey>, new() public class RenderableCacheLookup<TKey, TVal> where TVal: RenderableCacheItem<TKey>, new()
{ {
private ConcurrentStack<TVal> itemsToLoad = new ConcurrentStack<TVal>(); private ConcurrentQueue<TVal> itemsToLoad = new ConcurrentQueue<TVal>();
private ConcurrentStack<TVal> itemsToUnload = new ConcurrentStack<TVal>(); private ConcurrentQueue<TVal> itemsToUnload = new ConcurrentQueue<TVal>();
private ConcurrentStack<TVal> itemsToInvalidate = new ConcurrentStack<TVal>(); private ConcurrentQueue<TVal> itemsToInvalidate = new ConcurrentQueue<TVal>();
private ConcurrentStack<TKey> keysToInvalidate = new ConcurrentStack<TKey>(); private ConcurrentQueue<TKey> keysToInvalidate = new ConcurrentQueue<TKey>();
private LinkedList<TVal> loadeditems = new LinkedList<TVal>();//only use from content thread! private LinkedList<TVal> loadeditems = new LinkedList<TVal>();//only use from content thread!
private Dictionary<TKey, TVal> cacheitems = new Dictionary<TKey, TVal>();//only use from render thread! private Dictionary<TKey, TVal> cacheitems = new Dictionary<TKey, TVal>();//only use from render thread!
public long CacheLimit; public long CacheLimit;
@ -296,16 +296,16 @@ namespace CodeWalker.Rendering
public void Clear() public void Clear()
{ {
itemsToLoad.Clear(); itemsToLoad = new ConcurrentQueue<TVal>();
foreach (TVal rnd in loadeditems) foreach (TVal rnd in loadeditems)
{ {
rnd.Unload(); rnd.Unload();
} }
loadeditems.Clear(); loadeditems.Clear();
cacheitems.Clear(); cacheitems.Clear();
itemsToUnload.Clear(); itemsToUnload = new ConcurrentQueue<TVal>();
itemsToInvalidate.Clear(); itemsToInvalidate = new ConcurrentQueue<TVal>();
keysToInvalidate.Clear(); keysToInvalidate = new ConcurrentQueue<TKey>();
} }
@ -313,7 +313,7 @@ namespace CodeWalker.Rendering
{ {
TVal item; TVal item;
LoadedCount = 0; LoadedCount = 0;
while (itemsToLoad.TryPop(out item)) while (itemsToLoad.TryDequeue(out item))
{ {
if (item.IsLoaded) continue; //don't load it again... if (item.IsLoaded) continue; //don't load it again...
LoadedCount++; LoadedCount++;
@ -337,7 +337,7 @@ namespace CodeWalker.Rendering
} }
if (LoadedCount >= maxitemsperloop) break; if (LoadedCount >= maxitemsperloop) break;
} }
while (itemsToInvalidate.TryPop(out item)) while (itemsToInvalidate.TryDequeue(out item))
{ {
try try
{ {
@ -363,7 +363,7 @@ namespace CodeWalker.Rendering
if ((now - lu).TotalSeconds > CacheTime) if ((now - lu).TotalSeconds > CacheTime)
{ {
var nextnode = rnode.Next; var nextnode = rnode.Next;
itemsToUnload.Push(rnode.Value); itemsToUnload.Enqueue(rnode.Value);
loadeditems.Remove(rnode); loadeditems.Remove(rnode);
rnode = nextnode; rnode = nextnode;
} }
@ -380,18 +380,18 @@ namespace CodeWalker.Rendering
LastFrameTime = DateTime.UtcNow.ToBinary(); LastFrameTime = DateTime.UtcNow.ToBinary();
TVal item; TVal item;
TKey key; TKey key;
while (keysToInvalidate.TryPop(out key)) while (keysToInvalidate.TryDequeue(out key))
{ {
if (cacheitems.TryGetValue(key, out item)) if (cacheitems.TryGetValue(key, out item))
{ {
item.Unload(); item.Unload();
item.Init(key); item.Init(key);
item.LoadQueued = true; item.LoadQueued = true;
itemsToInvalidate.Push(item); itemsToInvalidate.Enqueue(item);
Interlocked.Add(ref CacheUse, -item.DataSize); Interlocked.Add(ref CacheUse, -item.DataSize);
} }
} }
while (itemsToUnload.TryPop(out item)) while (itemsToUnload.TryDequeue(out item))
{ {
if ((item.Key != null) && (cacheitems.ContainsKey(item.Key))) if ((item.Key != null) && (cacheitems.ContainsKey(item.Key)))
{ {
@ -418,7 +418,7 @@ namespace CodeWalker.Rendering
if ((!item.IsLoaded) && (!item.LoadQueued))// || if ((!item.IsLoaded) && (!item.LoadQueued))// ||
{ {
item.LoadQueued = true; item.LoadQueued = true;
itemsToLoad.Push(item); itemsToLoad.Enqueue(item);
} }
return item; return item;
} }
@ -428,7 +428,7 @@ namespace CodeWalker.Rendering
{ {
if (key == null) return; if (key == null) return;
keysToInvalidate.Push(key); keysToInvalidate.Enqueue(key);
} }

View File

@ -1721,6 +1721,7 @@ namespace CodeWalker.Rendering
} }
ent.Distance = dist;
ent.IsVisible = (dist <= loddist); ent.IsVisible = (dist <= loddist);
ent.ChildrenVisible = (dist <= cloddist) && (ent.CEntityDef.numChildren > 0); ent.ChildrenVisible = (dist <= cloddist) && (ent.CEntityDef.numChildren > 0);
@ -2009,6 +2010,7 @@ namespace CodeWalker.Rendering
bool usechild = false; bool usechild = false;
Vector3 camrel = entity.Position - camera.Position; Vector3 camrel = entity.Position - camera.Position;
float dist = (camrel + entity.BSCenter).Length(); float dist = (camrel + entity.BSCenter).Length();
entity.Distance = dist;
float rad = arch.BSRadius; float rad = arch.BSRadius;
float loddist = entity.CEntityDef.lodDist; float loddist = entity.CEntityDef.lodDist;
if (loddist < 1.0f) if (loddist < 1.0f)
@ -2380,6 +2382,7 @@ namespace CodeWalker.Rendering
Vector3 bbmax = (arche != null) ? arche.BBMax : rndbl.Key.BoundingBoxMax.XYZ(); Vector3 bbmax = (arche != null) ? arche.BBMax : rndbl.Key.BoundingBoxMax.XYZ();
Vector3 bscen = (arche != null) ? arche.BSCenter : rndbl.Key.BoundingCenter; Vector3 bscen = (arche != null) ? arche.BSCenter : rndbl.Key.BoundingCenter;
float radius = (arche != null) ? arche.BSRadius : rndbl.Key.BoundingSphereRadius; float radius = (arche != null) ? arche.BSRadius : rndbl.Key.BoundingSphereRadius;
float distance = 0;// (camrel + bscen).Length();
if (entity != null) if (entity != null)
{ {
position = entity.Position; position = entity.Position;
@ -2390,9 +2393,12 @@ namespace CodeWalker.Rendering
bbmax = entity.BBMax; bbmax = entity.BBMax;
bscen = entity.BSCenter; bscen = entity.BSCenter;
camrel += position; camrel += position;
distance = entity.Distance;
}
else
{
distance = (camrel + bscen).Length();
} }
float distance = (camrel + bscen).Length();
//bool usehdtxd = renderhdtextures && ((dist - bsrad) <= arche._BaseArchetypeDef.hdTextureDist); //bool usehdtxd = renderhdtextures && ((dist - bsrad) <= arche._BaseArchetypeDef.hdTextureDist);
@ -2660,13 +2666,14 @@ namespace CodeWalker.Rendering
var yptTexDict = (drawable.Owner as YptFile)?.PtfxList?.TextureDictionary; var yptTexDict = (drawable.Owner as YptFile)?.PtfxList?.TextureDictionary;
bool cacheSD = (rndbl.SDtxds == null);
if (rndbl.SDtxds == null) bool cacheHD = (renderhdtextures && (rndbl.HDtxds == null));
if (cacheSD || cacheHD)
{ {
//cache the txd hierarchies for this renderable //cache the txd hierarchies for this renderable
tryGetRenderableSDtxds.Clear(); tryGetRenderableSDtxds.Clear();
tryGetRenderableHDtxds.Clear(); tryGetRenderableHDtxds.Clear();
if (arche != null) //try get HD txd for the asset if (cacheHD && (arche != null)) //try get HD txd for the asset
{ {
MetaHash hdtxd = gameFileCache.TryGetHDTextureHash(arche._BaseArchetypeDef.assetName); MetaHash hdtxd = gameFileCache.TryGetHDTextureHash(arche._BaseArchetypeDef.assetName);
if (hdtxd != arche._BaseArchetypeDef.assetName) if (hdtxd != arche._BaseArchetypeDef.assetName)
@ -2680,59 +2687,71 @@ namespace CodeWalker.Rendering
} }
if (texDict != 0) if (texDict != 0)
{ {
var txdytd = gameFileCache.GetYtd(texDict); if (cacheSD)
if (txdytd != null)
{ {
tryGetRenderableSDtxds.Add(txdytd); var txdytd = gameFileCache.GetYtd(texDict);
} if (txdytd != null)
MetaHash hdtxd = gameFileCache.TryGetHDTextureHash(texDict);
if (hdtxd != texDict)
{
var txdhdytd = gameFileCache.GetYtd(hdtxd);
if (txdhdytd != null)
{ {
tryGetRenderableHDtxds.Add(txdhdytd); tryGetRenderableSDtxds.Add(txdytd);
}
}
if (cacheHD)
{
MetaHash hdtxd = gameFileCache.TryGetHDTextureHash(texDict);
if (hdtxd != texDict)
{
var txdhdytd = gameFileCache.GetYtd(hdtxd);
if (txdhdytd != null)
{
tryGetRenderableHDtxds.Add(txdhdytd);
}
} }
} }
MetaHash ptxdname = gameFileCache.TryGetParentYtdHash(texDict); MetaHash ptxdname = gameFileCache.TryGetParentYtdHash(texDict);
while (ptxdname != 0) //look for parent HD txds while (ptxdname != 0) //look for parent HD txds
{ {
var pytd = gameFileCache.GetYtd(ptxdname); if (cacheSD)
if (pytd != null)
{ {
tryGetRenderableSDtxds.Add(pytd); var pytd = gameFileCache.GetYtd(ptxdname);
} if (pytd != null)
MetaHash phdtxdname = gameFileCache.TryGetHDTextureHash(ptxdname);
if (phdtxdname != ptxdname)
{
var phdytd = gameFileCache.GetYtd(phdtxdname);
if (phdytd != null)
{ {
tryGetRenderableHDtxds.Add(phdytd); tryGetRenderableSDtxds.Add(pytd);
}
}
if (cacheHD)
{
MetaHash phdtxdname = gameFileCache.TryGetHDTextureHash(ptxdname);
if (phdtxdname != ptxdname)
{
var phdytd = gameFileCache.GetYtd(phdtxdname);
if (phdytd != null)
{
tryGetRenderableHDtxds.Add(phdytd);
}
} }
} }
ptxdname = gameFileCache.TryGetParentYtdHash(ptxdname); ptxdname = gameFileCache.TryGetParentYtdHash(ptxdname);
} }
} }
rndbl.SDtxds = tryGetRenderableSDtxds.ToArray(); if (cacheSD) rndbl.SDtxds = tryGetRenderableSDtxds.ToArray();
rndbl.HDtxds = tryGetRenderableHDtxds.ToArray(); if (cacheHD) rndbl.HDtxds = tryGetRenderableHDtxds.ToArray();
} }
//bool alltexsloaded = true;
for (int mi = 0; mi < rndbl.AllModels.Length; mi++) for (int mi = 0; mi < rndbl.AllModels.Length; mi++)
{ {
var model = rndbl.AllModels[mi]; var model = rndbl.AllModels[mi];
//if (!RenderIsModelFinalRender(model) && !renderproxies) if (!RenderIsModelFinalRender(model) && !renderproxies)
//{ {
// continue; //filter out reflection proxy models... continue; //filter out reflection proxy models...
//} }
foreach (var geom in model.Geometries) foreach (var geom in model.Geometries)
@ -2753,7 +2772,7 @@ namespace CodeWalker.Rendering
dtex = yptTexDict.Lookup(tex.NameHash); dtex = yptTexDict.Lookup(tex.NameHash);
} }
else //if (texDict != 0) if (dtex == null) //else //if (texDict != 0)
{ {
if (rndbl.SDtxds != null) if (rndbl.SDtxds != null)
@ -2772,13 +2791,13 @@ namespace CodeWalker.Rendering
} }
if (dtex != null) break; if (dtex != null) break;
} }
if (dtex == null)// rndbl.SDtxds.Length == 0)//ytd not found.. if (dtex == null)// rndbl.SDtxds.Length == 0)//texture not found..
{ {
if (drawable.ShaderGroup.TextureDictionary != null)//check any embedded texdict if (drawable.ShaderGroup.TextureDictionary != null)//check any embedded texdict
{ {
dtex = drawable.ShaderGroup.TextureDictionary.Lookup(tex.NameHash); dtex = drawable.ShaderGroup.TextureDictionary.Lookup(tex.NameHash);
if (dtex != null) if (dtex != null)
{ } { } //this shouldn't really happen as embedded textures should already be loaded! (not as TextureRef)
} }
} }
} }
@ -2806,11 +2825,16 @@ namespace CodeWalker.Rendering
} }
if (ttex != null) //ensure embedded renderable texture if (ttex != null) //ensure renderable texture
{ {
rdtex = renderableCache.GetRenderableTexture(ttex); rdtex = renderableCache.GetRenderableTexture(ttex);
} }
//if ((rdtex != null) && (rdtex.IsLoaded == false))
//{
// alltexsloaded = false;
//}
geom.RenderableTextures[i] = rdtex; geom.RenderableTextures[i] = rdtex;
@ -2856,7 +2880,29 @@ namespace CodeWalker.Rendering
} }
} }
rndbl.AllTexturesLoaded = true;// alltexsloaded || (missingtexcount < 2); //if (rndbl.SDtxds != null)
//{
// for (int i = 0; i < rndbl.SDtxds.Length; i++)
// {
// if (!rndbl.SDtxds[i].Loaded)
// {
// alltexsloaded = false;
// }
// }
//}
//if (rndbl.HDtxds != null)
//{
// for (int i = 0; i < rndbl.HDtxds.Length; i++)
// {
// if (!rndbl.HDtxds[i].Loaded)
// {
// rndbl.AllTexturesLoaded = false;
// }
// }
//}
rndbl.AllTexturesLoaded = true;// alltexsloaded;// || (missingtexcount < 2);
return rndbl; return rndbl;
} }