コード例 #1
0
        /// <summary>
        /// 通过 id  获取 GPURendererRes
        /// </summary>
        /// <param name="id">SkinnedMeshRenderer.sharedMesh.GetInstanceID()</param>
        /// <returns></returns>
        public GPURendererRes GetDataByID(int id)
        {
            GPURendererRes data = null;

            _dic.TryGetValue(id, out data);
            return(data);
        }
コード例 #2
0
        public void AddMeshRenderer(GPURendererRes res)
        {
            GPUSkinnedMeshRenderer renderer = new GPUSkinnedMeshRenderer();

            renderer.Init(this, res);
            _GPUMeshRenderers.Add(renderer);
        }
コード例 #3
0
        public void Init(BakedGPUAnimation animation, GPURendererRes res)
        {
            _bakedAnimation = animation;
            _rendererRes    = res;
            _skinningData   = animation.skinningData;
            _pixelPerFrame  = _skinningData.boneInfos.Length * 3;

            GameObject go = animation.gameObject;
            Transform  t  = go.transform;

            t.localPosition = Vector3.zero;
            t.localRotation = Quaternion.identity;

            _meshRenderer = go.GetOrAddComponent <MeshRenderer>();
            _meshFilter   = go.GetOrAddComponent <MeshFilter>();

            _meshFilter.sharedMesh = res.mesh;
            _rendererParamDirty    = true;

            _runningBakedAnimData = new RunningBakedAnimData();

            _meshRenderer.additionalVertexStreams = _rendererRes.additionalMesh;
            _meshRenderer.sharedMaterial          = _rendererRes.bakedGPUMaterial;

            _AnimParamId = Shader.PropertyToID("_AnimParam");

            _mbp = new MaterialPropertyBlock();
            _meshRenderer.SetPropertyBlock(_mbp);
        }
コード例 #4
0
        public void AddMeshRenderer(GPURendererRes res)
        {
            BakedGPUSkinnedMeshRenderer bsmr = new BakedGPUSkinnedMeshRenderer();

            bsmr.Init(this, res);

            _bakedRenderers.Add(bsmr);
        }
コード例 #5
0
 public void Add(int id, GPURendererRes data)
 {
     if (_dic.ContainsKey(id))
     {
         Debug.LogErrorFormat("AdditionalMeshCache already contains key {0}", id);
         return;
     }
     _dic.Add(id, data);
 }
コード例 #6
0
        private void CreateBakedTexture2D(GPURendererRes res)
        {
            Texture2D tex = new Texture2D(res.skinningData.width, res.skinningData.height, TextureFormat.RGBAHalf, false, true);

            tex.name       = string.Format("BakedAnimTexture_{0}", res.skinningData.name);
            tex.filterMode = FilterMode.Point;
            tex.LoadRawTextureData(res.skinningData.bakedBoneDatas);
            tex.Apply(false, true);
            tex.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor;

            res.bakedAnimTex = tex;
        }
コード例 #7
0
        /// <summary>
        /// 创建 GPUSkin 所需的 Mesh, 强制每个顶点只有两根骨骼
        ///
        /// 由于 Unity 没有开放 BLENDINDICES 和 BLENDWEIGHT 语义,我们又不想修改资源内的原始mesh,只能自己创建一个 mesh 来存储,
        /// 缺点就是每个顶点多出了 4 * 4 个字节的体积, 假设每个模型 4000 个顶点,共缓存了 30 套模型,那么将多出
        /// 16 * 4000 * 30 = 1920000 = 1.83MB, 可以接受
        /// </summary>
        /// <param name="smr"></param>
        /// <returns></returns>
        private void CreateSkinMesh(SkinnedMeshRenderer smr, GPURendererRes res)
        {
            int[] boneIdxMap = GPUAnimUtils.CalcBoneIdxMap(smr, res.skinningData);

            Mesh smrMesh = smr.sharedMesh;

            Mesh addMesh = new Mesh();

            BoneWeight[]   oriBoneWeights = smrMesh.boneWeights;
            int            weightCount    = oriBoneWeights.Length;
            List <Vector4> boneIndices    = new List <Vector4>(weightCount);
            List <Vector4> boneWeights    = new List <Vector4>(weightCount);

            for (int i = 0; i < weightCount; i++)
            {
                BoneWeight weight  = oriBoneWeights[i];
                Vector4    indices = new Vector4();
                indices.x = boneIdxMap[weight.boneIndex0]; // 骨骼索引重新映射下
                indices.y = boneIdxMap[weight.boneIndex1];
                indices.z = boneIdxMap[weight.boneIndex2];
                indices.w = boneIdxMap[weight.boneIndex3];
                boneIndices.Add(indices);

                Vector4 weights = new Vector4();
                weights.x = weight.weight0;
                weights.y = weight.weight1;
                weights.z = weight.weight2;
                weights.w = weight.weight3;
                boneWeights.Add(weights);

                //float sum = weight.weight0 + weight.weight1;
                //blendWeights[i].x = weight.weight0 / sum;
                //blendWeights[i].y = weight.weight1 /sum;
            }

            addMesh.vertices = smrMesh.vertices; // 由于 Unity 有判断要求其它 channel 长度必须与 vertices 相等,这个内存只能浪费掉了
            addMesh.SetUVs(2, boneIndices);
            addMesh.SetUVs(3, boneWeights);
            //addMesh.uv3      = blendIndices;
            //addMesh.uv4      = blendWeights;
            addMesh.UploadMeshData(true); // warning!, DeviceLost 时可能无法恢复数据

            res.additionalMesh = addMesh;
        }
コード例 #8
0
        /// <summary>
        /// 获取或者创建 Res
        /// </summary>
        /// <param name="smr"></param>
        /// <param name="skinningData"></param>
        /// <returns></returns>
        public GPURendererRes GetOrCreateRes(SkinnedMeshRenderer smr, SkinningData skinningData)
        {
            int            id  = smr.sharedMesh.GetInstanceID();
            GPURendererRes ret = null;

            if (_dic.TryGetValue(id, out ret))
            {
                return(ret);
            }

            ret = new GPURendererRes();
            ret.skinningData = skinningData;
            ret.mesh         = smr.sharedMesh;
            CreateSkinMesh(smr, ret);
            CreateBakedTexture2D(ret);
            CreateMaterial(smr, ret);

            _dic.Add(id, ret);

            return(ret);
        }
コード例 #9
0
        private void CreateMaterial(SkinnedMeshRenderer smr, GPURendererRes res)
        {
            Texture2D animTex = res.bakedAnimTex;

            Material srcMat = smr.sharedMaterial;

            Material bakedGPUMaterial = new Material(Shader.Find("GPUSkinning/BakedGPUSkinning"));

            bakedGPUMaterial.SetTexture("_MainTex", srcMat.mainTexture);
            bakedGPUMaterial.SetTexture("_BakedAnimTex", animTex);
            bakedGPUMaterial.SetVector("_BakedAnimTexWH", new Vector4(res.skinningData.width, res.skinningData.height, 0, 0));
            bakedGPUMaterial.enableInstancing = true;

            Material GPUMaterial = new Material(Shader.Find("GPUSkinning/GPUSkinning"));

            GPUMaterial.SetTexture("_MainTex", srcMat.mainTexture);
            GPUMaterial.enableInstancing = true;

            res.bakedGPUMaterial = bakedGPUMaterial;
            res.GPUMaterial      = GPUMaterial;
        }
コード例 #10
0
        private Vector4[]       _matrixPalette; // _boneIdxMap.Length * 3

        public void Init(GPUAnimation gpuAnim, GPURendererRes res)
        {
            _gpuAnimation  = gpuAnim;
            _res           = res;
            _matrixPalette = new Vector4[_boneIdxMap.Length * 3];
        }
コード例 #11
0
        /// <summary>
        /// 将除 mesh 节点,挂点(将其提到最顶级),rootMotion 之外的所有节点移除
        /// </summary>
        private void ProcessNode()
        {
            _rootMotionNode = transform.Find(Consts.ROOT_MOTION_NAME);

            List <Transform> allChildren = new List <Transform>();

            GPUAnimUtils.GetAllChildren(transform, allChildren);

            List <SkinnedMeshRenderer> smrs = new List <SkinnedMeshRenderer>();

            foreach (var node in allChildren)
            {
                if (node == transform)
                {
                    continue;
                }

                SkinnedMeshRenderer smr = node.GetComponent <SkinnedMeshRenderer>();
                if (smr != null)
                {
                    /*
                     *  调试代码,发布时把 if 去掉
                     *  (挂载的这个武器并不能使用模型的 Animation, 并且其 Bone 数量也为0,因此应该是用 MeshRenderer 而不是 SkinnedMeshRenderer)
                     */
                    if (node.name != "right_weapon")
                    {
                        // 某些 smr 不位于模型直接子节点,将其提升以避免被移除掉(显示不会受到影响)
                        if (node.parent != transform)
                        {
                            node.parent = transform;
                        }
                        smrs.Add(smr);
                        continue;
                    }
                }

                if (node == _rootMotionNode)
                {
                    continue;
                }

                bool isJoint = false;
                //foreach (var name in skinningData.jointNames)
                //{
                //    if (name == node.name)
                //    {
                //        node.parent = transform;
                //        isJoint = true;
                //        break;
                //    }
                //}

                if (!isJoint)
                {
                    // 不要使用 DestroyImmediate, 否则循环中的其它元素可能无法访问并且下面的 bsmr.Init 无法获取到 bones
                    Destroy(node.gameObject);
                }
            }

            // 原始的 SkinnedMeshRenderer 都创建对应的两种 Renderer
            foreach (var smr in smrs)
            {
                GPURendererRes res = GPUSkinRuntimeResMgr.Instance.GetOrCreateRes(smr, skinningData);
                _bakedGPUAnimation.AddMeshRenderer(res);
                _GPUAnimation.AddMeshRenderer(res);
                DestroyImmediate(smr);
            }

            Animation oriAnimation = gameObject.GetComponent <Animation>();

            if (oriAnimation != null)
            {
                DestroyImmediate(oriAnimation);
            }

            // 初始化绑点
            //_jointTrans = new Transform[skinningData.jointNames.Length];
            //for (int i = 0; i < _jointTrans.Length; i++)
            //{
            //    Transform t = transform.Find(skinningData.jointNames[i]);
            //    if (t == null)
            //    {
            //        Debug.LogErrorFormat("can not find join {0}", skinningData.jointNames[i]);
            //        return;
            //    }

            //    _jointTrans[i] = t;
            //}

            _bakedGPUAnimation.SetJointTransforms(_jointTrans);
            _GPUAnimation.SetJointTransforms(_jointTrans);
        }