< Summary

Class:GPUSkinning.SimpleGPUSkinning
Assembly:RenderUtils
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Rendering/Utils/GPUSkinning/SimpleGPUSkinning.cs
Covered lines:0
Uncovered lines:49
Coverable lines:49
Total lines:96
Line coverage:0% (0 of 49)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
SimpleGPUSkinning()0%2100%
SimpleGPUSkinning(...)0%12300%
ConfigureBindPoses(...)0%6200%
Update(...)0%30500%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Rendering/Utils/GPUSkinning/SimpleGPUSkinning.cs

#LineLine coverage
 1using System.Linq;
 2using UnityEngine;
 3using Object = UnityEngine.Object;
 4
 5namespace GPUSkinning
 6{
 7
 8    public class SimpleGPUSkinning
 9    {
 010        private static readonly int BONE_MATRICES = Shader.PropertyToID("_Matrices");
 011        private static readonly int BIND_POSES = Shader.PropertyToID("_BindPoses");
 012        private static readonly int RENDERER_WORLD_INVERSE = Shader.PropertyToID("_WorldInverse");
 13
 014        public MeshRenderer renderer { get; }
 15
 16        private Transform[] bones;
 17        private Matrix4x4[] boneMatrices;
 18
 019        public SimpleGPUSkinning (SkinnedMeshRenderer skr)
 20        {
 021            ConfigureBindPoses(skr);
 22
 023            boneMatrices = new Matrix4x4[skr.bones.Length];
 24
 025            GameObject go = skr.gameObject;
 26
 027            if (!go.TryGetComponent(out MeshFilter meshFilter))
 028                meshFilter = go.AddComponent<MeshFilter>();
 29
 030            meshFilter.sharedMesh = skr.sharedMesh;
 31
 032            renderer = go.AddComponent<MeshRenderer>();
 033            renderer.sharedMaterials = skr.sharedMaterials;
 034            foreach (Material material in renderer.sharedMaterials)
 35            {
 036                material.SetMatrixArray(BIND_POSES, skr.sharedMesh.bindposes.ToArray());
 037                material.EnableKeyword("_GPU_SKINNING");
 38            }
 039            bones = skr.bones;
 040            meshFilter.mesh.bounds = new Bounds(new Vector3(0, 2, 0), new Vector3(1, 3, 1));
 41
 042            Object.Destroy(skr);
 043        }
 44
 45        /// <summary>
 46        /// This must be done once per SkinnedMeshRenderer before animating.
 47        /// </summary>
 48        /// <param name="skr"></param>
 49        private static void ConfigureBindPoses(SkinnedMeshRenderer skr)
 50        {
 051            Mesh sharedMesh = skr.sharedMesh;
 052            int vertexCount = sharedMesh.vertexCount;
 053            Vector4[] bone01data = new Vector4[vertexCount];
 054            Vector4[] bone23data = new Vector4[vertexCount];
 55
 056            BoneWeight[] boneWeights = sharedMesh.boneWeights;
 57
 058            for ( int i = 0; i < vertexCount; i ++ )
 59            {
 060                BoneWeight boneWeight = boneWeights[i];
 061                bone01data[i].x = boneWeight.boneIndex0;
 062                bone01data[i].y = boneWeight.weight0;
 063                bone01data[i].z = boneWeight.boneIndex1;
 064                bone01data[i].w = boneWeight.weight1;
 65
 066                bone23data[i].x = boneWeight.boneIndex2;
 067                bone23data[i].y = boneWeight.weight2;
 068                bone23data[i].z = boneWeight.boneIndex3;
 069                bone23data[i].w = boneWeight.weight3;
 70            }
 71
 072            skr.sharedMesh.tangents = bone01data;
 073            skr.sharedMesh.SetUVs(1, bone23data);
 074        }
 75
 76        public void Update(bool forceUpdate = false)
 77        {
 078            if (!forceUpdate && !renderer.isVisible)
 079                return;
 80
 081            int bonesLength = bones.Length;
 82
 083            for (int i = 0; i < bonesLength; i++)
 84            {
 085                Transform bone = bones[i];
 086                boneMatrices[i] = bone.localToWorldMatrix;
 87            }
 088            for (int index = 0; index < renderer.sharedMaterials.Length; index++)
 89            {
 090                Material material = renderer.sharedMaterials[index];
 091                material.SetMatrix(RENDERER_WORLD_INVERSE, renderer.transform.worldToLocalMatrix);
 092                material.SetMatrixArray(BONE_MATRICES, boneMatrices);
 93            }
 094        }
 95    }
 96}