您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
445 行
13 KiB
445 行
13 KiB
using System;
|
|
using UnityEngine;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
|
|
namespace Unity.DemoTeam.DigitalHuman
|
|
{
|
|
public abstract class SnappersHeadDefinition : ScriptableObject
|
|
{
|
|
public struct InstanceData
|
|
{
|
|
public SnappersHeadDefinition definition;//TODO replace with hash
|
|
public Mesh sourceMesh;
|
|
public Transform sourceRig;
|
|
public Transform[] rigTransforms;
|
|
public SnappersController[] rigControllers;
|
|
public int blendShapeCount;
|
|
public int[] blendShapeIndices;
|
|
public float[] blendShapeWeights;
|
|
public float[] shaderParamFloats;
|
|
}
|
|
|
|
public abstract InstanceData CreateInstanceData(Mesh sourceMesh, Transform sourceRig, Warnings warnings);
|
|
public abstract unsafe void ResolveControllers(void* ptrSnappersControllers, void* ptrSnappersBlendShapes, void* ptrSnappersShaderParam);
|
|
public abstract unsafe void ResolveBlendShapes(void* ptrSnappersControllers, void* ptrSnappersBlendShapes, void* ptrSnappersShaderParam);
|
|
public abstract unsafe void ResolveShaderParam(void* ptrSnappersControllers, void* ptrSnappersBlendShapes, void* ptrSnappersShaderParam);
|
|
public abstract unsafe void InitializeControllerCaps(void* ptrSnappersControllers);
|
|
|
|
[Flags]
|
|
public enum Warnings : int
|
|
{
|
|
None = 0,
|
|
MissingTransforms = 1 << 0,
|
|
MissingBlendShapes = 1 << 1,
|
|
}
|
|
|
|
public InstanceData CreateInstanceData<NamedControllers, NamedBlendShapes>(Mesh sourceMesh, Transform sourceRig, Warnings warnings) where NamedControllers : struct where NamedBlendShapes : struct
|
|
{
|
|
var meshName = sourceMesh.name;
|
|
if (meshName.EndsWith(MeshInstanceBehaviour.meshInstanceSuffix))
|
|
meshName = meshName.Substring(0, meshName.IndexOf(MeshInstanceBehaviour.meshInstanceSuffix));
|
|
|
|
var blendShapePrefix = meshName + "_blendShape.";
|
|
var blendShapeNames = typeof(NamedBlendShapes).GetFields();
|
|
|
|
var controllerPrefix = string.Empty;
|
|
var controllerNames = typeof(NamedControllers).GetFields();
|
|
|
|
InstanceData instanceData;
|
|
instanceData.definition = this;
|
|
instanceData.sourceMesh = sourceMesh;
|
|
instanceData.sourceRig = sourceRig;
|
|
instanceData.rigTransforms = new Transform[controllerNames.Length];
|
|
instanceData.rigControllers = new SnappersController[controllerNames.Length];
|
|
instanceData.blendShapeCount = sourceMesh.blendShapeCount;
|
|
instanceData.blendShapeIndices = new int[blendShapeNames.Length];
|
|
instanceData.blendShapeWeights = new float[blendShapeNames.Length];
|
|
instanceData.shaderParamFloats = new float[UnsafeUtility.SizeOf<SnappersShaderParam>() / sizeof(float)];
|
|
|
|
//Debug.Log("CreateInstanceData for " + sourceMesh + " (blendShapePrefix = " + blendShapePrefix + ")");
|
|
|
|
unsafe
|
|
{
|
|
fixed (void* ptrSnappersControllers = instanceData.rigControllers)
|
|
{
|
|
InitializeControllerCaps(ptrSnappersControllers);
|
|
}
|
|
}
|
|
|
|
if (sourceRig != null)
|
|
{
|
|
for (int i = 0; i != controllerNames.Length; i++)
|
|
{
|
|
var transform = FindRecursive(sourceRig, controllerPrefix + controllerNames[i].Name);
|
|
if (transform != null)
|
|
instanceData.rigTransforms[i] = transform;
|
|
else if (warnings.HasFlag(Warnings.MissingTransforms))
|
|
Debug.LogWarningFormat("rig definition {0} targets transform not present in linked rig: {1}", this.name, controllerPrefix + controllerNames[i].Name);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i != blendShapeNames.Length; i++)
|
|
{
|
|
int blendShapeIndex = sourceMesh.GetBlendShapeIndex(blendShapePrefix + blendShapeNames[i].Name);
|
|
if (blendShapeIndex != -1)
|
|
instanceData.blendShapeIndices[i] = blendShapeIndex;
|
|
else if (warnings.HasFlag(Warnings.MissingBlendShapes))
|
|
Debug.LogWarningFormat("rig definition {0} targets blend shape not present in linked mesh: {1}", this.name, blendShapePrefix + blendShapeNames[i].Name);
|
|
}
|
|
|
|
return instanceData;
|
|
}
|
|
|
|
static Transform FindRecursive(Transform transform, string name)
|
|
{
|
|
if (transform.name == name)
|
|
{
|
|
return transform;
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i != transform.childCount; i++)
|
|
{
|
|
var child = transform.GetChild(i);
|
|
var childResult = FindRecursive(child, name);
|
|
if (childResult != null)
|
|
return childResult;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void PrepareInstance(ref InstanceData instanceData, SkinnedMeshRenderer smr, Transform sourceRig, Warnings warnings)
|
|
{
|
|
var inputsPossiblyChanged = false;
|
|
{
|
|
inputsPossiblyChanged |= (instanceData.definition != this);
|
|
inputsPossiblyChanged |= (instanceData.sourceMesh != smr.sharedMesh);
|
|
inputsPossiblyChanged |= (instanceData.sourceRig != sourceRig);
|
|
inputsPossiblyChanged |= (instanceData.blendShapeCount != smr.sharedMesh.blendShapeCount);
|
|
}
|
|
if (inputsPossiblyChanged)
|
|
{
|
|
instanceData = CreateInstanceData(smr.sharedMesh, sourceRig, warnings);
|
|
}
|
|
}
|
|
|
|
public void ResolveControllers(ref InstanceData instanceData)
|
|
{
|
|
const float mul_100 = 100.0f;
|
|
for (int i = 0; i != instanceData.rigTransforms.Length; i++)
|
|
{
|
|
var rigTransform = instanceData.rigTransforms[i];
|
|
if (rigTransform != null)
|
|
{
|
|
Vector3 localPos = rigTransform.localPosition;
|
|
Vector3 localRot = rigTransform.localRotation.eulerAngles;
|
|
Vector3 localMul = rigTransform.localScale;
|
|
|
|
instanceData.rigControllers[i].translateX = localPos.x * mul_100 * -1.0f;// flip
|
|
instanceData.rigControllers[i].translateY = localPos.y * mul_100;
|
|
instanceData.rigControllers[i].translateZ = localPos.z * mul_100;
|
|
|
|
instanceData.rigControllers[i].rotateX = localRot.x * -1.0f;
|
|
instanceData.rigControllers[i].rotateY = localRot.y;
|
|
instanceData.rigControllers[i].rotateZ = localRot.z;
|
|
|
|
instanceData.rigControllers[i].scaleX = localMul.x;
|
|
instanceData.rigControllers[i].scaleY = localMul.y;
|
|
instanceData.rigControllers[i].scaleZ = localMul.z;
|
|
}
|
|
//else
|
|
//{
|
|
// Debug.LogError("bad transform index: " + i);
|
|
//}
|
|
}
|
|
|
|
unsafe
|
|
{
|
|
fixed (void* ptrSnappersControllers = instanceData.rigControllers)
|
|
fixed (void* ptrSnappersBlendShapes = instanceData.blendShapeWeights)
|
|
fixed (void* ptrSnappersShaderParam = instanceData.shaderParamFloats)
|
|
{
|
|
ResolveControllers(ptrSnappersControllers, ptrSnappersBlendShapes, ptrSnappersShaderParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ResolveBlendShapes(ref InstanceData instanceData, SkinnedMeshRenderer smr)
|
|
{
|
|
const float rcp_100 = 1.0f / 100.0f;
|
|
for (int i = 0; i != instanceData.blendShapeIndices.Length; i++)
|
|
{
|
|
int blendShapeIndex = instanceData.blendShapeIndices[i];
|
|
if (blendShapeIndex != -1)
|
|
{
|
|
instanceData.blendShapeWeights[i] = smr.GetBlendShapeWeight(blendShapeIndex) * rcp_100;
|
|
}
|
|
//else
|
|
//{
|
|
// Debug.LogError("bad blendshape index: " + blendShapeIndex);
|
|
//}
|
|
}
|
|
|
|
unsafe
|
|
{
|
|
fixed (void* ptrSnappersControllers = instanceData.rigControllers)
|
|
fixed (void* ptrSnappersBlendShapes = instanceData.blendShapeWeights)
|
|
fixed (void* ptrSnappersShaderParam = instanceData.shaderParamFloats)
|
|
{
|
|
ResolveBlendShapes(ptrSnappersControllers, ptrSnappersBlendShapes, ptrSnappersShaderParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ResolveShaderParam(ref InstanceData instanceData)
|
|
{
|
|
unsafe
|
|
{
|
|
fixed (void* ptrSnappersControllers = instanceData.rigControllers)
|
|
fixed (void* ptrSnappersBlendShapes = instanceData.blendShapeWeights)
|
|
fixed (void* ptrSnappersShaderParam = instanceData.shaderParamFloats)
|
|
{
|
|
ResolveShaderParam(ptrSnappersControllers, ptrSnappersBlendShapes, ptrSnappersShaderParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void ResetShaderParam(ref InstanceData instanceData)
|
|
{
|
|
ArrayUtils.ClearChecked(instanceData.shaderParamFloats);
|
|
}
|
|
|
|
public static void ApplyControllers(ref InstanceData instanceData)
|
|
{
|
|
const float rcp_100 = 1.0f / 100.0f;
|
|
for (int i = 0; i != instanceData.rigTransforms.Length; i++)
|
|
{
|
|
var rigTransform = instanceData.rigTransforms[i];
|
|
if (rigTransform != null)
|
|
{
|
|
Vector3 localPos;
|
|
Vector3 localRot;
|
|
Vector3 localMul;
|
|
|
|
localPos.x = instanceData.rigControllers[i].translateX * rcp_100 * -1.0f;// flip
|
|
localPos.y = instanceData.rigControllers[i].translateY * rcp_100;
|
|
localPos.z = instanceData.rigControllers[i].translateZ * rcp_100;
|
|
|
|
localRot.x = instanceData.rigControllers[i].rotateX * -1.0f;
|
|
localRot.y = instanceData.rigControllers[i].rotateY;
|
|
localRot.z = instanceData.rigControllers[i].rotateZ;
|
|
|
|
localMul.x = instanceData.rigControllers[i].scaleX;
|
|
localMul.y = instanceData.rigControllers[i].scaleY;
|
|
localMul.z = instanceData.rigControllers[i].scaleZ;
|
|
|
|
rigTransform.localPosition = localPos;
|
|
rigTransform.localRotation = Quaternion.Euler(localRot);
|
|
rigTransform.localScale = localMul;
|
|
}
|
|
//else
|
|
//{
|
|
// Debug.LogError("bad transform index: " + i);
|
|
//}
|
|
}
|
|
}
|
|
|
|
public static void ApplyBlendShapes(ref InstanceData instanceData, SkinnedMeshRenderer smr)
|
|
{
|
|
const float mul_100 = 100.0f;
|
|
for (int i = 0; i != instanceData.blendShapeIndices.Length; i++)
|
|
{
|
|
int blendShapeIndex = instanceData.blendShapeIndices[i];
|
|
if (blendShapeIndex != -1)
|
|
{
|
|
smr.SetBlendShapeWeight(blendShapeIndex, instanceData.blendShapeWeights[i] * mul_100);
|
|
}
|
|
//else
|
|
//{
|
|
// Debug.LogError("bad blendshape index: " + blendShapeIndex);
|
|
//}
|
|
}
|
|
}
|
|
|
|
public static void ApplyShaderParam(ref InstanceData instanceData, MaterialPropertyBlock smrProps)
|
|
{
|
|
smrProps.SetFloatArray("_SnappersMaskParams", instanceData.shaderParamFloats);
|
|
}
|
|
}
|
|
|
|
public struct SnappersController
|
|
{
|
|
public float translateX;
|
|
public float translateY;
|
|
public float translateZ;
|
|
|
|
public float rotateX;
|
|
public float rotateY;
|
|
public float rotateZ;
|
|
|
|
public float scaleX;
|
|
public float scaleY;
|
|
public float scaleZ;
|
|
|
|
public SnappersControllerCaps caps;
|
|
}
|
|
|
|
[Flags]
|
|
public enum SnappersControllerCaps : uint
|
|
{
|
|
none = 0,
|
|
|
|
translateX = 1 << 0,
|
|
translateY = 1 << 1,
|
|
translateZ = 1 << 2,
|
|
|
|
rotateX = 1 << 3,
|
|
rotateY = 1 << 4,
|
|
rotateZ = 1 << 5,
|
|
|
|
scaleX = 1 << 6,
|
|
scaleY = 1 << 7,
|
|
scaleZ = 1 << 8,
|
|
}
|
|
|
|
public struct SnappersShaderParam
|
|
{
|
|
public float Mask1;
|
|
public float Mask2;
|
|
public float Mask3;
|
|
public float Mask4;
|
|
public float Mask5;
|
|
public float Mask6;
|
|
public float Mask7;
|
|
public float Mask8;
|
|
public float Mask9;
|
|
public float Mask10;
|
|
public float Mask11;
|
|
public float Mask12;
|
|
public float Mask13;
|
|
public float Mask14;
|
|
public float Mask15;
|
|
public float Mask16;
|
|
public float Mask17;
|
|
public float Mask18;
|
|
public float Mask19;
|
|
public float Mask20;
|
|
public float Mask21;
|
|
public float Mask22;
|
|
public float Mask23;
|
|
public float Mask24;
|
|
public float Mask25;
|
|
public float Mask26;
|
|
public float Mask27;
|
|
public float Mask28;
|
|
public float Mask29;
|
|
public float Mask30;
|
|
public float Mask31;
|
|
public float Mask32;
|
|
public float Mask33;
|
|
public float Mask34;
|
|
public float Mask35;
|
|
public float Mask36;
|
|
public float Mask37;
|
|
public float Mask38;
|
|
public float Mask39;
|
|
public float Mask40;
|
|
public float Mask41;
|
|
public float Mask42;
|
|
public float Mask43;
|
|
public float Mask44;
|
|
public float Mask45;
|
|
public float Mask46;
|
|
public float Mask47;
|
|
public float Mask48;
|
|
public float Mask49;
|
|
public float Mask50;
|
|
public float Mask51;
|
|
public float Mask52;
|
|
public float Mask53;
|
|
public float Mask54;
|
|
public float Mask55;
|
|
public float Mask56;
|
|
public float Mask57;
|
|
public float Mask58;
|
|
public float Mask59;
|
|
public float Mask60;
|
|
public float Mask61;
|
|
public float Mask62;
|
|
public float Mask63;
|
|
public float Mask64;
|
|
public float Mask65;
|
|
public float Mask66;
|
|
public float Mask67;
|
|
public float Mask68;
|
|
public float Mask69;
|
|
public float Mask70;
|
|
public float Mask71;
|
|
public float Mask72;
|
|
public float Mask73;
|
|
public float Mask74;
|
|
public float Mask75;
|
|
public float Mask76;
|
|
public float Mask77;
|
|
public float Mask78;
|
|
public float Mask79;
|
|
public float Mask80;
|
|
public float Mask81;
|
|
public float Mask82;
|
|
public float Mask83;
|
|
public float Mask84;
|
|
public float Mask85;
|
|
public float Mask86;
|
|
public float Mask87;
|
|
public float Mask88;
|
|
public float Mask89;
|
|
public float Mask90;
|
|
public float Mask91;
|
|
public float Mask92;
|
|
public float Mask93;
|
|
public float Mask94;
|
|
public float Mask95;
|
|
public float Mask96;
|
|
public float Mask97;
|
|
public float Mask98;
|
|
public float Mask99;
|
|
public float Mask100;
|
|
public float Mask101;
|
|
public float Mask102;
|
|
public float Mask103;
|
|
public float Mask104;
|
|
public float Mask105;
|
|
public float Mask106;
|
|
public float Mask107;
|
|
public float Mask108;
|
|
public float Mask109;
|
|
public float Mask110;
|
|
public float Mask111;
|
|
public float Mask112;
|
|
public float Mask113;
|
|
public float Mask114;
|
|
public float Mask115;
|
|
public float Mask116;
|
|
public float Mask117;
|
|
public float Mask118;
|
|
public float Mask119;
|
|
public float Mask120;
|
|
public float Mask121;
|
|
public float Mask122;
|
|
public float Mask123;
|
|
public float Mask124;
|
|
public float Mask125;
|
|
public float Mask126;
|
|
public float Mask127;
|
|
public float Mask128;
|
|
public float Mask129;
|
|
public float Mask130;
|
|
public float Mask131;
|
|
public float Mask132;
|
|
public float Mask133;
|
|
public float Mask134;
|
|
public float Mask135;
|
|
}
|
|
}
|