//Convert the original uv for multiple submeshes and materials into one uv set using the single texture atlas Vector2 ConvertUVToTextureAtlasUV(Vector2 origUV, AvatarTextureCreatorData.TextureSlot materialSlot, AvatarTextureCreatorData avData, int index) { Vector2 newUV = origUV; //Since some of the UVs are outside 0-1 range, we're going to trim them to make it easier to convert int integer = (int)(origUV.x - 0.001f); float remainder = origUV.x - integer; newUV.x = remainder; if (materialSlot == AvatarTextureCreatorData.TextureSlot.Chest01) { Debug.Log("index " + index + " x orig UV " + origUV + " int " + integer + " remainder " + remainder); } integer = 1;//(int)(origUV.y - 0.001f); remainder = origUV.y - integer; newUV.y = remainder; if (materialSlot == AvatarTextureCreatorData.TextureSlot.Chest01) { Debug.Log("index " + index + " y orig UV " + origUV + " int " + integer + " remainder " + remainder); Debug.Log("NEW UV " + newUV); } //Now we want to convert that to the pixel position (warning, we might lose some accuracy here) int pixelX = Mathf.RoundToInt(newUV.x * avData.SourceTextures[(int)materialSlot].width); int pixelY = Mathf.RoundToInt(newUV.y * avData.SourceTextures[(int)materialSlot].height); //Now we can offset the pixelX & Y by the new bottom left position in the larger atlas //These are hardcoded based on the template texture atlas //TODO make this completely hardcoded free (perhaps figure out original texture size and new texture atlas size?) switch (materialSlot) { case AvatarTextureCreatorData.TextureSlot.Chest01: //newUV += new Vector2(0 / 256f, 128f / 256f); Debug.Log("chest 01 index " + index + " " + pixelX + " , " + pixelY + " source width " + avData.SourceTextures[(int)materialSlot].width + " source height " + avData.SourceTextures[(int)materialSlot].height); pixelX += 0; pixelY += 128; break; case AvatarTextureCreatorData.TextureSlot.Chest02: //newUV += new Vector2(64f / 256f, 240f / 256f); pixelX += 64; pixelY += 240; break; case AvatarTextureCreatorData.TextureSlot.ForeArm01: //newUV += new Vector2(64f / 256f, 176f / 256f); pixelX += 64; pixelY += 176; break; case AvatarTextureCreatorData.TextureSlot.Foot01: //newUV += new Vector2(192f / 256f, 160f / 256f); pixelX += 192; pixelY += 160; break; case AvatarTextureCreatorData.TextureSlot.Foot02: //newUV += new Vector2(0f / 256f, 64f / 256f); pixelX += 0; pixelY += 64; break; case AvatarTextureCreatorData.TextureSlot.Head01: //newUV += new Vector2(0f / 256f, 0f / 256f); pixelX += 0; pixelY += 0; break; case AvatarTextureCreatorData.TextureSlot.Head02: //newUV += new Vector2(192f / 256f, 64f / 256f); pixelX += 192; pixelY += 64; break; case AvatarTextureCreatorData.TextureSlot.Head03: //newUV += new Vector2(128f / 256f, 0f / 256f); pixelX += 128; pixelY += 0; break; case AvatarTextureCreatorData.TextureSlot.Hand01: //newUV += new Vector2(64f / 256f, 144f / 256f); pixelX += 64; pixelY += 144; break; case AvatarTextureCreatorData.TextureSlot.Hand02: //newUV += new Vector2(64f / 256f, 112f / 256f); pixelX += 64; pixelY += 112; break; case AvatarTextureCreatorData.TextureSlot.Leg01: //newUV += new Vector2(128f / 256f, 192f / 256f); pixelX += 128; pixelY += 192; break; case AvatarTextureCreatorData.TextureSlot.Leg02: //newUV += new Vector2(128f / 256f, 128f / 256f); pixelX += 128; pixelY += 128; break; case AvatarTextureCreatorData.TextureSlot.Leg03: //newUV += new Vector2(128f / 256f, 96f / 256f); pixelX += 128; pixelY += 96; break; case AvatarTextureCreatorData.TextureSlot.UpperArm01: //newUV += new Vector2(196f / 256f, 192f / 256f); pixelX += 196; pixelY += 192; break; } //Remember: bottom left corner as 0,0, top right is 1,1 //Now we can convert back to relative UV float newUV.x = (float)pixelX / 256f; newUV.y = (float)pixelY / 256f; return newUV; }
public static Texture2D CreateTexture(GameObject template) { Texture2D newTexture = new Texture2D(256, 256, TextureFormat.ARGB32, true); EQBrowser.AvatarTextureCreatorData avatarTextureData = template.GetComponentInChildren <EQBrowser.AvatarTextureCreatorData>(); if (avatarTextureData == null) { Debug.LogError(string.Format("Cannot create texture for {0}, returning null", template.name)); return(null); } //Combine the textures in predefined positions for (int i = 0; i < avatarTextureData.SourceTextures.Length; i++) { if (avatarTextureData.SourceTextures[i] == null) { continue; } Color[] colors = avatarTextureData.SourceTextures[i].GetPixels(0, 0, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height); //Remember Y is inverted. 0,0 is bottom left corner of texture. See "textureatlasReference.psd" //TODO VELIOUS IS LARGER TEXTURES switch (i) { case 0: //Chest01 newTexture.SetPixels(0, 128, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 1: //Chest02 newTexture.SetPixels(64, 240, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 2: //ForeArm01 newTexture.SetPixels(64, 176, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 3: //Foot01 newTexture.SetPixels(192, 160, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 4: //Foot02 newTexture.SetPixels(0, 64, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 5: //Head01 newTexture.SetPixels(0, 0, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 6: //Head02 newTexture.SetPixels(192, 64, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 7: //Head03 newTexture.SetPixels(128, 0, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 8: //Hand01 newTexture.SetPixels(64, 144, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 9: //Hand02 newTexture.SetPixels(64, 112, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 10: //Leg01 newTexture.SetPixels(128, 192, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 11: //Leg02 newTexture.SetPixels(128, 128, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 12: //Leg03 newTexture.SetPixels(128, 96, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; case 13: //UpperArm01 newTexture.SetPixels(96, 192, avatarTextureData.SourceTextures[i].width, avatarTextureData.SourceTextures[i].height, colors); break; } newTexture.Apply(); } return(newTexture); }