< Summary

Class:SimpleGPUSkinning
Assembly:RenderUtils
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Rendering/Utils/GPUSkinning/SimpleGPUSkinning.cs
Covered lines:0
Uncovered lines:52
Coverable lines:52
Total lines:98
Line coverage:0% (0 of 52)
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%12300%
Update(...)0%30500%

File(s)

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

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Linq;
 3using UnityEngine;
 4
 5public class SimpleGPUSkinning
 6{
 07    private static readonly int BONE_MATRICES = Shader.PropertyToID("_Matrices");
 08    private static readonly int BIND_POSES = Shader.PropertyToID("_BindPoses");
 09    private static readonly int RENDERER_WORLD_INVERSE = Shader.PropertyToID("_WorldInverse");
 10
 011    public MeshRenderer renderer { get; }
 12
 13    private Transform[] bones;
 14    private Matrix4x4[] boneMatrices;
 15
 016    private static HashSet<Mesh> processedBindPoses = new HashSet<Mesh>();
 17
 018    public SimpleGPUSkinning (SkinnedMeshRenderer skr)
 19    {
 020        ConfigureBindPoses(skr);
 21
 022        boneMatrices = new Matrix4x4[skr.bones.Length];
 23
 024        GameObject go = skr.gameObject;
 25
 026        if (!go.TryGetComponent(out MeshFilter meshFilter))
 027            meshFilter = go.AddComponent<MeshFilter>();
 28
 029        meshFilter.sharedMesh = skr.sharedMesh;
 30
 031        renderer = go.AddComponent<MeshRenderer>();
 032        renderer.sharedMaterials = skr.sharedMaterials;
 033        foreach (Material material in renderer.sharedMaterials)
 34        {
 035            material.SetMatrixArray(BIND_POSES, skr.sharedMesh.bindposes.ToArray());
 036            material.EnableKeyword("_GPU_SKINNING");
 37        }
 038        bones = skr.bones;
 039        meshFilter.mesh.bounds = new Bounds(new Vector3(0, 2, 0), new Vector3(1, 3, 1));
 40
 041        Object.Destroy(skr);
 042    }
 43
 44    /// <summary>
 45    /// This must be done once per SkinnedMeshRenderer before animating.
 46    /// </summary>
 47    /// <param name="skr"></param>
 48    private static void ConfigureBindPoses(SkinnedMeshRenderer skr)
 49    {
 050        if ( processedBindPoses.Contains(skr.sharedMesh))
 051            return;
 52
 053        Mesh sharedMesh = skr.sharedMesh;
 054        processedBindPoses.Add(sharedMesh);
 55
 056        int vertexCount = sharedMesh.vertexCount;
 057        Vector4[] bone01data = new Vector4[vertexCount];
 058        Vector4[] bone23data = new Vector4[vertexCount];
 59
 060        BoneWeight[] boneWeights = sharedMesh.boneWeights;
 61
 062        for ( int i = 0; i < vertexCount; i ++ )
 63        {
 064            BoneWeight boneWeight = boneWeights[i];
 065            bone01data[i].x = boneWeight.boneIndex0;
 066            bone01data[i].y = boneWeight.weight0;
 067            bone01data[i].z = boneWeight.boneIndex1;
 068            bone01data[i].w = boneWeight.weight1;
 69
 070            bone23data[i].x = boneWeight.boneIndex2;
 071            bone23data[i].y = boneWeight.weight2;
 072            bone23data[i].z = boneWeight.boneIndex3;
 073            bone23data[i].w = boneWeight.weight3;
 74        }
 75
 076        skr.sharedMesh.tangents = bone01data;
 077        skr.sharedMesh.SetUVs(1, bone23data);
 078    }
 79
 80    public void Update(bool forceUpdate = false)
 81    {
 082        if (!forceUpdate && !renderer.isVisible)
 083            return;
 84
 085        int bonesLength = bones.Length;
 86
 087        for (int i = 0; i < bonesLength; i++)
 88        {
 089            Transform bone = bones[i];
 090            boneMatrices[i] = bone.localToWorldMatrix;
 91        }
 092        foreach (Material material in renderer.sharedMaterials)
 93        {
 094            material.SetMatrix(RENDERER_WORLD_INVERSE, renderer.transform.worldToLocalMatrix);
 095            material.SetMatrixArray(BONE_MATRICES, boneMatrices.ToArray());
 96        }
 097    }
 98}