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)
                    };
                }
            });
        }
Example #2
0
            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)
                    };
                }
            }
Example #3
0
    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();
Example #4
0
        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();
        }
Example #5
0
        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)
                    };
                }
            }
        }
Example #6
0
    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);
Example #7
0
        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)
                        };
                    }
                }
            });
        }