diff --git a/CubeMosaicGenerator.cs b/CubeMosaicGenerator.cs new file mode 100644 index 0000000..220e6a9 --- /dev/null +++ b/CubeMosaicGenerator.cs @@ -0,0 +1,372 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +public class CubeMosaicGenerator : MonoBehaviour +{ + + [HideInInspector] + public string version = "1.0.4"; + [HideInInspector] + public bool newVersionAvailable = false; + + [Header("Map Editor Reborn")] + [Tooltip("If true, the color of each cube will be applied to the Primitive Component Script, rather than the Material. This is necessary for Map Editor Reborn.")] + public bool MapEditorRebornUsage = true; + [Space(20)] + public Texture2D inputImage; // Assign the input image in the Inspector + public GameObject cubePrefab; // Assign the cube prefab in the Inspector + + public float cubeSize = 0.1f; // Adjust cube size as needed + [Header("Spacing")] + public bool useSpacing = false; // If true, the spacing between cubes will be adjusted to fit the target height + [Tooltip("Spacing between cubes. Adjust spacing as needed.")] + public float spacing = 0.1f; // Adjust spacing between cubes + [Header("Target Height")] + public bool useTargetHeight = true; // If true, the mosaic will be scaled to the target height + [Tooltip("One unit equals the height of one in-game door. Adjust the target height of the mosaic to fit the height of your door. (Otherwise, one door equals the height of 3 primitive cubes.)")] + public float targetHeightAsDoors = 1f; // Adjust the height of the mosaic + + [Header("Generate Mosaic")] + [Tooltip("If true, the mosaic will be cleared before generating a new one")] + public bool autoClean = true; // If true, the mosaic will be cleared before generating a new one + + [Tooltip("If true, the script will try to merge cubes that are roughly the same color and next to each other in order to reduce the amount primitives.")] + public bool optimization = true; // If true, the mosaic will be optimized vertically + + [Tooltip("The lower the value, the more similar the colors have to be to be considered the same color. (0.03 is a good value)")] + [Range(0.01f, 1f)] + public float sameColorMargin = 0.03f; + + + public void Start() + { + //TODO: Check for new version + } + public void GenerateMosaic() + { + + if (autoClean) + { + removeExistingCubes(); + } + if (useTargetHeight) + { + //calculate the amount of cubes needed to fit the target height + float targetHeight = targetHeightAsDoors * 3f / cubeSize; + int newHeight = Mathf.RoundToInt(targetHeight); + + //calculate the width of the mosaic based on the aspect ratio of the input image + int newWidth; + + int heightFaktor = Mathf.RoundToInt((float)inputImage.height / (float)newHeight); + newWidth = Mathf.RoundToInt((float)inputImage.width / (float)heightFaktor); + + // Create a new uncompressed texture with the desired size + Texture2D newImage = new Texture2D(newWidth, newHeight); + + // Copy pixel data from original texture to new resized texture + for (int y = 0; y < newHeight; y++) + { + for (int x = 0; x < newWidth; x++) + { + // Calculate the corresponding coordinates in the original texture + int originalX = Mathf.RoundToInt((float)x / newWidth * inputImage.width); + int originalY = Mathf.RoundToInt((float)y / newHeight * inputImage.height); + + Color pixelColor = inputImage.GetPixel(originalX, originalY); + newImage.SetPixel(x, y, pixelColor); + } + } + + // Apply changes to the new texture + newImage.Apply(); + + // Generate the cubes + GenerateCubes(newImage); + } + else + { + GenerateCubes(inputImage); + } + } + + private void GenerateCubes(Texture2D image) + { + Color[] pixels = image.GetPixels(); + int width = image.width; + int height = image.height; + + spacing = useSpacing ? cubeSize + spacing : cubeSize; + + // Get a reference to the parent GameObject (the object the script is attached to) + Transform parentTransform = transform; + + + // Calculate the starting position of the cubes + Vector3 startPosition = parentTransform.position - new Vector3(width * spacing / 2f, height * spacing / 2f, 0); + + for (int y = 0; y < height; y++) + { + GameObject previousCube = null; + Color previousColor = Color.clear; + int sameColorCount = 0; + + for (int x = 0; x < width; x++) + { + Color pixelColor = pixels[y * width + x]; + + if (previousCube == null) + { + // Spawn a new cube + GameObject cube = Instantiate(cubePrefab, startPosition + new Vector3(x * spacing, y * spacing, 0), Quaternion.identity, parentTransform); + cube.transform.localScale = new Vector3(cubeSize, cubeSize, cubeSize); + // Set the cube's color + if (MapEditorRebornUsage) + { + cube.GetComponent().Color = pixelColor; + } + else + { + + cube.GetComponent().material.color = pixelColor; + } + + // Set the previous cube + previousCube = cube; + + // Set the previous color + previousColor = pixelColor; + + // Reset the counter + sameColorCount = 0; + } + else + { + if (isRoughlyTheSameColor(pixelColor, previousColor)) + { + // Count the number of same-colored pixels to prepare for extending the cube + sameColorCount++; + } + else + { + if (sameColorCount > 0) + { + // Extend the previous cube + ExtendCube(previousCube, sameColorCount); + + // Spawn a new cube + GameObject cube = Instantiate(cubePrefab, startPosition + new Vector3(x * spacing, y * spacing, 0), Quaternion.identity, parentTransform); + cube.transform.localScale = new Vector3(cubeSize, cubeSize, cubeSize); + // Set the cube's color + if (MapEditorRebornUsage) + { + cube.GetComponent().Color = pixelColor; + } + else + { + + cube.GetComponent().material.color = pixelColor; + } + + + // Set the previous cube + previousCube = cube; + + // Set the previous color + previousColor = pixelColor; + + // Reset the counter + sameColorCount = 0; + } + else + { + // Spawn a new cube + GameObject cube = Instantiate(cubePrefab, startPosition + new Vector3(x * spacing, y * spacing, 0), Quaternion.identity, parentTransform); + cube.transform.localScale = new Vector3(cubeSize, cubeSize, cubeSize); + // Set the cube's color + if (MapEditorRebornUsage) + { + cube.GetComponent().Color = pixelColor; + } + else + { + + cube.GetComponent().material.color = pixelColor; + } + + // Set the previous cube + previousCube = cube; + + // Set the previous color + previousColor = pixelColor; + + // Reset the counter + sameColorCount = 0; + } + } + } + } + if (sameColorCount > 0) + { + // Extend the previous cube + ExtendCube(previousCube, sameColorCount); + } + } + + //Vertical optimization + /* + Go through every cube and check if the cube above has the same length, position and color. + If so, delete the cube above, and extend the current cube upwards. + */ + + //Fetch all children + Transform[] children = new Transform[parentTransform.childCount]; + for (int i = 0; i < parentTransform.childCount; i++) + { + children[i] = parentTransform.GetChild(i); + } + + //put all cubes in a list by row + List> cubesByRow = new List>(); + foreach (Transform child in children) + { + int row = Mathf.RoundToInt((child.position.y - startPosition.y) / spacing); + if (cubesByRow.Count <= row) + { + cubesByRow.Add(new List()); + } + cubesByRow[row].Add(child.gameObject); + } + print("cubesByRow.Count: " + cubesByRow.Count); + + + if (optimization) + { + //NCheck and extend + + //For every element in a row check firstly if there is an element in the row above that has the same x position (then color, then length) + //If so, delete the element above and extend the current element upwards + + for (int row = 0; row < cubesByRow.Count; row++) + { + for (int i = 0; i < cubesByRow[row].Count; i++) + { + + GameObject currentCube; + if (cubesByRow[row][i]) + { + currentCube = cubesByRow[row][i]; + } + else + { + continue; + } + + //find all cubes above with the same x position (then color, then length) + List validCubesAbove = new List(); + for (int a = row + 1; a < cubesByRow.Count; a++) + { + + GameObject validCubeAbove = null; + + foreach (GameObject cubeAbove in cubesByRow[a]) + { + if (cubeAbove.transform.localPosition.x == currentCube.transform.localPosition.x) + { + if (isRoughlyTheSameColor(cubeAbove.GetComponent().Color, currentCube.GetComponent().Color)) + { + if (cubeAbove.transform.localScale.x == currentCube.transform.localScale.x) + { + validCubeAbove = cubeAbove; + } + } + } + } + if (validCubeAbove) + { + validCubesAbove.Add(validCubeAbove); + } + else + { + break; + } + } + + //If there are no valid cubes above, continue + if (validCubesAbove.Count == 0) + { + continue; + } + + //Note the amount of valid cubes above + int amountOfValidCubesAbove = validCubesAbove.Count; + + //Destroy all valid cubes above + foreach (GameObject validCubeAbove in validCubesAbove) + { + //Remove the valid cube above from the list + foreach (List rowList in cubesByRow) + { + if (rowList.Contains(validCubeAbove)) + { + rowList.Remove(validCubeAbove); + break; + } + } + DestroyImmediate(validCubeAbove); + } + + + + //Extend the current cube upwards + currentCube.transform.localScale += new Vector3(0, amountOfValidCubesAbove * spacing, 0); + + //Move the current cube upwards + currentCube.transform.position += new Vector3(0, amountOfValidCubesAbove * spacing / 2f, 0); + } + } + } + + //refresh all the cubes if Map Editor Reborn is used + if (MapEditorRebornUsage) + { + print("Refreshing all cubes..."); + //trigger recompilation of all scripts + UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); + } + } + + public void removeExistingCubes() + { + Transform parentTransform = transform; + // Copy the children into an array + Transform[] children = new Transform[parentTransform.childCount]; + for (int i = 0; i < parentTransform.childCount; i++) + { + children[i] = parentTransform.GetChild(i); + } + + // Destroy the children from the copied array + foreach (Transform child in children) + { + DestroyImmediate(child.gameObject); + } + } + + + private bool isRoughlyTheSameColor(Color color1, Color color2) + { + return Mathf.Abs(color1.r - color2.r) < sameColorMargin && Mathf.Abs(color1.g - color2.g) < sameColorMargin && Mathf.Abs(color1.b - color2.b) < sameColorMargin; + } + + private void ExtendCube(GameObject cube, int length) + { + // Extend the previous cube's scale based on the number of same-colored pixels + cube.transform.localScale += new Vector3(cubeSize * length, 0, 0); + + // Move the previous cube's position based on the number of same-colored pixels + cube.transform.position += new Vector3(cubeSize * length / 2f, 0, 0); + } +} \ No newline at end of file diff --git a/CubeMosaicGenerator.cs.meta b/CubeMosaicGenerator.cs.meta new file mode 100644 index 0000000..71fcd0a --- /dev/null +++ b/CubeMosaicGenerator.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c513173bde01cc341a7481e2d0369364 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: + - inputImage: {instanceID: 0} + - cubePrefab: {fileID: 254159507964864611, guid: 8fa8447eda64b994e9a10cd87e61ac33, + type: 3} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example.meta b/Example.meta new file mode 100644 index 0000000..4a9681f --- /dev/null +++ b/Example.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 12effafcfa182024c9c937feb4d9a40a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/Lemon.jpg b/Example/Lemon.jpg new file mode 100644 index 0000000..71fbe73 Binary files /dev/null and b/Example/Lemon.jpg differ diff --git a/Example/Lemon.jpg.meta b/Example/Lemon.jpg.meta new file mode 100644 index 0000000..a3ddc1b --- /dev/null +++ b/Example/Lemon.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 20ba80ff0f251284eb89a619b43ad34d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/SPOILER_furstitchuwu.png b/Example/SPOILER_furstitchuwu.png new file mode 100644 index 0000000..334f725 Binary files /dev/null and b/Example/SPOILER_furstitchuwu.png differ diff --git a/Example/SPOILER_furstitchuwu.png.meta b/Example/SPOILER_furstitchuwu.png.meta new file mode 100644 index 0000000..0351688 --- /dev/null +++ b/Example/SPOILER_furstitchuwu.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 150800b71b44ce24bb0768b246ea1b92 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 3 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 3 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/calibaration.png b/Example/calibaration.png new file mode 100644 index 0000000..ff40778 Binary files /dev/null and b/Example/calibaration.png differ diff --git a/Example/calibaration.png.meta b/Example/calibaration.png.meta new file mode 100644 index 0000000..492e19b --- /dev/null +++ b/Example/calibaration.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: c37553493efe5c64f8d272a8b63f3a2a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/color.png b/Example/color.png new file mode 100644 index 0000000..68b7315 Binary files /dev/null and b/Example/color.png differ diff --git a/Example/color.png.meta b/Example/color.png.meta new file mode 100644 index 0000000..70b007f --- /dev/null +++ b/Example/color.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 444dcee0246edcc4994f806d58f6df19 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/kit.jpg b/Example/kit.jpg new file mode 100644 index 0000000..9898fc2 Binary files /dev/null and b/Example/kit.jpg differ diff --git a/Example/kit.jpg.meta b/Example/kit.jpg.meta new file mode 100644 index 0000000..ce194b5 --- /dev/null +++ b/Example/kit.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 1694040be6d39884b81e4760016af5f9 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/nature.jpg b/Example/nature.jpg new file mode 100644 index 0000000..4cf8c2c Binary files /dev/null and b/Example/nature.jpg differ diff --git a/Example/nature.jpg.meta b/Example/nature.jpg.meta new file mode 100644 index 0000000..b8ef2ba --- /dev/null +++ b/Example/nature.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 04f2ba87b08d7264aaf7584a4c0da614 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 4096 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 4096 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/qrcodealex.png b/Example/qrcodealex.png new file mode 100644 index 0000000..451b8f2 Binary files /dev/null and b/Example/qrcodealex.png differ diff --git a/Example/qrcodealex.png.meta b/Example/qrcodealex.png.meta new file mode 100644 index 0000000..1d5f683 --- /dev/null +++ b/Example/qrcodealex.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 66565f1fe2de811478c476cfb1f8fa54 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/shyguyad.jpg b/Example/shyguyad.jpg new file mode 100644 index 0000000..daf1ff3 Binary files /dev/null and b/Example/shyguyad.jpg differ diff --git a/Example/shyguyad.jpg.meta b/Example/shyguyad.jpg.meta new file mode 100644 index 0000000..bfd2735 --- /dev/null +++ b/Example/shyguyad.jpg.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: df6016c82dac3564a82c99d43947c2db +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Misc.meta b/Misc.meta new file mode 100644 index 0000000..af25cf9 --- /dev/null +++ b/Misc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 819dc11f2f6cba448a5f620daf915474 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Misc/Assets.meta b/Misc/Assets.meta new file mode 100644 index 0000000..81cec24 --- /dev/null +++ b/Misc/Assets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 58a31c22c9da2f146831890df6d0d916 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Misc/Assets/MosaicCube.prefab b/Misc/Assets/MosaicCube.prefab new file mode 100644 index 0000000..859a3eb --- /dev/null +++ b/Misc/Assets/MosaicCube.prefab @@ -0,0 +1,96 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &254159507964864611 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 254159507964864670} + - component: {fileID: 3548001987381241061} + - component: {fileID: 254159507964864608} + - component: {fileID: 1719437285518371689} + m_Layer: 0 + m_Name: MosaicCube + m_TagString: Cube + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &254159507964864670 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 254159507964864611} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 0.001} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &3548001987381241061 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 254159507964864611} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e46bc0fbd20723d42ac95df923d32087, type: 3} + m_Name: + m_EditorClassIdentifier: + Color: {r: 1, g: 1, b: 1, a: 1} + Collidable: 0 +--- !u!33 &254159507964864608 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 254159507964864611} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &1719437285518371689 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 254159507964864611} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 1 + m_DynamicOccludee: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 2 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: fff06561d0e2e5842844953d25884fff, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 diff --git a/Misc/Assets/MosaicCube.prefab.meta b/Misc/Assets/MosaicCube.prefab.meta new file mode 100644 index 0000000..044acb1 --- /dev/null +++ b/Misc/Assets/MosaicCube.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8fa8447eda64b994e9a10cd87e61ac33 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Misc/Scripts.meta b/Misc/Scripts.meta new file mode 100644 index 0000000..e085e8e --- /dev/null +++ b/Misc/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec91880357878eb44af88e67a332d584 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Misc/Scripts/CubeMosaicGeneratorEditor.cs b/Misc/Scripts/CubeMosaicGeneratorEditor.cs new file mode 100644 index 0000000..a1e090f --- /dev/null +++ b/Misc/Scripts/CubeMosaicGeneratorEditor.cs @@ -0,0 +1,45 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +[CustomEditor(typeof(CubeMosaicGenerator))] + +public class CubeMosaicGeneratorEditor : Editor +{ + public override void OnInspectorGUI() + { + CubeMosaicGenerator cmg = (CubeMosaicGenerator)target; + + //Version info in BOLD and blue text + GUIStyle style = new GUIStyle(); + style.richText = true; + style.fontStyle = FontStyle.Bold; + style.normal.textColor = Color.yellow; + GUILayout.Label("Cube Mosaic Generator - v" + cmg.version + "", style); + + //If a new version is available, show a button to open the download page + if (cmg.newVersionAvailable) + { + if (GUILayout.Button("Download new version")) + { + Application.OpenURL("https://github.com/AlexInABox/mer-mosaic-generator/releases/latest"); + } + } + + DrawDefaultInspector(); + + if (GUILayout.Button("Generate Mosaic")) + { + cmg.GenerateMosaic(); + } + + if (GUILayout.Button("Clear Mosaic")) + { + cmg.removeExistingCubes(); + } + + //Text that shows the amount of children in the parent object + GUILayout.Label("Number of cubes: " + cmg.transform.childCount); + } +} diff --git a/Misc/Scripts/CubeMosaicGeneratorEditor.cs.meta b/Misc/Scripts/CubeMosaicGeneratorEditor.cs.meta new file mode 100644 index 0000000..f2629cd --- /dev/null +++ b/Misc/Scripts/CubeMosaicGeneratorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd951110cce23b341a73a19092ae239f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: