gi stuff, static batching toggle
This commit is contained in:
@@ -4,6 +4,9 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FlaxEditor;
|
||||
@@ -61,6 +64,7 @@ namespace Game
|
||||
private float indirectLightMultiplier_ = 1.0f;
|
||||
private List<MapEntity> lightEnts = new List<MapEntity>();
|
||||
private Actor worldSpawnActor = null;
|
||||
private bool staticBatching_ = false;
|
||||
|
||||
[Range(0.1f, 4f)]
|
||||
public float BrightnessMultiplier
|
||||
@@ -97,6 +101,20 @@ namespace Game
|
||||
set { indirectLightMultiplier_ = value; resetLights = true; }
|
||||
}
|
||||
|
||||
public bool StaticBatching
|
||||
{
|
||||
get => staticBatching_;
|
||||
set
|
||||
{
|
||||
if (staticBatching_ == value)
|
||||
return;
|
||||
staticBatching_ = value;
|
||||
|
||||
FlaxEngine.Debug.Log("StaticBatching changed, reloading map");
|
||||
LoadMap(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void QuickHull(Float3[] points, out Float3[] outVertices)
|
||||
{
|
||||
@@ -345,6 +363,21 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsMapDirty(Actor worldSpawnActor, string mapPath)
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
LevelScript levelScript = worldSpawnActor.GetScript<LevelScript>();
|
||||
|
||||
if (levelScript.MapName != mapPath)
|
||||
return true;
|
||||
|
||||
DateTime timestamp = File.GetLastWriteTime(mapPath);
|
||||
if (timestamp != levelScript.MapTimestamp)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
private void LoadMap(bool forceLoad)
|
||||
{
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
@@ -354,26 +387,14 @@ namespace Game
|
||||
//Console.Print("Map parsing time: " + sw.Elapsed.TotalMilliseconds + "ms");
|
||||
|
||||
worldSpawnActor = Actor.FindActor("WorldSpawn");
|
||||
LevelScript levelScript = worldSpawnActor?.GetScript<LevelScript>();
|
||||
if (worldSpawnActor != null)
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
DateTime timestamp = File.GetLastWriteTime(mapPath);
|
||||
if (timestamp != levelScript.MapTimestamp)
|
||||
{
|
||||
FlaxEngine.Debug.Log($"Map dirty, reloading. {timestamp.ToString()} != {levelScript.MapTimestamp.ToString()}");
|
||||
forceLoad = true;
|
||||
levelScript.MapTimestamp = timestamp;
|
||||
}
|
||||
#endif
|
||||
if (forceLoad)
|
||||
worldSpawnActor.DestroyChildren();
|
||||
else
|
||||
{
|
||||
//FlaxEngine.Debug.Log("Map already loaded in the scene");
|
||||
resetLights = false;
|
||||
if (!forceLoad && !IsMapDirty(worldSpawnActor, mapPath))
|
||||
return;
|
||||
}
|
||||
|
||||
FlaxEngine.Debug.Log($"Map dirty, reloading.");
|
||||
worldSpawnActor.DestroyChildren();
|
||||
resetLights = false;
|
||||
}
|
||||
//else
|
||||
// FlaxEngine.Debug.Log("No WorldSpawn, loading map");
|
||||
@@ -388,24 +409,25 @@ namespace Game
|
||||
ConcurrentBag<Model> sdfModels = new ConcurrentBag<Model>();
|
||||
|
||||
bool oneMesh = false;
|
||||
bool useStaticBatching = false;
|
||||
bool useStaticBatching = StaticBatching;
|
||||
bool convexMesh = true;
|
||||
|
||||
if (worldSpawnActor == null)
|
||||
{
|
||||
worldSpawnActor = Actor.AddChild<Actor>();
|
||||
worldSpawnActor.Name = "WorldSpawn";
|
||||
|
||||
levelScript = worldSpawnActor.AddScript<LevelScript>();
|
||||
#if FLAX_EDITOR
|
||||
levelScript.MapTimestamp = File.GetLastWriteTime(mapPath);
|
||||
#endif
|
||||
worldSpawnActor.HideFlags &= ~HideFlags.DontSave;
|
||||
//worldSpawnActor.HideFlags |= HideFlags.DontSave;
|
||||
//worldSpawnActor.HideFlags |= HideFlags.DontSelect;
|
||||
}
|
||||
else
|
||||
levelScript = worldSpawnActor.GetScript<LevelScript>();
|
||||
|
||||
LevelScript levelScript =
|
||||
worldSpawnActor.GetScript<LevelScript>() ?? worldSpawnActor.AddScript<LevelScript>();
|
||||
|
||||
#if FLAX_EDITOR
|
||||
levelScript.MapTimestamp = File.GetLastWriteTime(mapPath);
|
||||
levelScript.MapName = mapPath;
|
||||
#endif
|
||||
|
||||
if (!oneMesh)
|
||||
{
|
||||
@@ -1041,6 +1063,45 @@ namespace Game
|
||||
//Debug.Log($"generate:{generateSdf}, GI:{Graphics.PostProcessSettings.GlobalIllumination.Mode != GlobalIlluminationMode.None}, {sdfModels.Count}");
|
||||
if (generateSdf /*&& Graphics.PostProcessSettings.GlobalIllumination.Mode != GlobalIlluminationMode.None*/ && sdfModels.Count > 1)
|
||||
{
|
||||
int modelIndex = 0;
|
||||
|
||||
// TODO: read sdf data from texture and dump it to file, and reuse it when generating sdf data
|
||||
using var sha1 = new SHA1Managed();
|
||||
string mapHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(levelScript.MapName + levelScript.MapTimestamp.Ticks.ToString())).ToString();
|
||||
|
||||
foreach (var model in sdfModels.ToList())
|
||||
{
|
||||
string sdfDataPath = Path.Combine(AssetManager.CachePath, "MapSdfData",
|
||||
$"{mapHash}_brush{modelIndex+1}");
|
||||
|
||||
/*if (File.Exists(sdfDataPath))
|
||||
{
|
||||
sdfModels.TryTake(out var model_);
|
||||
|
||||
T RawDeserialize<T>(byte[] rawData, int position)
|
||||
{
|
||||
int rawsize = Marshal.SizeOf(typeof(T));
|
||||
if (rawsize > rawData.Length - position)
|
||||
throw new ArgumentException("Not enough data to fill struct. Array length from position: " +
|
||||
(rawData.Length - position) + ", Struct length: " + rawsize);
|
||||
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
|
||||
Marshal.Copy(rawData, position, buffer, rawsize);
|
||||
T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T));
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
return retobj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ModelBase.SDFData sdfData = new ModelBase.SDFData();
|
||||
sdfData.Texture
|
||||
|
||||
model.SetSDF(sdfData);
|
||||
}*/
|
||||
modelIndex++;
|
||||
}
|
||||
|
||||
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
@@ -1048,14 +1109,34 @@ namespace Game
|
||||
|
||||
ParallelOptions opts = new ParallelOptions();
|
||||
FlaxEngine.Debug.Log("processorcount: " + Environment.ProcessorCount);
|
||||
float backfacesThreshold = 0.15f;
|
||||
if (useStaticBatching)
|
||||
opts.MaxDegreeOfParallelism = 2;//Environment.ProcessorCount / 2;
|
||||
Parallel.ForEach(sdfModels, opts, model =>
|
||||
{
|
||||
opts.MaxDegreeOfParallelism = 2; //Environment.ProcessorCount / 2;
|
||||
//backfacesThreshold = 1f;
|
||||
}
|
||||
|
||||
Parallel.ForEach(sdfModels, opts, (model, _, index) =>
|
||||
{
|
||||
if (model.WaitForLoaded())
|
||||
throw new Exception("model was not loaded");
|
||||
|
||||
model.GenerateSDF(0.9f, 6, true, 0.15f);
|
||||
model.GenerateSDF(0.9f, 6, true, backfacesThreshold);
|
||||
|
||||
/*byte[] RawSerialize(object anything)
|
||||
{
|
||||
int rawSize = Marshal.SizeOf(anything);
|
||||
IntPtr buffer = Marshal.AllocHGlobal(rawSize);
|
||||
Marshal.StructureToPtr(anything, buffer, false);
|
||||
byte[] rawDatas = new byte[rawSize];
|
||||
Marshal.Copy(buffer, rawDatas, 0, rawSize);
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
return rawDatas;
|
||||
}
|
||||
|
||||
string sdfDataPath = Path.Combine(AssetManager.CachePath, "MapSdfData",
|
||||
$"{mapHash}_brush{modelIndex+1}");*/
|
||||
|
||||
});
|
||||
|
||||
FlaxEngine.Debug.Log($"Generated level SDF in {sw.Elapsed.TotalMilliseconds}ms");
|
||||
|
||||
Reference in New Issue
Block a user