Beispiel #1
0
 /// <summary>
 /// Remove all component data
 /// </summary>
 public void ClearComponents()
 {
     TransformComponents.Clear();
     PhysicsComponents.Clear();
     CollisionComponents.Clear();
     MeshComponents.Clear();
 }
    Mesh[] SplitMeshes(MeshComponents mesh, int size)
    {
        //vertsPerMesh > 2*(size+1)
        //vertsPerMesh < 64512 (65534 exatctly)
        //vertsPerMesh must be multiple of 2

        int aux       = 0;
        int powerBase = 2;

        while (aux * size + 1 < 30000)
        {
            powerBase++;
            aux = (int)Mathf.Pow(2, powerBase);
        }


        int vertsPerMesh = (size + 1) * (int)Mathf.Pow(2.0f, powerBase);

        Debug.Log(vertsPerMesh);
        int numMeshes = mesh.vertices.Length / vertsPerMesh + 1;

        Mesh[] returnMeshes = new Mesh[numMeshes];

        for (int m = 0; m < numMeshes; m++)
        {
            returnMeshes[m] = new Mesh();
            List <Vector3> mVertices  = new List <Vector3>();
            List <int>     mTriangles = new List <int>();

            int index = 0;
            Debug.LogWarning(mesh.vertices.Length);
            for (int v = 0; v < vertsPerMesh; v++)
            {
                index = (m * (vertsPerMesh - (size + 1)) + v);
                if (index < mesh.vertices.Length)
                {
                    mVertices.Add(mesh.vertices[index]);
                }
                //Debug.Log("M: " + m + " vertsPerMesh: " + vertsPerMesh + " size+1: " + (size+1) + " v: " + v + " index: " + index);
            }

            for (int v = 0, x = 0; x < (mVertices.Count / (size + 1)) - 1; x++)
            {
                for (int z = 0; z < size; z++, v++)
                {
                    mTriangles.Add(v);
                    mTriangles.Add(v + 1);
                    mTriangles.Add(v + size + 1);
                    mTriangles.Add(v + size + 1);
                    mTriangles.Add(v + 1);
                    mTriangles.Add(v + size + 2);
                }
                v++;
            }
            returnMeshes[m].SetVertices(mVertices);
            returnMeshes[m].SetTriangles(mTriangles, 0);
        }

        return(returnMeshes);
    }
Beispiel #3
0
        Dictionary <int, int> ModifiedV;         // could use flat buffer for this?

        public VertexChangeBuilder(DMesh3 mesh, MeshComponents components = MeshComponents.All)
        {
            Mesh       = mesh;
            Components = components;

            ModifiedV    = new Dictionary <int, int>();
            ActiveChange = new ModifyVerticesMeshChange(mesh, components);
        }
 /// <summary>
 /// This method can be used to extend a mesh by some vertices.
 /// </summary>
 /// <param name="mesh">The mesh which shall be extended</param>
 /// <param name="extensionComponent">the information of the extension</param>
 /// <param name="transform">the transformobject of the extension component.</param>
 /// <returns>an extended mesh represented by an mesh-component object.</returns>
 public static MeshComponents ExtendMesh(this Mesh mesh, MeshComponents extensionComponent, Transform transform)
 {
     MeshComponents extendedMeshComponents = new MeshComponents();
     extendedMeshComponents.SetInitialTriangles(mesh.vertices, mesh.triangles);
     extensionComponent.ConvertWorldToLocalVertices(transform);
     extendedMeshComponents.AddTriangles(extensionComponent.GetVertices());
     return extendedMeshComponents;
 }
 private void Awake()
 {
     _lookupMesh   = new Dictionary <float3, ChunkTable>();
     textureAtlas  = material;
     tileMesh      = tileMeshComp;
     _drawDistance = drawDistance;
     instance      = this;
 }
Beispiel #6
0
        public static void Restore(DMesh3 mesh, BinaryReader reader)
        {
            int version = reader.ReadInt32();

            if (version != DMesh3Version)
            {
                throw new Exception("gSerialization.Restore: Incorrect DMesh3Version!");
            }

            MeshComponents components = (MeshComponents)reader.ReadInt32();

            Restore(mesh.VerticesBuffer, reader);
            Restore(mesh.TrianglesBuffer, reader);
            Restore(mesh.EdgesBuffer, reader);
            Restore(mesh.EdgesRefCounts.RawRefCounts, reader);

            if ((components & MeshComponents.VertexNormals) != 0)
            {
                mesh.EnableVertexNormals(Vector3f.AxisY);
                Restore(mesh.NormalsBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexNormals();
            }

            if ((components & MeshComponents.VertexColors) != 0)
            {
                mesh.EnableVertexColors(Vector3f.One);
                Restore(mesh.ColorsBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexColors();
            }

            if ((components & MeshComponents.VertexUVs) != 0)
            {
                mesh.EnableVertexUVs(Vector2f.Zero);
                Restore(mesh.UVBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexUVs();
            }

            if ((components & MeshComponents.FaceGroups) != 0)
            {
                mesh.EnableTriangleGroups(0);
                Restore(mesh.GroupsBuffer, reader);
            }
            else
            {
                mesh.DiscardTriangleGroups();
            }

            mesh.RebuildFromEdgeRefcounts();
        }
    public bool HasSolidNeighbour(int x, int y, int z, ConcurrentDictionary <int3, Chunk> chunkMap)
    {
        //If this is ever is Jobified, this will be a memory sink
        Block[,,] chunks;

        if (x < 0 || x >= MeshComponents.chunkSize ||
            y < 0 || y >= MeshComponents.chunkSize ||
            z < 0 || z >= MeshComponents.chunkSize)
        {
            //Block in another chunk
            float3 neighbourChunkPos = owner.position + new float3((x - (int)position.x) * MeshComponents.chunkSize,
                                                                   (y - (int)position.y) * MeshComponents.chunkSize,
                                                                   (z - (int)position.z) * MeshComponents.chunkSize);
            string nName = MeshComponents.BuildChunkName(neighbourChunkPos);
            x = ConvertBlockIndexToLocal(x);
            y = ConvertBlockIndexToLocal(y);
            z = ConvertBlockIndexToLocal(z);

            if (chunkMap.TryGetValue(new int3(neighbourChunkPos), out Chunk nChunk))
            {
                chunks = nChunk.chunkData;
            }
            else
            {
                //Edge of the known world
                return(false);
            }
        }
        else
        {
            //Block in this chunk
            chunks = owner.chunkData;
        }

        if (chunks.Length != 0)
        {
            try
            {
                return(chunks[x, y, z].isSolid);
            }
            catch (System.IndexOutOfRangeException ex) { }
            return(false);
        }
        else
        {
            return(false);
        }
    }
    MeshComponents CalculateMesh(int size)
    {
        MeshComponents mesh = new MeshComponents();

        mesh.vertices  = new Vector3[(size + 1) * (size + 1)];
        mesh.triangles = new int[size * size * 6];

        for (int i = 0, x = 0; x <= size; x++)
        {
            for (int z = 0; z <= size; z++, i++)
            {
                float y = Noise.PerlinNoise2D(x * 0.05f, z * 0.05f) * 8;
                mesh.vertices[i] = (new Vector3(x, y, z));
            }
        }

        return(mesh);
    }
Beispiel #9
0
    // Use this for initialization
    public void GenerateMesh()
    {
        var meshData = new MeshComponents(this.scaleCoeff);

        this.Tiles = new CityMeshTiles(this.Origin, new Vector2I(MeshWidth, MeshHeight), TileSize, Material);

        var materials = new List <Material>();

        foreach (var tile in this.Tiles.TileArray)
        {
            meshData.GenerateSquareAt(tile.FromX, tile.FromY, tile.SizeX);
            materials.Add(tile.Material);
        }

        var mesh = this.GetComponent <MeshFilter>().mesh;

        meshData.BuildMesh(mesh);
        this.GetComponent <Renderer>().materials = materials.ToArray();
    }
Beispiel #10
0
        /// <summary>
        /// Resizes all component arrays to contain at least maxSize amount of objects
        /// </summary>
        public void SetComponentArraySize(int maxSize)
        {
            int oldSize = TransformComponents.Length;

            if (maxSize > oldSize)
            {
                TransformComponents.SetSize(maxSize);
                PhysicsComponents.SetSize(maxSize);
                CollisionComponents.SetSize(maxSize);
                MeshComponents.SetSize(maxSize);

                for (int i = oldSize; i < maxSize; i++)
                {
                    // Initialize defaults
                    TransformComponents[i].SetDefaults();
                    CollisionComponents[i].SetDefaults();
                    MeshComponents[i].SetDefaults();
                }
            }
        }
 void initialize_buffers(DMesh3 mesh, MeshComponents components)
 {
     ModifiedV    = new DVector <int>();
     NewPositions = new DVector <Vector3d>();
     OldPositions = new DVector <Vector3d>();
     if (mesh.HasVertexNormals && (components & MeshComponents.VertexNormals) != 0)
     {
         NewNormals = new DVector <Vector3f>();
         OldNormals = new DVector <Vector3f>();
     }
     if (mesh.HasVertexColors && (components & MeshComponents.VertexColors) != 0)
     {
         NewColors = new DVector <Vector3f>();
         OldColors = new DVector <Vector3f>();
     }
     if (mesh.HasVertexUVs && (components & MeshComponents.VertexUVs) != 0)
     {
         NewUVs = new DVector <Vector2f>();
         OldUVs = new DVector <Vector2f>();
     }
 }
Beispiel #12
0
        /// <summary>
        /// Combines a set of meshes into the target mesh.
        /// </summary>
        /// <param name="target">Target.</param>
        /// <param name="sources">Sources.</param>
        public static void CombineMeshes(UMAMeshData target, CombineInstance[] sources, bool ignoreBlendShapes = false)
        {
            int vertexCount             = 0;
            int bindPoseCount           = 0;
            int transformHierarchyCount = 0;
            int blendShapeCount         = 0;

            MeshComponents meshComponents        = MeshComponents.none;
            int            subMeshCount          = FindTargetSubMeshCount(sources);
            var            subMeshTriangleLength = new int[subMeshCount];

            AnalyzeSources(sources, subMeshTriangleLength, ref vertexCount, ref bindPoseCount, ref transformHierarchyCount, ref meshComponents, ref blendShapeCount);

            int[][] submeshTriangles = new int[subMeshCount][];
            for (int i = 0; i < subMeshTriangleLength.Length; i++)
            {
                submeshTriangles[i]      = new int[subMeshTriangleLength[i]];
                subMeshTriangleLength[i] = 0;
            }

            bool has_normals     = (meshComponents & MeshComponents.has_normals) != MeshComponents.none;
            bool has_tangents    = (meshComponents & MeshComponents.has_tangents) != MeshComponents.none;
            bool has_uv          = (meshComponents & MeshComponents.has_uv) != MeshComponents.none;
            bool has_uv2         = (meshComponents & MeshComponents.has_uv2) != MeshComponents.none;
            bool has_uv3         = (meshComponents & MeshComponents.has_uv3) != MeshComponents.none;
            bool has_uv4         = (meshComponents & MeshComponents.has_uv4) != MeshComponents.none;
            bool has_colors32    = (meshComponents & MeshComponents.has_colors32) != MeshComponents.none;
            bool has_blendShapes = (meshComponents & MeshComponents.has_blendShapes) != MeshComponents.none;

            if (ignoreBlendShapes)
            {
                has_blendShapes = false;
            }

            Vector3[]    vertices    = EnsureArrayLength(target.vertices, vertexCount);
            BoneWeight[] boneWeights = EnsureArrayLength(target.unityBoneWeights, vertexCount);
            Vector3[]    normals     = has_normals ? EnsureArrayLength(target.normals, vertexCount) : null;
            Vector4[]    tangents    = has_tangents ? EnsureArrayLength(target.tangents, vertexCount) : null;
            Vector2[]    uv          = has_uv ? EnsureArrayLength(target.uv, vertexCount) : null;
            Vector2[]    uv2         = has_uv2 ? EnsureArrayLength(target.uv2, vertexCount) : null;
            Vector2[]    uv3         = has_uv3 ? EnsureArrayLength(target.uv3, vertexCount) : null;
            Vector2[]    uv4         = has_uv4 ? EnsureArrayLength(target.uv4, vertexCount) : null;
            Color32[]    colors32    = has_colors32 ? EnsureArrayLength(target.colors32, vertexCount) : null;

            UMABlendShape[] blendShapes = has_blendShapes ? new UMABlendShape[blendShapeCount] : null;

            UMATransform[] umaTransforms = EnsureArrayLength(target.umaBones, transformHierarchyCount);

            int boneCount = 0;

            foreach (var source in sources)
            {
                MergeSortedTransforms(umaTransforms, ref boneCount, source.meshData.umaBones);
            }
            int vertexIndex = 0;

            if (bonesCollection == null)
            {
                bonesCollection = new Dictionary <int, BoneIndexEntry>(boneCount);
            }
            else
            {
                bonesCollection.Clear();
            }
            if (bindPoses == null)
            {
                bindPoses = new List <Matrix4x4>(bindPoseCount);
            }
            else
            {
                bindPoses.Clear();
            }
            if (bonesList == null)
            {
                bonesList = new List <int>(boneCount);
            }
            else
            {
                bonesList.Clear();
            }

            int blendShapeIndex = 0;

            foreach (var source in sources)
            {
                vertexCount = source.meshData.vertices.Length;
                BuildBoneWeights(source.meshData.boneWeights, 0, boneWeights, vertexIndex, vertexCount, source.meshData.boneNameHashes, source.meshData.bindPoses, bonesCollection, bindPoses, bonesList);

                Array.Copy(source.meshData.vertices, 0, vertices, vertexIndex, vertexCount);

                if (has_normals)
                {
                    if (source.meshData.normals != null && source.meshData.normals.Length > 0)
                    {
                        Array.Copy(source.meshData.normals, 0, normals, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, vertexCount, Vector3.zero);
                    }
                }
                if (has_tangents)
                {
                    if (source.meshData.tangents != null && source.meshData.tangents.Length > 0)
                    {
                        Array.Copy(source.meshData.tangents, 0, tangents, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
                if (has_uv)
                {
                    if (source.meshData.uv != null && source.meshData.uv.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv, 0, uv, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
                if (has_uv2)
                {
                    if (source.meshData.uv2 != null && source.meshData.uv2.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv2, 0, uv2, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv2, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
                if (has_uv3)
                {
                    if (source.meshData.uv3 != null && source.meshData.uv3.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv3, 0, uv3, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv3, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
                if (has_uv4)
                {
                    if (source.meshData.uv4 != null && source.meshData.uv4.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv4, 0, uv4, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv4, vertexIndex, vertexCount, Vector4.zero);
                    }
                }

                if (has_colors32)
                {
                    if (source.meshData.colors32 != null && source.meshData.colors32.Length > 0)
                    {
                        Array.Copy(source.meshData.colors32, 0, colors32, vertexIndex, vertexCount);
                    }
                    else
                    {
                        Color32 white32 = Color.white;
                        FillArray(colors32, vertexIndex, vertexCount, white32);
                    }
                }

                if (has_blendShapes)
                {
                    if (source.meshData.blendShapes != null && source.meshData.blendShapes.Length > 0)
                    {
                        for (int shapeIndex = 0; shapeIndex < source.meshData.blendShapes.Length; shapeIndex++)
                        {
                            bool nameAlreadyExists = false;
                            int  i = 0;
                            //Probably this would be better with a dictionary
                            for (i = 0; i < blendShapeIndex; i++)
                            {
                                if (blendShapes [i].shapeName == source.meshData.blendShapes [shapeIndex].shapeName)
                                {
                                    nameAlreadyExists = true;
                                    break;
                                }
                            }

                            if (nameAlreadyExists)                            //Lets add the vertices data to the existing blendShape
                            {
                                if (blendShapes [i].frames.Length != source.meshData.blendShapes [shapeIndex].frames.Length)
                                {
                                    Debug.LogError("SkinnedMeshCombiner: mesh blendShape frame counts don't match!");
                                    break;
                                }
                                for (int frameIndex = 0; frameIndex < source.meshData.blendShapes [shapeIndex].frames.Length; frameIndex++)
                                {
                                    Array.Copy(source.meshData.blendShapes [shapeIndex].frames [frameIndex].deltaVertices, 0, blendShapes [i].frames [frameIndex].deltaVertices, vertexIndex, vertexCount);
                                    Array.Copy(source.meshData.blendShapes [shapeIndex].frames [frameIndex].deltaNormals, 0, blendShapes [i].frames [frameIndex].deltaNormals, vertexIndex, vertexCount);
                                    Array.Copy(source.meshData.blendShapes [shapeIndex].frames [frameIndex].deltaTangents, 0, blendShapes [i].frames [frameIndex].deltaTangents, vertexIndex, vertexCount);
                                }
                            }
                            else
                            {
                                blendShapes [blendShapeIndex]           = new UMABlendShape();
                                blendShapes [blendShapeIndex].shapeName = source.meshData.blendShapes [shapeIndex].shapeName;
                                blendShapes [blendShapeIndex].frames    = new UMABlendFrame[source.meshData.blendShapes [shapeIndex].frames.Length];

                                for (int frameIndex = 0; frameIndex < source.meshData.blendShapes [shapeIndex].frames.Length; frameIndex++)
                                {
                                    blendShapes [blendShapeIndex].frames [frameIndex]             = new UMABlendFrame(vertices.Length);
                                    blendShapes [blendShapeIndex].frames [frameIndex].frameWeight = source.meshData.blendShapes [shapeIndex].frames [frameIndex].frameWeight;
                                    Array.Copy(source.meshData.blendShapes [shapeIndex].frames [frameIndex].deltaVertices, 0, blendShapes [blendShapeIndex].frames [frameIndex].deltaVertices, vertexIndex, vertexCount);
                                    Array.Copy(source.meshData.blendShapes [shapeIndex].frames [frameIndex].deltaNormals, 0, blendShapes [blendShapeIndex].frames [frameIndex].deltaNormals, vertexIndex, vertexCount);
                                    Array.Copy(source.meshData.blendShapes [shapeIndex].frames [frameIndex].deltaTangents, 0, blendShapes [blendShapeIndex].frames [frameIndex].deltaTangents, vertexIndex, vertexCount);
                                }
                                blendShapeIndex++;
                            }
                        }
                    }
                }

                for (int i = 0; i < source.meshData.subMeshCount; i++)
                {
                    if (source.targetSubmeshIndices[i] >= 0)
                    {
                        int[] subTriangles   = source.meshData.submeshes[i].triangles;
                        int   triangleLength = subTriangles.Length;
                        int   destMesh       = source.targetSubmeshIndices[i];

                        CopyIntArrayAdd(subTriangles, 0, submeshTriangles[destMesh], subMeshTriangleLength[destMesh], triangleLength, vertexIndex);
                        subMeshTriangleLength[destMesh] += triangleLength;
                    }
                }

                vertexIndex += vertexCount;
            }
            vertexCount = vertexIndex;

            // fill in new values.
            target.vertexCount      = vertexCount;
            target.vertices         = vertices;
            target.unityBoneWeights = boneWeights;
            target.bindPoses        = bindPoses.ToArray();
            target.normals          = normals;
            target.tangents         = tangents;
            target.uv       = uv;
            target.uv2      = uv2;
            target.uv3      = uv3;
            target.uv4      = uv4;
            target.colors32 = colors32;

            if (has_blendShapes)
            {
                target.blendShapes = blendShapes;
            }

            target.subMeshCount = subMeshCount;
            target.submeshes    = new SubMeshTriangles[subMeshCount];
            target.umaBones     = umaTransforms;
            target.umaBoneCount = boneCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                target.submeshes[i].triangles = submeshTriangles[i];
            }
            target.boneNameHashes = bonesList.ToArray();
        }
Beispiel #13
0
        private static void AnalyzeSources(CombineInstance[] sources, int[] subMeshTriangleLength, ref int vertexCount, ref int bindPoseCount, ref int transformHierarchyCount, ref MeshComponents meshComponents, ref int blendShapeCount)
        {
            HashSet <string> blendShapeNames = new HashSet <string> ();           //Hash to find all the unique blendshape names

            for (int i = 0; i < subMeshTriangleLength.Length; i++)
            {
                subMeshTriangleLength[i] = 0;
            }

            foreach (var source in sources)
            {
                vertexCount             += source.meshData.vertices.Length;
                bindPoseCount           += source.meshData.bindPoses.Length;
                transformHierarchyCount += source.meshData.umaBones.Length;
                if (source.meshData.normals != null && source.meshData.normals.Length != 0)
                {
                    meshComponents |= MeshComponents.has_normals;
                }
                if (source.meshData.tangents != null && source.meshData.tangents.Length != 0)
                {
                    meshComponents |= MeshComponents.has_tangents;
                }
                if (source.meshData.uv != null && source.meshData.uv.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv;
                }
                if (source.meshData.uv2 != null && source.meshData.uv2.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv2;
                }
                if (source.meshData.uv3 != null && source.meshData.uv3.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv3;
                }
                if (source.meshData.uv4 != null && source.meshData.uv4.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv4;
                }
                if (source.meshData.colors32 != null && source.meshData.colors32.Length != 0)
                {
                    meshComponents |= MeshComponents.has_colors32;
                }

                //If we find a blendshape on this mesh then lets add it to the blendShapeNames hash to get all the unique names
                if (source.meshData.blendShapes != null && source.meshData.blendShapes.Length != 0)
                {
                    for (int shapeIndex = 0; shapeIndex < source.meshData.blendShapes.Length; shapeIndex++)
                    {
                        blendShapeNames.Add(source.meshData.blendShapes [shapeIndex].shapeName);
                    }
                }

                for (int i = 0; i < source.meshData.subMeshCount; i++)
                {
                    if (source.targetSubmeshIndices[i] >= 0)
                    {
                        int triangleLength = source.meshData.submeshes[i].triangles.Length;
                        subMeshTriangleLength[source.targetSubmeshIndices[i]] += triangleLength;
                    }
                }
            }

            //If our blendshape hash has at least 1 name, then we have a blendshape!
            if (blendShapeNames.Count > 0)
            {
                blendShapeCount = blendShapeNames.Count;
                meshComponents |= MeshComponents.has_blendShapes;
            }
        }
Beispiel #14
0
        private static void AnalyzeSources(CombineInstance[] sources, int[] subMeshTriangleLength, ref int vertexCount, ref int bindPoseCount, ref int transformHierarchyCount, ref MeshComponents meshComponents)
        {
            for (int i = 0; i < subMeshTriangleLength.Length; i++)
            {
                subMeshTriangleLength[i] = 0;
            }

            foreach (var source in sources)
            {
                vertexCount             += source.meshData.vertices.Length;
                bindPoseCount           += source.meshData.bindPoses.Length;
                transformHierarchyCount += source.meshData.umaBones.Length;
                if (source.meshData.normals != null && source.meshData.normals.Length != 0)
                {
                    meshComponents |= MeshComponents.has_normals;
                }
                if (source.meshData.tangents != null && source.meshData.tangents.Length != 0)
                {
                    meshComponents |= MeshComponents.has_tangents;
                }
                if (source.meshData.uv != null && source.meshData.uv.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv;
                }
                if (source.meshData.uv2 != null && source.meshData.uv2.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv2;
                }
                if (source.meshData.uv3 != null && source.meshData.uv3.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv3;
                }
                if (source.meshData.uv4 != null && source.meshData.uv4.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv4;
                }
                if (source.meshData.colors32 != null && source.meshData.colors32.Length != 0)
                {
                    meshComponents |= MeshComponents.has_colors32;
                }
                if (source.meshData.clothSkinningSerialized != null && source.meshData.clothSkinningSerialized.Length != 0)
                {
                    meshComponents |= MeshComponents.has_clothSkinning;
                }

                for (int i = 0; i < source.meshData.subMeshCount; i++)
                {
                    if (source.targetSubmeshIndices[i] >= 0)
                    {
                        int triangleLength = (source.triangleMask == null) ? source.meshData.submeshes[i].triangles.Length :
                                             (source.meshData.submeshes[i].triangles.Length - (UMAUtils.GetCardinality(source.triangleMask[i]) * 3));

                        subMeshTriangleLength[source.targetSubmeshIndices[i]] += triangleLength;
                    }
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// Combines a set of meshes into the target mesh.
        /// </summary>
        /// <param name="target">Target.</param>
        /// <param name="sources">Sources.</param>
        /// <param name="blendShapeSettings">BlendShape Settings.</param>
        public static void CombineMeshes(UMAMeshData target, CombineInstance[] sources, UMAData.BlendShapeSettings blendShapeSettings = null)
        {
            if (blendShapeSettings == null)
            {
                blendShapeSettings = new UMAData.BlendShapeSettings();
            }

            int vertexCount             = 0;
            int bindPoseCount           = 0;
            int transformHierarchyCount = 0;
            int blendShapeCount         = 0;

            MeshComponents meshComponents        = MeshComponents.none;
            int            subMeshCount          = FindTargetSubMeshCount(sources);
            var            subMeshTriangleLength = new int[subMeshCount];

            AnalyzeSources(sources, subMeshTriangleLength, ref vertexCount, ref bindPoseCount, ref transformHierarchyCount, ref meshComponents, ref blendShapeCount);

            int[][] submeshTriangles = new int[subMeshCount][];
            for (int i = 0; i < subMeshTriangleLength.Length; i++)
            {
                submeshTriangles[i]      = target.GetSubmeshBuffer(subMeshTriangleLength[i], i);
                subMeshTriangleLength[i] = 0;
            }

            bool has_normals     = (meshComponents & MeshComponents.has_normals) != MeshComponents.none;
            bool has_tangents    = (meshComponents & MeshComponents.has_tangents) != MeshComponents.none;
            bool has_uv          = (meshComponents & MeshComponents.has_uv) != MeshComponents.none;
            bool has_uv2         = (meshComponents & MeshComponents.has_uv2) != MeshComponents.none;
            bool has_uv3         = (meshComponents & MeshComponents.has_uv3) != MeshComponents.none;
            bool has_uv4         = (meshComponents & MeshComponents.has_uv4) != MeshComponents.none;
            bool has_colors32    = (meshComponents & MeshComponents.has_colors32) != MeshComponents.none;
            bool has_blendShapes = (meshComponents & MeshComponents.has_blendShapes) != MeshComponents.none;

            if (blendShapeSettings.ignoreBlendShapes)
            {
                has_blendShapes = false;
            }
            bool has_clothSkinning = (meshComponents & MeshComponents.has_clothSkinning) != MeshComponents.none;

            Vector3[]                  vertices           = EnsureArrayLength(target.vertices, vertexCount);
            BoneWeight[]               boneWeights        = EnsureArrayLength(target.unityBoneWeights, vertexCount);
            Vector3[]                  normals            = has_normals ? EnsureArrayLength(target.normals, vertexCount) : null;
            Vector4[]                  tangents           = has_tangents ? EnsureArrayLength(target.tangents, vertexCount) : null;
            Vector2[]                  uv                 = has_uv ? EnsureArrayLength(target.uv, vertexCount) : null;
            Vector2[]                  uv2                = has_uv2 ? EnsureArrayLength(target.uv2, vertexCount) : null;
            Vector2[]                  uv3                = has_uv3 ? EnsureArrayLength(target.uv3, vertexCount) : null;
            Vector2[]                  uv4                = has_uv4 ? EnsureArrayLength(target.uv4, vertexCount) : null;
            Color32[]                  colors32           = has_colors32 ? EnsureArrayLength(target.colors32, vertexCount) : null;
            UMABlendShape[]            blendShapes        = has_blendShapes ? new UMABlendShape[blendShapeCount] : null;
            UMATransform[]             umaTransforms      = EnsureArrayLength(target.umaBones, transformHierarchyCount);
            ClothSkinningCoefficient[] clothSkinning      = has_clothSkinning ? EnsureArrayLength(target.clothSkinning, vertexCount) : null;
            Dictionary <Vector3, int>  clothVertices      = has_clothSkinning ? new Dictionary <Vector3, int>(vertexCount) : null;
            Dictionary <Vector3, int>  localClothVertices = has_clothSkinning ? new Dictionary <Vector3, int>(vertexCount) : null;

            int boneCount = 0;

            foreach (var source in sources)
            {
                MergeSortedTransforms(umaTransforms, ref boneCount, source.meshData.umaBones);
            }
            int vertexIndex = 0;

            if (bonesCollection == null)
            {
                bonesCollection = new Dictionary <int, BoneIndexEntry>(boneCount);
            }
            else
            {
                bonesCollection.Clear();
            }
            if (bindPoses == null)
            {
                bindPoses = new List <Matrix4x4>(bindPoseCount);
            }
            else
            {
                bindPoses.Clear();
            }
            if (bonesList == null)
            {
                bonesList = new List <int>(boneCount);
            }
            else
            {
                bonesList.Clear();
            }

            int blendShapeIndex = 0;

            foreach (var source in sources)
            {
                int sourceVertexCount = source.meshData.vertices.Length;
                BuildBoneWeights(source.meshData.boneWeights, 0, boneWeights, vertexIndex, sourceVertexCount, source.meshData.boneNameHashes, source.meshData.bindPoses, bonesCollection, bindPoses, bonesList);

                Array.Copy(source.meshData.vertices, 0, vertices, vertexIndex, sourceVertexCount);

                if (has_normals)
                {
                    if (source.meshData.normals != null && source.meshData.normals.Length > 0)
                    {
                        Array.Copy(source.meshData.normals, 0, normals, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, sourceVertexCount, Vector3.zero);
                    }
                }
                if (has_tangents)
                {
                    if (source.meshData.tangents != null && source.meshData.tangents.Length > 0)
                    {
                        Array.Copy(source.meshData.tangents, 0, tangents, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv)
                {
                    if (source.meshData.uv != null && source.meshData.uv.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv, 0, uv, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv2)
                {
                    if (source.meshData.uv2 != null && source.meshData.uv2.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv2, 0, uv2, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv2, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv3)
                {
                    if (source.meshData.uv3 != null && source.meshData.uv3.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv3, 0, uv3, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv3, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv4)
                {
                    if (source.meshData.uv4 != null && source.meshData.uv4.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv4, 0, uv4, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv4, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }

                if (has_colors32)
                {
                    if (source.meshData.colors32 != null && source.meshData.colors32.Length > 0)
                    {
                        Array.Copy(source.meshData.colors32, 0, colors32, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        Color32 white32 = Color.white;
                        FillArray(colors32, vertexIndex, sourceVertexCount, white32);
                    }
                }

                if (has_blendShapes)
                {
                    if (source.meshData.blendShapes != null && source.meshData.blendShapes.Length > 0)
                    {
                        for (int shapeIndex = 0; shapeIndex < source.meshData.blendShapes.Length; shapeIndex++)
                        {
                            #region BlendShape Baking
                            if (blendShapeSettings.bakeBlendShapes != null && blendShapeSettings.bakeBlendShapes.Count > 0)
                            {
                                // If there are names in the bakeBlendShape dictionary and we find them in the meshData blendshape list, then lets bake them instead of adding them.
                                UMABlendShape currentShape = source.meshData.blendShapes[shapeIndex];

                                if (blendShapeSettings.bakeBlendShapes.ContainsKey(currentShape.shapeName))
                                {
                                    float weight = blendShapeSettings.bakeBlendShapes[currentShape.shapeName] * 100.0f;
                                    if (weight <= 0f)
                                    {
                                        continue;                                                   // Baking in nothing, so skip it entirely
                                    }
                                    // Let's find the frame this weight is in
                                    int frameIndex;
                                    int prevIndex;
                                    for (frameIndex = 0; frameIndex < currentShape.frames.Length; frameIndex++)
                                    {
                                        if (currentShape.frames[frameIndex].frameWeight >= weight)
                                        {
                                            break;
                                        }
                                    }

                                    // Let's calculate the weight for the frame we're in
                                    float frameWeight = 1f;
                                    float prevWeight  = 0f;
                                    bool  doLerp      = false;
                                    // Weight is higher than the last frame, shape is over 100%
                                    if (frameIndex >= currentShape.frames.Length)
                                    {
                                        frameIndex  = currentShape.frames.Length - 1;
                                        frameWeight = (weight / currentShape.frames[frameIndex].frameWeight);
                                    }
                                    else if (frameIndex > 0)
                                    {
                                        doLerp      = true;
                                        prevWeight  = currentShape.frames[frameIndex - 1].frameWeight;
                                        frameWeight = ((weight - prevWeight) / (currentShape.frames[frameIndex].frameWeight - prevWeight));
                                        prevWeight  = 1f - frameWeight;
                                    }
                                    else
                                    {
                                        frameWeight = (weight / currentShape.frames[frameIndex].frameWeight);
                                    }
                                    prevIndex = frameIndex - 1;

                                    // The blend shape frames lerp between the deltas of two adjacent frames.
                                    int vertIndex = vertexIndex;
                                    for (int bakeIndex = 0; bakeIndex < currentShape.frames[frameIndex].deltaVertices.Length; bakeIndex++, vertIndex++)
                                    {
                                        // Add the current frame's deltas
                                        vertices[vertIndex] += currentShape.frames[frameIndex].deltaVertices[bakeIndex] * frameWeight;
                                        // Add in the previous frame's deltas
                                        if (doLerp)
                                        {
                                            vertices[vertIndex] += currentShape.frames[prevIndex].deltaVertices[bakeIndex] * prevWeight;
                                        }
                                    }

                                    if (has_normals)
                                    {
                                        vertIndex = vertexIndex;
                                        for (int bakeIndex = 0; bakeIndex < currentShape.frames[frameIndex].deltaNormals.Length; bakeIndex++, vertIndex++)
                                        {
                                            normals[vertIndex] += currentShape.frames[frameIndex].deltaNormals[bakeIndex] * frameWeight;
                                            if (doLerp)
                                            {
                                                normals[vertIndex] += currentShape.frames[prevIndex].deltaNormals[bakeIndex] * prevWeight;
                                            }
                                        }
                                    }

                                    if (has_tangents)
                                    {
                                        vertIndex = vertexIndex;
                                        for (int bakeIndex = 0; bakeIndex < currentShape.frames[frameIndex].deltaTangents.Length; bakeIndex++, vertIndex++)
                                        {
                                            tangents[vertIndex] += (Vector4)currentShape.frames[frameIndex].deltaTangents[bakeIndex] * frameWeight;
                                            if (doLerp)
                                            {
                                                tangents[vertIndex] += (Vector4)currentShape.frames[prevIndex].deltaTangents[bakeIndex] * prevWeight;
                                            }
                                        }
                                    }
                                    continue; // If we bake then don't perform the rest of this interation of the loop.
                                }
                            }
                            #endregion

                            bool nameAlreadyExists = false;
                            int  i = 0;
                            //Probably this would be better with a dictionary
                            for (i = 0; i < blendShapeIndex; i++)
                            {
                                if (blendShapes[i].shapeName == source.meshData.blendShapes[shapeIndex].shapeName)
                                {
                                    nameAlreadyExists = true;
                                    break;
                                }
                            }

                            if (nameAlreadyExists)                            //Lets add the vertices data to the existing blendShape
                            {
                                if (blendShapes[i].frames.Length != source.meshData.blendShapes[shapeIndex].frames.Length)
                                {
                                    Debug.LogError("SkinnedMeshCombiner: mesh blendShape frame counts don't match!");
                                    break;
                                }
                                for (int frameIndex = 0; frameIndex < source.meshData.blendShapes[shapeIndex].frames.Length; frameIndex++)
                                {
                                    Array.Copy(source.meshData.blendShapes[shapeIndex].frames[frameIndex].deltaVertices, 0, blendShapes[i].frames[frameIndex].deltaVertices, vertexIndex, sourceVertexCount);
                                    Array.Copy(source.meshData.blendShapes[shapeIndex].frames[frameIndex].deltaNormals, 0, blendShapes[i].frames[frameIndex].deltaNormals, vertexIndex, sourceVertexCount);
                                    Array.Copy(source.meshData.blendShapes[shapeIndex].frames[frameIndex].deltaTangents, 0, blendShapes[i].frames[frameIndex].deltaTangents, vertexIndex, sourceVertexCount);
                                }
                            }
                            else
                            {
                                blendShapes[blendShapeIndex]           = new UMABlendShape();
                                blendShapes[blendShapeIndex].shapeName = source.meshData.blendShapes[shapeIndex].shapeName;
                                blendShapes[blendShapeIndex].frames    = new UMABlendFrame[source.meshData.blendShapes[shapeIndex].frames.Length];

                                for (int frameIndex = 0; frameIndex < source.meshData.blendShapes[shapeIndex].frames.Length; frameIndex++)
                                {
                                    blendShapes[blendShapeIndex].frames[frameIndex]             = new UMABlendFrame(vertexCount);
                                    blendShapes[blendShapeIndex].frames[frameIndex].frameWeight = source.meshData.blendShapes[shapeIndex].frames[frameIndex].frameWeight;
                                    Array.Copy(source.meshData.blendShapes[shapeIndex].frames[frameIndex].deltaVertices, 0, blendShapes[blendShapeIndex].frames[frameIndex].deltaVertices, vertexIndex, sourceVertexCount);
                                    Array.Copy(source.meshData.blendShapes[shapeIndex].frames[frameIndex].deltaNormals, 0, blendShapes[blendShapeIndex].frames[frameIndex].deltaNormals, vertexIndex, sourceVertexCount);
                                    Array.Copy(source.meshData.blendShapes[shapeIndex].frames[frameIndex].deltaTangents, 0, blendShapes[blendShapeIndex].frames[frameIndex].deltaTangents, vertexIndex, sourceVertexCount);
                                }
                                blendShapeIndex++;
                            }
                        }
                    }
                }
                if (has_clothSkinning)
                {
                    localClothVertices.Clear();
                    if (source.meshData.clothSkinningSerialized != null && source.meshData.clothSkinningSerialized.Length > 0)
                    {
                        for (int i = 0; i < source.meshData.vertexCount; i++)
                        {
                            var vertice = source.meshData.vertices[i];
                            if (!localClothVertices.ContainsKey(vertice))
                            {
                                int localCount = localClothVertices.Count;
                                localClothVertices.Add(vertice, localCount);
                                if (!clothVertices.ContainsKey(vertice))
                                {
                                    ConvertData(ref source.meshData.clothSkinningSerialized[localCount], ref clothSkinning[clothVertices.Count]);
                                    clothVertices.Add(vertice, clothVertices.Count);
                                }
                                else
                                {
                                    ConvertData(ref source.meshData.clothSkinningSerialized[localCount], ref clothSkinning[clothVertices[vertice]]);
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < source.meshData.vertexCount; i++)
                        {
                            var vertice = source.meshData.vertices[i];
                            if (!clothVertices.ContainsKey(vertice))
                            {
                                clothSkinning[clothVertices.Count].maxDistance             = 0;
                                clothSkinning[clothVertices.Count].collisionSphereDistance = float.MaxValue;
                                clothVertices.Add(vertice, clothVertices.Count);
                                localClothVertices.Add(vertice, clothVertices.Count);
                            }
                        }
                    }
                }

                for (int i = 0; i < source.meshData.subMeshCount; i++)
                {
                    if (source.targetSubmeshIndices[i] >= 0)
                    {
                        int[] subTriangles   = source.meshData.submeshes[i].triangles;
                        int   triangleLength = subTriangles.Length;
                        int   destMesh       = source.targetSubmeshIndices[i];

                        if (source.triangleMask == null)
                        {
                            CopyIntArrayAdd(subTriangles, 0, submeshTriangles[destMesh], subMeshTriangleLength[destMesh], triangleLength, vertexIndex);
                            subMeshTriangleLength[destMesh] += triangleLength;
                        }
                        else
                        {
                            MaskedCopyIntArrayAdd(subTriangles, 0, submeshTriangles[destMesh], subMeshTriangleLength[destMesh], triangleLength, vertexIndex, source.triangleMask[i]);
                            subMeshTriangleLength[destMesh] += (triangleLength - (UMAUtils.GetCardinality(source.triangleMask[i]) * 3));
                        }
                    }
                }

                vertexIndex += sourceVertexCount;
            }

            if (vertexCount != vertexIndex)
            {
                Debug.LogError("Combined vertices size didn't match precomputed value!");
            }

            // fill in new values.
            target.vertexCount      = vertexCount;
            target.vertices         = vertices;
            target.unityBoneWeights = boneWeights;
            target.bindPoses        = bindPoses.ToArray();
            target.normals          = normals;
            target.tangents         = tangents;
            target.uv       = uv;
            target.uv2      = uv2;
            target.uv3      = uv3;
            target.uv4      = uv4;
            target.colors32 = colors32;

            if (has_blendShapes)
            {
                target.blendShapes = blendShapes;
            }

            if (has_clothSkinning)
            {
                Array.Resize(ref clothSkinning, clothVertices.Count);
            }
            target.clothSkinning = clothSkinning;

            target.subMeshCount = subMeshCount;
            target.submeshes    = new SubMeshTriangles[subMeshCount];
            target.umaBones     = umaTransforms;
            target.umaBoneCount = boneCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                target.submeshes[i].triangles = submeshTriangles[i];
            }
            target.boneNameHashes = bonesList.ToArray();
        }
Beispiel #16
0
        /// <summary>
        /// Combines a set of meshes into the target mesh.
        /// </summary>
        /// <param name="target">Target.</param>
        /// <param name="sources">Sources.</param>
        /// <param name="blendShapeSettings">BlendShape Settings.</param>
        public static void CombineMeshes(UMAMeshData target, CombineInstance[] sources, BlendShapeSettings blendShapeSettings = null)
        {
            if (blendShapeSettings == null)
            {
                blendShapeSettings = new BlendShapeSettings();
            }

            int vertexCount             = 0;
            int bindPoseCount           = 0;
            int transformHierarchyCount = 0;
            Dictionary <string, BlendShapeVertexData> blendShapeNames = new Dictionary <string, BlendShapeVertexData>();

            MeshComponents meshComponents        = MeshComponents.none;
            int            subMeshCount          = FindTargetSubMeshCount(sources);
            var            subMeshTriangleLength = new int[subMeshCount];

            AnalyzeSources(sources, subMeshTriangleLength, ref vertexCount, ref bindPoseCount, ref transformHierarchyCount, ref meshComponents);

            if (!blendShapeSettings.ignoreBlendShapes)
            {
                AnalyzeBlendShapeSources(sources, blendShapeSettings, ref meshComponents, out blendShapeNames);
            }

            int[][] submeshTriangles = new int[subMeshCount][];
            for (int i = 0; i < subMeshTriangleLength.Length; i++)
            {
                submeshTriangles[i]      = target.GetSubmeshBuffer(subMeshTriangleLength[i], i);
                subMeshTriangleLength[i] = 0;
            }

            bool has_normals     = (meshComponents & MeshComponents.has_normals) != MeshComponents.none;
            bool has_tangents    = (meshComponents & MeshComponents.has_tangents) != MeshComponents.none;
            bool has_uv          = (meshComponents & MeshComponents.has_uv) != MeshComponents.none;
            bool has_uv2         = (meshComponents & MeshComponents.has_uv2) != MeshComponents.none;
            bool has_uv3         = (meshComponents & MeshComponents.has_uv3) != MeshComponents.none;
            bool has_uv4         = (meshComponents & MeshComponents.has_uv4) != MeshComponents.none;
            bool has_colors32    = (meshComponents & MeshComponents.has_colors32) != MeshComponents.none;
            bool has_blendShapes = (meshComponents & MeshComponents.has_blendShapes) != MeshComponents.none;

            if (blendShapeSettings.ignoreBlendShapes)
            {
                has_blendShapes = false;
            }
            bool has_clothSkinning = (meshComponents & MeshComponents.has_clothSkinning) != MeshComponents.none;

#if UNITY_2019_3_OR_NEWER
            if (nativeBoneWeights.Length < vertexCount)
            {
                if (nativeBoneWeights.IsCreated)
                {
                    nativeBoneWeights.Dispose();
                }

                nativeBoneWeights = new NativeArray <BoneWeight>(vertexCount, Allocator.Persistent);
            }
#else
            BoneWeight[] boneWeights = EnsureArrayLength(target.unityBoneWeights, vertexCount);
#endif
            Vector3[]                  vertices           = EnsureArrayLength(target.vertices, vertexCount);
            Vector3[]                  normals            = has_normals ? EnsureArrayLength(target.normals, vertexCount) : null;
            Vector4[]                  tangents           = has_tangents ? EnsureArrayLength(target.tangents, vertexCount) : null;
            Vector2[]                  uv                 = has_uv ? EnsureArrayLength(target.uv, vertexCount) : null;
            Vector2[]                  uv2                = has_uv2 ? EnsureArrayLength(target.uv2, vertexCount) : null;
            Vector2[]                  uv3                = has_uv3 ? EnsureArrayLength(target.uv3, vertexCount) : null;
            Vector2[]                  uv4                = has_uv4 ? EnsureArrayLength(target.uv4, vertexCount) : null;
            Color32[]                  colors32           = has_colors32 ? EnsureArrayLength(target.colors32, vertexCount) : null;
            UMABlendShape[]            blendShapes        = has_blendShapes ? new UMABlendShape[blendShapeNames.Keys.Count] : null;
            UMATransform[]             umaTransforms      = EnsureArrayLength(target.umaBones, transformHierarchyCount);
            ClothSkinningCoefficient[] clothSkinning      = has_clothSkinning ? EnsureArrayLength(target.clothSkinning, vertexCount) : null;
            Dictionary <Vector3, int>  clothVertices      = has_clothSkinning ? new Dictionary <Vector3, int>(vertexCount) : null;
            Dictionary <Vector3, int>  localClothVertices = has_clothSkinning ? new Dictionary <Vector3, int>(vertexCount) : null;

            InitializeBlendShapeData(ref vertexCount, blendShapeNames, blendShapes);

            int boneCount = 0;
            foreach (var source in sources)
            {
                MergeSortedTransforms(umaTransforms, ref boneCount, source.meshData.umaBones);
            }
            int vertexIndex = 0;

            if (bonesCollection == null)
            {
                bonesCollection = new Dictionary <int, BoneIndexEntry>(boneCount);
            }
            else
            {
                bonesCollection.Clear();
            }
            if (bindPoses == null)
            {
                bindPoses = new List <Matrix4x4>(bindPoseCount);
            }
            else
            {
                bindPoses.Clear();
            }
            if (bonesList == null)
            {
                bonesList = new List <int>(boneCount);
            }
            else
            {
                bonesList.Clear();
            }

            foreach (var source in sources)
            {
                int sourceVertexCount = source.meshData.vertices.Length;
#if UNITY_2019_3_OR_NEWER
                BuildBoneWeights(source.meshData.boneWeights, 0, nativeBoneWeights, vertexIndex, sourceVertexCount, source.meshData.boneNameHashes, source.meshData.bindPoses, bonesCollection, bindPoses, bonesList);
#else
                BuildBoneWeights(source.meshData.boneWeights, 0, boneWeights, vertexIndex, sourceVertexCount, source.meshData.boneNameHashes, source.meshData.bindPoses, bonesCollection, bindPoses, bonesList);
#endif
                Array.Copy(source.meshData.vertices, 0, vertices, vertexIndex, sourceVertexCount);

                if (has_normals)
                {
                    if (source.meshData.normals != null && source.meshData.normals.Length > 0)
                    {
                        Array.Copy(source.meshData.normals, 0, normals, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, sourceVertexCount, Vector3.zero);
                    }
                }
                if (has_tangents)
                {
                    if (source.meshData.tangents != null && source.meshData.tangents.Length > 0)
                    {
                        Array.Copy(source.meshData.tangents, 0, tangents, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv)
                {
                    if (source.meshData.uv != null && source.meshData.uv.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv, 0, uv, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv2)
                {
                    if (source.meshData.uv2 != null && source.meshData.uv2.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv2, 0, uv2, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv2, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv3)
                {
                    if (source.meshData.uv3 != null && source.meshData.uv3.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv3, 0, uv3, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv3, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }
                if (has_uv4)
                {
                    if (source.meshData.uv4 != null && source.meshData.uv4.Length >= sourceVertexCount)
                    {
                        Array.Copy(source.meshData.uv4, 0, uv4, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        FillArray(uv4, vertexIndex, sourceVertexCount, Vector4.zero);
                    }
                }

                if (has_colors32)
                {
                    if (source.meshData.colors32 != null && source.meshData.colors32.Length > 0)
                    {
                        Array.Copy(source.meshData.colors32, 0, colors32, vertexIndex, sourceVertexCount);
                    }
                    else
                    {
                        Color32 white32 = Color.white;
                        FillArray(colors32, vertexIndex, sourceVertexCount, white32);
                    }
                }

                if (has_blendShapes)
                {
                    if (source.meshData.blendShapes != null && source.meshData.blendShapes.Length > 0)
                    {
                        int sourceBlendShapeLength = source.meshData.blendShapes.Length;
                        for (int shapeIndex = 0; shapeIndex < sourceBlendShapeLength; shapeIndex++)
                        {
                            string shapeName = source.meshData.blendShapes[shapeIndex].shapeName;

                            //If we aren't loading all blendshapes and we don't find the blendshape name in the list of explicit blendshapes to combine, then skip to the next one.
                            if (!blendShapeSettings.loadAllBlendShapes && !blendShapeSettings.blendShapes.ContainsKey(shapeName))
                            {
                                continue;
                            }

                            #region BlendShape Baking
                            if (BakeBlendShape(blendShapeSettings.blendShapes, source.meshData.blendShapes[shapeIndex], ref vertexIndex, vertices, normals, tangents, has_normals, has_tangents))
                            {
                                continue;                                 //If we baked this blendshape, then continue to the next one and skip adding the regular blendshape.
                            }
                            #endregion

                            //If our dictionary contains the shape name, which it should
                            if (blendShapeNames.ContainsKey(shapeName))
                            {
                                UMABlendShape[] sourceBlendShapes = source.meshData.blendShapes;
                                int             i = blendShapeNames[shapeName].index;

                                if (blendShapes[i].frames.Length != sourceBlendShapes[shapeIndex].frames.Length)
                                {
                                    if (Debug.isDebugBuild)
                                    {
                                        Debug.LogError("SkinnedMeshCombiner: mesh blendShape frame counts don't match!");
                                    }
                                    break;
                                }

                                for (int frameIndex = 0; frameIndex < sourceBlendShapes[shapeIndex].frames.Length; frameIndex++)
                                {
                                    Array.Copy(sourceBlendShapes[shapeIndex].frames[frameIndex].deltaVertices, 0, blendShapes[i].frames[frameIndex].deltaVertices, vertexIndex, sourceVertexCount);

                                    Vector3[] sourceDeltaNormals  = sourceBlendShapes[shapeIndex].frames[frameIndex].deltaNormals;
                                    Vector3[] sourceDeltaTangents = sourceBlendShapes[shapeIndex].frames[frameIndex].deltaTangents;

                                    //if out dictionary says at least one source has normals or tangents and the current source has normals or tangents then copy them.
                                    if (blendShapeNames[shapeName].hasNormals && sourceDeltaNormals.Length > 0)
                                    {
                                        Array.Copy(sourceDeltaNormals, 0, blendShapes[i].frames[frameIndex].deltaNormals, vertexIndex, sourceVertexCount);
                                    }

                                    if (blendShapeNames[shapeName].hasTangents && sourceDeltaTangents.Length > 0)
                                    {
                                        Array.Copy(sourceDeltaTangents, 0, blendShapes[i].frames[frameIndex].deltaTangents, vertexIndex, sourceVertexCount);
                                    }
                                }
                            }
                            else
                            {
                                if (Debug.isDebugBuild)
                                {
                                    Debug.LogError("BlendShape " + shapeName + " not found in dictionary!");
                                }
                            }
                        }
                    }
                }
                if (has_clothSkinning)
                {
                    localClothVertices.Clear();
                    if (source.meshData.clothSkinningSerialized != null && source.meshData.clothSkinningSerialized.Length > 0)
                    {
                        for (int i = 0; i < source.meshData.vertexCount; i++)
                        {
                            var vertice = source.meshData.vertices[i];
                            if (!localClothVertices.ContainsKey(vertice))
                            {
                                int localCount = localClothVertices.Count;
                                localClothVertices.Add(vertice, localCount);
                                if (!clothVertices.ContainsKey(vertice))
                                {
                                    ConvertData(ref source.meshData.clothSkinningSerialized[localCount], ref clothSkinning[clothVertices.Count]);
                                    clothVertices.Add(vertice, clothVertices.Count);
                                }
                                else
                                {
                                    ConvertData(ref source.meshData.clothSkinningSerialized[localCount], ref clothSkinning[clothVertices[vertice]]);
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < source.meshData.vertexCount; i++)
                        {
                            var vertice = source.meshData.vertices[i];
                            if (!clothVertices.ContainsKey(vertice))
                            {
                                clothSkinning[clothVertices.Count].maxDistance             = 0;
                                clothSkinning[clothVertices.Count].collisionSphereDistance = float.MaxValue;
                                clothVertices.Add(vertice, clothVertices.Count);
                                localClothVertices.Add(vertice, clothVertices.Count);
                            }
                        }
                    }
                }

                for (int i = 0; i < source.meshData.subMeshCount; i++)
                {
                    if (source.targetSubmeshIndices[i] >= 0)
                    {
                        int[] subTriangles   = source.meshData.submeshes[i].triangles;
                        int   triangleLength = subTriangles.Length;
                        int   destMesh       = source.targetSubmeshIndices[i];

                        if (source.triangleMask == null)
                        {
                            CopyIntArrayAdd(subTriangles, 0, submeshTriangles[destMesh], subMeshTriangleLength[destMesh], triangleLength, vertexIndex);
                            subMeshTriangleLength[destMesh] += triangleLength;
                        }
                        else
                        {
                            MaskedCopyIntArrayAdd(subTriangles, 0, submeshTriangles[destMesh], subMeshTriangleLength[destMesh], triangleLength, vertexIndex, source.triangleMask[i]);
                            subMeshTriangleLength[destMesh] += (triangleLength - (UMAUtils.GetCardinality(source.triangleMask[i]) * 3));
                        }
                    }
                }

                vertexIndex += sourceVertexCount;
            }

            if (vertexCount != vertexIndex)
            {
                if (Debug.isDebugBuild)
                {
                    Debug.LogError("Combined vertices size didn't match precomputed value!");
                }
            }

            // fill in new values.
            target.vertexCount = vertexCount;
            target.vertices    = vertices;
#if UNITY_2019_3_OR_NEWER
            target.unityBoneWeights = nativeBoneWeights.GetSubArray(0, vertexCount).ToArray();
#else
            target.unityBoneWeights = boneWeights;
#endif
            target.bindPoses = bindPoses.ToArray();
            target.normals   = normals;
            target.tangents  = tangents;
            target.uv        = uv;
            target.uv2       = uv2;
            target.uv3       = uv3;
            target.uv4       = uv4;
            target.colors32  = colors32;

            if (has_blendShapes)
            {
                target.blendShapes = blendShapes;
            }

            if (has_clothSkinning)
            {
                Array.Resize(ref clothSkinning, clothVertices.Count);
            }
            target.clothSkinning = clothSkinning;

            target.subMeshCount = subMeshCount;
            target.submeshes    = new SubMeshTriangles[subMeshCount];
            target.umaBones     = umaTransforms;
            target.umaBoneCount = boneCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                target.submeshes[i].triangles = submeshTriangles[i];
            }
            target.boneNameHashes = bonesList.ToArray();
        }
Beispiel #17
0
        private static void AnalyzeBlendShapeSources(CombineInstance[] sources, BlendShapeSettings blendShapeSettings, ref MeshComponents meshComponents, out Dictionary <string, BlendShapeVertexData> blendShapeNames)
        {
            blendShapeNames = new Dictionary <string, BlendShapeVertexData>();

            if (blendShapeSettings.ignoreBlendShapes)
            {
                return;
            }

            int bakedCount = 0;

            foreach (var source in sources)
            {
                //If we find a blendshape on this mesh then lets add it to the blendShapeNames hash to get all the unique names
                if (source.meshData.blendShapes == null)
                {
                    continue;
                }

                if (source.meshData.blendShapes.Length == 0)
                {
                    continue;
                }

                for (int shapeIndex = 0; shapeIndex < source.meshData.blendShapes.Length; shapeIndex++)
                {
                    string shapeName = source.meshData.blendShapes[shapeIndex].shapeName;

                    //if we are baking this blendshape then skip and don't add to the blendshape names.
                    BlendShapeData data;
                    if (blendShapeSettings.blendShapes.TryGetValue(shapeName, out data))
                    {
                        if (data.isBaked)
                        {
                            bakedCount++;
                            continue;
                        }
                    }

                    if (!blendShapeNames.ContainsKey(shapeName))
                    {
                        BlendShapeVertexData newData = new BlendShapeVertexData();
                        blendShapeNames.Add(shapeName, newData);
                    }

                    blendShapeNames[shapeName].hasNormals  |= source.meshData.blendShapes[shapeIndex].frames[0].HasNormals();
                    blendShapeNames[shapeName].hasTangents |= source.meshData.blendShapes[shapeIndex].frames[0].HasTangents();

                    if (source.meshData.blendShapes[shapeIndex].frames.Length > blendShapeNames[shapeName].frameCount)
                    {
                        blendShapeNames[shapeName].frameCount   = source.meshData.blendShapes[shapeIndex].frames.Length;
                        blendShapeNames[shapeName].frameWeights = new float[blendShapeNames[shapeName].frameCount];

                        for (int i = 0; i < blendShapeNames[shapeName].frameCount; i++)
                        {
                            //technically two sources could have different frame weights for the same blendshape, but then thats a problem with the source.
                            blendShapeNames[shapeName].frameWeights[i] = source.meshData.blendShapes[shapeIndex].frames[i].frameWeight;
                        }
                    }
                }
            }

            //If our blendshape hash has at least 1 name, then we have a blendshape!
            if (blendShapeNames.Count > 0 || bakedCount > 0)
            {
                meshComponents |= MeshComponents.has_blendShapes;
            }
        }
 public ModifyVerticesMeshChange(DMesh3 mesh, MeshComponents wantComponents = MeshComponents.All)
 {
     initialize_buffers(mesh, wantComponents);
 }
Beispiel #19
0
        private static void AnalyzeSources(CombineInstance[] sources, int[] subMeshTriangleLength, ref int vertexCount, ref int bindPoseCount, ref int transformHierarchyCount, ref MeshComponents meshComponents)
        {
            for (int i = 0; i < subMeshTriangleLength.Length; i++)
            {
                subMeshTriangleLength[i] = 0;
            }

            foreach (var source in sources)
            {
                vertexCount             += source.meshData.vertices.Length;
                bindPoseCount           += source.meshData.bindPoses.Length;
                transformHierarchyCount += source.meshData.umaBones.Length;
                if (source.meshData.normals != null && source.meshData.normals.Length != 0)
                {
                    meshComponents |= MeshComponents.has_normals;
                }
                if (source.meshData.tangents != null && source.meshData.tangents.Length != 0)
                {
                    meshComponents |= MeshComponents.has_tangents;
                }
                if (source.meshData.uv != null && source.meshData.uv.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv;
                }
                if (source.meshData.uv2 != null && source.meshData.uv2.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv2;
                }
#if !UNITY_4_6
                if (source.meshData.uv3 != null && source.meshData.uv3.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv3;
                }
                if (source.meshData.uv4 != null && source.meshData.uv4.Length != 0)
                {
                    meshComponents |= MeshComponents.has_uv4;
                }
#endif
                if (source.meshData.colors32 != null && source.meshData.colors32.Length != 0)
                {
                    meshComponents |= MeshComponents.has_colors32;
                }

                for (int i = 0; i < source.meshData.subMeshCount; i++)
                {
                    if (source.targetSubmeshIndices[i] >= 0)
                    {
                        int triangleLength = source.meshData.submeshes[i].triangles.Length;
                        subMeshTriangleLength[source.targetSubmeshIndices[i]] += triangleLength;
                    }
                }
            }
        }
Beispiel #20
0
        /// <summary>
        /// Combines a set of meshes into the target mesh.
        /// </summary>
        /// <param name="target">Target.</param>
        /// <param name="sources">Sources.</param>
        public static void CombineMeshes(UMAMeshData target, CombineInstance[] sources)
        {
            int vertexCount             = 0;
            int bindPoseCount           = 0;
            int transformHierarchyCount = 0;

            MeshComponents meshComponents        = MeshComponents.none;
            int            subMeshCount          = FindTargetSubMeshCount(sources);
            var            subMeshTriangleLength = new int[subMeshCount];

            AnalyzeSources(sources, subMeshTriangleLength, ref vertexCount, ref bindPoseCount, ref transformHierarchyCount, ref meshComponents);

            int[][] submeshTriangles = new int[subMeshCount][];
            for (int i = 0; i < subMeshTriangleLength.Length; i++)
            {
                submeshTriangles[i]      = new int[subMeshTriangleLength[i]];
                subMeshTriangleLength[i] = 0;
            }

            bool has_normals  = (meshComponents & MeshComponents.has_normals) != MeshComponents.none;
            bool has_tangents = (meshComponents & MeshComponents.has_tangents) != MeshComponents.none;
            bool has_uv       = (meshComponents & MeshComponents.has_uv) != MeshComponents.none;
            bool has_uv2      = (meshComponents & MeshComponents.has_uv2) != MeshComponents.none;

#if !UNITY_4_6
            bool has_uv3 = (meshComponents & MeshComponents.has_uv3) != MeshComponents.none;
            bool has_uv4 = (meshComponents & MeshComponents.has_uv4) != MeshComponents.none;
#endif
            bool has_colors32 = (meshComponents & MeshComponents.has_colors32) != MeshComponents.none;

            Vector3[]    vertices    = EnsureArrayLength(target.vertices, vertexCount);
            BoneWeight[] boneWeights = EnsureArrayLength(target.unityBoneWeights, vertexCount);
            Vector3[]    normals     = has_normals ? EnsureArrayLength(target.normals, vertexCount) : null;
            Vector4[]    tangents    = has_tangents ? EnsureArrayLength(target.tangents, vertexCount) : null;
            Vector2[]    uv          = has_uv ? EnsureArrayLength(target.uv, vertexCount) : null;
            Vector2[]    uv2         = has_uv2 ? EnsureArrayLength(target.uv2, vertexCount) : null;
#if !UNITY_4_6
            Vector2[] uv3 = has_uv3 ? EnsureArrayLength(target.uv3, vertexCount) : null;
            Vector2[] uv4 = has_uv4 ? EnsureArrayLength(target.uv4, vertexCount) : null;
#endif
            Color32[] colors32 = has_colors32 ? EnsureArrayLength(target.colors32, vertexCount) : null;

            UMATransform[] umaTransforms = EnsureArrayLength(target.umaBones, transformHierarchyCount);

            int boneCount = 0;
            foreach (var source in sources)
            {
                MergeSortedTransforms(umaTransforms, ref boneCount, source.meshData.umaBones);
            }
            int vertexIndex = 0;

            if (bonesCollection == null)
            {
                bonesCollection = new Dictionary <int, BoneIndexEntry>(boneCount);
            }
            else
            {
                bonesCollection.Clear();
            }
            if (bindPoses == null)
            {
                bindPoses = new List <Matrix4x4>(bindPoseCount);
            }
            else
            {
                bindPoses.Clear();
            }
            if (bonesList == null)
            {
                bonesList = new List <int>(boneCount);
            }
            else
            {
                bonesList.Clear();
            }

            foreach (var source in sources)
            {
                vertexCount = source.meshData.vertices.Length;
                BuildBoneWeights(source.meshData.boneWeights, 0, boneWeights, vertexIndex, vertexCount, source.meshData.boneNameHashes, source.meshData.bindPoses, bonesCollection, bindPoses, bonesList);

                Array.Copy(source.meshData.vertices, 0, vertices, vertexIndex, vertexCount);

                if (has_normals)
                {
                    if (source.meshData.normals != null && source.meshData.normals.Length > 0)
                    {
                        Array.Copy(source.meshData.normals, 0, normals, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, vertexCount, Vector3.zero);
                    }
                }
                if (has_tangents)
                {
                    if (source.meshData.tangents != null && source.meshData.tangents.Length > 0)
                    {
                        Array.Copy(source.meshData.tangents, 0, tangents, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(tangents, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
                if (has_uv)
                {
                    if (source.meshData.uv != null && source.meshData.uv.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv, 0, uv, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
                if (has_uv2)
                {
                    if (source.meshData.uv2 != null && source.meshData.uv2.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv2, 0, uv2, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv2, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
#if !UNITY_4_6
                if (has_uv3)
                {
                    if (source.meshData.uv3 != null && source.meshData.uv3.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv3, 0, uv3, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv3, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
                if (has_uv4)
                {
                    if (source.meshData.uv4 != null && source.meshData.uv4.Length >= vertexCount)
                    {
                        Array.Copy(source.meshData.uv4, 0, uv4, vertexIndex, vertexCount);
                    }
                    else
                    {
                        FillArray(uv4, vertexIndex, vertexCount, Vector4.zero);
                    }
                }
#endif
                if (has_colors32)
                {
                    if (source.meshData.colors32 != null && source.meshData.colors32.Length > 0)
                    {
                        Array.Copy(source.meshData.colors32, 0, colors32, vertexIndex, vertexCount);
                    }
                    else
                    {
                        Color32 white32 = Color.white;
                        FillArray(colors32, vertexIndex, vertexCount, white32);
                    }
                }

                for (int i = 0; i < source.meshData.subMeshCount; i++)
                {
                    if (source.targetSubmeshIndices[i] >= 0)
                    {
                        int[] subTriangles   = source.meshData.submeshes[i].triangles;
                        int   triangleLength = subTriangles.Length;
                        int   destMesh       = source.targetSubmeshIndices[i];

                        CopyIntArrayAdd(subTriangles, 0, submeshTriangles[destMesh], subMeshTriangleLength[destMesh], triangleLength, vertexIndex);
                        subMeshTriangleLength[destMesh] += triangleLength;
                    }
                }

                vertexIndex += vertexCount;
            }
            vertexCount = vertexIndex;

            // fill in new values.
            target.vertexCount      = vertexCount;
            target.vertices         = vertices;
            target.unityBoneWeights = boneWeights;
            target.bindPoses        = bindPoses.ToArray();
            target.normals          = normals;
            target.tangents         = tangents;
            target.uv  = uv;
            target.uv2 = uv2;
#if !UNITY_4_6
            target.uv3 = uv3;
            target.uv4 = uv4;
#endif
            target.colors32 = colors32;

            target.subMeshCount = subMeshCount;
            target.submeshes    = new SubMeshTriangles[subMeshCount];
            target.umaBones     = umaTransforms;
            target.umaBoneCount = boneCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                target.submeshes[i].triangles = submeshTriangles[i];
            }
            target.boneNameHashes = bonesList.ToArray();
        }