Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crack stitching #372

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Plugins/API/Components/Runtime/CSGModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum ModelSettingsFlags
StitchLightmapSeams = 4096,
IgnoreNormals = 8192,
TwoSidedShadows = 16384,
AutoStitchCracks = 32768
}

[Serializable]
Expand Down Expand Up @@ -61,6 +62,7 @@ public sealed class CSGModel : CSGNode
public bool NeedAutoUpdateRigidBody { get { return (Settings & ModelSettingsFlags.AutoUpdateRigidBody) == (ModelSettingsFlags)0; } }
public bool PreserveUVs { get { return (Settings & ModelSettingsFlags.PreserveUVs) != (ModelSettingsFlags)0; } }
public bool StitchLightmapSeams { get { return (Settings & ModelSettingsFlags.StitchLightmapSeams) != (ModelSettingsFlags)0; } }
public bool AutoStitchCracks { get { return (Settings & ModelSettingsFlags.AutoStitchCracks) != (ModelSettingsFlags)0; } }
public bool AutoRebuildUVs { get { return (Settings & ModelSettingsFlags.AutoRebuildUVs) != (ModelSettingsFlags)0; } }
public bool IgnoreNormals { get { return (Settings & ModelSettingsFlags.IgnoreNormals) != (ModelSettingsFlags)0; } }

Expand Down
514 changes: 514 additions & 0 deletions Plugins/Editor/Scripts/Control/Helpers/CracksStitching.cs

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions Plugins/Editor/Scripts/Control/Helpers/CracksStitching.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

121 changes: 121 additions & 0 deletions Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//#define SHOW_GENERATED_MESHES
using System.Linq;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEditor;
Expand Down Expand Up @@ -926,6 +927,109 @@ private static bool NeedToGenerateLightmapUVsForInstance(GeneratedMeshInstance i
return !instance.HasUV2 && instance.RenderSurfaceType == RenderSurfaceType.Normal;
}

public static bool NeedToStitchCracksForModel(CSGModel model)
{
if (!ModelTraits.IsModelEditable(model))
return false;

if (!model.generatedMeshes)
return false;

var container = model.generatedMeshes;
if (!container || container.owner != model)
return false;

foreach (var instance in container.MeshInstances)
{
if (!instance)
continue;

if (NeedToStitchCracksForInstance(instance))
return true;
}
return false;
}

public static void StitchCracksForModel(CSGModel model)
{
if (!ModelTraits.IsModelEditable(model))
return;

if (!model.generatedMeshes)
return;

var container = model.generatedMeshes;
if (!container || !container.owner)
return;

if (!container.HasMeshInstances)
return;

foreach (var instance in container.MeshInstances)
{
if (!instance)
continue;
if (!instance.SharedMesh)
{
instance.FindMissingSharedMesh();
if (!instance.SharedMesh)
continue;
}

StitchCracksForInstance(instance, model);
}
}

private static void StitchCracksForInstance(GeneratedMeshInstance instance, CSGModel model)
{
var oldVertices = instance.SharedMesh.vertices;
if (oldVertices.Length == 0)
return;

var tempMesh = instance.SharedMesh.Clone();
instance.SharedMesh = tempMesh;

UnityEngine.Object pingObject = model;
if (model.ShowGeneratedMeshes) pingObject = instance;
Debug.Log($"Stitching cracks for the mesh {instance.name} of the Model named \"{model.name}\n", pingObject);

var genTime = EditorApplication.timeSinceStartup;
MeshUtility.Optimize(instance.SharedMesh);
instance.CracksSolverCancellation?.Cancel();
instance.CracksSolverCancellation = new CancellationTokenSource();
CracksStitching.SolveAsync(instance.SharedMesh, null, instance.CracksSolverCancellation.Token,
() =>
{
genTime = EditorApplication.timeSinceStartup - genTime;
Debug.Log($"\tCracks stitched in {(genTime* 1000):F1} ms\n", model);
EditorSceneManager.MarkSceneDirty(instance.gameObject.scene);
});

EditorSceneManager.MarkSceneDirty(instance.gameObject.scene);
instance.CracksHashValue = instance.MeshDescription.geometryHashValue;
instance.HasNoCracks = true;
}

/// <summary> Thin helper to debug issues related to crack stitching </summary>
private class CracksDebugger : CracksStitching.ISolverDebugProvider
{
public void HookIntoWorkingData(CracksStitching.WorkingData data){ }
public void LogWarning(string str) => Debug.LogWarning(str);
public void Log(string str){ }
}

private static bool NeedToStitchCracksForInstance(GeneratedMeshInstance instance)
{
return !instance.HasNoCracks;
}

public static void ClearCrackStitching(GeneratedMeshInstance instance)
{
instance.CracksHashValue = 0;
instance.HasNoCracks = false;
instance.CracksSolverCancellation?.Cancel();
}

private static bool AreBoundsEmpty(GeneratedMeshInstance instance)
{
return
Expand Down Expand Up @@ -1203,6 +1307,22 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool
}
}
}

if (instance.HasNoCracks && instance.CracksHashValue != instance.MeshDescription.geometryHashValue && meshRendererComponent)
{
instance.ResetStitchCracksTime = Time.realtimeSinceStartup;
if(instance.HasNoCracks)
ClearCrackStitching(instance);
}

if (owner.AutoStitchCracks || postProcessScene)
{
if ((float.IsPositiveInfinity(instance.ResetStitchCracksTime) || Time.realtimeSinceStartup - instance.ResetStitchCracksTime > 2.0f) &&
NeedToStitchCracksForModel(owner))
{
StitchCracksForModel(owner);
}
}

if (!postProcessScene &&
meshFilterComponent.sharedMesh != instance.SharedMesh)
Expand Down Expand Up @@ -1345,6 +1465,7 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool
meshRendererComponent.hideFlags = HideFlags.None; UnityEngine.Object.DestroyImmediate(meshRendererComponent); instance.Dirty = true;
}
instance.LightingHashValue = instance.MeshDescription.geometryHashValue;
instance.CracksHashValue = instance.MeshDescription.geometryHashValue;
meshFilterComponent = null;
meshRendererComponent = null;
instance.CachedMeshRendererSO = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ public static void OnInspectorGUI(UnityEngine.Object[] targets)
bool? DoNotRender = (Settings & ModelSettingsFlags.DoNotRender) == ModelSettingsFlags.DoNotRender;
bool? TwoSidedShadows = (Settings & ModelSettingsFlags.TwoSidedShadows) == ModelSettingsFlags.TwoSidedShadows;
// bool? ReceiveShadows = !((settings & ModelSettingsFlags.DoNotReceiveShadows) == ModelSettingsFlags.DoNotReceiveShadows);
bool? AutoStitchCracks = (Settings & ModelSettingsFlags.AutoStitchCracks) == ModelSettingsFlags.AutoStitchCracks;
bool? AutoRebuildUVs = (Settings & ModelSettingsFlags.AutoRebuildUVs) == ModelSettingsFlags.AutoRebuildUVs;
bool? PreserveUVs = (Settings & ModelSettingsFlags.PreserveUVs) == ModelSettingsFlags.PreserveUVs;
bool? StitchLightmapSeams = (Settings & ModelSettingsFlags.StitchLightmapSeams) == ModelSettingsFlags.StitchLightmapSeams;
Expand Down Expand Up @@ -266,6 +267,7 @@ public static void OnInspectorGUI(UnityEngine.Object[] targets)
bool currDoNotRender = (Settings & ModelSettingsFlags.DoNotRender) == ModelSettingsFlags.DoNotRender;
bool currTwoSidedShadows = (Settings & ModelSettingsFlags.TwoSidedShadows) == ModelSettingsFlags.TwoSidedShadows;
// bool currReceiveShadows = !((settings & ModelSettingsFlags.DoNotReceiveShadows) == ModelSettingsFlags.DoNotReceiveShadows);
bool currAutoStitchCracks = (Settings & ModelSettingsFlags.AutoStitchCracks) == ModelSettingsFlags.AutoStitchCracks;
bool currAutoRebuildUVs = (Settings & ModelSettingsFlags.AutoRebuildUVs) == ModelSettingsFlags.AutoRebuildUVs;
bool currPreserveUVs = (Settings & ModelSettingsFlags.PreserveUVs) == ModelSettingsFlags.PreserveUVs;
bool currStitchLightmapSeams = (Settings & ModelSettingsFlags.StitchLightmapSeams) == ModelSettingsFlags.StitchLightmapSeams;
Expand Down Expand Up @@ -303,6 +305,7 @@ public static void OnInspectorGUI(UnityEngine.Object[] targets)
if (TwoSidedShadows .HasValue && TwoSidedShadows .Value != currTwoSidedShadows ) TwoSidedShadows = null;
// if (ReceiveShadows .HasValue && ReceiveShadows .Value != currReceiveShadows ) ReceiveShadows = null;
// if (ShadowCastingMode .HasValue && ShadowCastingMode .Value != currShadowCastingMode ) ShadowCastingMode = null;
if (AutoStitchCracks .HasValue && AutoStitchCracks .Value != currAutoStitchCracks ) AutoStitchCracks = null;
if (AutoRebuildUVs .HasValue && AutoRebuildUVs .Value != currAutoRebuildUVs ) AutoRebuildUVs = null;
if (PreserveUVs .HasValue && PreserveUVs .Value != currPreserveUVs ) PreserveUVs = null;
if (StitchLightmapSeams .HasValue && StitchLightmapSeams .Value != currStitchLightmapSeams ) StitchLightmapSeams = null;
Expand Down Expand Up @@ -1130,6 +1133,27 @@ public static void OnInspectorGUI(UnityEngine.Object[] targets)
EditorApplication.RepaintHierarchyWindow();
EditorApplication.DirtyHierarchyWindowSorting();
}
{
var autoStitchCracks = AutoStitchCracks ?? false;
EditorGUI.BeginChangeCheck();
{
EditorGUI.showMixedValue = !AutoStitchCracks.HasValue;
autoStitchCracks = EditorGUILayout.Toggle(StitchCracksContent, autoStitchCracks);
}
if (EditorGUI.EndChangeCheck())
{
for (int i = 0; i < models.Length; i++)
{
if (autoStitchCracks)
models[i].Settings |= ModelSettingsFlags.AutoStitchCracks;
else
models[i].Settings &= ~ModelSettingsFlags.AutoStitchCracks;
MeshInstanceManager.Refresh(models[i], onlyFastRefreshes: false);
}
GUI.changed = true;
AutoStitchCracks = autoStitchCracks;
}
}

#if UNITY_2017_3_OR_NEWER
GUILayout.Space(10);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ internal sealed partial class CSGModelComponentInspectorGUI

private static readonly GUIContent MinimumChartSizeContent = new GUIContent("Min Chart Size", "Specifies the minimum texel size used for a UV chart. If stitching is required, a value of 4 will create a chart of 4x4 texels to store lighting and directionality. If stitching is not required, a value of 2 will reduce the texel density and provide better lighting build times and run time performance.");

private static readonly GUIContent StitchCracksContent = new GUIContent("Stitch Cracks", "Fill in cracks that came out through the mesh generation process, increases the amount of triangles.");

public static int[] MinimumChartSizeValues = { 2, 4 };
public static GUIContent[] MinimumChartSizeStrings =
{
Expand Down
16 changes: 12 additions & 4 deletions Plugins/Runtime/Scripts/Components/GeneratedMeshInstance.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using UnityEngine;
using UnityEngine.Serialization;
using MeshQuery = RealtimeCSG.Foundation.MeshQuery;
Expand Down Expand Up @@ -130,10 +131,14 @@ public sealed class GeneratedMeshInstance : MonoBehaviour

[HideInInspector] public bool HasGeneratedNormals = false;
[HideInInspector] public bool HasUV2 = false;
[NonSerialized]
[HideInInspector] public bool HasNoCracks = false;
[NonSerialized]
[HideInInspector] public float ResetUVTime = float.PositiveInfinity;
[HideInInspector] public float ResetStitchCracksTime = float.PositiveInfinity;
[HideInInspector] public Int64 LightingHashValue;

[HideInInspector] public Int64 CracksHashValue;

[NonSerialized] public CancellationTokenSource CracksSolverCancellation;
[NonSerialized] [HideInInspector] public bool Dirty = true;
[NonSerialized] [HideInInspector] public MeshCollider CachedMeshCollider;
[NonSerialized] [HideInInspector] public MeshFilter CachedMeshFilter;
Expand All @@ -145,11 +150,14 @@ public void Reset()
RenderMaterial = null;
PhysicsMaterial = null;
RenderSurfaceType = (RenderSurfaceType)999;
HasGeneratedNormals = false;
HasUV2 = false;
ResetUVTime = float.PositiveInfinity;
ResetUVTime = float.PositiveInfinity;
ResetStitchCracksTime = float.PositiveInfinity;
LightingHashValue = 0;
CracksHashValue = 0;
CracksSolverCancellation?.Cancel();

Dirty = true;

Expand Down