Example #1
0
 /// <summary>
 /// Removes a MeshInput from the MeshInput list to be processed.
 /// </summary>
 /// <remarks>
 /// This is useful if you are caching MeshInputs for future use, and just want to remove a mesh as its
 /// no longer being combined. Open worlds may find this very useful.
 /// </remarks>
 /// <returns><c>true</c>, if the MeshInput was removed, <c>false</c> otherwise.</returns>
 /// <param name="meshInput">The MeshInput to be removed.</param>
 public bool RemoveMesh(MeshInput meshInput)
 {
     if (_meshInputs.Contains(meshInput))
     {
         _meshInputs.Remove(meshInput);
         return(true);
     }
     return(false);
 }
Example #2
0
 /// <summary>
 /// Adds an existing MeshInput into the MeshCombiner.
 /// </summary>
 /// <remarks>
 /// This can be done without Unity's main thread, if you have access to the data already.
 /// Just need to make sure that the material codes are set correctly.
 /// </remarks>
 /// <returns><c>true</c>, if MeshInput was added, <c>false</c> otherwise.</returns>
 /// <param name="meshInput">The MeshInput to add.</param>
 public bool AddMesh(MeshInput meshInput)
 {
     if (!_meshInputs.Contains(meshInput))
     {
         _meshInputs.Add(meshInput);
         return(true);
     }
     return(false);
 }
Example #3
0
        /// <summary>
        /// Creates a MeshInput from the passed arguements.
        /// </summary>
        /// <remarks>This can only be used from within Unity's main thread.</remarks>
        /// <returns>The created MeshInput</returns>
        /// <param name="meshFilter">The source Mesh's MeshFilter.</param>
        /// <param name="renderer">The source Mesh's Renderer.</param>
        /// <param name="worldMatrix">The source Mesh's World Matrix</param>
        public MeshInput CreateMeshInput(MeshFilter meshFilter, Renderer renderer, Matrix4x4 worldMatrix)
        {
            var newMeshInput = new MeshInput();

            newMeshInput.Mesh          = new BufferedMesh();
            newMeshInput.Mesh.Name     = meshFilter.name;
            newMeshInput.Mesh.Vertices = meshFilter.sharedMesh.vertices;
            newMeshInput.Mesh.Normals  = meshFilter.sharedMesh.normals;
            newMeshInput.Mesh.Colors   = meshFilter.sharedMesh.colors;
            newMeshInput.Mesh.Tangents = meshFilter.sharedMesh.tangents;
            newMeshInput.Mesh.UV       = meshFilter.sharedMesh.uv;
            newMeshInput.Mesh.UV1      = meshFilter.sharedMesh.uv1;
            newMeshInput.Mesh.UV2      = meshFilter.sharedMesh.uv2;

            newMeshInput.Mesh.Topology = new MeshTopology[meshFilter.sharedMesh.subMeshCount];

            for (var i = 0; i < meshFilter.sharedMesh.subMeshCount; i++)
            {
                newMeshInput.Mesh.Topology [i] = meshFilter.sharedMesh.GetTopology(i);

                // Check for Unsupported Mesh Topology
                switch (newMeshInput.Mesh.Topology [i])
                {
                case MeshTopology.Lines:
                case MeshTopology.LineStrip:
                case MeshTopology.Points:
                    Debug.LogWarning("The MeshCombiner does not support this meshes (" +
                                     newMeshInput.Mesh.Name + "topology (" + newMeshInput.Mesh.Topology [i] + ")");
                    break;
                }
                newMeshInput.Mesh.Indexes.Add(meshFilter.sharedMesh.GetIndices(i));
            }

            // Create Materials
            newMeshInput.Materials = AddMaterials(renderer.sharedMaterials);


            // Determine Inversion of Scale
            // Don't Scale (NNP, PPP, PNN, NPN)
            Vector3 scaleTest = meshFilter.gameObject.transform.localScale;

            bool invertedX = (scaleTest.x < 0f);
            bool invertedY = (scaleTest.y < 0f);
            bool invertedZ = (scaleTest.z < 0f);

            if ((invertedX && invertedY && invertedZ) ||
                (invertedX && !invertedY && !invertedZ) ||
                (!invertedX && invertedY && !invertedZ) ||
                (!invertedX && !invertedY && invertedZ))
            {
                newMeshInput.ScaleInverted = true;
            }
            newMeshInput.WorldMatrix = worldMatrix;

            return(newMeshInput);
        }
Example #4
0
        /// <summary>
        /// Creates MeshInput(s) from the passed arguement arrays.
        /// </summary>
        /// <remarks>This can only be used from within Unity's main thread.</remarks>
        /// <returns>The created MeshInput(s)</returns>
        /// <param name="meshFilters">The source Meshes MeshFilters.</param>
        /// <param name="renderers">The source Meshes Renderers.</param>
        /// <param name="worldMatrices">The source Meshes World Matrices</param>
        public MeshInput[] CreateMeshInputs(MeshFilter[] meshFilters, Renderer[] renderers, Matrix4x4[] worldMatrices)
        {
            // Create our holder
            var meshInputs = new MeshInput[meshFilters.Length];

            // Lazy way of making a whole bunch.
            for (int i = 0; i < meshFilters.Length; i++)
            {
                meshInputs [i] = CreateMeshInput(meshFilters [i], renderers [i], worldMatrices [i]);
            }

            // Send it back!
            return(meshInputs);
        }
Example #5
0
        /// <summary>
        /// Thread safe creation of a TransitionMesh from a MeshInput.
        /// </summary>
        /// <param name="meshInput">Mesh input.</param>
        void CreateTransitionMesh(MeshInput meshInput)
        {
            var mesh                     = meshInput.Mesh;
            var subMeshCount             = mesh.SubMeshCount;
            var vertices                 = mesh.Vertices;
            var normals                  = mesh.Normals;
            var Colors                   = mesh.Colors;
            var tangents                 = mesh.Tangents;
            var uv                       = mesh.UV;
            var uv1                      = mesh.UV1;
            var uv2                      = mesh.UV2;
            var transitionMeshCounter    = new int [mesh.VertexCount];
            var inversedTransposedMatrix = meshInput.WorldMatrix.inverse.transpose;

            for (var i = 0; i < subMeshCount; i++)
            {
                var newTransitionMesh = new TransitionMesh();
                var indexes           = mesh.GetIndices(i);

                if (i > (meshInput.Materials.Length - 1))
                {
                    // If there is no material, dont add the mesh later to be rendered
                    // as it wasn't showing anyways!.
                    continue;
                }
                newTransitionMesh.Material = meshInput.Materials [i];

                // Determine how many actual vertices are to be used.
                // Former Count function
                int vc    = mesh.VertexCount;
                int count = 0;

                for (int j = 0; j < indexes.Length; j++)
                {
                    transitionMeshCounter [indexes [j]] = 1;
                }
                for (int j = 0; j < vc; j++)
                {
                    int c = count;
                    count += transitionMeshCounter [j];
                    transitionMeshCounter [j] = c;
                }
                newTransitionMesh.VertexCount = count;

                // Assign the rest of the things
                newTransitionMesh.IndexCount = indexes.Length;
                newTransitionMesh.Vertices   = new Vector3[newTransitionMesh.VertexCount];
                newTransitionMesh.Indexes    = new int[newTransitionMesh.IndexCount];

                if (meshInput.ScaleInverted)
                {
                    // Reverse Winding Order (0,2,1)
                    for (var j = 0; j < newTransitionMesh.IndexCount; j += 3)
                    {
                        newTransitionMesh.Indexes [j]     = transitionMeshCounter [indexes [j]];
                        newTransitionMesh.Indexes [j + 1] = transitionMeshCounter [indexes [j + 2]];
                        newTransitionMesh.Indexes [j + 2] = transitionMeshCounter [indexes [j + 1]];
                    }
                }
                else
                {
                    // Normal Winding Order (0,1,2)
                    for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                    {
                        newTransitionMesh.Indexes [j] = transitionMeshCounter [indexes [j]];
                    }
                }

                // Handle Vertices
                for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                {
                    var index = indexes [j];
                    newTransitionMesh.Vertices [transitionMeshCounter [index]] =
                        meshInput.WorldMatrix.MultiplyPoint(vertices [index]);
                }

                // Handle Normals
                if (mesh.Normals != null && mesh.Normals.Length > 0)
                {
                    newTransitionMesh.Normals = new Vector3[newTransitionMesh.VertexCount];

                    for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                    {
                        var index = indexes [j];
                        newTransitionMesh.Normals [transitionMeshCounter [index]] =
                            inversedTransposedMatrix.MultiplyVector(normals [index]).normalized;
                    }
                }

                // Handle Colors
                if (mesh.Colors != null && mesh.Colors.Length > 0)
                {
                    newTransitionMesh.Colors = new Color[newTransitionMesh.VertexCount];
                    for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                    {
                        var index = indexes [j];
                        newTransitionMesh.Colors [transitionMeshCounter [index]] =
                            Colors [index];
                    }
                }

                // Handle Tangents
                if (mesh.Tangents != null && mesh.Tangents.Length > 0)
                {
                    newTransitionMesh.Tangents = new Vector4[newTransitionMesh.VertexCount];
                    for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                    {
                        var index = indexes [j];
                        var p     = tangents [index];
                        var w     = p.w;
                        p = inversedTransposedMatrix.MultiplyVector(p).normalized;

                        newTransitionMesh.Tangents [transitionMeshCounter [index]] =
                            new Vector4(p.x, p.y, p.z, w);
                    }
                }

                // Handle UVs
                if (mesh.UV != null && mesh.UV.Length > 0)
                {
                    newTransitionMesh.UV = new Vector2[newTransitionMesh.VertexCount];
                    for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                    {
                        var index = indexes [j];
                        newTransitionMesh.UV [transitionMeshCounter [index]] = uv [index];
                    }
                }

                // Handle UV1s
                if (mesh.UV1 != null && mesh.UV1.Length > 0)
                {
                    newTransitionMesh.UV1 = new Vector2[newTransitionMesh.VertexCount];
                    for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                    {
                        var index = indexes [j];
                        newTransitionMesh.UV1 [transitionMeshCounter [index]] = uv1 [index];
                    }
                }

                // Handle UV2s
                if (mesh.UV2 != null && mesh.UV2.Length > 0)
                {
                    newTransitionMesh.UV2 = new Vector2[newTransitionMesh.VertexCount];
                    for (var j = 0; j < newTransitionMesh.IndexCount; j++)
                    {
                        var index = indexes [j];
                        newTransitionMesh.UV2 [transitionMeshCounter [index]] = uv2 [index];
                    }
                }

                // Lock the reference array, and add in as it can.
                lock (_transitionMeshes) {
                    _transitionMeshes.Add(newTransitionMesh);
                }
            }
        }
 internal bool TryGetRegisteredMeshInputs(Hash128 hash, out MeshInput inputData) =>
 m_MeshColliderJobs.TryGetValue(hash, out inputData);