Exemple #1
0
        private void ReleaseBuffer()
        {
#if USE_CONSTANT_BUFFER
#else
            foreach (var obj in vertexCachePool)
            {
                VertexCache vertexCache = obj.Value;
                vertexCache.bufVertex.Release();
                vertexCache.bufVertex = null;
                if (vertexCache.bufInstance != null)
                {
                    vertexCache.bufInstance.Release();
                    vertexCache.bufInstance = null;
                }

                foreach (var buf in vertexCache.bufArgs)
                {
                    buf.Release();
                }
                vertexCache.bufArgs = null;
            }
#endif
            if (vertexCachePool != null)
            {
                vertexCachePool.Clear();
            }
        }
    private void Render()
    {
        foreach (var obj in vertexCachePool)
        {
            VertexCache vertexCache = obj.Value;
            for (int k = 0; k != vertexCache.packageList.Length; ++k)
            {
                for (int i = 0; i != vertexCache.packageList[k].Count; ++i)
                {
                    VertexCache.InstancingPackage package = vertexCache.packageList[k][i];
                    if (package.instancingCount == 0)
                    {
                        continue;
                    }
                    for (int j = 0; j != package.subMeshCount; ++j)
                    {
                        if (UseInstancing)
                        {
#if UNITY_EDITOR
                            PreparePackageMaterial(package, vertexCache, k);
#endif
                            package.propertyBlock.SetFloatArray("frameIndex",
                                                                vertexCache.instanceData.FrameIndex[k][i]);
                            package.propertyBlock.SetFloatArray("preFrameIndex",
                                                                vertexCache.instanceData.PreFrameIndex[k][i]);
                            package.propertyBlock.SetFloatArray("transitionProgress",
                                                                vertexCache.instanceData.TransitionProgress[k][i]);
                            Graphics.DrawMeshInstanced(vertexCache.mesh,
                                                       j,
                                                       package.material[j],
                                                       vertexCache.instanceData.WorldMatrix[k][i],
                                                       package.instancingCount,
                                                       package.propertyBlock,
                                                       ShadowCastingMode.On,
                                                       true,
                                                       0);
                        }
                        else
                        {
                            package.material[j].SetFloat("frameIndex", vertexCache.instanceData.FrameIndex[k][i][0]);
                            package.material[j].SetFloat("preFrameIndex",
                                                         vertexCache.instanceData.PreFrameIndex[k][i][0]);
                            package.material[j].SetFloat("transitionProgress",
                                                         vertexCache.instanceData.TransitionProgress[k][i][0]);
                            Graphics.DrawMesh(vertexCache.mesh,
                                              vertexCache.instanceData.WorldMatrix[k][i][0],
                                              package.material[j],
                                              0,
                                              null,
                                              j);
                        }
                    }

                    package.instancingCount = 0;
                }

                vertexCache.runtimePackageIndex[k] = 0;
            }
        }
    }
Exemple #3
0
 protected internal override void Draw(int X, int Y)
 {
     if (this.m_Invalidated)
     {
         this.Refresh();
     }
     if (!this.m_Draw)
     {
         return;
     }
     Renderer.PushAlpha(this.m_fAlpha);
     if (!this.m_Clip)
     {
         if (this.m_vCache == null)
         {
             this.m_vCache = this.VCPool.GetInstance();
         }
         this.m_vCache.Draw(this.m_Image, X, Y);
     }
     else if (!this.m_Relative)
     {
         this.m_Image.DrawClipped(X, Y, this.m_Clipper);
     }
     else
     {
         this.m_Image.DrawClipped(X, Y, Clipper.TemporaryInstance(X + this.m_xClipOffset, Y + this.m_yClipOffset, this.m_xClipWidth, this.m_yClipHeight));
     }
     Renderer.PopAlpha();
 }
        public VertexCache FindVertexCache(int renderName)
        {
            VertexCache cache = null;

            vertexCachePool.TryGetValue(renderName, out cache);
            return(cache);
        }
Exemple #5
0
 protected internal override void Draw(int x, int y)
 {
     if (this.m_Invalidated)
     {
         this.Refresh();
     }
     if (!this.m_Draw)
     {
         return;
     }
     Renderer.PushAlpha(this.m_fAlpha);
     if (this.m_Clipper == null)
     {
         if (this.m_vCache == null)
         {
             this.m_vCache = this.VCPool.GetInstance();
         }
         this.m_vCache.Draw(this.m_Image, x, y);
     }
     else
     {
         this.m_Image.DrawClipped(x, y, this.m_Clipper);
     }
     Renderer.PopAlpha();
 }
Exemple #6
0
 public override void OnStop()
 {
     this.VCPool.ReleaseInstance(this.m_vCache);
     this.m_vCache = (VertexCache)null;
     this.VCPool.ReleaseInstance(this.m_vCache);
     this.m_vCacheDouble = (VertexCache)null;
 }
        public void BindAttachment(VertexCache parentCache, VertexCache attachmentCache, Mesh sharedMesh, int boneIndex)
        {
            Matrix4x4 mat = parentCache.bindPose[boneIndex].inverse;

            attachmentCache.mesh = Instantiate(sharedMesh);
            Vector3    offset = mat.GetColumn(3);
            Quaternion q      = RuntimeHelper.QuaternionFromMatrix(mat);

            Vector3[] vertices = attachmentCache.mesh.vertices;
            for (int k = 0; k != attachmentCache.mesh.vertexCount; ++k)
            {
                vertices[k] = q * vertices[k];
                vertices[k] = vertices[k] + offset;
            }
            attachmentCache.mesh.vertices = vertices;

            for (int j = 0; j != attachmentCache.mesh.vertexCount; ++j)
            {
                attachmentCache.weight[j].x    = 1.0f;
                attachmentCache.weight[j].y    = -0.1f;
                attachmentCache.weight[j].z    = -0.1f;
                attachmentCache.weight[j].w    = -0.1f;
                attachmentCache.boneIndex[j].x = boneIndex;
            }
        }
    private VertexCache CreateVertexCache(string prefabName, int renderName, int alias, Mesh mesh)
    {
        VertexCache vertexCache = new VertexCache();
        int         cacheName   = renderName + alias;

        vertexCachePool[cacheName]   = vertexCache;
        vertexCache.nameCode         = cacheName;
        vertexCache.mesh             = mesh;
        vertexCache.boneTextureIndex =
            FindTexture_internal(
                prefabName); //因为Texture不是从AnimationInfo读进来的,而是作为BoneInfo读入,所以需要在这里通过prefabName将boneTexture和vertexCache连起来。
        vertexCache.weight    = new Vector4[mesh.vertexCount];
        vertexCache.boneIndex = new Vector4[mesh.vertexCount];
        int packageCount = 1;

        if (vertexCache.boneTextureIndex >= 0) //如果找到了boneTexture,那么packageCount装载为该prefab的BoneTexture数。
        {
            BoneTextureInfo texture = _boneTextrueInfo[vertexCache.boneTextureIndex];
            packageCount = texture.BoneTexture.Length;
        }

        //建立了packageList,也是空的。

        vertexCache.packageList = new List <VertexCache.InstancingPackage> [packageCount];
        for (int i = 0; i != vertexCache.packageList.Length; ++i)
        {
            vertexCache.packageList[i] = new List <VertexCache.InstancingPackage>();
        }

        vertexCache.runtimePackageIndex = new int[packageCount];

        InstanceData data         = null;
        int          instanceName = prefabName.GetHashCode() + alias;

        //这里往instanceDataPool里面加入了一个空的data,只有Instancename。,并且创建只进行到List<float[]>[]的List层次,往List里面注入float[]在CreatPackage里面完成。
        if (!instanceDataPool.TryGetValue(instanceName, out data))
        {
            data                    = new InstanceData();
            data.WorldMatrix        = new List <Matrix4x4[]> [packageCount];
            data.FrameIndex         = new List <float[]> [packageCount];
            data.PreFrameIndex      = new List <float[]> [packageCount];
            data.TransitionProgress = new List <float[]> [packageCount];
            for (int i = 0; i != packageCount; ++i)
            {
                data.WorldMatrix[i]        = new List <Matrix4x4[]>();
                data.FrameIndex[i]         = new List <float[]>();
                data.PreFrameIndex[i]      = new List <float[]>();
                data.TransitionProgress[i] = new List <float[]>();
            }

            instanceDataPool.Add(instanceName, data);
        }

        vertexCache.instanceData = data;

        return(vertexCache);
    }
        int GetPackageCount(VertexCache vertexCache)
        {
            int packageCount = 1;

            if (vertexCache.boneTextureIndex >= 0)
            {
                AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex];
                packageCount = texture.boneTexture.Length;
            }
            return(packageCount);
        }
Exemple #10
0
        private void SetupVertexCache(VertexCache vertexCache,
                                      MeshRenderer render,
                                      Mesh mesh,
                                      Transform[] boneTransform,
                                      int bonePerVertex)
        {
            int boneIndex = -1;

            if (boneTransform != null)
            {
                for (int k = 0; k != boneTransform.Length; ++k)
                {
                    if (render.transform.parent.name.GetHashCode() == boneTransform[k].name.GetHashCode())
                    {
                        boneIndex = k;
                        break;
                    }
                }
            }
#if USE_CONSTANT_BUFFER
            if (boneIndex >= 0)
            {
                BindAttachment(vertexCache, vertexCache.mesh, boneIndex);
            }
#else
            for (int j = 0; j != mesh.vertexCount; ++j)
            {
                vertexCache.vertex[j].weight.x   = 1.0f;
                vertexCache.vertex[j].weight.y   = -0.1f;
                vertexCache.vertex[j].weight.z   = -0.1f;
                vertexCache.vertex[j].weight.w   = -0.1f;
                vertexCache.vertex[j].boneIndex1 = boneIndex[0];
            }
#endif

            if (vertexCache.materials == null)
            {
                vertexCache.materials = render.materials;
            }

#if USE_CONSTANT_BUFFER
            SetupAdditionalData(vertexCache);
            for (int i = 0; i != vertexCache.packageList.Length; ++i)
            {
                VertexCache.InstancingPackage package = CreatePackage(vertexCache.instanceData, vertexCache.mesh, render.materials, i);
                vertexCache.packageList[i].Add(package);
                PreparePackageMaterial(package, vertexCache, i);
            }
#else
            vertexCache.bufVertex = new ComputeBuffer(vertexCache.vertex.Length, 16 + 16);
            vertexCache.bufVertex.SetData(vertexCache.vertex);
#endif
        }
Exemple #11
0
        /// <summary>
        /// Finalize arrays for vertices and polygons
        /// by linking to cached versions
        /// </summary>
        public void FinalizePVArrays()
        {
            for (var i = 0; i < VertexArray.Vertices.Count; i++)
            {
                VertexArray.Vertices[i] = VertexCache.Get(VertexArray.Vertices[i]);
            }

            for (var i = 0; i < Polygons.Count; i++)
            {
                Polygons[i] = PolygonCache.Get(Polygons[i]);
            }
        }
Exemple #12
0
 public GItemArt(int x, int y, int itemID, IHue hue)
     : base(x, y)
 {
     this.m_vCache = new VertexCache();
     this.m_Hue    = hue;
     this.m_ItemID = itemID;
     this.m_Image  = hue.GetItem(itemID);
     if (this.m_Image == null || this.m_Image.IsEmpty())
     {
         return;
     }
     this.m_Width  = this.m_Image.Width;
     this.m_Height = this.m_Image.Height;
     this.m_Draw   = true;
 }
Exemple #13
0
        public int WriteVertex(byte[] vertexData, int posIdx, Vector2 texCoord)
        {
            if (_vertices[posIdx] == null)
            {
                _vertices[posIdx] = new List <VertexCache>();
                _taken[posIdx]    = true;
            }

            VertexCache vc = new VertexCache(posIdx, texCoord, _count);

            _vertices[posIdx].Add(vc);
            _vertexBufferData.Write(vertexData, 0, vertexData.Length);
            _count++;
            return(vc.VertexBufferIndex);
        }
 /// <summary>
 /// 设置anim_ins鱼类的效果
 /// </summary>
 /// <param name="go"></param>
 /// <param name="val"></param>
 public void SetInnerEffectState(GameObject go, int val)
 {
     AnimationInstancing.LodInfo[] lodinfo = go.GetComponentInChildren <AnimationInstancing>().lodInfo;
     for (int i = 0; i < lodinfo.Length; i++)
     {
         AnimationInstancing.LodInfo lod = lodinfo[i];
         for (int h = 0; h < lod.vertexCacheList.Length; h++)
         {
             VertexCache cache = lod.vertexCacheList[h];
             foreach (var block in cache.instanceBlockList)
             {
                 block.Value.instanceData.isshowInner = val;
             }
         }
     }
 }
Exemple #15
0
        /// <summary>
        /// Constructs a polygon from the DAT file
        /// </summary>
        public Polygon(DatLoader.Entity.Polygon polygon, DatLoader.Entity.CVertexArray vertexArray)
        {
            NegSurface = polygon.NegSurface;
            //NegUVIndices = polygon.NegUVIndices;
            PosSurface = polygon.PosSurface;
            //PosUVIndices = polygon.PosUVIndices;
            SidesType = polygon.SidesType;
            Stippling = polygon.Stippling;
            VertexIDs = polygon.VertexIds;
            Vertices  = new List <Vertex>();
            foreach (var vertexIdx in VertexIDs)
            {
                Vertices.Add(VertexCache.Get(vertexArray.Vertices[(ushort)vertexIdx]));
            }

            make_plane();
        }
        public void PreparePackageMaterial(InstancingPackage package, VertexCache vertexCache, int aniTextureIndex)
        {
            if (vertexCache.boneTextureIndex < 0)
            {
                return;
            }

            for (int i = 0; i != package.subMeshCount; ++i)
            {
                AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex];
                package.material[i].SetTexture("_boneTexture", texture.boneTexture[aniTextureIndex]);
                package.material[i].SetInt("_boneTextureWidth", texture.boneTexture[aniTextureIndex].width);
                package.material[i].SetInt("_boneTextureHeight", texture.boneTexture[aniTextureIndex].height);
                package.material[i].SetInt("_boneTextureBlockWidth", texture.blockWidth);
                package.material[i].SetInt("_boneTextureBlockHeight", texture.blockHeight);
            }
        }
Exemple #17
0
        void RefreshMaterial()
        {
            if (vertexCachePool == null)
            {
                return;
            }

            foreach (var obj in vertexCachePool)
            {
                VertexCache cache = obj.Value;
                for (int j = 0; j != cache.packageList.Length; ++j)
                {
                    for (int k = 0; k != cache.packageList[j].Count; ++k)
                    {
                        VertexCache.InstancingPackage package = cache.packageList[j][k];
                        PreparePackageMaterial(package, cache, j);
                    }
                }
            }
        }
    //SetupVertexCache(vertexCache, lod.meshRenderer[i], m, bones, bonePerVertex);
    private void SetupVertexCache(VertexCache vertexCache,
                                  MeshRenderer render,
                                  Mesh mesh,
                                  Transform[] boneTransform,
                                  int bonePerVertex)
    {
        int boneIndex = -1;

        if (boneTransform != null)
        {
            for (int k = 0; k != boneTransform.Length; ++k)
            {
                //找到vertexCache对应render的parent在boneTransform中的对应序号。
                if (render.transform.parent.name.GetHashCode() == boneTransform[k].name.GetHashCode())
                {
                    boneIndex = k;
                    break;
                }
            }
        }

        if (boneIndex >= 0)
        {
            BindAttachment(vertexCache, vertexCache.mesh, boneIndex);
        }


        if (vertexCache.materials == null)
        {
            vertexCache.materials =
                render.sharedMaterials; //材质从render.sharedMaterials里面获得,来自于prefab的materials,故需要在prefab中就对Materials更改为InstacingShader。
        }
        SetupAdditionalData(vertexCache);
        for (int i = 0; i != vertexCache.packageList.Length; ++i)
        {
            VertexCache.InstancingPackage package =
                CreatePackage(vertexCache.instanceData, vertexCache.mesh, render.sharedMaterials, i);
            vertexCache.packageList[i].Add(package);
            PreparePackageMaterial(package, vertexCache, i);
        }
    }
Exemple #19
0
 public void Draw(int x, int y)
 {
     if (!this.m_Draw)
     {
         return;
     }
     x += this.m_X;
     y += this.m_Y;
     if (this.m_Tile)
     {
         this.m_Image.Draw(x, y, this.m_Width, this.m_Height, 16777215);
     }
     else
     {
         if (this.m_vCache == null)
         {
             this.m_vCache = new VertexCache();
         }
         this.m_vCache.Draw(this.m_Image, x, y);
     }
 }
        public void SetupAdditionalData(VertexCache vertexCache)
        {
            Color[] colors = new Color[vertexCache.weight.Length];
            for (int i = 0; i != colors.Length; ++i)
            {
                colors[i].r = vertexCache.weight[i].x;
                colors[i].g = vertexCache.weight[i].y;
                colors[i].b = vertexCache.weight[i].z;
                colors[i].a = vertexCache.weight[i].w;
            }
            vertexCache.mesh.colors = colors;

            List <Vector4> uv2 = new List <Vector4>(vertexCache.boneIndex.Length);

            for (int i = 0; i != vertexCache.boneIndex.Length; ++i)
            {
                uv2.Add(vertexCache.boneIndex[i]);
            }
            vertexCache.mesh.SetUVs(2, uv2);
            vertexCache.mesh.UploadMeshData(false);
        }
        MaterialBlock CreateBlock(VertexCache cache, Material[] materials)
        {
            MaterialBlock block        = new MaterialBlock();
            int           packageCount = GetPackageCount(cache);

            block.instanceData = CreateInstanceData(packageCount);
            block.packageList  = new List <InstancingPackage> [packageCount];
            for (int i = 0; i != block.packageList.Length; ++i)
            {
                block.packageList[i] = new List <InstancingPackage>();

                InstancingPackage package = CreatePackage(block.instanceData,
                                                          cache.mesh,
                                                          materials,
                                                          i);
                block.packageList[i].Add(package);
                PreparePackageMaterial(package, cache, i);
                package.instancingCount = 1;
            }
            block.runtimePackageIndex = new int[packageCount];
            return(block);
        }
Exemple #22
0
        public int WriteVertex(byte[] vertexData, int posIdx, int normalIdx, int texCoordIdx)
        {
            _taken[posIdx] = true;

            if (_vertices[posIdx] == null)
            {
                _vertices[posIdx] = new List <VertexCache>();
            }

            VertexCache vc = new VertexCache
            {
                PosIndex          = posIdx,
                NormalIndex       = normalIdx,
                TexCoordIndex     = texCoordIdx,
                VertexBufferIndex = _count
            };

            _vertices[posIdx].Add(vc);
            _vertexBufferData.Write(vertexData, 0, vertexData.Length);
            _count++;
            return(vc.VertexBufferIndex);
        }
        private VertexCache CreateVertexCache(string prefabName, int renderName, int alias, Mesh mesh)
        {
            VertexCache vertexCache = new VertexCache();
            int         cacheName   = renderName + alias;

            vertexCachePool[cacheName]   = vertexCache;
            vertexCache.nameCode         = cacheName;
            vertexCache.mesh             = mesh;
            vertexCache.boneTextureIndex = FindTexture_internal(prefabName);
            vertexCache.weight           = new Vector4[mesh.vertexCount];
            vertexCache.boneIndex        = new Vector4[mesh.vertexCount];
            int          packageCount = GetPackageCount(vertexCache);
            InstanceData data         = null;
            int          instanceName = prefabName.GetHashCode() + alias;

            if (!instanceDataPool.TryGetValue(instanceName, out data))
            {
                data = CreateInstanceData(packageCount);
                instanceDataPool.Add(instanceName, data);
            }
            vertexCache.instanceBlockList = new Dictionary <int, MaterialBlock>();
            return(vertexCache);
        }
        private void SetupVertexCache(VertexCache vertexCache,
                                      MaterialBlock block,
                                      MeshRenderer render,
                                      Mesh mesh,
                                      Transform[] boneTransform,
                                      int bonePerVertex)
        {
            int boneIndex = -1;

            if (boneTransform != null)
            {
                for (int k = 0; k != boneTransform.Length; ++k)
                {
                    if (render.transform.parent.name.GetHashCode() == boneTransform[k].name.GetHashCode())
                    {
                        boneIndex = k;
                        break;
                    }
                }
            }
            if (boneIndex >= 0)
            {
                //todo
                BindAttachment(vertexCache, vertexCache, vertexCache.mesh, boneIndex);
            }
            if (vertexCache.materials == null)
            {
                vertexCache.materials = render.sharedMaterials;
            }
            SetupAdditionalData(vertexCache);
            for (int i = 0; i != block.packageList.Length; ++i)
            {
                InstancingPackage package = CreatePackage(block.instanceData, vertexCache.mesh, render.sharedMaterials, i);
                block.packageList[i].Add(package);
                PreparePackageMaterial(package, vertexCache, i);
            }
        }
Exemple #25
0
        // alias is to use for attachment, it's usually a bone name
        public void AddMeshVertex(string prefabName,
                                  AnimationInstancing.LodInfo[] lodInfo,
                                  Transform[] bones,
                                  List <Matrix4x4> bindPose,
                                  int bonePerVertex,
                                  string alias = null)
        {
            UnityEngine.Profiling.Profiler.BeginSample("AddMeshVertex()");
            for (int x = 0; x != lodInfo.Length; ++x)
            {
                AnimationInstancing.LodInfo lod = lodInfo[x];
                for (int i = 0; i != lod.skinnedMeshRenderer.Length; ++i)
                {
                    Mesh m = lod.skinnedMeshRenderer[i].sharedMesh;
                    if (m == null)
                    {
                        continue;
                    }

                    int         nameCode = lod.skinnedMeshRenderer[i].name.GetHashCode();
                    VertexCache cache    = null;
                    if (vertexCachePool.TryGetValue(nameCode, out cache))
                    {
                        lod.vertexCacheList[i] = cache;
#if !USE_CONSTANT_BUFFER
                        ++cache.instancingCount;
#endif
                        continue;
                    }

                    VertexCache vertexCache = CreateVertexCache(prefabName, nameCode, 0, m);
                    vertexCache.bindPose   = bindPose.ToArray();
                    lod.vertexCacheList[i] = vertexCache;
                    SetupVertexCache(vertexCache, lod.skinnedMeshRenderer[i], bones, bonePerVertex);
                }

                for (int i = 0, j = lod.skinnedMeshRenderer.Length; i != lod.meshRenderer.Length; ++i, ++j)
                {
                    Mesh m = lod.meshFilter[i].sharedMesh;
                    if (m == null)
                    {
                        continue;
                    }

                    int         renderName = lod.meshRenderer[i].name.GetHashCode();
                    int         aliasName  = (alias != null ? alias.GetHashCode() : 0);
                    VertexCache cache      = null;
                    if (vertexCachePool.TryGetValue(renderName + aliasName, out cache))
                    {
                        lod.vertexCacheList[j] = cache;
#if !USE_CONSTANT_BUFFER
                        ++cache.instancingCount;
#endif
                        continue;
                    }

                    VertexCache vertexCache = CreateVertexCache(prefabName, renderName, aliasName, m);
                    if (bindPose != null)
                    {
                        vertexCache.bindPose = bindPose.ToArray();
                    }
                    lod.vertexCacheList[lod.skinnedMeshRenderer.Length + i] = vertexCache;
                    SetupVertexCache(vertexCache, lod.meshRenderer[i], m, bones, bonePerVertex);
                }
#if !USE_CONSTANT_BUFFER
                foreach (var obj in vertexCachePool)
                {
                    VertexCache vertexCache = obj.Value;

                    for (int j = 0; j != vertexCache.subMeshCount; ++j)
                    {
                        Material material = vertexCache.instanceMaterial[j];
                        material.SetBuffer("buf_Vertex", vertexCache.bufVertex);
                    }
                }
#endif
            }

            UnityEngine.Profiling.Profiler.EndSample();
        }
        private void SetupVertexCache(VertexCache vertexCache,
                                      MaterialBlock block,
                                      SkinnedMeshRenderer render,
                                      Transform[] boneTransform,
                                      int bonePerVertex)
        {
            int[] boneIndex = null;
            if (render.bones.Length != boneTransform.Length)
            {
                if (render.bones.Length == 0)
                {
                    boneIndex = new int[1];
                    int hashRenderParentName = render.transform.parent.name.GetHashCode();
                    for (int k = 0; k != boneTransform.Length; ++k)
                    {
                        if (hashRenderParentName == boneTransform[k].name.GetHashCode())
                        {
                            boneIndex[0] = k;
                            break;
                        }
                    }
                }
                else
                {
                    boneIndex = new int[render.bones.Length];
                    for (int j = 0; j != render.bones.Length; ++j)
                    {
                        boneIndex[j] = -1;
                        Transform trans             = render.bones[j];
                        int       hashTransformName = trans.name.GetHashCode();
                        for (int k = 0; k != boneTransform.Length; ++k)
                        {
                            if (hashTransformName == boneTransform[k].name.GetHashCode())
                            {
                                boneIndex[j] = k;
                                break;
                            }
                        }
                    }

                    if (boneIndex.Length == 0)
                    {
                        boneIndex = null;
                    }
                }
            }

            UnityEngine.Profiling.Profiler.BeginSample("Copy the vertex data in SetupVertexCache()");
            Mesh m = render.sharedMesh;

            BoneWeight[] boneWeights = m.boneWeights;
            Debug.Assert(boneWeights.Length > 0);
            for (int j = 0; j != m.vertexCount; ++j)
            {
                vertexCache.weight[j].x = boneWeights[j].weight0;
                Debug.Assert(vertexCache.weight[j].x > 0.0f);
                vertexCache.weight[j].y = boneWeights[j].weight1;
                vertexCache.weight[j].z = boneWeights[j].weight2;
                vertexCache.weight[j].w = boneWeights[j].weight3;
                vertexCache.boneIndex[j].x
                    = boneIndex == null ? boneWeights[j].boneIndex0 : boneIndex[boneWeights[j].boneIndex0];
                vertexCache.boneIndex[j].y
                    = boneIndex == null ? boneWeights[j].boneIndex1 : boneIndex[boneWeights[j].boneIndex1];
                vertexCache.boneIndex[j].z
                    = boneIndex == null ? boneWeights[j].boneIndex2 : boneIndex[boneWeights[j].boneIndex2];
                vertexCache.boneIndex[j].w
                    = boneIndex == null ? boneWeights[j].boneIndex3 : boneIndex[boneWeights[j].boneIndex3];
                Debug.Assert(vertexCache.boneIndex[j].x >= 0);
                if (bonePerVertex == 3)
                {
                    float rate = 1.0f / (vertexCache.weight[j].x + vertexCache.weight[j].y + vertexCache.weight[j].z);
                    vertexCache.weight[j].x = vertexCache.weight[j].x * rate;
                    vertexCache.weight[j].y = vertexCache.weight[j].y * rate;
                    vertexCache.weight[j].z = vertexCache.weight[j].z * rate;
                    vertexCache.weight[j].w = -0.1f;
                }
                else if (bonePerVertex == 2)
                {
                    float rate = 1.0f / (vertexCache.weight[j].x + vertexCache.weight[j].y);
                    vertexCache.weight[j].x = vertexCache.weight[j].x * rate;
                    vertexCache.weight[j].y = vertexCache.weight[j].y * rate;
                    vertexCache.weight[j].z = -0.1f;
                    vertexCache.weight[j].w = -0.1f;
                }
                else if (bonePerVertex == 1)
                {
                    vertexCache.weight[j].x = 1.0f;
                    vertexCache.weight[j].y = -0.1f;
                    vertexCache.weight[j].z = -0.1f;
                    vertexCache.weight[j].w = -0.1f;
                }
            }
            UnityEngine.Profiling.Profiler.EndSample();

            if (vertexCache.materials == null)
            {
                vertexCache.materials = render.sharedMaterials;
            }
            SetupAdditionalData(vertexCache);
            for (int i = 0; i != block.packageList.Length; ++i)
            {
                InstancingPackage package = CreatePackage(block.instanceData, vertexCache.mesh, render.sharedMaterials, i);
                block.packageList[i].Add(package);
                //vertexCache.packageList[i].Add(package);
                PreparePackageMaterial(package, vertexCache, i);
            }
        }
        // alias is to use for attachment, it should be a bone name
        public void AddMeshVertex(string prefabName,
                                  AnimationInstancing.LodInfo[] lodInfo,
                                  Transform[] bones,
                                  List <Matrix4x4> bindPose,
                                  int bonePerVertex,
                                  string alias = null)
        {
            UnityEngine.Profiling.Profiler.BeginSample("AddMeshVertex()");
            for (int x = 0; x != lodInfo.Length; ++x)
            {
                AnimationInstancing.LodInfo lod = lodInfo[x];
                for (int i = 0; i != lod.skinnedMeshRenderer.Length; ++i)
                {
                    Mesh m = lod.skinnedMeshRenderer[i].sharedMesh;
                    if (m == null)
                    {
                        continue;
                    }

                    int         nameCode = lod.skinnedMeshRenderer[i].name.GetHashCode();
                    int         identify = GetIdentify(lod.skinnedMeshRenderer[i].sharedMaterials);
                    VertexCache cache    = null;
                    if (vertexCachePool.TryGetValue(nameCode, out cache))
                    {
                        MaterialBlock block = null;
                        if (!cache.instanceBlockList.TryGetValue(identify, out block))
                        {
                            block = CreateBlock(cache, lod.skinnedMeshRenderer[i].sharedMaterials);
                            cache.instanceBlockList.Add(identify, block);
                        }
                        lod.vertexCacheList[i]   = cache;
                        lod.materialBlockList[i] = block;
                        continue;
                    }

                    VertexCache vertexCache = CreateVertexCache(prefabName, nameCode, 0, m);
                    vertexCache.bindPose = bindPose.ToArray();
                    MaterialBlock matBlock = CreateBlock(vertexCache, lod.skinnedMeshRenderer[i].sharedMaterials);
                    vertexCache.instanceBlockList.Add(identify, matBlock);
                    SetupVertexCache(vertexCache, matBlock, lod.skinnedMeshRenderer[i], bones, bonePerVertex);
                    lod.vertexCacheList[i]   = vertexCache;
                    lod.materialBlockList[i] = matBlock;
                }

                for (int i = 0, j = lod.skinnedMeshRenderer.Length; i != lod.meshRenderer.Length; ++i, ++j)
                {
                    Mesh m = lod.meshFilter[i].sharedMesh;
                    if (m == null)
                    {
                        continue;
                    }

                    int         renderName = lod.meshRenderer[i].name.GetHashCode();
                    int         aliasName  = (alias != null ? alias.GetHashCode() : 0);
                    int         identify   = GetIdentify(lod.meshRenderer[i].sharedMaterials);
                    VertexCache cache      = null;
                    if (vertexCachePool.TryGetValue(renderName + aliasName, out cache))
                    {
                        MaterialBlock block = null;
                        if (!cache.instanceBlockList.TryGetValue(identify, out block))
                        {
                            block = CreateBlock(cache, lod.meshRenderer[i].sharedMaterials);
                            cache.instanceBlockList.Add(identify, block);
                        }
                        lod.vertexCacheList[j]   = cache;
                        lod.materialBlockList[j] = block;
                        continue;
                    }

                    VertexCache vertexCache = CreateVertexCache(prefabName, renderName, aliasName, m);
                    if (bindPose != null)
                    {
                        vertexCache.bindPose = bindPose.ToArray();
                    }
                    MaterialBlock matBlock = CreateBlock(vertexCache, lod.meshRenderer[i].sharedMaterials);
                    vertexCache.instanceBlockList.Add(identify, matBlock);
                    SetupVertexCache(vertexCache, matBlock, lod.meshRenderer[i], m, bones, bonePerVertex);
                    lod.vertexCacheList[lod.skinnedMeshRenderer.Length + i]   = vertexCache;
                    lod.materialBlockList[lod.skinnedMeshRenderer.Length + i] = matBlock;
                }
            }

            UnityEngine.Profiling.Profiler.EndSample();
        }
        void ApplyBoneMatrix()
        {
            Vector3 cameraPosition = cameraTransform.position;

            for (int i = 0; i != aniInstancingList.Count; ++i)
            {
                AnimationInstancing instance = aniInstancingList[i];
                if (!instance.IsPlaying())
                {
                    continue;
                }
                if (instance.aniIndex < 0 && instance.parentInstance == null)
                {
                    continue;
                }

                if (instance.applyRootMotion)
                {
                    ApplyRootMotion(instance);
                }

                instance.UpdateAnimation();
                instance.boundingSpere.position = instance.transform.position;
                boundingSphere[i] = instance.boundingSpere;

                if (!instance.visible)
                {
                    continue;
                }
                instance.UpdateLod(cameraPosition);

                AnimationInstancing.LodInfo lod = instance.lodInfo[instance.lodLevel];
                int aniTextureIndex             = -1;
                if (instance.parentInstance != null)
                {
                    aniTextureIndex = instance.parentInstance.aniTextureIndex;
                }
                else
                {
                    aniTextureIndex = instance.aniTextureIndex;
                }

                for (int j = 0; j != lod.vertexCacheList.Length; ++j)
                {
                    VertexCache   cache = lod.vertexCacheList[j];
                    MaterialBlock block = lod.materialBlockList[j];
                    Debug.Assert(block != null);
                    int packageIndex = block.runtimePackageIndex[aniTextureIndex];
                    Debug.Assert(packageIndex < block.packageList[aniTextureIndex].Count);
                    InstancingPackage package = block.packageList[aniTextureIndex][packageIndex];
                    if (package.instancingCount + 1 > instancingPackageSize)
                    {
                        ++block.runtimePackageIndex[aniTextureIndex];
                        packageIndex = block.runtimePackageIndex[aniTextureIndex];
                        if (packageIndex >= block.packageList[aniTextureIndex].Count)
                        {
                            InstancingPackage newPackage = CreatePackage(block.instanceData,
                                                                         cache.mesh,
                                                                         cache.materials,
                                                                         aniTextureIndex);
                            block.packageList[aniTextureIndex].Add(newPackage);
                            PreparePackageMaterial(newPackage, cache, aniTextureIndex);
                            newPackage.instancingCount = 1;
                        }
                        block.packageList[aniTextureIndex][packageIndex].instancingCount = 1;
                    }
                    else
                    {
                        ++package.instancingCount;
                    }

                    {
                        VertexCache       vertexCache = cache;
                        InstanceData      data        = block.instanceData;
                        int               index       = block.runtimePackageIndex[aniTextureIndex];
                        InstancingPackage pkg         = block.packageList[aniTextureIndex][index];
                        int               count       = pkg.instancingCount - 1;
                        if (count >= 0)
                        {
                            Matrix4x4   worldMat = instance.worldTransform.localToWorldMatrix;
                            Matrix4x4[] arrayMat = data.worldMatrix[aniTextureIndex][index];
                            arrayMat[count].m00 = worldMat.m00;
                            arrayMat[count].m01 = worldMat.m01;
                            arrayMat[count].m02 = worldMat.m02;
                            arrayMat[count].m03 = worldMat.m03;
                            arrayMat[count].m10 = worldMat.m10;
                            arrayMat[count].m11 = worldMat.m11;
                            arrayMat[count].m12 = worldMat.m12;
                            arrayMat[count].m13 = worldMat.m13;
                            arrayMat[count].m20 = worldMat.m20;
                            arrayMat[count].m21 = worldMat.m21;
                            arrayMat[count].m22 = worldMat.m22;
                            arrayMat[count].m23 = worldMat.m23;
                            arrayMat[count].m30 = worldMat.m30;
                            arrayMat[count].m31 = worldMat.m31;
                            arrayMat[count].m32 = worldMat.m32;
                            arrayMat[count].m33 = worldMat.m33;
                            float frameIndex = 0, preFrameIndex = -1, transition = 0f;
                            if (instance.parentInstance != null)
                            {
                                frameIndex = instance.parentInstance.aniInfo[instance.parentInstance.aniIndex].animationIndex + instance.parentInstance.curFrame;
                                if (instance.parentInstance.preAniIndex >= 0)
                                {
                                    preFrameIndex = instance.parentInstance.aniInfo[instance.parentInstance.preAniIndex].animationIndex + instance.parentInstance.preAniFrame;
                                }
                                transition = instance.parentInstance.transitionProgress;
                            }
                            else
                            {
                                frameIndex = instance.aniInfo[instance.aniIndex].animationIndex + instance.curFrame;
                                if (instance.preAniIndex >= 0)
                                {
                                    preFrameIndex = instance.aniInfo[instance.preAniIndex].animationIndex + instance.preAniFrame;
                                }
                                transition = instance.transitionProgress;
                            }
                            data.frameIndex[aniTextureIndex][index][count]         = frameIndex;
                            data.preFrameIndex[aniTextureIndex][index][count]      = preFrameIndex;
                            data.transitionProgress[aniTextureIndex][index][count] = transition;
                        }
                    }
                }
            }
        }
        private void Render()
        {
            foreach (var obj in vertexCachePool)
            {
                VertexCache vertexCache = obj.Value;
                foreach (var block in vertexCache.instanceBlockList)
                {
                    List <InstancingPackage>[] packageList = block.Value.packageList;
                    for (int k = 0; k != packageList.Length; ++k)
                    {
                        for (int i = 0; i != packageList[k].Count; ++i)
                        {
                            InstancingPackage package = packageList[k][i];
                            if (package.instancingCount == 0)
                            {
                                continue;
                            }
                            for (int j = 0; j != package.subMeshCount; ++j)
                            {
                                InstanceData data = block.Value.instanceData;
                                if (useInstancing)
                                {
#if UNITY_EDITOR
                                    PreparePackageMaterial(package, vertexCache, k);
#endif
                                    package.propertyBlock.SetFloatArray("frameIndex", data.frameIndex[k][i]);
                                    package.propertyBlock.SetFloatArray("preFrameIndex", data.preFrameIndex[k][i]);
                                    package.propertyBlock.SetFloatArray("transitionProgress", data.transitionProgress[k][i]);
                                    Graphics.DrawMeshInstanced(vertexCache.mesh,
                                                               j,
                                                               package.material[j],
                                                               data.worldMatrix[k][i],
                                                               package.instancingCount,
                                                               package.propertyBlock,
                                                               vertexCache.shadowcastingMode,
                                                               vertexCache.receiveShadow,
                                                               vertexCache.layer);
                                }
                                else
                                {
                                    package.material[j].SetFloat("frameIndex", data.frameIndex[k][i][0]);
                                    package.material[j].SetFloat("preFrameIndex", data.preFrameIndex[k][i][0]);
                                    package.material[j].SetFloat("transitionProgress", data.transitionProgress[k][i][0]);
                                    Graphics.DrawMesh(vertexCache.mesh,
                                                      data.worldMatrix[k][i][0],
                                                      package.material[j],
                                                      0,
                                                      null,
                                                      j);
                                }
                            }
                            package.instancingCount = 0;
                        }
                        block.Value.runtimePackageIndex[k] = 0;
                    }
                }

//                 if (obj.Value.instancingData == null)
//                     continue;
//                 vertexCache.bufInstance.SetData(obj.Value.instancingData);
//
//                 for (int i = 0; i != vertexCache.subMeshCount; ++i)
//                 {
//                     Material material = vertexCache.instanceMaterial[i];
//                     material.SetBuffer("buf_InstanceMatrices", vertexCache.bufInstance);
//                     vertexCache.args[i][1] = (uint)vertexCache.currentInstancingIndex;
//                     vertexCache.bufArgs[i].SetData(vertexCache.args[i]);
//
//                     Graphics.DrawMeshInstancedIndirect(vertexCache.mesh,
//                                     i,
//                                     vertexCache.instanceMaterial[i],
//                                     new Bounds(Vector3.zero, new Vector3(10000.0f, 10000.0f, 10000.0f)),
//                                     vertexCache.bufArgs[i]);
//                 }
//                 vertexCache.currentInstancingIndex = 0;
            }
        }
Exemple #30
0
        private VertexCache CreateVertexCache(string prefabName, int renderName, int alias, Mesh mesh)
        {
            VertexCache vertexCache = new VertexCache();
            int         cacheName   = renderName + alias;

            vertexCachePool[cacheName]   = vertexCache;
            vertexCache.nameCode         = cacheName;
            vertexCache.mesh             = mesh;
            vertexCache.boneTextureIndex = FindTexture_internal(prefabName);
#if USE_CONSTANT_BUFFER
            vertexCache.weight    = new Vector4[mesh.vertexCount];
            vertexCache.boneIndex = new Vector4[mesh.vertexCount];
            int packageCount = 1;
            if (vertexCache.boneTextureIndex >= 0)
            {
                AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex];
                packageCount = texture.boneTexture.Length;
            }

            vertexCache.packageList = new List <VertexCache.InstancingPackage> [packageCount];
            for (int i = 0; i != vertexCache.packageList.Length; ++i)
            {
                vertexCache.packageList[i] = new List <VertexCache.InstancingPackage>();
            }
            vertexCache.runtimePackageIndex = new int[packageCount];

            InstanceData data         = null;
            int          instanceName = prefabName.GetHashCode() + alias;
            if (!instanceDataPool.TryGetValue(instanceName, out data))
            {
                data             = new InstanceData();
                data.worldMatrix = new List <Matrix4x4[]> [packageCount];
                data.frameIndex  = new List <float[]> [packageCount];
                for (int i = 0; i != packageCount; ++i)
                {
                    data.worldMatrix[i] = new List <Matrix4x4[]>();
                    data.frameIndex[i]  = new List <float[]>();
                }
                instanceDataPool.Add(instanceName, data);
            }
            vertexCache.instanceData = data;
#else
            ++vertexCache.instancingCount;
            //vertexCache.indexCount = new uint[m.subMeshCount];
            vertexCache.args             = new uint[mesh.subMeshCount][];
            vertexCache.vertex           = new InstancingVertex[mesh.vertexCount];
            vertexCache.bufArgs          = new ComputeBuffer[mesh.subMeshCount];
            vertexCache.instanceMaterial = new Material[mesh.subMeshCount];
            vertexCache.subMeshCount     = mesh.subMeshCount;
            uint startIndex = 0;
            for (int j = 0; j != mesh.subMeshCount; ++j)
            {
                vertexCache.args[j]    = new uint[5];
                vertexCache.bufArgs[j] = new ComputeBuffer(1, vertexCache.args[j].Length * sizeof(uint), ComputeBufferType.IndirectArguments);
                vertexCache.args[j][0] = mesh.GetIndexCount(j);
                vertexCache.args[j][2] = startIndex;
                startIndex             = vertexCache.args[j][0];
                vertexCache.bufArgs[j].SetData(vertexCache.args[j]);
                vertexCache.instanceMaterial[j] = new Material(renderer.materials[j]);
                vertexCache.instanceMaterial[j].DisableKeyword("USE_CONSTANT_BUFFER");
                vertexCache.instanceMaterial[j].EnableKeyword("USE_COMPUTE_BUFFER");
                AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex] as AnimationTexture;
                vertexCache.instanceMaterial[j].SetTexture("_boneTexture", texture.boneTexture);
                //vertexCache.instanceMaterial[j].SetTexture("_albedoTexture", renderer.materials[j].GetTexture("_MainTex"));
                vertexCache.instanceMaterial[j].SetInt("_boneTextureBlockWidth", texture.blockWidth);
                vertexCache.instanceMaterial[j].SetInt("_boneTextureBlockHeight", texture.blockHeight);
                vertexCache.instanceMaterial[j].SetInt("_boneTextureWidth", texture.boneTexture.width);
                vertexCache.instanceMaterial[j].SetInt("_boneTextureHeight", texture.boneTexture.height);
            }
#endif
            return(vertexCache);
        }