public static void ResetShaderParam(ref InstanceData instanceData)
 {
     ArrayUtils.ClearChecked(instanceData.shaderParamFloats);
 }
Exemple #2
0
        public void LoadFrom(MeshBuffers meshBuffers, bool welded = false)
        {
            vertexCount = meshBuffers.vertexCount;
            vertexTriangles.Allocate(vertexCount, vertexCount * 8);
            vertexVertices.Allocate(vertexCount, vertexCount * 8);
            vertexWelded.Allocate(vertexCount, vertexCount);

            ArrayUtils.ResizeCheckedIfLessThan(ref vertexResolve, vertexCount);

            triangleCount = meshBuffers.triangleCount / 3;
            triangleTriangles.Allocate(triangleCount, triangleCount * 8);
            triangleVertices.Allocate(triangleCount, triangleCount * 3);

            int[] triangles = meshBuffers.triangles;

            // build vertex-triangle
            {
                for (int i = 0; i != triangleCount; i++)
                {
                    int _0 = i * 3;
                    int v0 = triangles[_0 + 0];
                    int v1 = triangles[_0 + 1];
                    int v2 = triangles[_0 + 2];

                    vertexTriangles.Append(v0, i);
                    vertexTriangles.Append(v1, i);
                    vertexTriangles.Append(v2, i);
                }
            }

            // build vertex-welded
            unsafe
            {
                if (welded)
                {
                    // for each vertex
                    //   if vertex != closest vertex
                    //     replace references to vertex with closest vertex
                    triangles = triangles.Clone() as int[];

                    using (var vertexWeldedMap = new UnsafeArrayBool(meshBuffers.vertexCount))
                    {
                        vertexWeldedMap.Clear(false);

                        var vertexBSP = new KdTree3(meshBuffers.vertexPositions, meshBuffers.vertexCount);

                        for (int i = 0; i != vertexCount; i++)
                        {
                            int j = vertexBSP.FindNearest(ref meshBuffers.vertexPositions[i]);
                            if (j != i)
                            {
                                //Debug.Assert(vertexWeldedMap.val[j] == false);

                                // replace references to i with j, keeping j
                                foreach (var triangle in vertexTriangles[i])
                                {
                                    int _0 = triangle * 3;
                                    int v0 = triangles[_0 + 0];
                                    int v1 = triangles[_0 + 1];
                                    //..v2 = triangles[_0 + 2];

                                    if (v0 == i)
                                    {
                                        triangles[_0 + 0] = j;
                                    }
                                    else if (v1 == i)
                                    {
                                        triangles[_0 + 1] = j;
                                    }
                                    else                                     // (v2 == i)
                                    {
                                        triangles[_0 + 2] = j;
                                    }

                                    // store i under j, so we can recover i at a later time
                                    if (vertexWeldedMap.val[i] == false)
                                    {
                                        vertexWeldedMap.val[i] = true;
                                        vertexWelded.Append(j, i);
                                    }
                                }
                            }
                        }
                    }

                    // rebuild vertex-triangle
                    vertexTriangles.Clear();

                    for (int i = 0; i != triangleCount; i++)
                    {
                        int _0 = i * 3;
                        int v0 = triangles[_0 + 0];
                        int v1 = triangles[_0 + 1];
                        int v2 = triangles[_0 + 2];

                        vertexTriangles.Append(v0, i);
                        vertexTriangles.Append(v1, i);
                        vertexTriangles.Append(v2, i);
                    }
                }
            }

            // build vertex-resolve
            {
                for (int i = 0; i != vertexCount; i++)
                {
                    vertexResolve[i] = i;
                }

                for (int i = 0; i != vertexCount; i++)
                {
                    foreach (var j in vertexWelded[i])
                    {
                        vertexResolve[j] = i;
                    }
                }
            }

            // build vertex-vertex
            unsafe
            {
                using (var vertexAdded = new UnsafeArrayBool(vertexCount))
                {
                    vertexAdded.Clear(false);

                    for (int i = 0; i != vertexCount; i++)
                    {
                        foreach (int triangle in vertexTriangles[i])
                        {
                            int _0 = triangle * 3;
                            int v0 = triangles[_0 + 0];
                            int v1 = triangles[_0 + 1];
                            int v2 = triangles[_0 + 2];

                            int vA, vB;
                            if (i == v0)
                            {
                                vA = v1;
                                vB = v2;
                            }
                            else if (i == v1)
                            {
                                vA = v2;
                                vB = v0;
                            }
                            else                             // (i == v2)
                            {
                                vA = v0;
                                vB = v1;
                            }

                            if (vertexAdded.val[vA] == false && (vertexAdded.val[vA] = true))
                            {
                                vertexVertices.Append(i, vA);
                            }

                            if (vertexAdded.val[vB] == false && (vertexAdded.val[vB] = true))
                            {
                                vertexVertices.Append(i, vB);
                            }
                        }

                        foreach (int j in vertexVertices[i])
                        {
                            vertexAdded.val[j] = false;
                        }
                    }
                }
            }

            // build triangle-triangle
            unsafe
            {
                using (var triangleAdded = new UnsafeArrayBool(triangleCount))
                {
                    triangleAdded.Clear(false);

                    for (int i = 0; i != triangleCount; i++)
                    {
                        int _0 = i * 3;
                        int v0 = triangles[_0 + 0];
                        int v1 = triangles[_0 + 1];
                        int v2 = triangles[_0 + 2];

                        triangleAdded.val[i] = true;

                        foreach (int j in vertexTriangles[v0])
                        {
                            if (triangleAdded.val[j] == false && (triangleAdded.val[j] = true))
                            {
                                triangleTriangles.Append(i, j);
                            }
                        }

                        foreach (int j in vertexTriangles[v1])
                        {
                            if (triangleAdded.val[j] == false && (triangleAdded.val[j] = true))
                            {
                                triangleTriangles.Append(i, j);
                            }
                        }

                        foreach (int j in vertexTriangles[v2])
                        {
                            if (triangleAdded.val[j] == false && (triangleAdded.val[j] = true))
                            {
                                triangleTriangles.Append(i, j);
                            }
                        }

                        triangleAdded.val[i] = false;

                        foreach (int j in triangleTriangles[i])
                        {
                            triangleAdded.val[j] = false;
                        }
                    }
                }
            }

            // build triangle-vertex
            {
                for (int i = 0; i != triangleCount; i++)
                {
                    int _0 = i * 3;
                    int v0 = triangles[_0 + 0];
                    int v1 = triangles[_0 + 1];
                    int v2 = triangles[_0 + 2];

                    triangleVertices.Append(i, v0);
                    triangleVertices.Append(i, v1);
                    triangleVertices.Append(i, v2);
                }
            }
        }
 public MeshEdges()
 {
     ArrayUtils.ResizeChecked(ref edges, 0);
 }
        void RenderBlendInputs()
        {
            int fittedWeightsBufferSize = 0;

            {
                fittedWeightsAvailable = false;
                for (int i = 0; i != blendInputs.Length; i++)
                {
                    if (blendInputs[i].active == false || blendInputs[i].clip.framesContainFittedWeights == false)
                    {
                        continue;
                    }

                    fittedWeightsBufferSize = Mathf.Max(fittedWeightsBufferSize, blendInputs[i].clip.frameFittedWeightsCount);
                    fittedWeightsAvailable  = true;
                }

                if (fittedWeightsAvailable)
                {
                    ArrayUtils.ResizeChecked(ref fittedWeights, fittedWeightsBufferSize);
                }

                for (int i = 0; i != fittedWeights.Length; i++)
                {
                    fittedWeights[i] = 0.0f;
                }
            }

            ArrayUtils.ResizeChecked(ref blendedPositions, meshAssetBuffers.vertexCount);
            ArrayUtils.ResizeChecked(ref blendedNormals, meshAssetBuffers.vertexCount);

            Array.Copy(meshAssetBuffers.vertexPositions, blendedPositions, meshAssetBuffers.vertexCount);
            Array.Copy(meshAssetBuffers.vertexNormals, blendedNormals, meshAssetBuffers.vertexCount);
            {
                if (smrProps == null)
                {
                    smrProps = new MaterialPropertyBlock();
                }

                smr.GetPropertyBlock(smrProps);
                {
                    for (int i = 0; i != blendInputs.Length; i++)
                    {
                        RenderBlendInputAdditive(i);
                    }
                }
                smr.SetPropertyBlock(smrProps);
            }

            meshInstance.SilentlySetVertices(blendedPositions);
            meshInstance.SilentlySetNormals(blendedNormals);

            if (forceRecalculateTangents)
            {
                meshInstance.SilentlyRecalculateTangents();
            }

            if (renderFittedWeights)
            {
                if (fittedWeightsAvailable == false)
                {
                    Debug.LogWarning("SkinDeformationRenderer is trying to render fitted weights, but none are available", this);
                }

                for (int i = 0; i != fittedWeights.Length; i++)
                {
                    smr.SetBlendShapeWeight(i, 100.0f * (fittedWeights[i] * renderFittedWeightsScale));
                }
            }
            else
            {
                if (renderFittedWeightsPrev)
                {
                    for (int i = 0; i != fittedWeights.Length; i++)
                    {
                        smr.SetBlendShapeWeight(i, 0.0f);
                    }
                }

                if (muteFacialRig)
                {
                    var blendShapeCount = meshInstance.blendShapeCount;
                    if (blendShapeCount != muteFacialRigExcludeMark.Length || muteFacialRigExclude != muteFacialRigExcludePrev)
                    {
                        ArrayUtils.ResizeChecked(ref muteFacialRigExcludeMark, blendShapeCount);
                        Array.Clear(muteFacialRigExcludeMark, 0, blendShapeCount);

                        var excludeNames = muteFacialRigExclude.Split(',');
                        foreach (var excludeName in excludeNames)
                        {
                            var excludeIndex = meshInstance.GetBlendShapeIndex(meshAsset.name + "_" + excludeName.Trim());
                            if (excludeIndex != -1)
                            {
                                muteFacialRigExcludeMark[excludeIndex] = true;
                            }
                        }

                        muteFacialRigExcludePrev = muteFacialRigExclude;
                    }

                    for (int i = 0; i != blendShapeCount; i++)
                    {
                        if (muteFacialRigExcludeMark[i] == false)
                        {
                            smr.SetBlendShapeWeight(i, 0.0f);
                        }
                    }
                }
                else
                {
                    ArrayUtils.ResizeChecked(ref muteFacialRigExcludeMark, 0);
                }
            }

            blendInputsRendered = true;
        }