protected override void OnUpdate() { Entities.ForEach((SkinnedMesh meshRenderer) => { var entity = GetPrimaryEntity(meshRenderer.SkinnedMeshRenderer); Entity rigEntity = GetPrimaryEntity(meshRenderer.Rig); var animatedSkinMatricesArray = DstEntityManager.AddBuffer <AnimatedLocalToRoot>(rigEntity); animatedSkinMatricesArray.ResizeUninitialized(meshRenderer.Rig.Bones.Length); DstEntityManager.AddComponentData(entity, new SkinnedMeshRigEntity { Value = rigEntity }); DstEntityManager.AddComponentData(entity, new LocalToWorld()); DstEntityManager.AddComponentData(entity, new BoneIndexOffset()); DstEntityManager.AddBuffer <SkinnedMeshToRigIndex>(entity); DstEntityManager.AddBuffer <BindPose>(entity); DstEntityManager.AddBuffer <SkinMatrix>(entity); var skeletonIndexArray = DstEntityManager.GetBuffer <SkinnedMeshToRigIndex>(entity); var bindPoseArray = DstEntityManager.GetBuffer <BindPose>(entity); var skinMatrices = DstEntityManager.GetBuffer <SkinMatrix>(entity); var smBones = meshRenderer.SkinnedMeshRenderer.bones; skeletonIndexArray.ResizeUninitialized(smBones.Length); bindPoseArray.ResizeUninitialized(smBones.Length); skinMatrices.ResizeUninitialized(smBones.Length); var skBones = meshRenderer.Rig.Bones; for (int j = 0; j != smBones.Length; ++j) { var remap = new SkinnedMeshToRigIndex { Value = -1 }; for (int k = 0; k != skBones.Length; ++k) { if (smBones[j] == skBones[k]) { remap.Value = k; break; } } skeletonIndexArray[j] = remap; var bindPose = meshRenderer.SkinnedMeshRenderer.sharedMesh.bindposes[j]; bindPoseArray[j] = new BindPose { Value = bindPose }; var skinMat = math.mul(meshRenderer.SkinnedMeshRenderer.bones[j].localToWorldMatrix, bindPose); skinMatrices[j] = new SkinMatrix { Value = new float3x4(skinMat.c0.xyz, skinMat.c1.xyz, skinMat.c2.xyz, skinMat.c3.xyz) }; } }); }
static void ComputeRenderingSkinMatrix( [ReadOnly] DynamicBuffer <SkinnedMeshToRigIndex> skinMeshToRigIndices, [ReadOnly] DynamicBuffer <BindPose> bindPoses, [ReadOnly] DynamicBuffer <AnimatedLocalToRoot> animatedLocalToRootMatrices, DynamicBuffer <SkinMatrix> outSkinMatrices ) { for (int i = 0; i != outSkinMatrices.Length; ++i) { var index = skinMeshToRigIndices[i].Value; var skinMat = math.mul(animatedLocalToRootMatrices[index].Value, bindPoses[i].Value); outSkinMatrices[i] = new SkinMatrix { Value = new float3x4(skinMat.c0.xyz, skinMat.c1.xyz, skinMat.c2.xyz, skinMat.c3.xyz) }; } }
protected override void OnUpdate() { Entities.ForEach((ref DynamicBuffer <SkinMatrix> skinMatrices, in DynamicBuffer <ModifiedTransform> modifiedMatrices, in DynamicBuffer <BindPose> bindposes) => { for (int i = 0; i < skinMatrices.Length; ++i) { var skinMat = math.mul(modifiedMatrices[i].Value, bindposes[i].Value); skinMatrices[i] = new SkinMatrix { Value = new float3x4(skinMat.c0.xyz, skinMat.c1.xyz, skinMat.c2.xyz, skinMat.c3.xyz) }; } }).ScheduleParallel();
protected override void OnUpdate() { var materials = new List <Material>(10); var context = new RenderMeshConversionContext(DstEntityManager, this) { AttachToPrimaryEntityForSingleMaterial = false, }; Entities.ForEach((SkinnedMeshRenderer meshRenderer) => { meshRenderer.GetSharedMaterials(materials); foreach (var material in materials) { if (material == null) { continue; } var supportsSkinning = material.HasProperty(s_SkinMatrixIndexProperty) || material.HasProperty(s_ComputeMeshIndexProperty); if (!supportsSkinning) { string errorMsg = ""; errorMsg += $"Shader [{material.shader.name}] on [{meshRenderer.name}] does not support skinning. This can result in incorrect rendering.{System.Environment.NewLine}"; errorMsg += $"Please see documentation for Linear Blend Skinning Node and Compute Deformation Node in Shader Graph.{System.Environment.NewLine}"; Debug.LogWarning(errorMsg, meshRenderer); } } var mesh = meshRenderer.sharedMesh; var root = meshRenderer.rootBone ? meshRenderer.rootBone : meshRenderer.transform; var hasSkinning = mesh == null ? false : mesh.boneWeights.Length > 0 && mesh.bindposes.Length > 0; var hasBlendShapes = mesh == null ? false : mesh.blendShapeCount > 0; var deformedEntity = GetPrimaryEntity(meshRenderer); // Convert Renderers as normal MeshRenderers. // No need to process light maps as skinned objects are never light mapped. context.Convert(meshRenderer, mesh, materials, root); foreach (var rendererEntity in GetEntities(meshRenderer)) { if (DstEntityManager.HasComponent <RenderMesh>(rendererEntity)) { // Add relevant deformation tags to converted render entities and link them to the DeformedEntity. #if ENABLE_COMPUTE_DEFORMATIONS DstEntityManager.AddComponentData(rendererEntity, new DeformedMeshIndex()); #endif DstEntityManager.AddComponentData(rendererEntity, new DeformedEntity { Value = deformedEntity }); DstEntityManager.AddComponentData(rendererEntity, new RenderBounds { Value = meshRenderer.localBounds.ToAABB() }); if (hasSkinning) { DstEntityManager.AddComponent <SkinningTag>(rendererEntity); } if (hasBlendShapes) { DstEntityManager.AddComponent <BlendShapeTag>(rendererEntity); } } } // Fill the blend shape weights. if (hasBlendShapes && !DstEntityManager.HasComponent <BlendShapeWeight>(deformedEntity)) { DstEntityManager.AddBuffer <BlendShapeWeight>(deformedEntity); var weights = DstEntityManager.GetBuffer <BlendShapeWeight>(deformedEntity); weights.ResizeUninitialized(meshRenderer.sharedMesh.blendShapeCount); for (int i = 0; i < weights.Length; ++i) { weights[i] = new BlendShapeWeight { Value = meshRenderer.GetBlendShapeWeight(i) }; } } // Fill the skin matrices with bindpose skin matrices. if (hasSkinning && !DstEntityManager.HasComponent <SkinMatrix>(deformedEntity)) { var bones = meshRenderer.bones; var rootMatrixInv = root.localToWorldMatrix.inverse; DstEntityManager.AddBuffer <SkinMatrix>(deformedEntity); var skinMatrices = DstEntityManager.GetBuffer <SkinMatrix>(deformedEntity); skinMatrices.ResizeUninitialized(bones.Length); for (int i = 0; i < bones.Length; ++i) { var bindPose = meshRenderer.sharedMesh.bindposes[i]; var boneMatRootSpace = math.mul(rootMatrixInv, bones[i].localToWorldMatrix); var skinMatRootSpace = math.mul(boneMatRootSpace, bindPose); skinMatrices[i] = new SkinMatrix { Value = new float3x4(skinMatRootSpace.c0.xyz, skinMatRootSpace.c1.xyz, skinMatRootSpace.c2.xyz, skinMatRootSpace.c3.xyz) }; } } }); context.EndConversion(); }
void ConvertSkinnedMeshRenderes(RigBasedAssetAuthoring assetAuthoring, Entity assetEntity, RigComponent rigComponent) { var skinnedMeshRenderers = assetAuthoring.GetComponentsInChildren <SkinnedMeshRenderer>(); if (skinnedMeshRenderers.Length > 0) { DstEntityManager.AddBuffer <RigBasedAsset.SkinnedMeshRenderer>(assetEntity); } foreach (var meshRenderer in skinnedMeshRenderers) { var skinEntity = GetPrimaryEntity(meshRenderer.gameObject); //var skinEntity = conversionSystem.CreateAdditionalEntity(meshRenderer); #if UNITY_EDITOR DstEntityManager.SetName(skinEntity, "Entity " + skinEntity.Index + " Skin_" + meshRenderer.gameObject.name); #endif var skinRendererBuffer = DstEntityManager.GetBuffer <RigBasedAsset.SkinnedMeshRenderer>(assetEntity); skinRendererBuffer.Add(new RigBasedAsset.SkinnedMeshRenderer { Value = skinEntity, }); //var rigEntity = GetPrimaryEntity(src.Rig); //DstEntityManager.AddComponentData(entity, new SkinnedMeshComponentData { RigEntity = rigEntity }); DstEntityManager.AddComponentData(skinEntity, new SkinnedMeshRigEntity { Value = assetEntity }); DstEntityManager.AddComponentData(skinEntity, new LocalToWorld()); DstEntityManager.AddComponentData(skinEntity, new BoneIndexOffset()); DstEntityManager.AddBuffer <SkinnedMeshToRigIndex>(skinEntity); DstEntityManager.AddBuffer <BindPose>(skinEntity); DstEntityManager.AddBuffer <SkinMatrix>(skinEntity); var skeletonIndexArray = DstEntityManager.GetBuffer <SkinnedMeshToRigIndex>(skinEntity); var bindPoseArray = DstEntityManager.GetBuffer <BindPose>(skinEntity); var skinMatrices = DstEntityManager.GetBuffer <SkinMatrix>(skinEntity); var smBones = meshRenderer.bones; skeletonIndexArray.ResizeUninitialized(smBones.Length); bindPoseArray.ResizeUninitialized(smBones.Length); skinMatrices.ResizeUninitialized(smBones.Length); //GameDebug.Log("skin smBones"); //for (int i = 0; i < smBones.Length; i++) //{ // var relativePath = RigGenerator.ComputeRelativePath(smBones[i], transform); // var id = (StringHash)relativePath; // GameDebug.Log(" " + i + ":" + id.Id + " path:" + relativePath); //} for (int j = 0; j != smBones.Length; ++j) { var remap = new SkinnedMeshToRigIndex { Value = -1 }; var smBoneRelativePath = RigGenerator.ComputeRelativePath(smBones[j], assetAuthoring.transform); var smBoneId = (StringHash)smBoneRelativePath; for (int k = 0; k != rigComponent.Bones.Length; ++k) { var relativePath = RigGenerator.ComputeRelativePath(rigComponent.Bones[k], rigComponent.transform); var id = (StringHash)relativePath; if (smBoneId.Equals(id)) { remap.Value = k; break; } } skeletonIndexArray[j] = remap; var bindPose = meshRenderer.sharedMesh.bindposes[j]; bindPoseArray[j] = new BindPose { Value = bindPose }; var skinMat = math.mul(meshRenderer.bones[j].localToWorldMatrix, bindPose); skinMatrices[j] = new SkinMatrix { Value = new float3x4(skinMat.c0.xyz, skinMat.c1.xyz, skinMat.c2.xyz, skinMat.c3.xyz) }; } } }
protected override void OnUpdate() { var boneCount = m_BoneEntityQuery.CalculateEntityCount(); var bonesLocalToWorld = new NativeHashMap <Entity, float4x4>(boneCount, Allocator.TempJob); var bonesLocalToWorldParallel = bonesLocalToWorld.AsParallelWriter(); var dependency = Dependency; var bone = Entities .WithName("GatherBoneTransforms") .WithAll <BoneTag>() .ForEach((Entity entity, in LocalToWorld localToWorld) => { bonesLocalToWorldParallel.TryAdd(entity, localToWorld.Value); }).ScheduleParallel(dependency); var rootCount = m_RootEntityQuery.CalculateEntityCount(); var rootWorldToLocal = new NativeHashMap <Entity, float4x4>(rootCount, Allocator.TempJob); var rootWorldToLocalParallel = rootWorldToLocal.AsParallelWriter(); var root = Entities .WithName("GatherRootTransforms") .WithAll <RootTag>() .ForEach((Entity entity, in WorldToLocal worldToLocal) => { rootWorldToLocalParallel.TryAdd(entity, worldToLocal.Value); }).ScheduleParallel(dependency); dependency = JobHandle.CombineDependencies(bone, root); dependency = Entities .WithName("CalculateSkinMatrices") .WithReadOnly(bonesLocalToWorld) .WithReadOnly(rootWorldToLocal) .ForEach((ref DynamicBuffer <SkinMatrix> skinMatrices, in DynamicBuffer <BindPose> bindPoses, in DynamicBuffer <BoneEntity> bones, in RootEntity root) => { // Loop over each bone for (int i = 0; i < skinMatrices.Length; ++i) { // Grab localToWorld matrix of bone var boneEntity = bones[i].Value; var rootEntity = root.Value; // #TODO: this is necessary for LiveLink? if (!bonesLocalToWorld.ContainsKey(boneEntity) || !rootWorldToLocal.ContainsKey(rootEntity)) { return; } var matrix = bonesLocalToWorld[boneEntity]; // Convert matrix relative to root var rootMatrixInv = rootWorldToLocal[rootEntity]; matrix = math.mul(rootMatrixInv, matrix); // Compute to skin matrix var bindPose = bindPoses[i].Value; matrix = math.mul(matrix, bindPose); // Assign SkinMatrix skinMatrices[i] = new SkinMatrix { Value = new float3x4(matrix.c0.xyz, matrix.c1.xyz, matrix.c2.xyz, matrix.c3.xyz) }; } }).ScheduleParallel(dependency);
protected override void OnUpdate() { var materials = new List <Material>(10); Entities.ForEach((SkinnedMeshRenderer meshRenderer) => { meshRenderer.GetSharedMaterials(materials); var mesh = meshRenderer.sharedMesh; var root = meshRenderer.rootBone ? meshRenderer.rootBone : meshRenderer.transform; var hasSkinning = mesh == null ? false : mesh.boneWeights.Length > 0 && mesh.bindposes.Length > 0; var hasBlendShapes = mesh == null ? false : mesh.blendShapeCount > 0; var deformedEntity = GetPrimaryEntity(meshRenderer); // Convert Renderers as normal MeshRenderers. MeshRendererConversion.Convert(DstEntityManager, this, k_AttachToPrimaryEntityForSingleMaterial, meshRenderer, mesh, materials, root, meshRenderer.localBounds.ToAABB()); foreach (var rendererEntity in GetEntities(meshRenderer)) { if (DstEntityManager.HasComponent <RenderMesh>(rendererEntity)) { // Add relevant deformation tags to converted render entities and link them to the DeformedEntity. #if ENABLE_COMPUTE_DEFORMATIONS DstEntityManager.AddComponentData(rendererEntity, new DeformedMeshIndex()); #endif DstEntityManager.AddComponentData(rendererEntity, new DeformedEntity { Value = deformedEntity }); if (hasSkinning) { DstEntityManager.AddComponent <SkinningTag>(rendererEntity); } if (hasBlendShapes) { DstEntityManager.AddComponent <BlendShapeTag>(rendererEntity); } } } // Fill the blend shape weights. if (hasBlendShapes && !DstEntityManager.HasComponent <BlendShapeWeight>(deformedEntity)) { DstEntityManager.AddBuffer <BlendShapeWeight>(deformedEntity); var weights = DstEntityManager.GetBuffer <BlendShapeWeight>(deformedEntity); weights.ResizeUninitialized(meshRenderer.sharedMesh.blendShapeCount); for (int i = 0; i < weights.Length; ++i) { weights[i] = new BlendShapeWeight { Value = meshRenderer.GetBlendShapeWeight(i) }; } } // Fill the skin matrices with bindpose skin matrices. if (hasSkinning && !DstEntityManager.HasComponent <SkinMatrix>(deformedEntity)) { var bones = meshRenderer.bones; var rootMatrixInv = root.localToWorldMatrix.inverse; DstEntityManager.AddBuffer <SkinMatrix>(deformedEntity); var skinMatrices = DstEntityManager.GetBuffer <SkinMatrix>(deformedEntity); skinMatrices.ResizeUninitialized(bones.Length); for (int i = 0; i < bones.Length; ++i) { var bindPose = meshRenderer.sharedMesh.bindposes[i]; var boneMatRootSpace = math.mul(rootMatrixInv, bones[i].localToWorldMatrix); var skinMatRootSpace = math.mul(boneMatRootSpace, bindPose); skinMatrices[i] = new SkinMatrix { Value = new float3x4(skinMatRootSpace.c0.xyz, skinMatRootSpace.c1.xyz, skinMatRootSpace.c2.xyz, skinMatRootSpace.c3.xyz) }; } } }); }