您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
151 行
5.3 KiB
151 行
5.3 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.DemoTeam.DigitalHuman
|
|
{
|
|
using MeshInfo = SkinAttachmentTarget.MeshInfo;
|
|
|
|
public static class SkinAttachmentDataBuilder
|
|
{
|
|
public static unsafe int BuildPosesTriangle(SkinAttachmentPose* pose, in MeshInfo meshInfo, ref Vector3 target, int triangle)
|
|
{
|
|
var meshPositions = meshInfo.meshBuffers.vertexPositions;
|
|
var meshTriangles = meshInfo.meshBuffers.triangles;
|
|
|
|
int _0 = triangle * 3;
|
|
var v0 = meshTriangles[_0];
|
|
var v1 = meshTriangles[_0 + 1];
|
|
var v2 = meshTriangles[_0 + 2];
|
|
|
|
var p0 = meshPositions[v0];
|
|
var p1 = meshPositions[v1];
|
|
var p2 = meshPositions[v2];
|
|
|
|
var v0v1 = p1 - p0;
|
|
var v0v2 = p2 - p0;
|
|
|
|
var triangleNormal = Vector3.Cross(v0v1, v0v2);
|
|
var triangleArea = Vector3.Magnitude(triangleNormal);
|
|
|
|
triangleNormal /= triangleArea;
|
|
triangleArea *= 0.5f;
|
|
|
|
if (triangleArea < float.Epsilon)
|
|
return 0;// no pose
|
|
|
|
var targetDist = Vector3.Dot(triangleNormal, target - p0);
|
|
var targetProjected = target - targetDist * triangleNormal;
|
|
var targetCoord = new Barycentric(ref targetProjected, ref p0, ref p1, ref p2);
|
|
|
|
pose->v0 = v0;
|
|
pose->v1 = v1;
|
|
pose->v2 = v2;
|
|
pose->area = triangleArea;
|
|
pose->targetDist = targetDist;
|
|
pose->targetCoord = targetCoord;
|
|
return 1;
|
|
}
|
|
|
|
public static unsafe int BuildPosesVertex(SkinAttachmentPose* pose, in MeshInfo meshInfo, ref Vector3 target, int vertex)
|
|
{
|
|
int poseCount = 0;
|
|
foreach (int triangle in meshInfo.meshAdjacency.vertexTriangles[vertex])
|
|
{
|
|
poseCount += BuildPosesTriangle(pose + poseCount, meshInfo, ref target, triangle);
|
|
}
|
|
return poseCount;
|
|
}
|
|
|
|
// note: unused -- remove?
|
|
public static unsafe void BuildDataAttachToTriangle(SkinAttachmentData attachData, int* attachmentIndex, int* attachmentCount, in MeshInfo meshInfo, Vector3* targetPositions, int* targetTriangles, int targetCount)
|
|
{
|
|
var poseIndex = attachData.poseCount;
|
|
var itemIndex = attachData.itemCount;
|
|
|
|
fixed (SkinAttachmentPose* pose = attachData.pose)
|
|
fixed (SkinAttachmentItem* item = attachData.item)
|
|
{
|
|
for (int i = 0; i != targetCount; i++)
|
|
{
|
|
var poseCount = BuildPosesTriangle(pose + poseIndex, meshInfo, ref targetPositions[i], targetTriangles[i]);
|
|
if (poseCount == 0)
|
|
{
|
|
Debug.LogError("no valid poses for target triangle " + i + ", aborting");
|
|
poseIndex = attachData.poseCount;
|
|
itemIndex = attachData.itemCount;
|
|
break;
|
|
}
|
|
|
|
item[itemIndex].poseIndex = poseIndex;
|
|
item[itemIndex].poseCount = poseCount;
|
|
item[itemIndex].baseVertex = meshInfo.meshBuffers.triangles[3 * targetTriangles[i]];
|
|
item[itemIndex].baseNormal = meshInfo.meshBuffers.vertexNormals[item[itemIndex].baseVertex];
|
|
item[itemIndex].targetNormal = item[itemIndex].baseNormal;
|
|
item[itemIndex].targetOffset = Vector3.zero;
|
|
|
|
poseIndex += poseCount;
|
|
itemIndex += 1;
|
|
}
|
|
}
|
|
|
|
*attachmentIndex = itemIndex > attachData.itemCount ? attachData.itemCount : -1;
|
|
*attachmentCount = itemIndex - attachData.itemCount;
|
|
|
|
attachData.poseCount = poseIndex;
|
|
attachData.itemCount = itemIndex;
|
|
}
|
|
|
|
public static unsafe void BuildDataAttachToVertex(SkinAttachmentData attachData, int* attachmentIndex, int* attachmentCount, in MeshInfo meshInfo, Vector3* targetPositions, Vector3* targetOffsets, Vector3* targetNormals, int* targetVertices, int targetCount)
|
|
{
|
|
var poseIndex = attachData.poseCount;
|
|
var descIndex = attachData.itemCount;
|
|
|
|
fixed (SkinAttachmentPose* pose = attachData.pose)
|
|
fixed (SkinAttachmentItem* desc = attachData.item)
|
|
{
|
|
for (int i = 0; i != targetCount; i++)
|
|
{
|
|
var poseCount = BuildPosesVertex(pose + poseIndex, meshInfo, ref targetPositions[i], targetVertices[i]);
|
|
if (poseCount == 0)
|
|
{
|
|
Debug.LogError("no valid poses for target vertex " + i + ", aborting");
|
|
poseIndex = attachData.poseCount;
|
|
descIndex = attachData.itemCount;
|
|
break;
|
|
}
|
|
|
|
desc[descIndex].poseIndex = poseIndex;
|
|
desc[descIndex].poseCount = poseCount;
|
|
desc[descIndex].baseVertex = targetVertices[i];
|
|
desc[descIndex].baseNormal = meshInfo.meshBuffers.vertexNormals[targetVertices[i]];
|
|
desc[descIndex].targetNormal = targetNormals[i];
|
|
desc[descIndex].targetOffset = targetOffsets[i];
|
|
|
|
poseIndex += poseCount;
|
|
descIndex += 1;
|
|
}
|
|
}
|
|
|
|
*attachmentIndex = descIndex > attachData.itemCount ? attachData.itemCount : -1;
|
|
*attachmentCount = descIndex - attachData.itemCount;
|
|
|
|
attachData.poseCount = poseIndex;
|
|
attachData.itemCount = descIndex;
|
|
}
|
|
|
|
public static unsafe void BuildDataAttachToClosestVertex(SkinAttachmentData attachData, int* attachmentIndex, int* attachmentCount, in MeshInfo meshInfo, Vector3* targetPositions, Vector3* targetNormals, int targetCount)
|
|
{
|
|
using (var targetOffsets = new UnsafeArrayVector3(targetCount))
|
|
using (var targetVertices = new UnsafeArrayInt(targetCount))
|
|
{
|
|
for (int i = 0; i != targetCount; i++)
|
|
{
|
|
targetOffsets.val[i] = Vector3.zero;
|
|
targetVertices.val[i] = meshInfo.meshVertexBSP.FindNearest(ref targetPositions[i]);
|
|
}
|
|
BuildDataAttachToVertex(attachData, attachmentIndex, attachmentCount, meshInfo, targetPositions, targetOffsets.val, targetNormals, targetVertices.val, targetCount);
|
|
}
|
|
}
|
|
}
|
|
}
|