Skip to content
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