mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 22:39:22 +00:00
AvatarCloneTest: push so i can reference in an email
This commit is contained in:
parent
6d30fe1f41
commit
3660b8f683
16 changed files with 1155 additions and 0 deletions
181
AvatarCloneTest/AvatarClone/AvatarClone.Update.cs
Normal file
181
AvatarCloneTest/AvatarClone/AvatarClone.Update.cs
Normal file
|
@ -0,0 +1,181 @@
|
|||
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<Material> 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<float> 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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue