/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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);