diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.API.cs b/AvatarCloneTest/AvatarClone/AvatarClone.API.cs
deleted file mode 100644
index 89835bd..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.API.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- #region Public API Methods
-
- ///
- /// Sets whether the specific renderer requires additional runtime checks when copying to the clone.
- /// For example, Magica Cloth modifies the sharedMesh & bones of the renderer at runtime. This is not needed
- /// for most renderers, so copying for all renderers would be inefficient.
- ///
- public void SetRendererNeedsAdditionalChecks(Renderer rend, bool needsChecks)
- {
- switch (rend)
- {
- case MeshRenderer meshRenderer:
- {
- int index = _standardRenderers.IndexOf(meshRenderer);
- if (index == -1) return;
-
- if (needsChecks && !_standardRenderersNeedingChecks.Contains(index))
- {
- int insertIndex = _standardRenderersNeedingChecks.Count;
- _standardRenderersNeedingChecks.Add(index);
- _cachedSharedMeshes.Insert(insertIndex, null);
- }
- else if (!needsChecks)
- {
- int removeIndex = _standardRenderersNeedingChecks.IndexOf(index);
- if (removeIndex != -1)
- {
- _standardRenderersNeedingChecks.RemoveAt(removeIndex);
- _cachedSharedMeshes.RemoveAt(removeIndex);
- }
- }
- return;
- }
- case SkinnedMeshRenderer skinnedRenderer:
- {
- int index = _skinnedRenderers.IndexOf(skinnedRenderer);
- if (index == -1) return;
-
- if (needsChecks && !_skinnedRenderersNeedingChecks.Contains(index))
- {
- int insertIndex = _skinnedRenderersNeedingChecks.Count;
- _skinnedRenderersNeedingChecks.Add(index);
- _cachedSharedMeshes.Insert(_standardRenderersNeedingChecks.Count + insertIndex, null);
- _cachedSkinnedBoneCounts.Add(0);
- }
- else if (!needsChecks)
- {
- int removeIndex = _skinnedRenderersNeedingChecks.IndexOf(index);
- if (removeIndex != -1)
- {
- _skinnedRenderersNeedingChecks.RemoveAt(removeIndex);
- _cachedSharedMeshes.RemoveAt(_standardRenderersNeedingChecks.Count + removeIndex);
- _cachedSkinnedBoneCounts.RemoveAt(removeIndex);
- }
- }
- break;
- }
- }
- }
-
- #endregion Public API Methods
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.Clones.cs b/AvatarCloneTest/AvatarClone/AvatarClone.Clones.cs
deleted file mode 100644
index 8fb54ec..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.Clones.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using ABI_RC.Core;
-using UnityEngine;
-using UnityEngine.Rendering;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- #region Clone Creation
-
- private void CreateClones()
- {
- int standardCount = _standardRenderers.Count;
- _standardClones = new List(standardCount);
- _standardCloneFilters = new List(standardCount);
- for (int i = 0; i < standardCount; i++) CreateStandardClone(i);
-
- int skinnedCount = _skinnedRenderers.Count;
- _skinnedClones = new List(skinnedCount);
- for (int i = 0; i < skinnedCount; i++) CreateSkinnedClone(i);
- }
-
- private void CreateStandardClone(int index)
- {
- MeshRenderer sourceRenderer = _standardRenderers[index];
- MeshFilter sourceFilter = _standardFilters[index];
-
- GameObject go = new(sourceRenderer.name + "_VisualClone")
- {
- layer = CVRLayers.PlayerClone
- };
-
- go.transform.SetParent(sourceRenderer.transform, false);
- //go.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
-
- MeshRenderer cloneRenderer = go.AddComponent();
- MeshFilter cloneFilter = go.AddComponent();
-
- // Initial setup
- cloneRenderer.sharedMaterials = sourceRenderer.sharedMaterials;
- cloneRenderer.shadowCastingMode = ShadowCastingMode.Off;
- cloneRenderer.probeAnchor = sourceRenderer.probeAnchor;
- cloneRenderer.localBounds = new Bounds(Vector3.zero, Vector3.positiveInfinity);
- cloneFilter.sharedMesh = sourceFilter.sharedMesh;
-
- // Optimizations to enforce
- cloneRenderer.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
- cloneRenderer.allowOcclusionWhenDynamic = false;
-
- // Optimizations to enforce
- sourceRenderer.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
- sourceRenderer.allowOcclusionWhenDynamic = false;
-
- _standardClones.Add(cloneRenderer);
- _standardCloneFilters.Add(cloneFilter);
- }
-
- private void CreateSkinnedClone(int index)
- {
- SkinnedMeshRenderer source = _skinnedRenderers[index];
-
- GameObject go = new(source.name + "_VisualClone")
- {
- layer = CVRLayers.PlayerClone
- };
-
- go.transform.SetParent(source.transform, false);
- //go.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
-
- SkinnedMeshRenderer clone = go.AddComponent();
-
- // Initial setup
- clone.sharedMaterials = source.sharedMaterials;
- clone.shadowCastingMode = ShadowCastingMode.Off;
- clone.probeAnchor = source.probeAnchor;
- clone.localBounds = new Bounds(Vector3.zero, Vector3.positiveInfinity);
- clone.sharedMesh = source.sharedMesh;
- clone.rootBone = source.rootBone;
- clone.bones = source.bones;
- clone.quality = source.quality;
- clone.updateWhenOffscreen = source.updateWhenOffscreen;
-
- // Optimizations to enforce
- clone.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
- clone.allowOcclusionWhenDynamic = false;
- clone.updateWhenOffscreen = false;
- clone.skinnedMotionVectors = false;
- clone.forceMatrixRecalculationPerRender = false;
- clone.quality = SkinQuality.Bone4;
-
- // Optimizations to enforce
- source.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
- source.allowOcclusionWhenDynamic = false;
- source.updateWhenOffscreen = false;
- source.skinnedMotionVectors = false;
- source.forceMatrixRecalculationPerRender = false;
- source.quality = SkinQuality.Bone4;
-
- _skinnedClones.Add(clone);
- }
-
- #endregion Clone Creation
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.Exclusion.cs b/AvatarCloneTest/AvatarClone/AvatarClone.Exclusion.cs
deleted file mode 100644
index d5136e3..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.Exclusion.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using ABI.CCK.Components;
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- private readonly Dictionary> _exclusionDirectRenderers = new();
- private readonly Dictionary> _exclusionControlledBones = new();
-
- private void InitializeExclusions()
- {
- // Add head exclusion for humanoid avatars if not present
- var animator = GetComponent();
- if (animator != null && animator.isHuman)
- {
- var headBone = animator.GetBoneTransform(HumanBodyBones.Head);
- if (headBone != null && headBone.GetComponent() == null)
- {
- var exclusion = headBone.gameObject.AddComponent();
- exclusion.isShown = false;
- exclusion.target = headBone;
- exclusion.shrinkToZero = true;
- }
- }
-
- // Process existing exclusions bottom-up
- var exclusions = GetComponentsInChildren(true);
-
- for (int i = exclusions.Length - 1; i >= 0; i--)
- {
- var exclusion = exclusions[i];
- if (exclusion.target == null)
- exclusion.target = exclusion.transform;
-
- // Skip invalid exclusions or already processed targets
- if (exclusion.target == null || _exclusionDirectRenderers.ContainsKey(exclusion.target))
- {
- Destroy(exclusion);
- continue;
- }
-
- // Initialize data for this exclusion
- _exclusionDirectRenderers[exclusion.target] = new HashSet();
- _exclusionControlledBones[exclusion.target] = new HashSet();
-
- // Set up our behaviour
- exclusion.behaviour = new AvatarCloneExclusion(this, exclusion.target);
-
- // Collect affected renderers and bones
- CollectExclusionData(exclusion.target);
-
- // Initial update
- exclusion.UpdateExclusions();
- }
- }
-
- private void CollectExclusionData(Transform target)
- {
- var stack = new Stack();
- stack.Push(target);
-
- while (stack.Count > 0)
- {
- var current = stack.Pop();
-
- // Skip if this transform belongs to another exclusion
- if (current != target && current.GetComponent() != null)
- continue;
-
- _exclusionControlledBones[target].Add(current);
-
- // Add renderers that will need their clone visibility toggled
- foreach (var renderer in current.GetComponents())
- {
- // Find corresponding clone renderer
- if (renderer is MeshRenderer meshRenderer)
- {
- int index = _standardRenderers.IndexOf(meshRenderer);
- if (index != -1)
- _exclusionDirectRenderers[target].Add(_standardClones[index]);
- }
- else if (renderer is SkinnedMeshRenderer skinnedRenderer)
- {
- int index = _skinnedRenderers.IndexOf(skinnedRenderer);
- if (index != -1)
- _exclusionDirectRenderers[target].Add(_skinnedClones[index]);
- }
- }
-
- // Add children to stack
- foreach (Transform child in current)
- {
- stack.Push(child);
- }
- }
- }
-
- public void HandleExclusionUpdate(Transform target, Transform shrinkBone, bool isShown)
- {
- if (!_exclusionDirectRenderers.TryGetValue(target, out var directCloneRenderers) ||
- !_exclusionControlledBones.TryGetValue(target, out var controlledBones))
- return;
-
- // Handle direct clone renderers
- foreach (var cloneRenderer in directCloneRenderers)
- {
- cloneRenderer.enabled = isShown;
- }
-
- // Update bone references in clone renderers
- int cloneCount = _skinnedClones.Count;
- var cloneRenderers = _skinnedClones;
- var sourceRenderers = _skinnedRenderers;
-
- for (int i = 0; i < cloneCount; i++)
- {
- var clone = cloneRenderers[i];
- var source = sourceRenderers[i];
- var sourceBones = source.bones;
- var cloneBones = clone.bones;
- int boneCount = cloneBones.Length;
- bool needsUpdate = false;
-
- for (int j = 0; j < boneCount; j++)
- {
- // Check if this bone is in our controlled set
- if (controlledBones.Contains(sourceBones[j]))
- {
- cloneBones[j] = isShown ? sourceBones[j] : shrinkBone;
- needsUpdate = true;
- }
- }
-
- if (needsUpdate)
- {
- clone.bones = cloneBones;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.Fields.cs b/AvatarCloneTest/AvatarClone/AvatarClone.Fields.cs
deleted file mode 100644
index 0ba69b0..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.Fields.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- #region Profile Markers
-//#if UNITY_EDITOR
- private static readonly UnityEngine.Profiling.CustomSampler s_CopyMaterials =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.CopyMaterials");
- private static readonly UnityEngine.Profiling.CustomSampler s_CopyBlendShapes =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.CopyBlendShapes");
- private static readonly UnityEngine.Profiling.CustomSampler s_CopyMeshes =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.CopyMeshes");
-
- private static readonly UnityEngine.Profiling.CustomSampler s_MyOnPreRender =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.MyOnPreRender");
- private static readonly UnityEngine.Profiling.CustomSampler s_SetShadowsOnly =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.SetShadowsOnly");
- private static readonly UnityEngine.Profiling.CustomSampler s_UndoShadowsOnly =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.UndoShadowsOnly");
- private static readonly UnityEngine.Profiling.CustomSampler s_SetUiCulling =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.SetUiCulling");
- private static readonly UnityEngine.Profiling.CustomSampler s_UndoUiCulling =
- UnityEngine.Profiling.CustomSampler.Create("AvatarClone2.UndoUiCulling");
-
-//#endif
- #endregion Profile Markers
-
- #region Source Renderers
- private List _standardRenderers;
- private List _standardFilters;
- private List _skinnedRenderers;
- private List _allSourceRenderers; // For shadow casting only
- #endregion Source Renderers
-
- #region Clone Renderers
- private List _standardClones;
- private List _standardCloneFilters;
- private List _skinnedClones;
- #endregion Clone Renderers
-
- #region Dynamic Check Lists
- private List _standardRenderersNeedingChecks; // Stores indices into _standardRenderers
- private List _skinnedRenderersNeedingChecks; // Stores indices into _skinnedRenderers
- private List _cachedSkinnedBoneCounts; // So we don't copy the bones unless they've changed
- private List _cachedSharedMeshes; // So we don't copy the mesh unless it's changed
- #endregion Dynamic Check Lists
-
- #region Material Data
- private List _localMaterials;
- private List _cullingMaterials;
- private List _mainMaterials;
- private MaterialPropertyBlock _propertyBlock;
- #endregion Material Data
-
- #region Blend Shape Data
- private List> _blendShapeWeights;
- #endregion Blend Shape Data
-
- #region Shadow and UI Culling Settings
- private bool _uiCullingActive;
- private bool _shadowsOnlyActive;
- private bool[] _originallyHadShadows;
- private bool[] _originallyWasEnabled;
- #endregion Shadow and UI Culling Settings
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.Init.cs b/AvatarCloneTest/AvatarClone/AvatarClone.Init.cs
deleted file mode 100644
index 41bd84b..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.Init.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-using ABI_RC.Core.Player.ShadowClone;
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- #region Initialization
-
- private void InitializeCollections()
- {
- _standardRenderers = new List();
- _standardFilters = new List();
- _skinnedRenderers = new List();
- _allSourceRenderers = new List();
-
- _standardClones = new List();
- _standardCloneFilters = new List();
- _skinnedClones = new List();
-
- _standardRenderersNeedingChecks = new List();
- _skinnedRenderersNeedingChecks = new List();
- _cachedSkinnedBoneCounts = new List();
- _cachedSharedMeshes = new List();
-
- _localMaterials = new List();
- _cullingMaterials = new List();
- _mainMaterials = new List();
- _propertyBlock = new MaterialPropertyBlock();
-
- _blendShapeWeights = new List>();
- }
-
- private void InitializeRenderers()
- {
- var renderers = GetComponentsInChildren(true);
-
- // Pre-size lists based on found renderers
- // _standardRenderers.Capacity = renderers.Length;
- // _standardFilters.Capacity = renderers.Length;
- // _skinnedRenderers.Capacity = renderers.Length;
- // _allSourceRenderers.Capacity = renderers.Length;
-
- // Sort renderers into their respective lists
- foreach (Renderer render in renderers)
- {
- _allSourceRenderers.Add(render);
-
- switch (render)
- {
- case MeshRenderer meshRenderer:
- {
- MeshFilter filter = meshRenderer.GetComponent();
- if (filter != null && filter.sharedMesh != null)
- {
- _standardRenderers.Add(meshRenderer);
- _standardFilters.Add(filter);
- }
- break;
- }
- case SkinnedMeshRenderer skinnedRenderer:
- {
- if (skinnedRenderer.sharedMesh != null) _skinnedRenderers.Add(skinnedRenderer);
- break;
- }
- }
- }
- }
-
- private void SetupMaterialsAndBlendShapes()
- {
- // Cache counts
- int standardCount = _standardRenderers.Count;
- int skinnedCount = _skinnedRenderers.Count;
- var standardRenderers = _standardRenderers;
- var skinnedRenderers = _skinnedRenderers;
- var localMats = _localMaterials;
- var cullingMats = _cullingMaterials;
- var blendWeights = _blendShapeWeights;
-
- // Setup standard renderer materials
- for (int i = 0; i < standardCount; i++)
- {
- MeshRenderer render = standardRenderers[i];
- int matCount = render.sharedMaterials.Length;
-
- // Local materials array
- var localMatArray = new Material[matCount];
- for (int j = 0; j < matCount; j++) localMatArray[j] = render.sharedMaterials[j];
- localMats.Add(localMatArray);
-
- // Culling materials array
- var cullingMatArray = new Material[matCount];
- for (int j = 0; j < matCount; j++) cullingMatArray[j] = ShadowCloneUtils.cullingMaterial;
- cullingMats.Add(cullingMatArray);
- }
-
- // Setup skinned renderer materials and blend shapes
- for (int i = 0; i < skinnedCount; i++)
- {
- SkinnedMeshRenderer render = skinnedRenderers[i];
- int matCount = render.sharedMaterials.Length;
-
- // Local materials array
- var localMatArray = new Material[matCount];
- for (int j = 0; j < matCount; j++) localMatArray[j] = render.sharedMaterials[j];
- localMats.Add(localMatArray);
-
- // Culling materials array
- var cullingMatArray = new Material[matCount];
- for (int j = 0; j < matCount; j++) cullingMatArray[j] = ShadowCloneUtils.cullingMaterial;
- cullingMats.Add(cullingMatArray);
-
- // Blend shape weights
- int blendShapeCount = render.sharedMesh.blendShapeCount;
- var weights = new List(blendShapeCount);
- for (int j = 0; j < blendShapeCount; j++) weights.Add(0f);
- blendWeights.Add(weights);
- }
-
- // Initialize renderer state arrays
- int totalRenderers = _allSourceRenderers.Count;
- _originallyHadShadows = new bool[totalRenderers];
- _originallyWasEnabled = new bool[totalRenderers];
- }
-
- #endregion Initialization
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.MagicaSupport.cs b/AvatarCloneTest/AvatarClone/AvatarClone.MagicaSupport.cs
deleted file mode 100644
index 7ae5855..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.MagicaSupport.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using MagicaCloth;
-using MagicaCloth2;
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- #region Magica Cloth Support
-
- private void SetupMagicaClothSupport()
- {
- var magicaCloths1 = GetComponentsInChildren(true);
- foreach (MagicaRenderDeformer magicaCloth in magicaCloths1)
- {
- // Get the renderer on the same object
- Renderer renderer = magicaCloth.gameObject.GetComponent();
- SetRendererNeedsAdditionalChecks(renderer, true);
- }
-
- var magicaCloths2 = GetComponentsInChildren(true);
- foreach (MagicaCloth2.MagicaCloth magicaCloth in magicaCloths2)
- {
- if (magicaCloth.serializeData.clothType != ClothProcess.ClothType.MeshCloth)
- continue; // Only matters for cloth physics
-
- // Set the affected renderers as requiring extra checks
- var renderers = magicaCloth.serializeData.sourceRenderers;
- foreach (Renderer renderer in renderers) SetRendererNeedsAdditionalChecks(renderer, true);
- }
- }
-
- #endregion Magica Cloth Support
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.Update.cs b/AvatarCloneTest/AvatarClone/AvatarClone.Update.cs
deleted file mode 100644
index 42cef73..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.Update.cs
+++ /dev/null
@@ -1,181 +0,0 @@
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- #region Update Methods
-
- private void UpdateStandardRenderers()
- {
- int count = _standardRenderers.Count;
- var sourceRenderers = _standardRenderers;
- var cloneRenderers = _standardClones;
- var localMats = _localMaterials;
-
- for (int i = 0; i < count; i++)
- {
- if (!IsRendererValid(sourceRenderers[i])) continue;
- CopyMaterialsAndProperties(
- sourceRenderers[i],
- cloneRenderers[i],
- _propertyBlock,
- _mainMaterials,
- localMats[i]);
- }
- }
-
- private void UpdateSkinnedRenderers()
- {
- int standardCount = _standardRenderers.Count;
- int count = _skinnedRenderers.Count;
- var sourceRenderers = _skinnedRenderers;
- var cloneRenderers = _skinnedClones;
- var localMats = _localMaterials;
- var blendWeights = _blendShapeWeights;
-
- for (int i = 0; i < count; i++)
- {
- SkinnedMeshRenderer source = sourceRenderers[i];
- if (!IsRendererValid(source)) continue;
-
- SkinnedMeshRenderer clone = cloneRenderers[i];
- CopyMaterialsAndProperties(
- source,
- clone,
- _propertyBlock,
- _mainMaterials,
- localMats[i + standardCount]);
-
- CopyBlendShapes(source, clone, blendWeights[i]);
- }
- }
-
- private void UpdateStandardRenderersWithChecks()
- {
- s_CopyMeshes.Begin();
-
- var cloneFilters = _standardCloneFilters;
- var sourceFilters = _standardFilters;
- var cachedMeshes = _cachedSharedMeshes;
- var checkIndices = _standardRenderersNeedingChecks;
- int checkCount = checkIndices.Count;
-
- while (cachedMeshes.Count < checkCount) cachedMeshes.Add(null);
-
- for (int i = 0; i < checkCount; i++)
- {
- int rendererIndex = checkIndices[i];
- Mesh newMesh = sourceFilters[rendererIndex].sharedMesh;
- if (ReferenceEquals(newMesh, cachedMeshes[i])) continue;
- cloneFilters[rendererIndex].sharedMesh = newMesh; // expensive & allocates
- cachedMeshes[i] = newMesh;
- }
-
- s_CopyMeshes.End();
- }
-
- private void UpdateSkinnedRenderersWithChecks()
- {
- s_CopyMeshes.Begin();
-
- var sourceRenderers = _skinnedRenderers;
- var cloneRenderers = _skinnedClones;
- var cachedMeshes = _cachedSharedMeshes;
- var cachedBoneCounts = _cachedSkinnedBoneCounts;
- var checkIndices = _skinnedRenderersNeedingChecks;
- int checkCount = checkIndices.Count;
- int meshOffset = _standardRenderersNeedingChecks.Count;
-
- // Ensure cache lists are properly sized
- while (cachedMeshes.Count < meshOffset + checkCount) cachedMeshes.Add(null);
- while (cachedBoneCounts.Count < checkCount) cachedBoneCounts.Add(0);
-
- for (int i = 0; i < checkCount; i++)
- {
- int rendererIndex = checkIndices[i];
- SkinnedMeshRenderer source = sourceRenderers[rendererIndex];
- SkinnedMeshRenderer clone = cloneRenderers[rendererIndex];
-
- // Check mesh changes
- Mesh newMesh = source.sharedMesh; // expensive & allocates
- if (!ReferenceEquals(newMesh, cachedMeshes[meshOffset + i]))
- {
- clone.sharedMesh = newMesh;
- cachedMeshes[meshOffset + i] = newMesh;
- }
-
- // Check bone changes
- var sourceBones = source.bones;
- int newBoneCount = sourceBones.Length;
- int oldBoneCount = cachedBoneCounts[i];
- if (newBoneCount == oldBoneCount)
- continue;
-
- var cloneBones = clone.bones; // expensive & allocates
- if (newBoneCount > oldBoneCount)
- {
- // Resize array and copy only the new bones (Magica Cloth appends bones when enabling Mesh Cloth)
- Array.Resize(ref cloneBones, newBoneCount);
- for (int boneIndex = oldBoneCount; boneIndex < newBoneCount; boneIndex++)
- cloneBones[boneIndex] = sourceBones[boneIndex];
- clone.bones = cloneBones;
- }
- else
- {
- // If shrinking, just set the whole array
- clone.bones = sourceBones;
- }
-
- cachedBoneCounts[i] = newBoneCount;
- }
-
- s_CopyMeshes.End();
- }
-
- private static void CopyMaterialsAndProperties(
- Renderer source, Renderer clone,
- MaterialPropertyBlock propertyBlock,
- List mainMaterials,
- Material[] localMaterials)
- {
- s_CopyMaterials.Begin();
-
- source.GetSharedMaterials(mainMaterials);
-
- int matCount = mainMaterials.Count;
- bool hasChanged = false;
- for (var i = 0; i < matCount; i++)
- {
- if (ReferenceEquals(mainMaterials[i], localMaterials[i])) continue;
- localMaterials[i] = mainMaterials[i];
- hasChanged = true;
- }
- if (hasChanged) clone.sharedMaterials = localMaterials;
-
- source.GetPropertyBlock(propertyBlock);
- clone.SetPropertyBlock(propertyBlock);
-
- s_CopyMaterials.End();
- }
-
- private static void CopyBlendShapes(
- SkinnedMeshRenderer source,
- SkinnedMeshRenderer target,
- List blendShapeWeights)
- {
- s_CopyBlendShapes.Begin();
-
- int weightCount = blendShapeWeights.Count;
- for (var i = 0; i < weightCount; i++)
- {
- var weight = source.GetBlendShapeWeight(i);
- // ReSharper disable once CompareOfFloatsByEqualityOperator
- if (weight == blendShapeWeights[i]) continue; // Halves the work
- target.SetBlendShapeWeight(i, blendShapeWeights[i] = weight);
- }
-
- s_CopyBlendShapes.End();
- }
- #endregion Update Methods
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.Util.cs b/AvatarCloneTest/AvatarClone/AvatarClone.Util.cs
deleted file mode 100644
index c6fb033..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.Util.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using ABI_RC.Core;
-using ABI_RC.Core.Player;
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone
-{
- private static bool CameraRendersPlayerLocalLayer(Camera cam)
- => (cam.cullingMask & (1 << CVRLayers.PlayerLocal)) != 0;
-
- private static bool CameraRendersPlayerCloneLayer(Camera cam)
- => (cam.cullingMask & (1 << CVRLayers.PlayerClone)) != 0;
-
- private static bool IsUIInternalCamera(Camera cam)
- => cam == PlayerSetup.Instance.activeUiCam;
-
- private static bool IsRendererValid(Renderer renderer)
- => renderer && renderer.gameObject.activeInHierarchy;
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/AvatarClone.cs b/AvatarCloneTest/AvatarClone/AvatarClone.cs
deleted file mode 100644
index 88c8112..0000000
--- a/AvatarCloneTest/AvatarClone/AvatarClone.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-using UnityEngine;
-using UnityEngine.Rendering;
-
-namespace NAK.AvatarCloneTest;
-
-public partial class AvatarClone : MonoBehaviour
-{
- #region Unity Events
-
- private void Start()
- {
- InitializeCollections();
- InitializeRenderers();
- SetupMaterialsAndBlendShapes();
- CreateClones();
-
- InitializeExclusions();
- SetupMagicaClothSupport();
-
- Camera.onPreCull += MyOnPreRender;
- }
-
- private void OnDestroy()
- {
- Camera.onPreCull -= MyOnPreRender;
- }
-
- private void LateUpdate()
- {
- // Update all renderers with basic properties (Materials & BlendShapes)
- UpdateStandardRenderers();
- UpdateSkinnedRenderers();
-
- // Additional pass for renderers needing extra checks (Shared Mesh & Bone Changes)
- UpdateStandardRenderersWithChecks();
- UpdateSkinnedRenderersWithChecks();
- }
-
- private void MyOnPreRender(Camera cam)
- {
- s_MyOnPreRender.Begin();
-
- bool isOurUiCamera = IsUIInternalCamera(cam);
- bool rendersOurPlayerLayer = CameraRendersPlayerLocalLayer(cam);
- bool rendersOurCloneLayer = CameraRendersPlayerCloneLayer(cam);
-
- // Renders both player layers.
- // PlayerLocal will now act as a shadow caster, while PlayerClone will act as the actual head-hidden renderer.
- bool rendersBothPlayerLayers = rendersOurPlayerLayer && rendersOurCloneLayer;
- if (!_shadowsOnlyActive && rendersBothPlayerLayers)
- {
- s_SetShadowsOnly.Begin();
-
- int sourceCount = _allSourceRenderers.Count;
- var sourceRenderers = _allSourceRenderers;
- for (int i = 0; i < sourceCount; i++)
- {
- Renderer renderer = sourceRenderers[i];
- if (!IsRendererValid(renderer)) continue;
-
- bool shouldRender = renderer.shadowCastingMode != ShadowCastingMode.Off;
- _originallyWasEnabled[i] = renderer.enabled;
- _originallyHadShadows[i] = shouldRender;
- renderer.shadowCastingMode = ShadowCastingMode.ShadowsOnly;
- if (renderer.forceRenderingOff == shouldRender) renderer.forceRenderingOff = !shouldRender; // TODO: Eval if check is needed
- }
- _shadowsOnlyActive = true;
-
- s_SetShadowsOnly.End();
- }
- else if (_shadowsOnlyActive && !rendersBothPlayerLayers)
- {
- s_UndoShadowsOnly.Begin();
-
- int sourceCount = _allSourceRenderers.Count;
- var sourceRenderers = _allSourceRenderers;
- for (int i = 0; i < sourceCount; i++)
- {
- Renderer renderer = sourceRenderers[i];
- if (!IsRendererValid(renderer)) continue;
-
- renderer.shadowCastingMode = _originallyHadShadows[i] ? ShadowCastingMode.On : ShadowCastingMode.Off;
- if (renderer.forceRenderingOff == _originallyWasEnabled[i]) renderer.forceRenderingOff = !_originallyWasEnabled[i]; // TODO: Eval if check is needed
- }
- _shadowsOnlyActive = false;
-
- s_UndoShadowsOnly.End();
- }
-
- // Handle UI culling material changes
- if (isOurUiCamera && !_uiCullingActive && rendersOurCloneLayer)
- {
- s_SetUiCulling.Begin();
-
- int standardCount = _standardRenderers.Count;
- var standardClones = _standardClones;
- var cullingMaterials = _cullingMaterials;
- for (int i = 0; i < standardCount; i++)
- standardClones[i].sharedMaterials = cullingMaterials[i];
-
- int skinnedCount = _skinnedRenderers.Count;
- var skinnedClones = _skinnedClones;
- for (int i = 0; i < skinnedCount; i++)
- skinnedClones[i].sharedMaterials = cullingMaterials[i + standardCount];
-
- _uiCullingActive = true;
-
- s_SetUiCulling.End();
- }
- else if (!isOurUiCamera && _uiCullingActive)
- {
- s_UndoUiCulling.Begin();
-
- int standardCount = _standardRenderers.Count;
- var standardClones = _standardClones;
- var localMaterials = _localMaterials;
- for (int i = 0; i < standardCount; i++)
- standardClones[i].sharedMaterials = localMaterials[i];
-
- int skinnedCount = _skinnedRenderers.Count;
- var skinnedClones = _skinnedClones;
- for (int i = 0; i < skinnedCount; i++)
- skinnedClones[i].sharedMaterials = localMaterials[i + standardCount];
-
- _uiCullingActive = false;
-
- s_UndoUiCulling.End();
- }
-
- s_MyOnPreRender.End();
- }
-
- #endregion Unity Events
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarClone/FPRExclusion/AvatarCloneExclusion.cs b/AvatarCloneTest/AvatarClone/FPRExclusion/AvatarCloneExclusion.cs
deleted file mode 100644
index 5681761..0000000
--- a/AvatarCloneTest/AvatarClone/FPRExclusion/AvatarCloneExclusion.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using ABI.CCK.Components;
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public class AvatarCloneExclusion : IExclusionBehaviour
-{
- private readonly AvatarClone _cloneSystem;
- private readonly Transform _target;
- private Transform _shrinkBone;
-
- public bool isImmuneToGlobalState { get; set; }
-
- public AvatarCloneExclusion(AvatarClone cloneSystem, Transform target)
- {
- _cloneSystem = cloneSystem;
- _target = target;
- }
-
- public void UpdateExclusions(bool isShown, bool shrinkToZero)
- {
- Debug.Log($"[AvatarClone2] Updating exclusion for {_target.name}: isShown={isShown}, shrinkToZero={shrinkToZero}");
-
- if (_shrinkBone == null)
- {
- // Create shrink bone parented directly to target
- _shrinkBone = new GameObject($"{_target.name}_Shrink").transform;
- _shrinkBone.SetParent(_target, false);
- Debug.Log($"[AvatarClone2] Created shrink bone for {_target.name}");
- }
-
- // Set scale based on shrink mode
- _shrinkBone.localScale = shrinkToZero ? Vector3.zero : Vector3.positiveInfinity;
-
- // Let the clone system handle the update
- _cloneSystem.HandleExclusionUpdate(_target, _shrinkBone, isShown);
- }
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/AvatarCloneTest.csproj b/AvatarCloneTest/AvatarCloneTest.csproj
deleted file mode 100644
index 2e58669..0000000
--- a/AvatarCloneTest/AvatarCloneTest.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- LocalCloneFix
-
-
- TRACE;TRACE;
-
-
diff --git a/AvatarCloneTest/Main.cs b/AvatarCloneTest/Main.cs
deleted file mode 100644
index 21a34bf..0000000
--- a/AvatarCloneTest/Main.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using ABI_RC.Core;
-using MelonLoader;
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public class AvatarCloneTestMod : MelonMod
-{
- #region Melon Preferences
-
- private static readonly MelonPreferences_Category Category =
- MelonPreferences.CreateCategory(nameof(AvatarCloneTest));
-
- internal static readonly MelonPreferences_Entry EntryUseAvatarCloneTest =
- Category.CreateEntry("use_avatar_clone_test", true,
- "Use Avatar Clone", description: "Uses the Avatar Clone setup for the local avatar.");
-
- // internal static readonly MelonPreferences_Entry EntryCopyBlendShapes =
- // Category.CreateEntry("copy_blend_shapes", true,
- // "Copy Blend Shapes", description: "Copies the blend shapes from the original avatar to the clone.");
- //
- // internal static readonly MelonPreferences_Entry EntryCopyMaterials =
- // Category.CreateEntry("copy_materials", true,
- // "Copy Materials", description: "Copies the materials from the original avatar to the clone.");
- //
- // internal static readonly MelonPreferences_Entry EntryCopyMeshes =
- // Category.CreateEntry("copy_meshes", true,
- // "Copy Meshes", description: "Copies the meshes from the original avatar to the clone.");
-
- #endregion Melon Preferences
-
- #region Melon Events
-
- public override void OnInitializeMelon()
- {
- ApplyPatches(typeof(Patches)); // slapped together a fix cause HarmonyInstance.Patch was null ref for no reason?
- }
-
- public override void OnUpdate()
- {
- // press f1 to find all cameras that arent tagged main and set them tno not render CVRLayers.PlayerClone
- if (Input.GetKeyDown(KeyCode.F1))
- {
- foreach (var camera in UnityEngine.Object.FindObjectsOfType())
- {
- if (camera.tag != "MainCamera")
- {
- camera.cullingMask &= ~(1 << CVRLayers.PlayerClone);
- }
- }
- }
- }
-
- #endregion Melon Events
-
- #region Melon Mod Utilities
-
- private void ApplyPatches(Type type)
- {
- try
- {
- HarmonyInstance.PatchAll(type);
- }
- catch (Exception e)
- {
- LoggerInstance.Msg($"Failed while patching {type.Name}!");
- LoggerInstance.Error(e);
- }
- }
-
- #endregion Melon Mod Utilities
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/Patches.cs b/AvatarCloneTest/Patches.cs
deleted file mode 100644
index b4cec17..0000000
--- a/AvatarCloneTest/Patches.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using ABI_RC.Core;
-using ABI_RC.Core.Player;
-using ABI_RC.Core.Player.TransformHider;
-using ABI_RC.Core.Savior;
-using ABI_RC.Systems.Camera;
-using HarmonyLib;
-using UnityEngine;
-
-namespace NAK.AvatarCloneTest;
-
-public static class Patches
-{
- [HarmonyPrefix]
- [HarmonyPatch(typeof(TransformHiderUtils), nameof(TransformHiderUtils.SetupAvatar))]
- private static bool OnSetupAvatar(GameObject avatar)
- {
- if (!AvatarCloneTestMod.EntryUseAvatarCloneTest.Value) return true;
- avatar.AddComponent();
- return false;
- }
-
- // [HarmonyPostfix]
- // [HarmonyPatch(typeof(FPRExclusion), nameof(FPRExclusion.UpdateExclusions))]
- // private static void OnUpdateExclusions(ref FPRExclusion __instance)
- // {
- // AvatarClone clone = PlayerSetup.Instance._avatar.GetComponent();
- // if (clone == null) return;
- // clone.SetBoneChainVisibility(__instance.target, !__instance.isShown, !__instance.shrinkToZero);
- // }
-
- [HarmonyPostfix]
- [HarmonyPatch(typeof(CVRMirror), nameof(CVRMirror.Start))]
- private static void OnMirrorStart(CVRMirror __instance)
- {
- if (!AvatarCloneTestMod.EntryUseAvatarCloneTest.Value)
- return;
-
- // Don't reflect the player clone layer
- __instance.m_ReflectLayers &= ~(1 << CVRLayers.PlayerClone);
- }
-
- [HarmonyPostfix]
- [HarmonyPatch(typeof(PlayerSetup), nameof(PlayerSetup.Update))]
- private static void OnTransformHiderManagerUpdate(PlayerSetup __instance)
- {
- if (!AvatarCloneTestMod.EntryUseAvatarCloneTest.Value)
- return;
-
- if (MetaPort.Instance.settings.GetSettingsBool("ExperimentalAvatarOverrenderUI"))
- __instance.activeUiCam.cullingMask |= 1 << CVRLayers.PlayerClone;
- else
- __instance.activeUiCam.cullingMask &= ~(1 << CVRLayers.PlayerClone);
- }
-
- private static bool _wasDebugInPortableCamera;
-
- [HarmonyPostfix]
- [HarmonyPatch(typeof(PortableCamera), nameof(PortableCamera.Update))]
- private static void OnPortableCameraUpdate(ref PortableCamera __instance)
- {
- if (!AvatarCloneTestMod.EntryUseAvatarCloneTest.Value)
- {
- // Show both PlayerLocal and PlayerClone
- __instance.cameraComponent.cullingMask |= 1 << CVRLayers.PlayerLocal;
- __instance.cameraComponent.cullingMask |= 1 << CVRLayers.PlayerClone;
- return;
- }
-
- if (TransformHiderManager.s_DebugInPortableCamera == _wasDebugInPortableCamera)
- return;
-
- if (TransformHiderManager.s_DebugInPortableCamera)
- {
- // Hide PlayerLocal, show PlayerClone
- __instance.cameraComponent.cullingMask &= ~(1 << CVRLayers.PlayerLocal);
- __instance.cameraComponent.cullingMask |= 1 << CVRLayers.PlayerClone;
- }
- else
- {
- // Show PlayerLocal, hide PlayerClone
- __instance.cameraComponent.cullingMask |= 1 << CVRLayers.PlayerLocal;
- __instance.cameraComponent.cullingMask &= ~(1 << CVRLayers.PlayerClone);
- }
-
- _wasDebugInPortableCamera = TransformHiderManager.s_DebugInPortableCamera;
- }
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/Properties/AssemblyInfo.cs b/AvatarCloneTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3334b28..0000000
--- a/AvatarCloneTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using MelonLoader;
-using NAK.AvatarCloneTest.Properties;
-using System.Reflection;
-
-[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
-[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
-[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
-[assembly: AssemblyTitle(nameof(NAK.AvatarCloneTest))]
-[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
-[assembly: AssemblyProduct(nameof(NAK.AvatarCloneTest))]
-
-[assembly: MelonInfo(
- typeof(NAK.AvatarCloneTest.AvatarCloneTestMod),
- nameof(NAK.AvatarCloneTest),
- AssemblyInfoParams.Version,
- AssemblyInfoParams.Author,
- downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/AvatarCloneTest"
-)]
-
-[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
-[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
-[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
-[assembly: MelonColor(255, 246, 25, 99)] // red-pink
-[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
-[assembly: HarmonyDontPatchAll]
-
-namespace NAK.AvatarCloneTest.Properties;
-internal static class AssemblyInfoParams
-{
- public const string Version = "1.0.0";
- public const string Author = "NotAKidoS";
-}
\ No newline at end of file
diff --git a/AvatarCloneTest/README.md b/AvatarCloneTest/README.md
deleted file mode 100644
index cc12a9c..0000000
--- a/AvatarCloneTest/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# VisualCloneFix
-
-Fixes the Visual Clone system and allows you to use it again.
-
-Using the Visual Clone should be faster than the default Head Hiding & Shadow Clones, but will add a longer hitch on initial avatar load.
-
-**NOTE:** The Visual Clone is still an experimental feature that was temporarily removed in [ChilloutVR 2024r175 Hotfix 1](https://abinteractive.net/blog/chilloutvr_2024r175_hotfix_1), so there may be bugs or issues with it.
-
----
-
-Here is the block of text where I tell you this mod is not affiliated with or endorsed by ABI.
-https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
-
-> This mod is an independent creation not affiliated with, supported by, or approved by Alpha Blend Interactive.
-
-> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
-
-> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
diff --git a/AvatarCloneTest/format.json b/AvatarCloneTest/format.json
deleted file mode 100644
index 6634e9f..0000000
--- a/AvatarCloneTest/format.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "_id": 221,
- "name": "VisualCloneFix",
- "modversion": "1.0.1",
- "gameversion": "2024r175",
- "loaderversion": "0.6.1",
- "modtype": "Mod",
- "author": "NotAKidoS",
- "description": "Fixes the Visual Clone system and allows you to use it again.\n\nUsing the Visual Clone should be faster than the default Head Hiding & Shadow Clones, but will add a longer hitch on initial avatar load.\n\n**NOTE:** The Visual Clone is still an experimental feature that was temporarily removed in [ChilloutVR 2024r175 Hotfix 1](https://abinteractive.net/blog/chilloutvr_2024r175_hotfix_1), so there may be bugs or issues with it.",
- "searchtags": [
- "visual",
- "clone",
- "head",
- "hiding"
- ],
- "requirements": [
- "None"
- ],
- "downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r36/VisualCloneFix.dll",
- "sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/VisualCloneFix/",
- "changelog": "- Fixed FPRExclusions IsShown state being inverted when toggled.\n- Fixed head FPRExclusion generation not checking for existing exclusion.\n- Sped up FindExclusionVertList by 100x by not being an idiot. This heavily reduces avatar hitch with Visual Clone active.",
- "embedcolor": "#f61963"
-}
\ No newline at end of file