/// <summary> /// Aggregates all the color data for a given mesh vertex index. /// Checks overlapping verticies for vertex color data and collects it in the provided /// collection. /// </summary> /// <param name="textureCoords">Texture coordinates to treat as colors.</param> /// <param name="vertexColorVertices">The vertices that contain the color information.</param> /// <param name="vertices">The main vertices.</param> /// <param name="vertIndexToCheck">The index of the vertices being checked.</param> /// <param name="colorsToAdd">The collection of colors to add to.</param> /// <param name="coordToColorConversionStrategy">The strategy to use for converting the texture coordinates to colors.</param> /// <returns>The number of colors added to the collection.</returns> private static int AggregateVertexColorsForIndex(Vector2[] textureCoords, Vector3[] vertexColorVertices, Vector3[] vertices, int vertIndexToCheck, ICollection <Color> colorsToAdd, IUVToColorConversionStrategy coordToColorConversionStrategy) { if (textureCoords == null) { throw new ArgumentNullException("textureCoords"); } if (vertexColorVertices == null) { throw new ArgumentNullException("vertexColorVertices"); } if (vertices == null) { throw new ArgumentNullException("vertices"); } if (colorsToAdd == null) { throw new ArgumentNullException("colorsToAdd"); } if (coordToColorConversionStrategy == null) { throw new ArgumentNullException("coordToColorConversionStrategy"); } if (vertIndexToCheck < 0) { throw new ArgumentOutOfRangeException("vertIndexToCheck", "The vertex index to check cannot be less than 0."); } int count = colorsToAdd.Count; //So for each vertex we want to find one that matches in the vertex color mesh //so that we we assign the color to the texture mesh for (int colorVertIndex = 0; colorVertIndex < textureCoords.Length && colorVertIndex < vertices.Length; colorVertIndex++) { //If it's within distance (don't assume same position) then we should consider it a match and aggregate the color at this point if (!(Vector3.Distance(vertexColorVertices[vertIndexToCheck], vertices[colorVertIndex]) <= Vector3.kEpsilon * 10)) { continue; } colorsToAdd.Add(coordToColorConversionStrategy.ConvertCoordinate(textureCoords[colorVertIndex])); } return(colorsToAdd.Count - count); }
private Color ParseCoordinatesToColor(IList <GameObject> vertexColoredGameObjectList, GameObject currentVertexColoredGameObject, Mesh vertexColorMesh, Vector2[] textureCoords, Vector3[] tmVertices, Vector3[] vertexColoredVertices, int vertIndex, IUVToColorConversionStrategy coordToColorConversionStrategy) { List <Color> colorsToAdd = new List <Color>(10); AggregateVertexColorsForIndex(textureCoords, tmVertices, vertexColoredVertices, vertIndex, colorsToAdd, coordToColorConversionStrategy); if (useVertexBlending) { //Now we need to check nearby meshes to see if we share points and should blend/average vertex colors with them //This can be done efficiently using bounding box volume distance comparisions IEnumerable <Mesh> nearbyUnswappedMeshes = vertexColoredGameObjectList .Where(go => go != currentVertexColoredGameObject) .Select(go => go.GetComponent <MeshFilter>().sharedMesh) .Where(m => m.bounds.Intersects(vertexColorMesh.bounds)); //Then once we've gathered all nearby meshes we can perform the same process against each mesh to blend colors //TODO: This is insanely costly N^3. Could be VERY slow for large meshes nearby large meshes foreach (Mesh m in nearbyUnswappedMeshes) { Vector3[] nearbyVertices = m.vertices; Vector2[] nearbyUVColorCoords = m.uv; //For performance we should only be interested in vertices that are contained in nearby bounding boxes if (!m.bounds.Contains(tmVertices[vertIndex])) { continue; } AggregateVertexColorsForIndex(nearbyUVColorCoords, tmVertices, nearbyVertices, vertIndex, colorsToAdd, coordToColorConversionStrategy); } } return(AggregateColorData(colorsToAdd)); }