浏览代码

fix visual glitch caused by attachment gizmos (enabling "root lines" caused starting index to be overwritten in subject), add dirty flag to root transform when using the revert transform hierarchy utility, add option in the head importer to also compact the imported rig

/main
Lasse Jon Fuglsang Pedersen 4 年前
当前提交
25fe33aa
共有 9 个文件被更改,包括 454 次插入182 次删除
  1. 3
      Editor/EyeRendererEditor.cs
  2. 5
      Editor/SnappersHeadImporterEditor.cs
  3. 1
      Editor/Utility/PrefabTransformHierarchyEditor.cs
  4. 20
      Runtime/SkinAttachment.cs
  5. 65
      Runtime/SkinAttachmentDataBuilder.cs
  6. 2
      Runtime/SkinDeformationClip.cs
  7. 492
      Runtime/SnappersHeadImporter.cs
  8. 37
      Runtime/SnappersHeadDefinitionMath.cs
  9. 11
      Runtime/SnappersHeadDefinitionMath.cs.meta

3
Editor/EyeRendererEditor.cs


if (eye == null)
return;
DrawEyeHandles(eye);
if (eye.coneDebug == false)
DrawEyeHandles(eye);
}
void DrawEyeHandles(EyeRenderer eye)

5
Editor/SnappersHeadImporterEditor.cs


{
const string ASSETS_STRING = @"The following files will be written:
{0}_SnappersBlendShapes.cs
{0}_SnappersControllers.cs
{0}_SnappersControllers.cs
{0}_SnappersBlendShapes.cs
{0}_SnappersHeadImpl.cs
(and overwritten if they already exist)";

1
Editor/Utility/PrefabTransformHierarchyEditor.cs


}
EditorUtility.ClearProgressBar();
EditorUtility.SetDirty(root);
}
}
}

20
Runtime/SkinAttachment.cs


var d = Vector3.Dot(target.meshBuffers.vertexNormals[closestNode], r);
var c = (d >= 0.0f) ? Color.cyan : Color.magenta;
Gizmos.color = Color.Lerp(Color.clear, c, 0.75f);
Gizmos.color = Color.Lerp(Color.clear, c, 0.25f);
Gizmos.DrawSphere(targetLocalPos, Mathf.Sqrt(closestDist));
Gizmos.color = Color.Lerp(Color.clear, c, 0.75f);

{
for (int island = 0; island != meshIslands.islandCount; island++)
{
Gizmos.color = Color.Lerp(Color.clear, debugColors[island % debugColors.Length], 0.3f);
Gizmos.color = Color.Lerp(Color.clear, debugColors[island % debugColors.Length], 0.5f);
foreach (var i in meshIslands.islandVertices[island])
{
foreach (var j in meshAdjacency.vertexVertices[i])

int dryRunPoseCount = -1;
int dryRunItemCount = -1;
SkinAttachmentDataBuilder.BuildDataAttachSubject(ref debugData, target.transform, target.GetCachedMeshInfo(), this, dryRun: true, ref dryRunPoseCount, ref dryRunItemCount);
SkinAttachmentDataBuilder.BuildDataAttachSubjectReadOnly(ref debugData, target.transform, target.GetCachedMeshInfo(), this, dryRun: true, ref dryRunPoseCount, ref dryRunItemCount);
SkinAttachmentDataBuilder.BuildDataAttachSubject(ref debugData, target.transform, target.GetCachedMeshInfo(), this, dryRun: false, ref dryRunPoseCount, ref dryRunItemCount);
SkinAttachmentDataBuilder.BuildDataAttachSubjectReadOnly(ref debugData, target.transform, target.GetCachedMeshInfo(), this, dryRun: false, ref dryRunPoseCount, ref dryRunItemCount);
Matrix4x4 targetToWorld = Matrix4x4.TRS(target.transform.position, target.transform.rotation, Vector3.one);
// NOTE: targetToWorld specifically excludes scale, since source data (BakeMesh) is already scaled

targetToSubject = this.transform.worldToLocalMatrix * targetToWorld;
}
Gizmos.color = Color.white;
for (int i = 0; i != meshBuffers.vertexCount; i++)
for (int island = 0; island != meshIslands.islandCount; island++)
Vector3 rootOffset = targetToSubject.MultiplyVector(-debugData.item[i].targetOffset);
Gizmos.DrawRay(subjectPositions[i], rootOffset);
Gizmos.color = Color.Lerp(Color.clear, debugColors[island % debugColors.Length], 0.5f);
foreach (var i in meshIslands.islandVertices[island])
{
Vector3 rootOffset = targetToSubject.MultiplyVector(-debugData.item[i].targetOffset);
Gizmos.DrawRay(subjectPositions[i], rootOffset);
}
}
}
}

65
Runtime/SkinAttachmentDataBuilder.cs


}
}
public static void BuildDataAttachSubject(ref SkinAttachmentData attachData, Transform target, in MeshInfo meshInfo, SkinAttachment subject, bool dryRun, ref int dryRunPoseCount, ref int dryRunItemCount)
public static unsafe void BuildDataAttachSubject(ref SkinAttachmentData attachData, int* attachmentIndex, int* attachmentCount, Transform target, in MeshInfo meshInfo, SkinAttachment subject, bool dryRun, ref int dryRunPoseCount, ref int dryRunItemCount)
{
Matrix4x4 subjectToTarget;
{

switch (subject.attachmentType)
{
case SkinAttachment.AttachmentType.Transform:
unsafe
fixed (int* attachmentIndex = &subject.attachmentIndex)
fixed (int* attachmentCount = &subject.attachmentCount)
{
if (dryRun)
CountDataAttachToClosestVertex(ref dryRunPoseCount, ref dryRunItemCount, meshInfo, &targetPosition, &targetNormal, 1);
else
BuildDataAttachToClosestVertex(attachData, attachmentIndex, attachmentCount, meshInfo, &targetPosition, &targetNormal, 1);
}
if (dryRun)
CountDataAttachToClosestVertex(ref dryRunPoseCount, ref dryRunItemCount, meshInfo, &targetPosition, &targetNormal, 1);
else
BuildDataAttachToClosestVertex(attachData, attachmentIndex, attachmentCount, meshInfo, &targetPosition, &targetNormal, 1);
unsafe
{
if (subject.meshInstance == null)
break;

targetNormals.val[i] = subjectToTarget.MultiplyVector(subjectNormals[i]);
}
fixed (int* attachmentIndex = &subject.attachmentIndex)
fixed (int* attachmentCount = &subject.attachmentCount)
{
if (dryRun)
CountDataAttachToClosestVertex(ref dryRunPoseCount, ref dryRunItemCount, meshInfo, targetPositions.val, targetNormals.val, subjectVertexCount);
else
BuildDataAttachToClosestVertex(attachData, attachmentIndex, attachmentCount, meshInfo, targetPositions.val, targetNormals.val, subjectVertexCount);
}
if (dryRun)
CountDataAttachToClosestVertex(ref dryRunPoseCount, ref dryRunItemCount, meshInfo, targetPositions.val, targetNormals.val, subjectVertexCount);
else
BuildDataAttachToClosestVertex(attachData, attachmentIndex, attachmentCount, meshInfo, targetPositions.val, targetNormals.val, subjectVertexCount);
unsafe
{
if (subject.meshInstance == null)
break;

targetVertices.val[i] = rootIdx.val[i];
}
fixed (int* attachmentIndex = &subject.attachmentIndex)
fixed (int* attachmentCount = &subject.attachmentCount)
{
if (dryRun)
CountDataAttachToVertex(ref dryRunPoseCount, ref dryRunItemCount, meshInfo, targetPositions.val, targetOffsets.val, targetNormals.val, targetVertices.val, subjectVertexCount);
else
BuildDataAttachToVertex(attachData, attachmentIndex, attachmentCount, meshInfo, targetPositions.val, targetOffsets.val, targetNormals.val, targetVertices.val, subjectVertexCount);
}
if (dryRun)
CountDataAttachToVertex(ref dryRunPoseCount, ref dryRunItemCount, meshInfo, targetPositions.val, targetOffsets.val, targetNormals.val, targetVertices.val, subjectVertexCount);
else
BuildDataAttachToVertex(attachData, attachmentIndex, attachmentCount, meshInfo, targetPositions.val, targetOffsets.val, targetNormals.val, targetVertices.val, subjectVertexCount);
}
}
public static void BuildDataAttachSubject(ref SkinAttachmentData attachData, Transform target, in MeshInfo meshInfo, SkinAttachment subject, bool dryRun, ref int dryRunPoseCount, ref int dryRunItemCount)
{
unsafe
{
fixed (int* attachmentIndex = &subject.attachmentIndex)
fixed (int* attachmentCount = &subject.attachmentCount)
{
BuildDataAttachSubject(ref attachData, attachmentIndex, attachmentCount, target, meshInfo, subject, dryRun, ref dryRunPoseCount, ref dryRunItemCount);
}
}
}
public static void BuildDataAttachSubjectReadOnly(ref SkinAttachmentData attachData, Transform target, in MeshInfo meshInfo, SkinAttachment subject, bool dryRun, ref int dryRunPoseCount, ref int dryRunItemCount)
{
unsafe
{
int attachmentIndex = 0;
int attachmentCount = 0;
{
BuildDataAttachSubject(ref attachData, &attachmentIndex, &attachmentCount, target, meshInfo, subject, dryRun, ref dryRunPoseCount, ref dryRunItemCount);
}
}
}
}

2
Runtime/SkinDeformationClip.cs


public Vector3 applyRotation = Vector3.zero;
public float applyScale = 1.0f;
[Header("Mesh differential processing")]
[Header("Mesh processing")]
[Tooltip("Regions are specified in text files. Each file should contain an array of vertex indices on the form: [i, j, k, ...]")]
public TextAsset[] denoiseRegions;
[Range(0.0f, 1.0f)]

492
Runtime/SnappersHeadImporter.cs


using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

[Header("Output settings")]
public string csClassPrefix = "MyCharacter";
public string csNamespace = "MyNamespace";
public bool csCompacted = true;
const string compactedControllers = "a";
const string compactedBlendShapes = "b";
const string compactedShaderParam = "c";
#if UNITY_EDITOR
[ContextMenu("Generate")]

var includedBlendShapes = new HashSet<string>();
var includedShaderParam = new HashSet<string>();
// generate the evaluation functions
var indicesControllers = new Dictionary<string, int>();
var indicesBlendShapes = new Dictionary<string, int>();
var indicesShaderParam = new Dictionary<string, int>();
// discover data members
GenerateEvaluationFunctions(scriptsResolveControllers, scriptsResolveBlendShapes, scriptsResolveShaderParam, includedControllers, includedBlendShapes, includedShaderParam);
DiscoverDataMembers(scriptsResolveControllers, includedControllers, includedBlendShapes, includedShaderParam, skipCaps: true);
DiscoverDataMembers(scriptsResolveBlendShapes, includedControllers, includedBlendShapes, includedShaderParam, skipCaps: false);
DiscoverDataMembers(scriptsResolveShaderParam, includedControllers, includedBlendShapes, includedShaderParam, skipCaps: false);
// generate the data structures
// generate data structures
GenerateDataStructure("SnappersControllers", includedControllers.Keys);
GenerateDataStructure("SnappersBlendShapes", includedBlendShapes);
GenerateDataStructure("SnappersControllers", indicesControllers, includedControllers.Keys);
GenerateDataStructure("SnappersBlendShapes", indicesBlendShapes, includedBlendShapes);
GenerateDataStructureIndices<SnappersShaderParam>(indicesShaderParam);
}
// generate implementation
{
GenerateImplementation(scriptsResolveControllers, scriptsResolveBlendShapes, scriptsResolveShaderParam, includedControllers, indicesControllers, indicesBlendShapes, indicesShaderParam);
}
AssetDatabase.Refresh();

}
}
public void GenerateEvaluationFunctions(List<TextAsset> resolveControllers, List<TextAsset> resolveBlendShapes, List<TextAsset> resolveShaderParam, Dictionary<string, SnappersControllerCaps> includedControllers, HashSet<string> includedBlendShapes, HashSet<string> includedShaderParam)
public void DiscoverDataMembers(List<TextAsset> scripts, Dictionary<string, SnappersControllerCaps> includedControllers, HashSet<string> includedBlendShapes, HashSet<string> includedShaderParams, bool skipCaps)
{
foreach (var script in scripts)
{
if (script == null)
continue;
DiscoverDataMembers(script, includedControllers, includedBlendShapes, includedShaderParams, skipCaps);
}
}
public void DiscoverDataMembers(TextAsset script, Dictionary<string, SnappersControllerCaps> includedControllers, HashSet<string> includedBlendShapes, HashSet<string> includedShaderParams, bool skipCaps)
{
var regexMember = new Regex("([a-zA-Z_]+[\\w]*)\\.([a-zA-Z_]+[\\w]*)");
var inputPath = AssetDatabase.GetAssetPath(script);
var inputStream = new StreamReader(inputPath);
while (inputStream.EndOfStream == false)
{
var line = inputStream.ReadLine();
if (line.Length == 0)
continue;
// gather struct.member
var matches = regexMember.Matches(line);
{
// note: this needs to be kept in sync with GenerateEvaluationFunctionSegment
foreach (Match match in matches)
{
var nameStruct = match.Groups[1].Value;
var nameMember = match.Groups[2].Value;
if (nameStruct == namedBlendShapes)
{
includedBlendShapes.Add(nameMember);
}
else if (nameStruct == namedShaderParam)
{
includedShaderParams.Add(nameMember);
}
else
{
SnappersControllerCaps caps;
includedControllers.TryGetValue(nameStruct, out caps);
includedControllers[nameStruct] = caps | (skipCaps ? SnappersControllerCaps.none : TranslateControllerField(nameMember));
}
}
}
}
inputStream.Close();
}
public void GenerateDataStructure(string name, Dictionary<string, int> indices, IEnumerable<string> fields)
{
var sb = new StringBuilder(SB_SIZE);
List<string> sortedFields;
sortedFields = new List<string>(fields);
sortedFields.Sort();
sb.AppendLine("using Unity.DemoTeam.DigitalHuman;");
sb.AppendLine();
sb.AppendFormat("namespace {0}\n", csNamespace);
sb.AppendLine("{");
sb.AppendFormat(" public struct {0}_{1}<T> where T : struct\n", csClassPrefix, name);
sb.AppendLine(" {");
for (int i = 0; i != sortedFields.Count; i++)
{
string field = sortedFields[i];
sb.Append(" public T ");
sb.Append(field);
sb.AppendLine(";");
indices.Add(field, i);
}
sb.AppendLine(" }");
sb.AppendLine("}");
WriteScriptAsset(string.Format("{0}_{1}", csClassPrefix, name), sb.ToString());
}
public void GenerateDataStructureIndices<T>(Dictionary<string, int> indices) where T : struct
{
var names = typeof(T).GetFields();
for (int i = 0; i != names.Length; i++)
{
indices.Add(names[i].Name, i);
}
}
public void GenerateImplementation(List<TextAsset> resolveControllers, List<TextAsset> resolveBlendShapes, List<TextAsset> resolveShaderParam, Dictionary<string, SnappersControllerCaps> includedControllers, Dictionary<string, int> indicesControllers, Dictionary<string, int> indicesBlendShapes, Dictionary<string, int> indicesShaderParam)
{
var sb = new StringBuilder(SB_SIZE);

sb.AppendLine();
sb.AppendLine("using static Unity.DemoTeam.DigitalHuman.SnappersHeadDefinitionMath;");
sb.AppendLine();
sb.AppendFormat("namespace {0}\n", csNamespace);
sb.AppendLine("{");

sb.AppendLine(" return CreateInstanceData<SnappersControllers, SnappersBlendShapes>(sourceMesh, sourceRig, warnings);");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" bool CheckSizes()");
sb.AppendLine(" {");
unsafe
{
sb.AppendFormat(" const int INDEXED_SIZE_CONTROLLERS = {0};\n", indicesControllers.Count * sizeof(SnappersController));
sb.AppendFormat(" const int INDEXED_SIZE_BLENDSHAPES = {0};\n", indicesBlendShapes.Count * sizeof(float));
sb.AppendFormat(" const int INDEXED_SIZE_SHADERPARAM = {0};\n", indicesShaderParam.Count * sizeof(float));
}
sb.AppendLine();
sb.AppendLine(" return");
sb.AppendLine(" INDEXED_SIZE_CONTROLLERS <= UnsafeUtility.SizeOf<SnappersControllers>() &&");
sb.AppendLine(" INDEXED_SIZE_BLENDSHAPES <= UnsafeUtility.SizeOf<SnappersBlendShapes>() &&");
sb.AppendLine(" INDEXED_SIZE_SHADERPARAM <= UnsafeUtility.SizeOf<SnappersShaderParam>();");
sb.AppendLine(" }");
sb.AppendLine();
GenerateEvaluationFunctionCallsite(sb, " ", "ResolveControllers");
sb.AppendLine();
GenerateEvaluationFunctionCallsite(sb, " ", "ResolveBlendShapes");
sb.AppendLine();
GenerateEvaluationFunctionCallsite(sb, " ", "ResolveShaderParam");
sb.AppendLine();
GenerateInitializeControllerCapsCallsite(sb, " ", "InitializeControllerCaps");
sb.AppendLine(" }");
sb.AppendLine("}");
WriteScriptAsset(string.Format("{0}_{1}", csClassPrefix, "SnappersHead"), sb.ToString());
sb.Clear();
sb.AppendLine();
sb.AppendFormat("namespace {0}\n", csNamespace);
sb.AppendLine("{");
GenerateEvaluationFunction(sb, " ", "ResolveControllers", resolveControllers, includedControllers, includedBlendShapes, includedShaderParam, skipCaps: true);
if (csCompacted == false)
{
sb.AppendFormat(" using SnappersControllers = {0}_SnappersControllers<SnappersController>;\n", csClassPrefix);
sb.AppendFormat(" using SnappersBlendShapes = {0}_SnappersBlendShapes<float>;\n", csClassPrefix);
sb.AppendLine();
}
sb.AppendFormat(" public static class {0}_{1}\n", csClassPrefix, "SnappersHeadImpl");
sb.AppendLine(" {");
GenerateEvaluationFunction(sb, " ", "ResolveControllers", resolveControllers, includedControllers, indicesControllers, indicesBlendShapes, indicesShaderParam);
sb.AppendLine();
GenerateEvaluationFunction(sb, " ", "ResolveBlendShapes", resolveBlendShapes, includedControllers, indicesControllers, indicesBlendShapes, indicesShaderParam);
GenerateEvaluationFunction(sb, " ", "ResolveBlendShapes", resolveBlendShapes, includedControllers, includedBlendShapes, includedShaderParam, skipCaps: false);
GenerateEvaluationFunction(sb, " ", "ResolveShaderParam", resolveShaderParam, includedControllers, indicesControllers, indicesBlendShapes, indicesShaderParam);
GenerateEvaluationFunction(sb, " ", "ResolveShaderParam", resolveShaderParam, includedControllers, includedBlendShapes, includedShaderParam, skipCaps: false);
GenerateInitializeControllerCaps(sb, " ", "InitializeControllerCaps", includedControllers, indicesControllers);
GenerateInitializeControllerCaps(sb, " ", "InitializeControllerCaps", includedControllers);
sb.AppendLine(@" static float clamp(float value, float min, float max)
{
if (value < min)
return min;
else if (value > max)
return max;
else
return value;
}
static float min(float a, float b)
{
if (a < b)
return a;
else
return b;
}
static float max(float a, float b)
{
if (a > b)
return a;
else
return b;
}
sb.AppendLine("#pragma warning restore 0219");
static float hermite(float p0, float p1, float r0, float r1, float t)
{
float t2 = t * t;
float t3 = t2 * t;
float _3t2 = 3.0f * t2;
float _2t3 = 2.0f * t3;
return (p0 * (_2t3 - _3t2 + 1.0f) + p1 * (-_2t3 + _3t2) + r0 * (t3 - 2.0f * t2 + t) + r1 * (t3 - t2));
}
static float linstep(float a, float b, float value)
{
if (a != b)
return clamp((value - a) / (b - a), 0.0f, 1.0f);
else
return 0.0f;
}
");
WriteScriptAsset(string.Format("{0}_{1}", csClassPrefix, "SnappersHead"), sb.ToString());
WriteScriptAsset(string.Format("{0}_{1}", csClassPrefix, "SnappersHeadImpl"), sb.ToString());
public void GenerateEvaluationFunction(StringBuilder sb, string tabs, string name, List<TextAsset> scripts, Dictionary<string, SnappersControllerCaps> includedControllers, HashSet<string> includedBlendShapes, HashSet<string> includedShaderParam, bool skipCaps)
public void GenerateEvaluationFunctionCallsite(StringBuilder sb, string tabs, string name)
sb.AppendFormat(" // --- {0}\n", name);
sb.AppendFormat(" {0}(\n", name);
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersControllers>(ptrSnappersControllers),");
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersBlendShapes>(ptrSnappersBlendShapes),");
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersShaderParam>(ptrSnappersShaderParam)");
sb.AppendLine(" if (!CheckSizes())");
sb.AppendLine(" return;");
sb.AppendLine();
sb.AppendFormat(" {0}_SnappersHeadImpl.{1}(\n", csClassPrefix, name);
if (csCompacted)
{
sb.AppendLine(" (float*)ptrSnappersControllers,");
sb.AppendLine(" (float*)ptrSnappersBlendShapes,");
sb.AppendLine(" (float*)ptrSnappersShaderParam");
}
else
{
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersControllers>(ptrSnappersControllers),");
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersBlendShapes>(ptrSnappersBlendShapes),");
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersShaderParam>(ptrSnappersShaderParam)");
}
sb.AppendFormat(" public void {0}(ref SnappersControllers {1}, ref SnappersBlendShapes {2}, ref SnappersShaderParam {3})\n", name, namedControllers, namedBlendShapes, namedShaderParam);
}
public void GenerateEvaluationFunction(StringBuilder sb, string tabs, string name, List<TextAsset> scripts, Dictionary<string, SnappersControllerCaps> includedControllers, Dictionary<string, int> indicesControllers, Dictionary<string, int> indicesBlendShapes, Dictionary<string, int> indicesShaderParam)
{
if (csCompacted)
{
sb.AppendFormat(" public static unsafe void {0}(float* {1}, float* {2}, float* {3})\n", name, compactedControllers, compactedBlendShapes, compactedShaderParam);
}
else
{
sb.AppendFormat(" public static void {0}(ref SnappersControllers {1}, ref SnappersBlendShapes {2}, ref SnappersShaderParam {3})\n", name, namedControllers, namedBlendShapes, namedShaderParam);
}
sb.AppendLine(" {");
foreach (var script in scripts)

sb.AppendFormat(" // this segment generated from '{0}'\n", script.name);
if (csCompacted == false)
{
sb.AppendFormat(" // this segment generated from '{0}'\n", script.name);
}
GenerateEvaluationFunctionSegment(sb, " ", script, includedControllers, includedBlendShapes, includedShaderParam, skipCaps);
GenerateEvaluationFunctionSegment(sb, " ", script, includedControllers, indicesControllers, indicesBlendShapes, indicesShaderParam);
sb.AppendLine(" }");
}

public void GenerateEvaluationFunctionSegment(StringBuilder sb, string tabs, TextAsset script, Dictionary<string, SnappersControllerCaps> includedControllers, HashSet<string> includedBlendShapes, HashSet<string> includedShaderParams, bool skipCaps)
public void GenerateEvaluationFunctionSegment(StringBuilder sb, string tabs, TextAsset script, Dictionary<string, SnappersControllerCaps> includedControllers, Dictionary<string, int> indicesControllers, Dictionary<string, int> indicesBlendShapes, Dictionary<string, int> indicesShaderParam)
var regexSymbol = new Regex("\\$([_a-zA-Z][_a-zA-Z0-9]*)");
var symbolCount = 0;
var symbolTable = new Dictionary<string, string>();
var inputPath = AssetDatabase.GetAssetPath(script);
var inputStream = new StreamReader(inputPath);

if (line.Length == 0)
continue;
// add tabs
// remove comments
if (csCompacted)
{
var commentIndex = line.IndexOf("//");
if (commentIndex != -1)
line = line.Substring(0, commentIndex);
}
// remove blanks
line = line.Trim();
if (line.Length == 0)
continue;
// insert tabs
line = line.Replace('$', '_');
if (csCompacted)
{
Match match;
while ((match = regexSymbol.Match(line)).Success)
{
var symbol = match.Groups[0].Value;
var symbolCompact = null as string;
if (!symbolTable.TryGetValue(symbol, out symbolCompact))
{
symbolCompact = "_s" + (++symbolCount);
symbolTable.Add(symbol, symbolCompact);
}
line = line.Replace(symbol, symbolCompact);
}
}
else
{
line = line.Replace('$', '_');
}
// replace eeg. 0.0 with 0.0f
// replace 0.0 with 0.0f
// replace and gather struct.member
// gather and replace struct.member
// note: this needs to be kept in sync with DiscoverDataMembers
// add everything until match
sb.Append(line, lineCursor, match.Index - lineCursor);
var nameStruct = match.Groups[1].Value;

includedBlendShapes.Add(nameMember);
// e.g. Head_blendShape.nameMember
if (csCompacted)
{
sb.Append(compactedBlendShapes);
sb.Append('[');
sb.Append(indicesBlendShapes[nameMember]);
sb.Append(']');
}
//else if (nameStruct == namedControllers)
//{
// includedControllers.Add(nameMember);
//}
includedShaderParams.Add(nameMember);
// e.g. SkinShader.nameMember
if (csCompacted)
{
sb.Append(compactedShaderParam);
sb.Append('[');
sb.Append(indicesShaderParam[nameMember]);
sb.Append(']');
}
else// controller
else
SnappersControllerCaps caps;
includedControllers.TryGetValue(nameStruct, out caps);
includedControllers[nameStruct] = caps | (skipCaps ? SnappersControllerCaps.none : TranslateControllerField(nameMember));
sb.Append(namedControllers);
sb.Append('.');
// e.g. nameStruct.nameMember
if (csCompacted)
{
unsafe
{
sb.Append(compactedControllers);
sb.Append('[');
sb.Append(indicesControllers[nameStruct] * (sizeof(SnappersController) / sizeof(float)) + IndexControllerField(nameMember));
sb.Append(']');
}
}
else
{
sb.Append(namedControllers);
sb.Append('.');
}
lineCursor = match.Index;
if (csCompacted)
lineCursor = match.Index + match.Length;
else
lineCursor = match.Index;
}
sb.Append(line, lineCursor, line.Length - lineCursor);

inputStream.Close();
}
public void GenerateInitializeControllerCaps(StringBuilder sb, string tabs, string name, Dictionary<string, SnappersControllerCaps> includedControllers)
public void GenerateInitializeControllerCapsCallsite(StringBuilder sb, string tabs, string name)
{
sb.AppendFormat(" public override unsafe void {0}(void* ptrSnappersControllers)\n", name);
sb.AppendLine(" {");
sb.AppendFormat(" {0}_SnappersHeadImpl.{1}(\n", csClassPrefix, name);
if (csCompacted)
{
sb.AppendLine(" (uint*)ptrSnappersControllers");
}
else
{
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersControllers>(ptrSnappersControllers)");
}
sb.AppendLine(" );");
sb.AppendLine(" }");
}
public void GenerateInitializeControllerCaps(StringBuilder sb, string tabs, string name, Dictionary<string, SnappersControllerCaps> includedControllers, Dictionary<string, int> indicesControllers)
{
Func<StringBuilder, int, SnappersControllerCaps, SnappersControllerCaps, int> concatCap = (_sb, _capCount, _caps, _cap) =>
{

return _capCount;
};
sb.AppendFormat(" // --- {0}\n", name);
sb.AppendFormat(" public override unsafe void {0}(void* ptrSnappersControllers)\n", name);
sb.AppendLine(" {");
sb.AppendFormat(" {0}(\n", name);
sb.AppendLine(" ref UnsafeUtilityEx.AsRef<SnappersControllers>(ptrSnappersControllers)");
sb.AppendLine(" );");
sb.AppendLine(" }");
sb.AppendFormat(" public void {0}(ref SnappersControllers {1})\n", name, namedControllers);
if (csCompacted)
{
sb.AppendFormat(" public static unsafe void {0}(uint* {1})\n", name, compactedControllers);
}
else
{
sb.AppendFormat(" public static void {0}(ref SnappersControllers {1})\n", name, namedControllers);
}
sb.AppendLine(" {");
List<string> sortedFields;

foreach (var field in sortedFields)
{
sb.AppendFormat(" {0}.{1}.caps = ", namedControllers, field);
var caps = includedControllers[field];
var capCount = 0;
if (csCompacted)
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.translateX);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.translateY);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.translateZ);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.rotateX);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.rotateY);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.rotateZ);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.scaleX);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.scaleY);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.scaleZ);
if (capCount == 0)
sb.AppendLine("SnappersControllerCaps.none;");
{
unsafe
{
sb.AppendFormat(" {0}[{1}] = {2};\n", compactedControllers, indicesControllers[field] * (sizeof(SnappersController) / sizeof(float)) + 9, (int)includedControllers[field]);
}
}
sb.AppendLine(";");
}
{
sb.AppendFormat(" {0}.{1}.caps = ", namedControllers, field);
sb.AppendLine(" }");
}
var caps = includedControllers[field];
var capCount = 0;
public void GenerateDataStructure(string name, IEnumerable<string> fields)
{
var sb = new StringBuilder(SB_SIZE);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.translateX);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.translateY);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.translateZ);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.rotateX);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.rotateY);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.rotateZ);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.scaleX);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.scaleY);
capCount = concatCap(sb, capCount, caps, SnappersControllerCaps.scaleZ);
List<string> sortedFields;
sortedFields = new List<string>(fields);
sortedFields.Sort();
sb.AppendLine("using Unity.DemoTeam.DigitalHuman;");
sb.AppendLine();
sb.AppendFormat("namespace {0}\n", csNamespace);
sb.AppendLine("{");
sb.AppendFormat(" public struct {0}_{1}<T> where T : struct\n", csClassPrefix, name);
sb.AppendLine(" {");
foreach (var field in sortedFields)
{
sb.Append(" public T ");
sb.Append(field);
sb.AppendLine(";");
if (capCount == 0)
sb.AppendLine("SnappersControllerCaps.none;");
else
sb.AppendLine(";");
}
sb.AppendLine(" }");
sb.AppendLine("}");
WriteScriptAsset(string.Format("{0}_{1}", csClassPrefix, name), sb.ToString());
sb.AppendLine(" }");
}
public string GetWritePath()

case "scaleZ": return SnappersControllerCaps.scaleZ;
default: return SnappersControllerCaps.none;
}
}
static int IndexControllerField(string field)
{
switch (field)
{
case "translateX": return 0;
case "translateY": return 1;
case "translateZ": return 2;
case "rotateX": return 3;
case "rotateY": return 4;
case "rotateZ": return 5;
case "scaleX": return 6;
case "scaleY": return 7;
case "scaleZ": return 8;
default: return -1;
}
}
#endif

37
Runtime/SnappersHeadDefinitionMath.cs


using System;
using UnityEngine;
namespace Unity.DemoTeam.DigitalHuman
{
public static class SnappersHeadDefinitionMath
{
public static float clamp(float value, float min, float max)
{
return Mathf.Clamp(value, min, max);
}
public static float min(float a, float b)
{
return Mathf.Min(a, b);
}
public static float max(float a, float b)
{
return Mathf.Max(a, b);
}
public static float hermite(float p0, float p1, float r0, float r1, float t)
{
var t2 = t * t;
var t3 = t2 * t;
var _3t2 = 3.0f * t2;
var _2t3 = 2.0f * t3;
return (p0 * (_2t3 - _3t2 + 1.0f) + p1 * (-_2t3 + _3t2) + r0 * (t3 - 2.0f * t2 + t) + r1 * (t3 - t2));
}
public static float linstep(float start, float end, float parameter)
{
return Mathf.InverseLerp(start, end, parameter);
}
}
}

11
Runtime/SnappersHeadDefinitionMath.cs.meta


fileFormatVersion: 2
guid: 872d5285ef9854d448e72a450408cbac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存