浏览代码

support skinning renderers in attachments

/main
Lasse Jon Fuglsang Pedersen 5 年前
当前提交
949d9130
共有 2 个文件被更改,包括 98 次插入11 次删除
  1. 77
      Runtime/SkinAttachment.cs
  2. 32
      Runtime/SkinAttachmentTarget.cs

77
Runtime/SkinAttachment.cs


using System;
using UnityEngine;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.DemoTeam.Attributes;
namespace Unity.DemoTeam.DigitalHuman

[NonSerialized] public MeshAdjacency meshAdjacency;
[NonSerialized] public MeshIslands meshIslands;
[NonSerialized] public Transform skinningBone;
[NonSerialized] public Matrix4x4 skinningBoneBindPose;
[NonSerialized] public Matrix4x4 skinningBoneBindPoseInverse;
void DiscoverSkinningBone()
{
skinningBone = null;
skinningBoneBindPose = Matrix4x4.identity;
skinningBoneBindPoseInverse = Matrix4x4.identity;
// search for skinning bone
var smr = GetComponent<SkinnedMeshRenderer>();
if (smr != null)
{
int skinningBoneIndex = -1;
unsafe
{
var boneWeights = meshAsset.GetAllBoneWeights();
var boneWeightPtr = (BoneWeight1*)boneWeights.GetUnsafeReadOnlyPtr();
for (int i = 0; i != boneWeights.Length; i++)
{
if (boneWeightPtr[i].weight > 0.0f)
{
if (skinningBoneIndex == -1)
skinningBoneIndex = boneWeightPtr[i].boneIndex;
if (skinningBoneIndex != boneWeightPtr[i].boneIndex)
{
skinningBoneIndex = -1;
break;
}
}
}
}
if (skinningBoneIndex != -1)
{
skinningBone = smr.bones[skinningBoneIndex];
skinningBoneBindPose = meshInstance.bindposes[skinningBoneIndex];
skinningBoneBindPoseInverse = skinningBoneBindPose.inverse;
//Debug.Log("discovered skinning bone for " + this.name + " : " + skinningBone.name);
}
}
}
protected override void OnMeshInstanceCreated()
{
meshAssetRadius = meshAsset.bounds.extents.magnitude;// conservative

meshIslands = new MeshIslands(meshAdjacency);
else
meshIslands.LoadFrom(meshAdjacency);
DiscoverSkinningBone();
}
protected override void OnMeshInstanceDeleted()

return;
}
Gizmos.matrix = this.transform.localToWorldMatrix;
if (skinningBone != null)
Gizmos.matrix = skinningBone.localToWorldMatrix * skinningBoneBindPose;
else
Gizmos.matrix = this.transform.localToWorldMatrix;
if (attachmentType == AttachmentType.Mesh)
{

var positions = meshBuffers.vertexPositions;
var targetPositions = new Vector3[positions.Length];
var subjectToTarget = target.transform.worldToLocalMatrix * this.transform.localToWorldMatrix;
var targetToSubject = this.transform.worldToLocalMatrix * target.transform.localToWorldMatrix;
Matrix4x4 targetToWorld = Matrix4x4.TRS(target.transform.position, target.transform.rotation, Vector3.one);
Matrix4x4 subjectToTarget;
Matrix4x4 targetToSubject;
{
if (skinningBone != null)
{
subjectToTarget = target.transform.worldToLocalMatrix * (skinningBone.localToWorldMatrix * skinningBoneBindPose);
targetToSubject = (skinningBoneBindPoseInverse * skinningBone.worldToLocalMatrix) * targetToWorld;
}
else
{
subjectToTarget = target.transform.worldToLocalMatrix * this.transform.localToWorldMatrix;
targetToSubject = this.transform.worldToLocalMatrix * targetToWorld;
}
}
for (int i = 0; i != positions.Length; i++)
{

32
Runtime/SkinAttachmentTarget.cs


{
Profiler.BeginSample("attach-subj");
var subjectToTarget = this.transform.worldToLocalMatrix * subject.transform.localToWorldMatrix;
Matrix4x4 subjectToTarget;
{
if (subject.skinningBone != null)
subjectToTarget = this.transform.worldToLocalMatrix * (subject.skinningBone.localToWorldMatrix * subject.skinningBoneBindPose);
else
subjectToTarget = this.transform.worldToLocalMatrix * subject.transform.localToWorldMatrix;
}
switch (subject.attachmentType)
{

Profiler.EndSample();
}
//--------
// Attach
// moved to SkinAttachmentDataBuilder
//---------
// Resolve

case SkinAttachment.AttachmentType.Mesh:
case SkinAttachment.AttachmentType.MeshRoots:
{
var targetToSubject = subject.transform.worldToLocalMatrix * targetToWorld;
Matrix4x4 targetToSubject;
{
// this used to always read:
// var targetToSubject = subject.transform.worldToLocalMatrix * targetToWorld;
//
// to support attachments that have skinning renderers, we sometimes have to transform
// the vertices into a space that takes into account the subsequently applied skinning:
// var targetToSubject = (subject.skinningBone.localToWorldMatrix * subject.meshInstanceBoneBindPose).inverse * targetToWorld;
//
// we can reshuffle a bit to get rid of the per-resolve inverse:
// var targetToSubject = (subject.skinningBoneBindPoseInverse * subject.meshInstanceBone.worldToLocalMatrix) * targetToWorld;
if (subject.skinningBone != null)
targetToSubject = (subject.skinningBoneBindPoseInverse * subject.skinningBone.worldToLocalMatrix) * targetToWorld;
else
targetToSubject = subject.transform.worldToLocalMatrix * targetToWorld;
}
stagingJobs[i] = ScheduleResolve(attachmentIndex, attachmentCount, ref targetToSubject, resolvedPositions, resolvedNormals);
}
break;

正在加载...
取消
保存