Resizes the texture.
/// <summary> /// Reads from the provided file name all parameters and data for a /// heightmap. If the data for the heightmap does not exist, then /// no data is written to the provided texture. /// </summary> /// <param name='fileName'> /// The file name. This can be relative or fully-qualified. /// </param> /// <param name='no'> /// The <see cref="NormalOptions" /> that will store read-in parameters. /// </param> /// <param name='co'> /// The <see cref="CloudOptions" /> that will store read-in parameters for /// <see cref="CloudFractal" />. /// </param> /// <param name='wo'> /// The <see cref="WorleyOptions" /> that will store read-in parameters for /// <see cref="WorleyNoise" />. /// </param> /// <param name='tex'> /// The <code>Texture2D</code> containing the heightmap data. /// </param> public static void Read(string fileName, ref NormalOptions no, ref CloudOptions co, ref VoronoiOptions vo, ref Texture2D tex) { using(BinaryReader r = new BinaryReader(File.OpenRead(fileName))) { no.size = r.ReadInt32(); no.seed = r.ReadInt32(); no.cloudInf = r.ReadSingle(); no.voronoiInf = r.ReadSingle(); no.useThermalErosion = r.ReadBoolean(); no.useHydroErosion = r.ReadBoolean(); no.showSeams = r.ReadBoolean(); co.upperLeftStart = r.ReadSingle(); co.lowerLeftStart = r.ReadSingle(); co.lowerRightStart = r.ReadSingle(); co.upperRightStart = r.ReadSingle(); vo.metric = (DistanceFunctions.DistanceMetric)r.ReadInt32(); vo.combiner = (CombinerFunctions.CombineFunction)r.ReadInt32(); vo.numberOfFeaturePoints = r.ReadInt32(); vo.numberOfSubregions = r.ReadInt32(); vo.multiplier = r.ReadSingle(); tex.Resize(no.size, no.size); int bLeft = (int)(r.BaseStream.Length - r.BaseStream.Position); if(bLeft > 0) tex.LoadImage(r.ReadBytes(bLeft)); } }
static int QPYX_Resize_YXQP(IntPtr L_YXQP) { try { int QPYX_count_YXQP = LuaDLL.lua_gettop(L_YXQP); if (QPYX_count_YXQP == 3) { UnityEngine.Texture2D QPYX_obj_YXQP = (UnityEngine.Texture2D)ToLua.CheckObject(L_YXQP, 1, typeof(UnityEngine.Texture2D)); int QPYX_arg0_YXQP = (int)LuaDLL.luaL_checknumber(L_YXQP, 2); int QPYX_arg1_YXQP = (int)LuaDLL.luaL_checknumber(L_YXQP, 3); bool QPYX_o_YXQP = QPYX_obj_YXQP.Resize(QPYX_arg0_YXQP, QPYX_arg1_YXQP); LuaDLL.lua_pushboolean(L_YXQP, QPYX_o_YXQP); return(1); } else if (QPYX_count_YXQP == 5) { UnityEngine.Texture2D QPYX_obj_YXQP = (UnityEngine.Texture2D)ToLua.CheckObject(L_YXQP, 1, typeof(UnityEngine.Texture2D)); int QPYX_arg0_YXQP = (int)LuaDLL.luaL_checknumber(L_YXQP, 2); int QPYX_arg1_YXQP = (int)LuaDLL.luaL_checknumber(L_YXQP, 3); UnityEngine.TextureFormat QPYX_arg2_YXQP = (UnityEngine.TextureFormat)ToLua.CheckObject(L_YXQP, 4, typeof(UnityEngine.TextureFormat)); bool QPYX_arg3_YXQP = LuaDLL.luaL_checkboolean(L_YXQP, 5); bool QPYX_o_YXQP = QPYX_obj_YXQP.Resize(QPYX_arg0_YXQP, QPYX_arg1_YXQP, QPYX_arg2_YXQP, QPYX_arg3_YXQP); LuaDLL.lua_pushboolean(L_YXQP, QPYX_o_YXQP); return(1); } else { return(LuaDLL.luaL_throw(L_YXQP, "invalid arguments to method: UnityEngine.Texture2D.Resize")); } } catch (Exception e_YXQP) { return(LuaDLL.toluaL_exception(L_YXQP, e_YXQP)); } }
void Start() { Renderer rend = GetComponent<Renderer>(); // duplicate the original texture and assign to the material tex = Instantiate(rend.material.mainTexture) as Texture2D; tex.Resize (200, 100); rend.material.mainTexture = tex; // colors used to tint the first 3 mip levels Color[] colors = new Color[3]; colors[0] = Color.red; colors[1] = Color.green; colors[2] = Color.blue; mipCount = Mathf.Min(3, tex.mipmapCount); // tint each mip level for( var mip = 0; mip < mipCount; ++mip ) { var cols = tex.GetPixels( mip ); for( var i = 0; i < cols.Length; ++i ) { cols[i] = new Color(Random.value,Random.value,Random.value); } tex.SetPixels( cols, mip ); } // actually apply all SetPixels, don't recalculate mip levels tex.Apply(false); int length = tex.GetPixels ().Length; wat = new float[length]; for (int i =0; i< wat.Length; i++) wat [i] = Random.value; Debug.Log ("n minmaps: " + mipCount); //for(int i =0; i< wa }
public static void CropTexture(Texture2D tex, int x, int y, int width, int height) { var newPixels = tex.GetPixels(x, y, width, height); tex.Resize(width, height); tex.SetPixels(newPixels); tex.Apply(); }
static public int Resize(IntPtr l) { try { #if DEBUG var method = System.Reflection.MethodBase.GetCurrentMethod(); string methodName = GetMethodName(method); #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.BeginSample(methodName); #else Profiler.BeginSample(methodName); #endif #endif int argc = LuaDLL.lua_gettop(l); if (argc == 3) { UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l); System.Int32 a1; checkType(l, 2, out a1); System.Int32 a2; checkType(l, 3, out a2); var ret = self.Resize(a1, a2); pushValue(l, true); pushValue(l, ret); return(2); } else if (argc == 5) { UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l); System.Int32 a1; checkType(l, 2, out a1); System.Int32 a2; checkType(l, 3, out a2); UnityEngine.TextureFormat a3; a3 = (UnityEngine.TextureFormat)LuaDLL.luaL_checkinteger(l, 4); System.Boolean a4; checkType(l, 5, out a4); var ret = self.Resize(a1, a2, a3, a4); pushValue(l, true); pushValue(l, ret); return(2); } pushValue(l, false); LuaDLL.lua_pushstring(l, "No matched override function Resize to call"); return(2); } catch (Exception e) { return(error(l, e)); } #if DEBUG finally { #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.EndSample(); #else Profiler.EndSample(); #endif } #endif }
/// <summary> /// Scales the texture data of the given texture. /// </summary> /// <param name="tex">Texure to scale</param> /// <param name="width">New width</param> /// <param name="height">New height</param> /// <param name="mode">Filtering mode</param> public static void scale(Texture2D tex, int width, int height, FilterMode mode = FilterMode.Trilinear) { Rect texR = new Rect(0, 0, width, height); _gpu_scale(tex, width, height, mode); // Update new texture tex.Resize(width, height); tex.ReadPixels(texR, 0, 0, true); tex.Apply(true); //Remove this if you hate us applying textures for you :) }
private void Awake() { bricksContainer = new GameObject("Bricks").transform; brickTexture = TextureE.whitePixel; brickTexture.Resize(brickWidth, brickHeight); brickSprite = Sprite.Create(brickTexture, new Rect(0, 0, brickWidth, brickHeight), new Vector2(0.5f, 0.5f)); material = new PhysicsMaterial2D {name = "Bouncy", bounciness = 1, friction = 0}; GeneratePaddle(); GenerateBorders(); }
/// <summary> /// Returns a scaled copy of given texture. /// </summary> /// <param name="tex">Source texure to scale</param> /// <param name="width">Destination texture width</param> /// <param name="height">Destination texture height</param> /// <param name="mode">Filtering mode</param> public static Texture2D scaled(Texture2D src, int width, int height, FilterMode mode = FilterMode.Trilinear) { Rect texR = new Rect(0, 0, width, height); _gpu_scale(src, width, height, mode); //Get rendered data back to a new texture Texture2D result = new Texture2D(width, height, TextureFormat.ARGB32, true); result.Resize(width, height); result.ReadPixels(texR, 0, 0, true); return result; }
static int Resize(IntPtr L) { int count = LuaDLL.lua_gettop(L); if (count == 3 && ToLua.CheckTypes(L, 1, typeof(UnityEngine.Texture2D), typeof(int), typeof(int))) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.ToObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); bool o; try { o = obj.Resize(arg0, arg1); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } LuaDLL.lua_pushboolean(L, o); return(1); } else if (count == 5 && ToLua.CheckTypes(L, 1, typeof(UnityEngine.Texture2D), typeof(int), typeof(int), typeof(UnityEngine.TextureFormat), typeof(bool))) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.ToObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); UnityEngine.TextureFormat arg2 = (UnityEngine.TextureFormat)ToLua.ToObject(L, 4); bool arg3 = LuaDLL.lua_toboolean(L, 5); bool o; try { o = obj.Resize(arg0, arg1, arg2, arg3); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } LuaDLL.lua_pushboolean(L, o); return(1); } else { LuaDLL.luaL_error(L, "invalid arguments to method: UnityEngine.Texture2D.Resize"); } return(0); }
/// <summary>Resize the given image with the given scale ratio.</summary> public static Texture2D Resize(Texture2D original,float ratio){ // Get the original size: int maxY=original.height; int maxX=original.width; // What's the target size? int height=(int)(maxY * ratio); int width=(int)(maxX * ratio); if(height==maxY && width==maxX){ // Unchanged: return original; } Color32[] texColors = original.GetPixels32(); Color32[] newColors = new Color32[width * height]; float ratioX = 1f / ((float)width / (float)(maxX-1)); float ratioY = 1f / ((float)height / (float)(maxY-1)); for (int y = 0; y < height; y++) { int yFloor = (int)Mathf.Floor (y * ratioY); int y1 = yFloor * maxX; int y2 = (yFloor+1) * maxX; int yw = y * width; for (int x = 0; x < width; x++){ int xFloor = (int)Mathf.Floor (x * ratioX); float xLerp = x * ratioX-xFloor; newColors[yw + x] = ColorLerpUnclamped (ColorLerpUnclamped (texColors[y1 + xFloor], texColors[y1 + xFloor+1], xLerp), ColorLerpUnclamped (texColors[y2 + xFloor], texColors[y2 + xFloor+1], xLerp), y*ratioY-yFloor); } } original.Resize(width,height,TextureFormat.ARGB32,false); original.SetPixels32(newColors); // Flush the texture: original.Apply(); // Return it: return original; }
private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear) { texColors = tex.GetPixels(); newColors = new Color[newWidth * newHeight]; if (useBilinear) { ratioX = 1.0f / ((float)newWidth / (tex.width - 1)); ratioY = 1.0f / ((float)newHeight / (tex.height - 1)); } else { ratioX = ((float)tex.width) / newWidth; ratioY = ((float)tex.height) / newHeight; } w = tex.width; w2 = newWidth; var cores = Mathf.Min(SystemInfo.processorCount, newHeight); var slice = newHeight / cores; finishCount = 0; if (mutex == null) { mutex = new Mutex(false); } if (cores > 1) { int i = 0; ThreadData threadData; for (i = 0; i < cores - 1; i++) { threadData = new ThreadData(slice * i, slice * (i + 1)); ParameterizedThreadStart ts = useBilinear ? new ParameterizedThreadStart(BilinearScale) : new ParameterizedThreadStart(PointScale); Thread thread = new Thread(ts); thread.Start(threadData); } threadData = new ThreadData(slice * i, newHeight); if (useBilinear) { BilinearScale(threadData); } else { PointScale(threadData); } while (finishCount < cores) { Thread.Sleep(1); } } else { ThreadData threadData = new ThreadData(0, newHeight); if (useBilinear) { BilinearScale(threadData); } else { PointScale(threadData); } } tex.Resize(newWidth, newHeight); tex.SetPixels(newColors); tex.Apply(); }
public static void ScaleTexture(Texture2D tex, int width, int height) { var newPixels = new Color[width * height]; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { newPixels[y * width + x] = tex.GetPixelBilinear(((float)x) / width, ((float)y) / height); } } tex.Resize(width, height); tex.SetPixels(newPixels); tex.Apply(); }
public static void Resize(Texture2D texture, int width, int height) { Color[] pixelArray = new Color[width * height]; float incX = (1.0f / (float)width); float incY = (1.0f / (float)height); for (int px = 0; px < pixelArray.Length; px++) { pixelArray[px] = texture.GetPixelBilinear(incX * ((float)px % width), incY * ((float)Mathf.Floor(px / width))); } texture.Resize(width, height); texture.SetPixels(pixelArray, 0); texture.Apply(); }
static int Resize(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject(L, 1, typeof(UnityEngine.Texture2D)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); bool o = obj.Resize(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return(1); } else if (count == 5 && TypeChecker.CheckTypes <UnityEngine.TextureFormat, bool>(L, 4)) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject(L, 1, typeof(UnityEngine.Texture2D)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); UnityEngine.TextureFormat arg2 = (UnityEngine.TextureFormat)ToLua.ToObject(L, 4); bool arg3 = LuaDLL.lua_toboolean(L, 5); bool o = obj.Resize(arg0, arg1, arg2, arg3); LuaDLL.lua_pushboolean(L, o); return(1); } else if (count == 5 && TypeChecker.CheckTypes <UnityEngine.Experimental.Rendering.GraphicsFormat, bool>(L, 4)) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject(L, 1, typeof(UnityEngine.Texture2D)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); UnityEngine.Experimental.Rendering.GraphicsFormat arg2 = (UnityEngine.Experimental.Rendering.GraphicsFormat)ToLua.ToObject(L, 4); bool arg3 = LuaDLL.lua_toboolean(L, 5); bool o = obj.Resize(arg0, arg1, arg2, arg3); LuaDLL.lua_pushboolean(L, o); return(1); } else { return(LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.Texture2D.Resize")); } } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight) { TextureScale.texColors = tex.GetPixels(); TextureScale.newColors = new Color[newWidth * newHeight]; TextureScale.ratioX = (float)tex.width / (float)newWidth; TextureScale.ratioY = (float)tex.height / (float)newHeight; TextureScale.w = tex.width; TextureScale.w2 = newWidth; TextureScale.finishCount = 0; if (TextureScale.mutex == null) { TextureScale.mutex = new Mutex(false); } TextureScale.PointScale(0, newHeight); tex.Resize(newWidth, newHeight); tex.SetPixels(TextureScale.newColors); tex.Apply(); }
public static int Resize1_wrap(long L) { try { long nThisPtr = FCLibHelper.fc_get_inport_obj_ptr(L); UnityEngine.Texture2D obj = get_obj(nThisPtr); int arg0 = FCLibHelper.fc_get_int(L, 0); int arg1 = FCLibHelper.fc_get_int(L, 1); bool ret = obj.Resize(arg0, arg1); long ret_ptr = FCLibHelper.fc_get_return_ptr(L); FCLibHelper.fc_set_value_bool(ret_ptr, ret); } catch (Exception e) { Debug.LogException(e); } return(0); }
// Use this for initialization void Start() { rend = GetComponent<Renderer> (); tex = new Texture2D (1,1,TextureFormat.RGBAFloat,false); rend.material.mainTexture = tex; TactonicDeviceList dl = Tactonic.GetDeviceList (); if (dl.GetNumDevices () > id) { device = dl.GetDevice (id); Debug.Log ("id: " + id + ", serial number: " + device.serialNumber); frame = new TactonicFrame (device); Tactonic.AddFrameCallback (device, this); Tactonic.StartDevice (device); newFrame = false; tex.Resize (device.GetRows (), device.GetCols ()); Debug.Log ("rows: " + device.GetRows() + ", cols: " + device.GetCols()); } else { Debug.Log ("id " + id + " not found! " + dl.GetNumDevices () + " devices found."); } }
/// <summary> /// Renders the given material into the given render target using a full-screen quad. /// Assumes the material uses a shader generated from a Graph. /// Optionally copies the resulting texture data into a Texture2D for further processing. /// </summary> /// <param name="rendTarget"> /// If set to "null", the noise will be rendered onto the screen. /// </param> public static void GenerateToTexture(RenderTexture rendTarget, Material noiseMat, Texture2D copyTo = null) { int width = (rendTarget == null ? Screen.width : rendTarget.width), height = (rendTarget == null ? Screen.height : rendTarget.height); //Set up rendering state. RenderTexture activeTarget = RenderTexture.active; RenderTexture.active = rendTarget; noiseMat.SetPass(0); //Render a quad using immediate mode. GL.PushMatrix(); GL.LoadIdentity(); GL.Viewport(new Rect(0, 0, width, height)); GL.Begin(GL.TRIANGLE_STRIP); GL.Color(Color.white); GL.TexCoord(new Vector3(0.0f, 0.0f, 0.0f)); GL.Vertex3(-1.0f, -1.0f, 0.0f); GL.TexCoord(new Vector3(1.0f, 0.0f, 0.0f)); GL.Vertex3(1.0f, -1.0f, 0.0f); GL.TexCoord(new Vector3(0.0f, 1.0f, 0.0f)); GL.Vertex3(-1.0f, 1.0f, 0.0f); GL.TexCoord(new Vector3(1.0f, 1.0f, 0.0f)); GL.Vertex3(1.0f, 1.0f, 0.0f); GL.End(); GL.PopMatrix(); //Copy the results into the Texture2D. if (copyTo != null) { if (copyTo.width != width || copyTo.height != height) copyTo.Resize(width, height); copyTo.ReadPixels(new Rect(0, 0, width, height), 0, 0); copyTo.Apply(); } //Reset rendering state. RenderTexture.active = activeTarget; }
static public int Resize(IntPtr l) { try { int argc = LuaDLL.lua_gettop(l); if (argc == 5) { UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l); System.Int32 a1; checkType(l, 2, out a1); System.Int32 a2; checkType(l, 3, out a2); UnityEngine.TextureFormat a3; checkEnum(l, 4, out a3); System.Boolean a4; checkType(l, 5, out a4); var ret = self.Resize(a1, a2, a3, a4); pushValue(l, true); pushValue(l, ret); return(2); } else if (argc == 3) { UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l); System.Int32 a1; checkType(l, 2, out a1); System.Int32 a2; checkType(l, 3, out a2); var ret = self.Resize(a1, a2); pushValue(l, true); pushValue(l, ret); return(2); } pushValue(l, false); LuaDLL.lua_pushstring(l, "No matched override function to call"); return(2); } catch (Exception e) { return(error(l, e)); } }
static int Resize(IntPtr L) { #if UNITY_EDITOR ToluaProfiler.AddCallRecord("UnityEngine.Texture2D.Register"); #endif try { int count = LuaDLL.lua_gettop(L); if (count == 3) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject(L, 1, typeof(UnityEngine.Texture2D)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); bool o = obj.Resize(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return(1); } else if (count == 5) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject(L, 1, typeof(UnityEngine.Texture2D)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); UnityEngine.TextureFormat arg2 = (UnityEngine.TextureFormat)ToLua.CheckObject(L, 4, typeof(UnityEngine.TextureFormat)); bool arg3 = LuaDLL.luaL_checkboolean(L, 5); bool o = obj.Resize(arg0, arg1, arg2, arg3); LuaDLL.lua_pushboolean(L, o); return(1); } else { return(LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.Texture2D.Resize")); } } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
static public int Resize(IntPtr l) { try{ if (matchType(l, 2, typeof(int), typeof(int), typeof(UnityEngine.TextureFormat), typeof(bool))) { UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l); System.Int32 a1; checkType(l, 2, out a1); System.Int32 a2; checkType(l, 3, out a2); UnityEngine.TextureFormat a3; checkEnum(l, 4, out a3); System.Boolean a4; checkType(l, 5, out a4); System.Boolean ret = self.Resize(a1, a2, a3, a4); pushValue(l, ret); return(1); } else if (matchType(l, 2, typeof(int), typeof(int))) { UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l); System.Int32 a1; checkType(l, 2, out a1); System.Int32 a2; checkType(l, 3, out a2); System.Boolean ret = self.Resize(a1, a2); pushValue(l, ret); return(1); } LuaDLL.luaL_error(l, "No matched override function to call"); return(0); } catch (Exception e) { LuaDLL.luaL_error(l, e.ToString()); return(0); } }
static int Resize(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject <UnityEngine.Texture2D>(L, 1); int arg0 = (int)LuaDLL.luaL_checkinteger(L, 2); int arg1 = (int)LuaDLL.luaL_checkinteger(L, 3); bool o = obj.Resize(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return(1); } else if (count == 5) { UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject <UnityEngine.Texture2D>(L, 1); int arg0 = (int)LuaDLL.luaL_checkinteger(L, 2); int arg1 = (int)LuaDLL.luaL_checkinteger(L, 3); UnityEngine.TextureFormat arg2 = (UnityEngine.TextureFormat)ToLua.CheckObject(L, 4, TypeTraits <UnityEngine.TextureFormat> .type); bool arg3 = LuaDLL.luaL_checkboolean(L, 5); bool o = obj.Resize(arg0, arg1, arg2, arg3); LuaDLL.lua_pushboolean(L, o); return(1); } else { return(LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.Texture2D.Resize")); } } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
//LOADERS public static bool readPFM(ref Texture2D tex, string path) { string fullPath = Application.dataPath + "/" + path.Substring(7); FileStream fs = new FileStream(fullPath, FileMode.Open); BinaryReader stream = new BinaryReader(fs); string [] line = new string[4]; char c; for( int i=0; i<4; ++i ) { do {//read up to whitespace c = stream.ReadChar(); line[i] += c; } while( c != '\n' && c!='\t' && c!=' ' && c!='\r' ); //in between lines kill the whitespace if( i<3 ) while( c != '\n' && c!='\t' && c!=' ' && c!='\r' ) { c = stream.ReadChar(); } } int mComponentSize, mComponentCount; bool float32 = false; bool float16 = false; if( line[0][0] == 'P' ) { mComponentSize = 4; float32 = true; } else if( line[0][0] == 'p' ) { mComponentSize = 2; float16 = true; } else { Debug.LogError( "image not in PFM format\n" ); return false; } if( line[0][1] == 'F' ) { mComponentCount = 3; } else if( line[0][1] == 'f' ) { mComponentCount = 1; } else { Debug.LogError( "image not in PFM format\n" ); return false; } if( float16 ) { Debug.LogError("float16 PFMs not supported, please convert to float32\n"); return false; } int mWidth = Convert.ToInt32(line[1]); int mHeight = Convert.ToInt32(line[2]); float scale = Convert.ToSingle(line[3]); int mDataSize = mComponentSize * mComponentCount * mWidth * mHeight; float[] floatData = new float[mDataSize/4]; for( int i = 0; i<mDataSize/4; ++i ) { floatData[i] = stream.ReadSingle(); } stream.Close(); fs.Close(); tex.Resize(mWidth, mHeight,TextureFormat.ARGB32,false); Color32[] pixels32 = tex.GetPixels32(); //apply scale scale = Mathf.Abs(scale); if( float32 ) { Color pixel = new Color(); for( int x=0; x<mWidth; ++x ) for( int y=0; y<mHeight; ++y ) { int i = x + y*mWidth; int j = x + (mHeight-y-1)*mWidth; pixel.r = scale * floatData[j*mComponentCount]; pixel.g = scale * floatData[j*mComponentCount+1]; pixel.b = scale * floatData[j*mComponentCount+2]; RGB.toRGBM(ref pixels32[i], pixel, true); } } else if( float16 ) { //float16 pfms are something we made up for toolbag apparently. } tex.SetPixels32(pixels32); tex.Apply(false); return true; }
public Texture2D GetMazeTexture() { SetDefaultColors (); Debug.Log ("Generating Texture."); //MeshRenderer MyRenderer = MazeTextureObject.GetComponent<MeshRenderer> (); // duplicate the original texture and assign to the material Texture2D MyTexture2D = new Texture2D (Mathf.FloorToInt(MyBlocks.Size.x), Mathf.FloorToInt(MyBlocks.Size.z)); //MyRenderer.material.mainTexture); //MyRenderer.materials[0].SetTexture(0, MyTexture2D); //MyRawImage.texture = (MyTexture2D); MaxMipMapLevel = MyTexture2D.mipmapCount; MyTexture2D.filterMode = FilterMode.Point; int MipMapLevel = 0; //for (int z = MaxMipMapLevel; MaxMipMapLevel < MaxMipMapLevel; MaxMipMapLevel++) { MyTexture2D.Resize (Mathf.RoundToInt (MyBlocks.Size.x), Mathf.RoundToInt (MyBlocks.Size.z)); //Texture2D MyTexture2D = MyTexture; Color32[] NewColors = MyTexture2D.GetPixels32 (MipMapLevel); for (int i = 0; i < MyBlocks.Size.x; i++) for (int k = 0; k < MyBlocks.Size.z; k++) { int PixelIndex = Mathf.RoundToInt (i * MyBlocks.Size.x + k); NewColors[PixelIndex] = BlockColors[MyBlocks.GetBlockType (new Vector3 (i, StartLocation.y, k))]; } MyTexture2D.SetPixels32 (NewColors, MipMapLevel); MyTexture2D.Apply( true ); Debug.Log ("Applied Texture."); return MyTexture2D; }
static void fillPowerOfTwo(Texture2D pImage) { int lPreWidth = pImage.width; int lPreHeight = pImage.height; if (Mathf.IsPowerOfTwo(lPreWidth) && Mathf.IsPowerOfTwo(lPreHeight)) { print("don't need fillPowerOfTwo"); return; } var lPixels = pImage.GetPixels(); pImage.Resize(Mathf.NextPowerOfTwo(lPreWidth), Mathf.NextPowerOfTwo(lPreHeight)); pImage.SetPixels(0, 0, lPreWidth, lPreHeight, lPixels); //var lNewPixels = new UnityEngine.Color[pImage.width * pImage.height]; //int lSrcY = 0; //for (int y = pImage.height - lPreHeight; y < pImage.height; ++y) //{ // int lSrc = lSrcY * lPreWidth - 1; // int lSrcEnd = lSrc + lPreWidth; // int lDest = y * pImage.width - 1; // while (lSrc < lSrcEnd) // { // lNewPixels[++lDest] = lPixels[++lSrc]; // } // ++lSrcY; //} //pImage.SetPixels(lNewPixels); pImage.Apply(); }
public static bool Rebuild(tk2dSpriteCollection gen) { // avoid "recursive" build being triggered by texture watcher if (currentBuild != null) return false; currentBuild = gen; List<Texture2D> allocatedTextures = new List<Texture2D>(); string path = AssetDatabase.GetAssetPath(gen); string subDirName = Path.GetDirectoryName( path.Substring(7) ); if (subDirName.Length > 0) subDirName += "/"; string dataDirFullPath = Application.dataPath + "/" + subDirName + Path.GetFileNameWithoutExtension(path) + "_Data"; string dataDirName = "Assets/" + dataDirFullPath.Substring( Application.dataPath.Length + 1 ) + "/"; if (gen.atlasTextures == null || gen.atlasTextures.Length == 0 || gen.atlasMaterials == null || gen.atlasMaterials.Length == 0 || gen.spriteCollection == null) { if (!Directory.Exists(dataDirFullPath)) Directory.CreateDirectory(dataDirFullPath); AssetDatabase.Refresh(); } string prefabObjectPath = gen.spriteCollection?AssetDatabase.GetAssetPath(gen.spriteCollection):(dataDirName + "data.prefab"); if (!CheckAndFixUpParams(gen)) { // Params failed check return false; } SetUpSourceTextureFormats(gen); SetUpSpriteSheets(gen); TrimTextureList(gen); // blank texture used when texture has been deleted Texture2D blankTexture = new Texture2D(2, 2); blankTexture.SetPixel(0, 0, Color.magenta); blankTexture.SetPixel(0, 1, Color.yellow); blankTexture.SetPixel(1, 0, Color.cyan); blankTexture.SetPixel(1, 1, Color.grey); blankTexture.Apply(); // make local texture sources sourceTextures = new Texture2D[gen.textureRefs.Length]; for (int i = 0; i < gen.textureParams.Length; ++i) { var param = gen.textureParams[i]; if (param.extractRegion && gen.textureRefs[i] != null) { Texture2D localTex = new Texture2D(param.regionW, param.regionH); for (int y = 0; y < param.regionH; ++y) { for (int x = 0; x < param.regionW; ++x) { localTex.SetPixel(x, y, gen.textureRefs[i].GetPixel(param.regionX + x, param.regionY + y)); } } localTex.name = gen.textureRefs[i].name + "/" + param.regionId.ToString(); localTex.Apply(); allocatedTextures.Add(localTex); sourceTextures[i] = localTex; } else { sourceTextures[i] = gen.textureRefs[i]; } } // catalog all textures to atlas int numTexturesToAtlas = 0; List<SpriteLut> spriteLuts = new List<SpriteLut>(); for (int i = 0; i < gen.textureParams.Length; ++i) { Texture2D currentTexture = sourceTextures[i]; if (sourceTextures[i] == null) { gen.textureParams[i].dice = false; gen.textureParams[i].anchor = tk2dSpriteCollectionDefinition.Anchor.MiddleCenter; gen.textureParams[i].name = ""; gen.textureParams[i].extractRegion = false; gen.textureParams[i].fromSpriteSheet = false; currentTexture = blankTexture; } else { if (gen.textureParams[i].name == null || gen.textureParams[i].name == "") { if (gen.textureParams[i].texture != currentTexture && !gen.textureParams[i].fromSpriteSheet) { gen.textureParams[i].name = currentTexture.name; } } } gen.textureParams[i].texture = currentTexture; if (gen.textureParams[i].dice) { // prepare to dice this up int diceUnitX = gen.textureParams[i].diceUnitX; int diceUnitY = gen.textureParams[i].diceUnitY; if (diceUnitX <= 0) diceUnitX = 128; // something sensible, please if (diceUnitY <= 0) diceUnitY = diceUnitX; // make square if not set Texture2D srcTex = currentTexture; for (int sx = 0; sx < srcTex.width; sx += diceUnitX) { for (int sy = 0; sy < srcTex.height; sy += diceUnitY) { int tw = Mathf.Min(diceUnitX, srcTex.width - sx); int th = Mathf.Min(diceUnitY, srcTex.height - sy); SpriteLut diceLut = new SpriteLut(); diceLut.source = i; diceLut.isSplit = true; diceLut.sourceTex = srcTex; diceLut.isDuplicate = false; // duplicate diced textures can be chopped up differently, so don't detect dupes here Texture2D dest = ProcessTexture(gen, gen.textureParams[i].additive, true, srcTex, sx, sy, tw, th, ref diceLut, GetPadAmount(gen, i)); if (dest) { diceLut.atlasIndex = numTexturesToAtlas++; spriteLuts.Add(diceLut); } } } } else { SpriteLut lut = new SpriteLut(); lut.sourceTex = currentTexture; lut.source = i; lut.isSplit = false; lut.isDuplicate = false; for (int j = 0; j < spriteLuts.Count; ++j) { if (spriteLuts[j].sourceTex == lut.sourceTex) { lut.isDuplicate = true; lut.atlasIndex = spriteLuts[j].atlasIndex; lut.tex = spriteLuts[j].tex; // get old processed tex lut.rx = spriteLuts[j].rx; lut.ry = spriteLuts[j].ry; lut.rw = spriteLuts[j].rw; lut.rh = spriteLuts[j].rh; break; } } if (!lut.isDuplicate) { lut.atlasIndex = numTexturesToAtlas++; bool stretchPad = false; if (gen.textureParams[i].pad == tk2dSpriteCollectionDefinition.Pad.Extend) stretchPad = true; Texture2D dest = ProcessTexture(gen, gen.textureParams[i].additive, stretchPad, currentTexture, 0, 0, currentTexture.width, currentTexture.height, ref lut, GetPadAmount(gen, i)); if (dest == null) { // fall back to a tiny blank texture lut.tex = new Texture2D(1, 1); lut.tex.SetPixel(0, 0, new Color( 0, 0, 0, 0 )); PadTexture(lut.tex, GetPadAmount(gen, i), stretchPad); lut.tex.Apply(); lut.rx = currentTexture.width / 2; lut.ry = currentTexture.height / 2; lut.rw = 1; lut.rh = 1; } } spriteLuts.Add(lut); } } // Font Dictionary<tk2dSpriteCollectionFont, tk2dEditor.Font.Info> fontInfoDict = new Dictionary<tk2dSpriteCollectionFont, tk2dEditor.Font.Info>(); if (gen.fonts != null) { for (int i = 0; i < gen.fonts.Length; ++i) { var font = gen.fonts[i]; if (!font.InUse) continue; var fontInfo = tk2dEditor.Font.Builder.ParseBMFont( AssetDatabase.GetAssetPath(font.bmFont) ); fontInfoDict[font] = fontInfo; foreach (var c in fontInfo.chars) { // skip empty textures if (c.width <= 0 || c.height <= 0) continue; SpriteLut lut = new SpriteLut(); int cy = font.flipTextureY?c.y:(fontInfo.scaleH - c.y - c.height); Texture2D dest = ProcessTexture(gen, false, false, font.texture, c.x, cy, c.width, c.height, ref lut, GetPadAmount(gen, -1)); if (dest == null) { // probably fully transparent continue; } lut.sourceTex = dest; lut.tex = dest; lut.source = -1; lut.isFont = true; lut.isDuplicate = false; lut.fontId = i; lut.charId = c.id; lut.rx = lut.rx - c.x; lut.ry = lut.ry - cy; lut.atlasIndex = numTexturesToAtlas++; spriteLuts.Add(lut); } // Add one blank char for fallbacks { int dims = 5; SpriteLut lut = new SpriteLut(); lut.tex = new Texture2D(dims, dims); for (int y = 0; y < dims; ++y) for (int x = 0; x < dims; ++x) lut.tex.SetPixel(x, y, Color.clear); lut.tex.Apply(); lut.sourceTex = lut.tex; lut.isFont = true; lut.isDuplicate = false; lut.fontId = i; lut.charId = -1; lut.atlasIndex = numTexturesToAtlas++; spriteLuts.Add(lut); } } } // Create texture Texture2D[] textureList = new Texture2D[numTexturesToAtlas]; int titer = 0; for (int i = 0; i < spriteLuts.Count; ++i) { SpriteLut _lut = spriteLuts[i]; if (!_lut.isDuplicate) { textureList[titer++] = _lut.tex; } } // Build atlas tk2dEditor.Atlas.Builder atlasBuilder = new tk2dEditor.Atlas.Builder(gen.maxTextureSize, gen.maxTextureSize, gen.allowMultipleAtlases?64:1, gen.forceSquareAtlas); if (textureList.Length > 0) { foreach (Texture2D currTexture in textureList) { atlasBuilder.AddRect(currTexture.width, currTexture.height); } if (atlasBuilder.Build() != 0) { if (atlasBuilder.HasOversizeTextures()) { EditorUtility.DisplayDialog("Unable to fit in atlas", "You have a texture which exceeds the atlas size." + "Consider putting it in a separate atlas, enabling dicing, or" + "reducing the texture size", "Ok"); } else { EditorUtility.DisplayDialog("Unable to fit textures in requested atlas area", "There are too many textures in this collection for the requested " + "atlas size.", "Ok"); } return false; } } // Fill atlas textures tk2dEditor.Atlas.Data[] atlasData = atlasBuilder.GetAtlasData(); System.Array.Resize(ref gen.atlasTextures, atlasData.Length); System.Array.Resize(ref gen.atlasMaterials, atlasData.Length); for (int atlasIndex = 0; atlasIndex < atlasData.Length; ++atlasIndex) { Texture2D tex = new Texture2D(64, 64, TextureFormat.ARGB32, false); gen.atlasWastage = (1.0f - atlasData[0].occupancy) * 100.0f; gen.atlasWidth = atlasData[0].width; gen.atlasHeight = atlasData[0].height; tex.Resize(atlasData[atlasIndex].width, atlasData[atlasIndex].height); // Clear texture, unsure if this is REALLY necessary // Turns out it is for (int yy = 0; yy < tex.height; ++yy) { for (int xx = 0; xx < tex.width; ++xx) { tex.SetPixel(xx, yy, Color.clear); } } for (int i = 0; i < atlasData[atlasIndex].entries.Length; ++i) { var entry = atlasData[atlasIndex].entries[i]; Texture2D source = textureList[entry.index]; if (!entry.flipped) { for (int y = 0; y < source.height; ++y) { for (int x = 0; x < source.width; ++x) { tex.SetPixel(entry.x + x, entry.y + y, source.GetPixel(x, y)); } } } else { for (int y = 0; y < source.height; ++y) { for (int x = 0; x < source.width; ++x) { tex.SetPixel(entry.x + y, entry.y + x, source.GetPixel(x, y)); } } } } tex.Apply(); string texturePath = gen.atlasTextures[atlasIndex]?AssetDatabase.GetAssetPath(gen.atlasTextures[atlasIndex]):(dataDirName + "atlas" + atlasIndex + ".png"); // Write filled atlas to disk byte[] bytes = tex.EncodeToPNG(); System.IO.FileStream fs = System.IO.File.Create(texturePath); fs.Write(bytes, 0, bytes.Length); fs.Close(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Object.DestroyImmediate(tex); tex = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D; gen.atlasTextures[atlasIndex] = tex; // Make sure texture is set up with the correct max size and compression type SetUpTargetTexture(gen, tex); // Create material if necessary if (gen.atlasMaterials[atlasIndex] == null) { Material mat; if (gen.premultipliedAlpha) mat = new Material(Shader.Find("tk2d/PremulVertexColor")); else mat = new Material(Shader.Find("tk2d/BlendVertexColor")); mat.mainTexture = tex; string materialPath = gen.atlasMaterials[atlasIndex]?AssetDatabase.GetAssetPath(gen.atlasMaterials[atlasIndex]):(dataDirName + "atlas" + atlasIndex + "_material.mat"); AssetDatabase.CreateAsset(mat, materialPath); AssetDatabase.SaveAssets(); gen.atlasMaterials[atlasIndex] = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material; } } // Create prefab if (gen.spriteCollection == null) { GameObject go = new GameObject(); go.AddComponent<tk2dSpriteCollectionData>(); #if (UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_4) Object p = EditorUtility.CreateEmptyPrefab(prefabObjectPath); EditorUtility.ReplacePrefab(go, p); #else Object p = PrefabUtility.CreateEmptyPrefab(prefabObjectPath); PrefabUtility.ReplacePrefab(go, p); #endif GameObject.DestroyImmediate(go); AssetDatabase.SaveAssets(); gen.spriteCollection = AssetDatabase.LoadAssetAtPath(prefabObjectPath, typeof(tk2dSpriteCollectionData)) as tk2dSpriteCollectionData; } tk2dSpriteCollectionData coll = gen.spriteCollection; coll.textures = new Texture[gen.atlasTextures.Length]; coll.materials = new Material[gen.atlasMaterials.Length]; for (int i = 0; i < gen.atlasTextures.Length; ++i) { coll.textures[i] = gen.atlasTextures[i]; } for (int i = 0; i < gen.atlasMaterials.Length; ++i) { coll.materials[i] = gen.atlasMaterials[i]; } // Wipe out legacy data coll.material = null; coll.premultipliedAlpha = gen.premultipliedAlpha; coll.spriteDefinitions = new tk2dSpriteDefinition[gen.textureParams.Length]; coll.version = tk2dSpriteCollectionData.CURRENT_VERSION; coll.spriteCollectionGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(gen)); coll.spriteCollectionName = gen.name; coll.invOrthoSize = 1.0f / gen.targetOrthoSize; coll.halfTargetHeight = gen.targetHeight * 0.5f; int buildKey = Random.Range(0, int.MaxValue); while (buildKey == coll.buildKey) { buildKey = Random.Range(0, int.MaxValue); } coll.buildKey = buildKey; // a random build number so we can identify changed collections quickly for (int i = 0; i < coll.spriteDefinitions.Length; ++i) { coll.spriteDefinitions[i] = new tk2dSpriteDefinition(); if (gen.textureRefs[i]) { string assetPath = AssetDatabase.GetAssetPath(gen.textureRefs[i]); string guid = AssetDatabase.AssetPathToGUID(assetPath); coll.spriteDefinitions[i].sourceTextureGUID = guid; } else { coll.spriteDefinitions[i].sourceTextureGUID = ""; } coll.spriteDefinitions[i].extractRegion = gen.textureParams[i].extractRegion; coll.spriteDefinitions[i].regionX = gen.textureParams[i].regionX; coll.spriteDefinitions[i].regionY = gen.textureParams[i].regionY; coll.spriteDefinitions[i].regionW = gen.textureParams[i].regionW; coll.spriteDefinitions[i].regionH = gen.textureParams[i].regionH; } coll.allowMultipleAtlases = gen.allowMultipleAtlases; coll.dataGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(coll)); float scale = 1.0f; if (gen.useTk2dCamera) { scale = 1.0f; } else { scale = 2.0f * gen.targetOrthoSize / gen.targetHeight; } // Build fonts foreach (var font in fontInfoDict.Keys) { var fontInfo = fontInfoDict[font]; List<SpriteLut> fontSpriteLut = new List<SpriteLut>(); int fontId = 0; for (fontId = 0; fontId < gen.fonts.Length; ++fontId) if (gen.fonts[fontId] == font) break; foreach (var v in spriteLuts) { if (v.isFont && v.fontId == fontId) fontSpriteLut.Add(v); } fontInfo.scaleW = coll.textures[0].width; fontInfo.scaleH = coll.textures[0].height; // Build a local sprite lut only relevant to this font UpdateFontData(gen, scale, atlasData, fontSpriteLut, font, fontInfo); // Set material font.data.material = coll.materials[0]; font.editorData.material = coll.materials[0]; // Mark to save EditorUtility.SetDirty(font.data); } // Build textures UpdateVertexCache(gen, scale, atlasData, coll, spriteLuts); // Free tmp textures foreach (var sprite in spriteLuts) { if (!sprite.isDuplicate) Object.DestroyImmediate(sprite.tex); } foreach (var tex in allocatedTextures) Object.DestroyImmediate(tex); // refresh existing RefreshExistingAssets(gen.spriteCollection); // save changes var index = tk2dEditorUtility.GetOrCreateIndex(); index.AddSpriteCollectionData(gen.spriteCollection); EditorUtility.SetDirty(gen.spriteCollection); EditorUtility.SetDirty(gen); sourceTextures = null; // need to clear, its static currentBuild = null; tk2dEditorUtility.GetOrCreateIndex().AddSpriteCollectionData(gen.spriteCollection); tk2dEditorUtility.CommitIndex(); Object.DestroyImmediate(blankTexture); return true; }
/// <summary> /// /// </summary> void Start() { playDestruction = true; //Warning. if (tileHorizontal % 2 != 0 || tileVertical % 2 != 0) { Debug.LogWarning("Use power of 2 tile horizontal and vertical!"); } destructAudio = GameSoundManager.GetClip("glass_destruction"); hitAudio = GameSoundManager.GetClip("glass_hit"); if(GetComponent<AudioSource>() == null) { gameObject.AddComponent<AudioSource>(); } GetComponent<AudioSource>().loop = false; GetComponent<AudioSource>().playOnAwake = false; //Intialize with false the first hit (used to change texture to breaked). firstHit = false; //Set base alpha texture size. sizeTextureX = (int)((textureBaseMarks[0].width / 4.0f) * tileHorizontal); sizeTextureY = (int)((textureBaseMarks[0].height / 4.0f) * tileVertical); textureCurrentAlpha = new Texture2D(2, 2, TextureFormat.ARGB32, true);//(Texture2D)renderer.material.GetTexture("_AlphaTex"); GetComponent<Renderer>().material.SetTexture("_AlphaTex", textureCurrentAlpha); //Resize the base alpha color of glass. textureCurrentAlpha.Resize(sizeTextureX, sizeTextureY); //Set all glass with white color and apply. Color[] auxTexColors = new Color[(int)(textureCurrentAlpha.width * textureCurrentAlpha.height)]; for (int i = 0; i < auxTexColors.Length; i++) { auxTexColors[i] = Color.white; } textureCurrentAlpha.SetPixels(0, 0, textureCurrentAlpha.width, textureCurrentAlpha.height, auxTexColors); textureCurrentAlpha.Apply(); //Create the glass matrix. matrixOfGlass = new bool[tileHorizontal + 2, tileVertical + 2]; selectedMarkNumber = new int[tileHorizontal + 2, tileVertical + 2]; for (int i = 0; i < matrixOfGlass.GetLength(0); i++) { for (int j = 0; j < matrixOfGlass.GetLength(1); j++) { matrixOfGlass[i, j] = false; selectedMarkNumber[i, j] = -1; } } selectedMarkNumber = new int[tileHorizontal + 2, tileVertical + 2]; //Create object that simulate colliding bullet. objectColliding = new GameObject("object_colliding"); objectColliding.transform.parent = transform; objectColliding.transform.localPosition = Vector3.zero; //Calculate the size of one recorte base alpha texture. baseQuadSizeX = (int)(textureBaseMarks[0].width * 0.25f); baseQuadSizeY = (int)(textureBaseMarks[0].height * 0.25f); //Start all marks squares. glassStruct = new GlassStruct[16]; for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { glassStruct[(i * 4) + j] = new GlassStruct((i * 4) + j, new GlassMark(textureBaseMarks[0].GetPixels(i * baseQuadSizeX, j * baseQuadSizeY, baseQuadSizeX, baseQuadSizeY)), new GlassMark(textureBaseMarks[1].GetPixels (i * baseQuadSizeX, j * baseQuadSizeY, baseQuadSizeX, baseQuadSizeY))); } } //Create a basic black square to fill intersections of four breaked points. GlassStruct.blackFillTexture = new Color[baseQuadSizeX * baseQuadSizeY]; for (int i = 0; i < baseQuadSizeX; i++) { for (int j = 0; j < baseQuadSizeY; j++) { GlassStruct.blackFillTexture[(i * baseQuadSizeX) + j] = Color.black; } } //Set base marks with sides (left side, top side, right side, bottom side) -> True if breaked, False if not breaked. glassStruct[0].SetSides(true, false, true, true); glassStruct[1].SetSides(false, true, true, false); glassStruct[2].SetSides(false, true, false, false); glassStruct[3].SetSides(false, false, false, false); glassStruct[4].SetSides(true, true, false, true); glassStruct[5].SetSides(false, false, true, true); glassStruct[6].SetSides(true, false, true, false); glassStruct[7].SetSides(true, false, false, false); glassStruct[8].SetSides(true, true, true, false); glassStruct[9].SetSides(true, false, false, true); glassStruct[10].SetSides(false, true, false, true); glassStruct[11].SetSides(false, false, true, false); glassStruct[12].SetSides(true, true, true, true); glassStruct[13].SetSides(false, true, true, true); glassStruct[14].SetSides(true, true, false, false); glassStruct[15].SetSides(false, false, false, true); //Create particle system. parentEmmiters = new GameObject("particle_emmiters").transform; parentEmmiters.parent = transform; parentEmmiters.localPosition = Vector3.zero; parentEmmiters.rotation = transform.rotation; parentEmmiters.localScale = Vector3.one; matrixEmmiters = new ParticleEmitter[tileHorizontal, tileVertical]; auxHorizontal = 10f / (float)tileHorizontal; auxVertical = 10f / (float)tileVertical; /* for (int i = 0; i < tileHorizontal; i++) { for (int j = 0; j < tileVertical; j++) { //Crate emmiters and set position. matrixEmmiters[i, j] = ((GameObject)GameObject.Instantiate(particlePrefab, Vector3.zero, Quaternion.identity)).GetComponent<ParticleEmitter>(); matrixEmmiters[i, j].name = string.Format("emmiter{0}{1}", i, j); matrixEmmiters[i, j].transform.parent = parentEmmiters; matrixEmmiters[i, j].transform.forward = parentEmmiters.forward; matrixEmmiters[i, j].transform.localPosition = new Vector3((auxHorizontal * (tileHorizontal - i - 1)) + (auxHorizontal * 0.5f) - 5f, 0.0f, (auxVertical * (tileVertical - j - 1)) + (auxVertical * 0.5f) - 5f); matrixEmmiters[i, j].gameObject.active = false; } } //*/ //Initialize number of break points with 0. numberToBreak = 0; }
public static void Rebuild(tk2dSpriteCollection gen) { // avoid "recursive" build being triggered by texture watcher if (currentBuild == gen) return; currentBuild = gen; string path = AssetDatabase.GetAssetPath(gen); string subDirName = Path.GetDirectoryName( path.Substring(7) ); if (subDirName.Length > 0) subDirName += "/"; string dataDirFullPath = Application.dataPath + "/" + subDirName + Path.GetFileNameWithoutExtension(path) + "_Data"; string dataDirName = "Assets/" + dataDirFullPath.Substring( Application.dataPath.Length + 1 ) + "/"; if (gen.atlasTextures == null || gen.atlasTextures.Length == 0 || gen.atlasMaterials == null || gen.atlasMaterials.Length == 0 || gen.spriteCollection == null) { if (!Directory.Exists(dataDirFullPath)) Directory.CreateDirectory(dataDirFullPath); AssetDatabase.Refresh(); } string prefabObjectPath = gen.spriteCollection?AssetDatabase.GetAssetPath(gen.spriteCollection):(dataDirName + "data.prefab"); if (!CheckAndFixUpParams(gen)) { // Params failed check return; } SetUpSourceTextureFormats(gen); SetUpSpriteSheets(gen); TrimTextureList(gen); // blank texture used when texture has been deleted Texture2D blankTexture = new Texture2D(2, 2); blankTexture.SetPixel(0, 0, Color.magenta); blankTexture.SetPixel(0, 1, Color.yellow); blankTexture.SetPixel(1, 0, Color.cyan); blankTexture.SetPixel(1, 1, Color.grey); blankTexture.Apply(); // make local texture sources sourceTextures = new Texture2D[gen.textureRefs.Length]; for (int i = 0; i < gen.textureParams.Length; ++i) { var param = gen.textureParams[i]; if (param.extractRegion && gen.textureRefs[i] != null) { Texture2D localTex = new Texture2D(param.regionW, param.regionH); for (int y = 0; y < param.regionH; ++y) { for (int x = 0; x < param.regionW; ++x) { localTex.SetPixel(x, y, gen.textureRefs[i].GetPixel(param.regionX + x, param.regionY + y)); } } localTex.name = gen.textureRefs[i].name + "/" + param.regionId.ToString(); localTex.Apply(); sourceTextures[i] = localTex; } else { sourceTextures[i] = gen.textureRefs[i]; } } // catalog all textures to atlas int numTexturesToAtlas = 0; List<SCGE.SpriteLut> spriteLuts = new List<SCGE.SpriteLut>(); for (int i = 0; i < gen.textureParams.Length; ++i) { Texture2D currentTexture = sourceTextures[i]; if (sourceTextures[i] == null) { gen.textureParams[i].dice = false; gen.textureParams[i].anchor = tk2dSpriteCollectionDefinition.Anchor.MiddleCenter; gen.textureParams[i].name = ""; gen.textureParams[i].extractRegion = false; gen.textureParams[i].fromSpriteSheet = false; currentTexture = blankTexture; } else { if (gen.textureParams[i].name == null || gen.textureParams[i].name == "" || gen.textureParams[i].texture != currentTexture) gen.textureParams[i].name = currentTexture.name; } gen.textureParams[i].texture = currentTexture; if (gen.textureParams[i].dice) { // prepare to dice this up int diceUnitX = gen.textureParams[i].diceUnitX; int diceUnitY = gen.textureParams[i].diceUnitY; if (diceUnitX <= 0) diceUnitX = 128; // something sensible, please if (diceUnitY <= 0) diceUnitY = diceUnitX; // make square if not set Texture2D srcTex = currentTexture; for (int sx = 0; sx < srcTex.width; sx += diceUnitX) { for (int sy = 0; sy < srcTex.height; sy += diceUnitY) { int tw = Mathf.Min(diceUnitX, srcTex.width - sx); int th = Mathf.Min(diceUnitY, srcTex.height - sy); SCGE.SpriteLut diceLut = new SCGE.SpriteLut(); diceLut.source = i; diceLut.isSplit = true; diceLut.sourceTex = srcTex; diceLut.isDuplicate = false; // duplicate diced textures can be chopped up differently, so don't detect dupes here Texture2D dest = ProcessTexture(gen.premultipliedAlpha, gen.textureParams[i].additive, true, srcTex, sx, sy, tw, th, ref diceLut, GetPadAmount(gen)); if (dest) { diceLut.atlasIndex = numTexturesToAtlas++; spriteLuts.Add(diceLut); } } } } else { SCGE.SpriteLut lut = new SCGE.SpriteLut(); lut.sourceTex = currentTexture; lut.source = i; lut.isSplit = false; lut.isDuplicate = false; for (int j = 0; j < spriteLuts.Count; ++j) { if (spriteLuts[j].sourceTex == lut.sourceTex) { lut.isDuplicate = true; lut.atlasIndex = spriteLuts[j].atlasIndex; lut.tex = spriteLuts[j].tex; // get old processed tex lut.rx = spriteLuts[j].rx; lut.ry = spriteLuts[j].ry; lut.rw = spriteLuts[j].rw; lut.rh = spriteLuts[j].rh; break; } } if (!lut.isDuplicate) { lut.atlasIndex = numTexturesToAtlas++; bool stretchPad = false; if (gen.textureParams[i].pad == tk2dSpriteCollectionDefinition.Pad.Extend) stretchPad = true; Texture2D dest = ProcessTexture(gen.premultipliedAlpha, gen.textureParams[i].additive, stretchPad, currentTexture, 0, 0, currentTexture.width, currentTexture.height, ref lut, GetPadAmount(gen)); if (dest == null) { // fall back to a tiny blank texture lut.tex = new Texture2D(1, 1); lut.tex.SetPixel(0, 0, new Color( 0, 0, 0, 0 )); PadTexture(lut.tex, GetPadAmount(gen), stretchPad); lut.tex.Apply(); lut.rx = currentTexture.width / 2; lut.ry = currentTexture.height / 2; lut.rw = 1; lut.rh = 1; } } spriteLuts.Add(lut); } } // Create texture Texture2D[] textureList = new Texture2D[numTexturesToAtlas]; int titer = 0; for (int i = 0; i < spriteLuts.Count; ++i) { SCGE.SpriteLut _lut = spriteLuts[i]; if (!_lut.isDuplicate) { textureList[titer++] = _lut.tex; } } // Build atlas Atlas.AtlasBuilder atlasBuilder = new Atlas.AtlasBuilder(gen.maxTextureSize, gen.maxTextureSize, gen.allowMultipleAtlases?64:1); if (textureList.Length > 0) { foreach (Texture2D currTexture in textureList) { atlasBuilder.AddRect(currTexture.width, currTexture.height); } if (atlasBuilder.Build() != 0) { if (atlasBuilder.HasOversizeTextures()) { EditorUtility.DisplayDialog("Unable to fit in atlas", "You have a texture which exceeds the atlas size." + "Consider putting it in a separate atlas, enabling dicing, or" + "reducing the texture size", "Ok"); } else { EditorUtility.DisplayDialog("Unable to fit textures in requested atlas area", "There are too many textures in this collection for the requested " + "atlas size.", "Ok"); } return; } } // Fill atlas textures Atlas.AtlasData[] atlasData = atlasBuilder.GetAtlasData(); System.Array.Resize(ref gen.atlasTextures, atlasData.Length); System.Array.Resize(ref gen.atlasMaterials, atlasData.Length); for (int atlasIndex = 0; atlasIndex < atlasData.Length; ++atlasIndex) { Texture2D tex = new Texture2D(64, 64, TextureFormat.ARGB32, false); gen.atlasWastage = (1.0f - atlasData[0].occupancy) * 100.0f; gen.atlasWidth = atlasData[0].width; gen.atlasHeight = atlasData[0].height; tex.Resize(atlasData[atlasIndex].width, atlasData[atlasIndex].height); // Clear texture, unsure if this is REALLY necessary for (int yy = 0; yy < tex.height; ++yy) { for (int xx = 0; xx < tex.width; ++xx) { tex.SetPixel(xx, yy, Color.black); } } for (int i = 0; i < atlasData[atlasIndex].entries.Length; ++i) { var entry = atlasData[atlasIndex].entries[i]; Texture2D source = textureList[entry.index]; if (!entry.flipped) { for (int y = 0; y < source.height; ++y) { for (int x = 0; x < source.width; ++x) { tex.SetPixel(entry.x + x, entry.y + y, source.GetPixel(x, y)); } } } else { for (int y = 0; y < source.height; ++y) { for (int x = 0; x < source.width; ++x) { tex.SetPixel(entry.x + y, entry.y + x, source.GetPixel(x, y)); } } } } tex.Apply(); string texturePath = gen.atlasTextures[atlasIndex]?AssetDatabase.GetAssetPath(gen.atlasTextures[atlasIndex]):(dataDirName + "atlas" + atlasIndex + ".png"); // Write filled atlas to disk byte[] bytes = tex.EncodeToPNG(); System.IO.FileStream fs = System.IO.File.Create(texturePath); fs.Write(bytes, 0, bytes.Length); fs.Close(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); tex = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D; gen.atlasTextures[atlasIndex] = tex; // Make sure texture is set up with the correct max size and compression type SetUpTargetTexture(gen, tex); // Create material if necessary if (gen.atlasMaterials[atlasIndex] == null) { Material mat; if (gen.premultipliedAlpha) mat = new Material(Shader.Find("tk2d/PremulVertexColor")); else mat = new Material(Shader.Find("tk2d/BlendVertexColor")); mat.mainTexture = tex; string materialPath = gen.atlasMaterials[atlasIndex]?AssetDatabase.GetAssetPath(gen.atlasMaterials[atlasIndex]):(dataDirName + "atlas" + atlasIndex + "_material.mat"); AssetDatabase.CreateAsset(mat, materialPath); AssetDatabase.SaveAssets(); gen.atlasMaterials[atlasIndex] = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material; } } // Create prefab if (gen.spriteCollection == null) { Object p = EditorUtility.CreateEmptyPrefab(prefabObjectPath); GameObject go = new GameObject(); go.AddComponent<tk2dSpriteCollectionData>(); EditorUtility.ReplacePrefab(go, p); GameObject.DestroyImmediate(go); AssetDatabase.SaveAssets(); gen.spriteCollection = AssetDatabase.LoadAssetAtPath(prefabObjectPath, typeof(tk2dSpriteCollectionData)) as tk2dSpriteCollectionData; } tk2dSpriteCollectionData coll = gen.spriteCollection; coll.textures = new Texture[gen.atlasTextures.Length]; coll.materials = new Material[gen.atlasMaterials.Length]; for (int i = 0; i < gen.atlasTextures.Length; ++i) { coll.textures[i] = gen.atlasTextures[i]; } for (int i = 0; i < gen.atlasMaterials.Length; ++i) { coll.materials[i] = gen.atlasMaterials[i]; } // Wipe out legacy data coll.material = null; coll.premultipliedAlpha = gen.premultipliedAlpha; coll.spriteDefinitions = new tk2dSpriteDefinition[gen.textureParams.Length]; coll.version = tk2dSpriteCollectionData.CURRENT_VERSION; coll.spriteCollectionGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(gen)); coll.spriteCollectionName = gen.name; for (int i = 0; i < coll.spriteDefinitions.Length; ++i) { coll.spriteDefinitions[i] = new tk2dSpriteDefinition(); if (gen.textureRefs[i]) { string assetPath = AssetDatabase.GetAssetPath(gen.textureRefs[i]); string guid = AssetDatabase.AssetPathToGUID(assetPath); coll.spriteDefinitions[i].sourceTextureGUID = guid; } else { coll.spriteDefinitions[i].sourceTextureGUID = ""; } coll.spriteDefinitions[i].extractRegion = gen.textureParams[i].extractRegion; coll.spriteDefinitions[i].regionX = gen.textureParams[i].regionX; coll.spriteDefinitions[i].regionY = gen.textureParams[i].regionY; coll.spriteDefinitions[i].regionW = gen.textureParams[i].regionW; coll.spriteDefinitions[i].regionH = gen.textureParams[i].regionH; } coll.allowMultipleAtlases = gen.allowMultipleAtlases; UpdateVertexCache(gen, atlasData, coll, spriteLuts); // refresh existing tk2dSprite[] sprs = Resources.FindObjectsOfTypeAll(typeof(tk2dSprite)) as tk2dSprite[]; foreach (tk2dSprite spr in sprs) { if (spr.collection == gen.spriteCollection) { if (spr.spriteId < 0 || spr.spriteId >= spr.collection.spriteDefinitions.Length) spr.spriteId = 0; spr.Build(); } } tk2dStaticSpriteBatcher[] batchedSprs = Resources.FindObjectsOfTypeAll(typeof(tk2dStaticSpriteBatcher)) as tk2dStaticSpriteBatcher[]; foreach (var spr in batchedSprs) { if (spr.spriteCollection == gen.spriteCollection) { spr.Build(); } } // save changes EditorUtility.SetDirty(gen.spriteCollection); EditorUtility.SetDirty(gen); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); sourceTextures = null; // need to clear, its static currentBuild = null; tk2dEditorUtility.GetOrCreateIndex().AddSpriteCollectionData(gen.spriteCollection); tk2dEditorUtility.CommitIndex(); }
public static void Crop(Texture2D texture, int width, int height, CropAnchor anchor = CropAnchor.CENTER) { int resultPosX = 0; int resultPosY = 0; int resultWidth = 0; int resultHeight = 0; float ratioWidth = (float)width/(float)texture.width; float ratioHeight = (float)height/(float)texture.height; if (ratioHeight < ratioWidth) { resultWidth = width; resultHeight = (int)(texture.height * ratioWidth); switch(anchor) { case CropAnchor.TOP: resultPosY = (int)(resultHeight - height); break; case CropAnchor.BOTTOM: resultPosY = 0; break; default: resultPosY = (int)((resultHeight - height) * 0.5f); break; } } else { resultWidth = (int)(texture.width * ratioHeight); resultHeight = height; switch(anchor) { case CropAnchor.LEFT: resultPosX = 0; break; case CropAnchor.RIGHT: resultPosX = (int)(resultWidth - width); break; default: resultPosX = (int)((resultWidth - width) * 0.5f); break; } } Resize(texture, resultWidth, resultHeight); Color[] pixelArray = texture.GetPixels(resultPosX, resultPosY, width, height); texture.Resize(width, height); texture.SetPixels(pixelArray, 0); texture.Apply(); }
private static Rect[] PackTextures( Texture2D texture, Texture2D[] sprites, int padding, int width, int height, int maxSize, bool forceSquare ) { if( ( width > maxSize && height < maxSize ) || ( height > maxSize && width < maxSize ) ) { width = height = maxSize; } if( width > maxSize || height > maxSize ) throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" ); if( forceSquare ) { var max = Mathf.Max( width, height ); width = max; height = max; } else if( height > width ) { int temp = width; width = height; height = temp; } MaxRectsBinPack bp = new MaxRectsBinPack( width, height, false ); Rect[] rects = new Rect[ sprites.Length ]; for( int i = 0; i < sprites.Length; i++ ) { Texture2D sprite = sprites[ i ]; var spriteWidth = sprite.width + padding; var spriteHeight = sprite.height + padding; var packingMethodConfig = (dfTexturePacker.dfTexturePackingMethod)EditorPrefs.GetInt( "DaikonForge.AtlasPackingMethod", (int)dfTexturePacker.dfTexturePackingMethod.RectBestAreaFit ); Rect rect = bp.Insert( spriteWidth, spriteHeight, packingMethodConfig ); // If the rect could not be packed into the current dimensions, // increase the texture size. if( rect.width == 0 || rect.height == 0 ) { return PackTextures( texture, sprites, padding, ( width <= height ? width << 1 : width ), ( height < width ? height << 1 : height ), maxSize, forceSquare ); } rects[ i ] = rect; } // Check for max size if( width > maxSize || height > maxSize ) throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" ); texture.Resize( width, height ); texture.SetPixels( new Color[ width * height ] ); var extrudeEdges = EditorPrefs.GetBool( "DaikonForge.AtlasExtrudeSprites", false ) && padding > 0; for( int i = 0; i < sprites.Length; i++ ) { Texture2D sprite = sprites[ i ]; Rect rect = rects[ i ]; Color[] colors = sprite.GetPixels(); #region Edge extrusion coded provided by Mistale - http://www.daikonforge.com/dfgui/forums/topic/dilate-texture-atlas/ // Dilate border if padding is set if( extrudeEdges ) { int w = (int)sprite.width; int h = (int)sprite.height; int xStart = (int)rect.x; int yStart = (int)rect.y; int xStop = xStart + w - 1; int yStop = yStart + h - 1; Color[] wColors; int halfPadding = (int)( padding / 2f ); // Top border wColors = sprite.GetPixels( 0, 0, sprite.width, 1 ); for( int p = 0; p < halfPadding && yStart - p >= 1; p++ ) texture.SetPixels( xStart, yStart - p - 1, sprite.width, 1, wColors ); // Bottom border wColors = sprite.GetPixels( 0, sprite.height - 1, sprite.width, 1 ); for( int p = 0; p < halfPadding && yStop + p < texture.height - 1; p++ ) texture.SetPixels( xStart, yStop + p + 1, sprite.width, 1, wColors ); // Left border wColors = sprite.GetPixels( 0, 0, 1, sprite.height ); for( int p = 0; p < halfPadding && xStart - p >= 1; p++ ) texture.SetPixels( xStart - p - 1, yStart, 1, sprite.height, wColors ); // Right border wColors = sprite.GetPixels( sprite.width - 1, 0, 1, sprite.height ); for( int p = 0; p < halfPadding && xStop + p < texture.width - 1; p++ ) texture.SetPixels( xStop + p + 1, yStart, 1, sprite.height, wColors ); } #endregion texture.SetPixels( (int)rect.x, (int)rect.y, (int)sprite.width, (int)sprite.height, colors ); rects[ i ] = new Rect( rect.x / width, rect.y / height, ( rect.width - padding ) / width, ( rect.height - padding ) / height ); } return rects; }
private static Rect[] PackTextures( Texture2D texture, Texture2D[] sprites, int padding, int width, int height, int maxSize ) { if( ( width > maxSize && height < maxSize ) || ( height > maxSize && width < maxSize ) ) { width = height = maxSize; } if( width > maxSize || height > maxSize ) throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" ); if( height > width ) { int temp = width; width = height; height = temp; } MaxRectsBinPack bp = new MaxRectsBinPack( width, height, false ); Rect[] rects = new Rect[ sprites.Length ]; for( int i = 0; i < sprites.Length; i++ ) { Texture2D sprite = sprites[ i ]; var spriteWidth = sprite.width + padding; var spriteHeight = sprite.height + padding; Rect rect = bp.Insert( spriteWidth, spriteHeight, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestAreaFit ); // If the rect could not be packed into the current dimensions, // increase the texture size. if( rect.width == 0 || rect.height == 0 ) { return PackTextures( texture, sprites, padding, ( width <= height ? width << 1 : width ), ( height < width ? height << 1 : height ), maxSize ); } rects[ i ] = rect; } // Check for max size if( width > maxSize || height > maxSize ) throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" ); texture.Resize( width, height ); texture.SetPixels( new Color[ width * height ] ); for( int i = 0; i < sprites.Length; i++ ) { Texture2D sprite = sprites[ i ]; Rect rect = rects[ i ]; Color[] colors = sprite.GetPixels(); texture.SetPixels( (int)rect.x, (int)rect.y, (int)sprite.width, (int)sprite.height, colors ); rects[ i ] = new Rect( rect.x / width, rect.y / height, ( rect.width - padding ) / width, ( rect.height - padding ) / height ); } return rects; }
public static bool Rebuild(tk2dSpriteCollection gen) { // avoid "recursive" build being triggered by texture watcher if (currentBuild != null) return false; // Version specific checks. These need to be done before the sprite collection is upgraded. if (gen.version < 2) { if (!tk2dEditor.SpriteCollectionBuilder.Deprecated.CheckAndFixUpParams(gen)) { // Params failed check return false; } tk2dEditor.SpriteCollectionBuilder.Deprecated.SetUpSpriteSheets(gen); tk2dEditor.SpriteCollectionBuilder.Deprecated.TrimTextureList(gen); } currentBuild = gen; gen.Upgrade(); // upgrade if necessary. could be invoked by texture watcher. // Get some sensible paths to work with string dataDirName = GetOrCreateDataPath(gen) + "/"; string prefabObjectPath = ""; if (gen.spriteCollection) prefabObjectPath = AssetDatabase.GetAssetPath(gen.spriteCollection); else prefabObjectPath = dataDirName + gen.name + ".prefab"; BuildDirectoryToFile(prefabObjectPath); // Create prefab object, needed for next stage CreateDataObject( gen, prefabObjectPath ); // Special build for platform specific sprite collection if (gen.HasPlatformData) { // Initialize required sprite collections tk2dEditor.SpriteCollectionBuilder.PlatformBuilder.InitializeSpriteCollectionPlatforms(gen, System.IO.Path.GetDirectoryName(prefabObjectPath)); // The first sprite collection is always THIS tk2dAssetPlatform baseAssetPlatform = tk2dSystem.GetAssetPlatform(gen.platforms[0].name); float baseScale = (baseAssetPlatform != null)?baseAssetPlatform.scale:1.0f; // Building platform specific data, allow recursive builds temporarily currentBuild = null; // Transfer to platform sprite collections, and build those for (int i = 0; i < gen.platforms.Count; ++i) { tk2dSpriteCollectionPlatform platform = gen.platforms[i]; tk2dAssetPlatform thisAssetPlatform = tk2dSystem.GetAssetPlatform(gen.platforms[i].name); float thisScale = (thisAssetPlatform != null)?thisAssetPlatform.scale:1.0f; bool validPlatform = platform.name.Length > 0 && platform.spriteCollection != null; bool isRootSpriteCollection = (i == 0); if (validPlatform) { tk2dSpriteCollection thisPlatformCollection = gen.platforms[i].spriteCollection; // Make sure data directory exists, material overrides will be created in here string dataPath = GetOrCreateDataPath(thisPlatformCollection); tk2dEditor.SpriteCollectionBuilder.PlatformBuilder.UpdatePlatformSpriteCollection( gen, thisPlatformCollection, dataPath, isRootSpriteCollection, thisScale / baseScale, platform.name); Rebuild(thisPlatformCollection); } } // Pull atlas data from default platform gen.atlasMaterials = gen.platforms[0].spriteCollection.atlasMaterials; gen.altMaterials = gen.platforms[0].spriteCollection.altMaterials; // Fill up our sprite collection data List<string> platformNames = new List<string>(); List<string> platformGUIDs = new List<string>(); for (int i = 0; i < gen.platforms.Count; ++i) { tk2dSpriteCollectionPlatform platform = gen.platforms[i]; if (!platform.Valid) continue; platformNames.Add(platform.name); tk2dSpriteCollectionData data = platform.spriteCollection.spriteCollection; string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(data)); platformGUIDs.Add(guid); // Make loadable tk2dSystemUtility.MakeLoadableAsset(data, ""); // unnamed loadable object } // Set up fonts for (int j = 0; j < gen.fonts.Length; ++j) { tk2dSpriteCollectionFont font = gen.fonts[j]; if (font == null) continue; tk2dFontData data = font.data; if (!data) continue; data.hasPlatformData = true; data.material = null; data.materialInst = null; data.fontPlatforms = platformNames.ToArray(); data.fontPlatformGUIDs = new string[platformNames.Count]; for (int i = 0; i < gen.platforms.Count; ++i) { tk2dSpriteCollectionPlatform platform = gen.platforms[i]; if (!platform.Valid) continue; data.fontPlatformGUIDs[i] = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(gen.platforms[i].spriteCollection.fonts[j].data)); } EditorUtility.SetDirty(data); } gen.spriteCollection.version = tk2dSpriteCollectionData.CURRENT_VERSION; gen.spriteCollection.spriteCollectionName = gen.name; gen.spriteCollection.spriteCollectionGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(gen)); gen.spriteCollection.dataGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(gen.spriteCollection)); // Clear out data gen.spriteCollection.spriteDefinitions = new tk2dSpriteDefinition[0]; gen.spriteCollection.materials = new Material[0]; gen.spriteCollection.textures = new Texture2D[0]; gen.spriteCollection.hasPlatformData = true; gen.spriteCollection.spriteCollectionPlatforms = platformNames.ToArray(); gen.spriteCollection.spriteCollectionPlatformGUIDs = platformGUIDs.ToArray(); EditorUtility.SetDirty(gen); EditorUtility.SetDirty(gen.spriteCollection); // Index this properly tk2dEditorUtility.GetOrCreateIndex().AddSpriteCollectionData(gen.spriteCollection); tk2dEditorUtility.CommitIndex(); AssetDatabase.SaveAssets(); ResetCurrentBuild(); return true; } else { // clear platform data gen.spriteCollection.ResetPlatformData(); // in case its being used gen.spriteCollection.hasPlatformData = false; gen.spriteCollection.spriteCollectionPlatforms = new string[0]; gen.spriteCollection.spriteCollectionPlatformGUIDs = new string[0]; // Set up fonts for (int j = 0; j < gen.fonts.Length; ++j) { tk2dFontData f = gen.fonts[j].data; if (f != null) { f.ResetPlatformData(); f.hasPlatformData = false; f.fontPlatforms = new string[0]; f.fontPlatformGUIDs = new string[0]; EditorUtility.SetDirty(f); } } } // Make sure all source textures are in the correct format SetUpSourceTextureFormats(gen); // blank texture used when texture has been deleted Texture2D blankTexture = new Texture2D(2, 2); blankTexture.SetPixel(0, 0, Color.magenta); blankTexture.SetPixel(0, 1, Color.yellow); blankTexture.SetPixel(1, 0, Color.cyan); blankTexture.SetPixel(1, 1, Color.grey); blankTexture.Apply(); // make local texture sources List<Texture2D> allocatedTextures = new List<Texture2D>(); sourceTextures = new Texture2D[gen.textureParams.Length]; for (int i = 0; i < gen.textureParams.Length; ++i) { var param = gen.textureParams[i]; if (param.extractRegion && param.texture != null) { Texture2D localTex = new Texture2D(param.regionW, param.regionH); for (int y = 0; y < param.regionH; ++y) { for (int x = 0; x < param.regionW; ++x) { localTex.SetPixel(x, y, param.texture.GetPixel(param.regionX + x, param.regionY + y)); } } localTex.name = param.texture.name + "/" + param.regionId.ToString(); localTex.Apply(); allocatedTextures.Add(localTex); sourceTextures[i] = localTex; } else { sourceTextures[i] = gen.textureParams[i].texture; } } // catalog all textures to atlas int numTexturesToAtlas = 0; List<SpriteLut> spriteLuts = new List<SpriteLut>(); for (int i = 0; i < gen.textureParams.Length; ++i) { Texture2D currentTexture = sourceTextures[i]; if (sourceTextures[i] == null) { gen.textureParams[i].dice = false; gen.textureParams[i].anchor = tk2dSpriteCollectionDefinition.Anchor.MiddleCenter; gen.textureParams[i].name = ""; gen.textureParams[i].extractRegion = false; gen.textureParams[i].fromSpriteSheet = false; currentTexture = blankTexture; } else { if (gen.textureParams[i].name == null || gen.textureParams[i].name == "") { if (gen.textureParams[i].texture != currentTexture && !gen.textureParams[i].fromSpriteSheet) { gen.textureParams[i].name = currentTexture.name; } } } if (gen.textureParams[i].dice) { // prepare to dice this up int diceUnitX = gen.textureParams[i].diceUnitX; int diceUnitY = gen.textureParams[i].diceUnitY; if (diceUnitX <= 0) diceUnitX = 128; // something sensible, please if (diceUnitY <= 0) diceUnitY = diceUnitX; // make square if not set Texture2D srcTex = currentTexture; for (int sx = 0; sx < srcTex.width; sx += diceUnitX) { for (int sy = 0; sy < srcTex.height; sy += diceUnitY) { int tw = Mathf.Min(diceUnitX, srcTex.width - sx); int th = Mathf.Min(diceUnitY, srcTex.height - sy); SpriteLut diceLut = new SpriteLut(); diceLut.source = i; diceLut.isSplit = true; diceLut.sourceTex = srcTex; diceLut.isDuplicate = false; // duplicate diced textures can be chopped up differently, so don't detect dupes here Texture2D dest = ProcessTexture(gen, gen.textureParams[i].additive, true, gen.textureParams[i].disableTrimming, false, srcTex, sx, sy, tw, th, ref diceLut, GetPadAmount(gen, i)); if (dest) { diceLut.atlasIndex = numTexturesToAtlas++; spriteLuts.Add(diceLut); } } } } else { SpriteLut lut = new SpriteLut(); lut.sourceTex = currentTexture; lut.source = i; lut.isSplit = false; lut.isDuplicate = false; for (int j = 0; j < spriteLuts.Count; ++j) { if (spriteLuts[j].sourceTex == lut.sourceTex) { lut.isDuplicate = true; lut.atlasIndex = spriteLuts[j].atlasIndex; lut.tex = spriteLuts[j].tex; // get old processed tex lut.rx = spriteLuts[j].rx; lut.ry = spriteLuts[j].ry; lut.rw = spriteLuts[j].rw; lut.rh = spriteLuts[j].rh; break; } } if (!lut.isDuplicate) { lut.atlasIndex = numTexturesToAtlas++; bool stretchPad = false; if (gen.textureParams[i].pad == tk2dSpriteCollectionDefinition.Pad.Extend) stretchPad = true; Texture2D dest = ProcessTexture(gen, gen.textureParams[i].additive, stretchPad, gen.textureParams[i].disableTrimming, false, currentTexture, 0, 0, currentTexture.width, currentTexture.height, ref lut, GetPadAmount(gen, i)); if (dest == null) { // fall back to a tiny blank texture lut.tex = new Texture2D(1, 1); lut.tex.SetPixel(0, 0, new Color( 0, 0, 0, 0 )); PadTexture(lut.tex, GetPadAmount(gen, i), stretchPad); lut.tex.Apply(); lut.rx = currentTexture.width / 2; lut.ry = currentTexture.height / 2; lut.rw = 1; lut.rh = 1; } } spriteLuts.Add(lut); } } // Font Dictionary<tk2dSpriteCollectionFont, tk2dEditor.Font.Info> fontInfoDict = new Dictionary<tk2dSpriteCollectionFont, tk2dEditor.Font.Info>(); if (gen.fonts != null) { for (int i = 0; i < gen.fonts.Length; ++i) { var font = gen.fonts[i]; if (!font.InUse) continue; var fontInfo = tk2dEditor.Font.Builder.ParseBMFont( AssetDatabase.GetAssetPath(font.bmFont) ); fontInfoDict[font] = fontInfo; foreach (var c in fontInfo.chars) { // skip empty textures if (c.width <= 0 || c.height <= 0) continue; SpriteLut lut = new SpriteLut(); int cy = font.flipTextureY?c.y:(fontInfo.scaleH - c.y - c.height); Texture2D dest = ProcessTexture(gen, false, false, false, true, font.texture, c.x, cy, c.width, c.height, ref lut, GetPadAmount(gen, -1)); if (dest == null) { // probably fully transparent continue; } lut.sourceTex = dest; lut.tex = dest; lut.source = -1; lut.isFont = true; lut.isDuplicate = false; lut.fontId = i; lut.charId = c.id; lut.rx = lut.rx - c.x; lut.ry = lut.ry - cy; lut.atlasIndex = numTexturesToAtlas++; spriteLuts.Add(lut); } // Add one blank char for fallbacks { int dims = 5; SpriteLut lut = new SpriteLut(); lut.tex = new Texture2D(dims, dims); for (int y = 0; y < dims; ++y) for (int x = 0; x < dims; ++x) lut.tex.SetPixel(x, y, Color.clear); lut.tex.Apply(); lut.sourceTex = lut.tex; lut.isFont = true; lut.isDuplicate = false; lut.fontId = i; lut.charId = -1; lut.atlasIndex = numTexturesToAtlas++; spriteLuts.Add(lut); } } } // Create texture Texture2D[] textureList = new Texture2D[numTexturesToAtlas]; int titer = 0; for (int i = 0; i < spriteLuts.Count; ++i) { SpriteLut _lut = spriteLuts[i]; if (!_lut.isDuplicate) { textureList[titer++] = _lut.tex; } } // Build atlas bool forceAtlasSize = gen.forceTextureSize; int atlasWidth = forceAtlasSize?gen.forcedTextureWidth:gen.maxTextureSize; int atlasHeight = forceAtlasSize?gen.forcedTextureHeight:gen.maxTextureSize; bool forceSquareAtlas = forceAtlasSize?false:gen.forceSquareAtlas; bool allowFindingOptimalSize = !forceAtlasSize; tk2dEditor.Atlas.Builder atlasBuilder = new tk2dEditor.Atlas.Builder(atlasWidth, atlasHeight, gen.allowMultipleAtlases?64:1, allowFindingOptimalSize, forceSquareAtlas); if (textureList.Length > 0) { foreach (Texture2D currTexture in textureList) { atlasBuilder.AddRect(currTexture.width, currTexture.height); } if (atlasBuilder.Build() != 0) { if (atlasBuilder.HasOversizeTextures()) { EditorUtility.DisplayDialog("Unable to fit in atlas", "You have a texture which exceeds the atlas size. " + "Consider putting it in a separate atlas, enabling dicing, or " + "reducing the texture size", "Ok"); } else { EditorUtility.DisplayDialog("Unable to fit textures in requested atlas area", "There are too many textures in this collection for the requested " + "atlas size.", "Ok"); } return false; } } // Fill atlas textures tk2dEditor.Atlas.Data[] atlasData = atlasBuilder.GetAtlasData(); System.Array.Resize(ref gen.atlasTextures, atlasData.Length); System.Array.Resize(ref gen.atlasMaterials, atlasData.Length); if (atlasData.Length > 1) { // wipe out alt materials when atlas spanning is on gen.altMaterials = new Material[0]; } for (int atlasIndex = 0; atlasIndex < atlasData.Length; ++atlasIndex) { Texture2D tex = new Texture2D(64, 64, TextureFormat.ARGB32, false); gen.atlasWastage = (1.0f - atlasData[0].occupancy) * 100.0f; gen.atlasWidth = atlasData[0].width; gen.atlasHeight = atlasData[0].height; tex.Resize(atlasData[atlasIndex].width, atlasData[atlasIndex].height); // Clear texture, unsure if this is REALLY necessary // Turns out it is for (int yy = 0; yy < tex.height; ++yy) { for (int xx = 0; xx < tex.width; ++xx) { tex.SetPixel(xx, yy, Color.clear); } } for (int i = 0; i < atlasData[atlasIndex].entries.Length; ++i) { var entry = atlasData[atlasIndex].entries[i]; Texture2D source = textureList[entry.index]; if (!entry.flipped) { for (int y = 0; y < source.height; ++y) { for (int x = 0; x < source.width; ++x) { tex.SetPixel(entry.x + x, entry.y + y, source.GetPixel(x, y)); } } } else { for (int y = 0; y < source.height; ++y) { for (int x = 0; x < source.width; ++x) { tex.SetPixel(entry.x + y, entry.y + x, source.GetPixel(x, y)); } } } } tex.Apply(); string texturePath = gen.atlasTextures[atlasIndex]?AssetDatabase.GetAssetPath(gen.atlasTextures[atlasIndex]):(dataDirName + "atlas" + atlasIndex + ".png"); BuildDirectoryToFile(texturePath); // Write filled atlas to disk byte[] bytes = tex.EncodeToPNG(); System.IO.FileStream fs = System.IO.File.Create(texturePath); fs.Write(bytes, 0, bytes.Length); fs.Close(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Object.DestroyImmediate(tex); tex = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D; gen.atlasTextures[atlasIndex] = tex; // Make sure texture is set up with the correct max size and compression type SetUpTargetTexture(gen, tex); // Create material if necessary if (gen.atlasMaterials[atlasIndex] == null) { Material mat; if (gen.premultipliedAlpha) mat = new Material(Shader.Find("tk2d/PremulVertexColor")); else mat = new Material(Shader.Find("tk2d/BlendVertexColor")); mat.mainTexture = tex; string materialPath = gen.atlasMaterials[atlasIndex]?AssetDatabase.GetAssetPath(gen.atlasMaterials[atlasIndex]):(dataDirName + "atlas" + atlasIndex + " material.mat"); BuildDirectoryToFile(materialPath); AssetDatabase.CreateAsset(mat, materialPath); AssetDatabase.SaveAssets(); gen.atlasMaterials[atlasIndex] = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material; } // gen.altMaterials must either have length 0, or contain at least the material used in the game if (!gen.allowMultipleAtlases && (gen.altMaterials == null || gen.altMaterials.Length == 0)) gen.altMaterials = new Material[1] { gen.atlasMaterials[0] }; } tk2dSpriteCollectionData coll = gen.spriteCollection; coll.textures = new Texture[gen.atlasTextures.Length]; for (int i = 0; i < gen.atlasTextures.Length; ++i) { coll.textures[i] = gen.atlasTextures[i]; } if (gen.atlasMaterials.Length == 1) { coll.materials = new Material[gen.altMaterials.Length]; for (int i = 0; i < gen.altMaterials.Length; ++i) coll.materials[i] = gen.altMaterials[i]; } else { coll.materials = new Material[gen.atlasMaterials.Length]; for (int i = 0; i < gen.atlasMaterials.Length; ++i) coll.materials[i] = gen.atlasMaterials[i]; } // Wipe out legacy data coll.material = null; coll.premultipliedAlpha = gen.premultipliedAlpha; coll.spriteDefinitions = new tk2dSpriteDefinition[gen.textureParams.Length]; coll.version = tk2dSpriteCollectionData.CURRENT_VERSION; coll.materialIdsValid = true; coll.spriteCollectionGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(gen)); coll.spriteCollectionName = gen.name; coll.invOrthoSize = 1.0f / gen.targetOrthoSize; coll.halfTargetHeight = gen.targetHeight * 0.5f; int buildKey = Random.Range(0, int.MaxValue); while (buildKey == coll.buildKey) { buildKey = Random.Range(0, int.MaxValue); } coll.buildKey = buildKey; // a random build number so we can identify changed collections quickly for (int i = 0; i < coll.spriteDefinitions.Length; ++i) { coll.spriteDefinitions[i] = new tk2dSpriteDefinition(); if (gen.textureParams[i].texture) { string assetPath = AssetDatabase.GetAssetPath(gen.textureParams[i].texture); string guid = AssetDatabase.AssetPathToGUID(assetPath); coll.spriteDefinitions[i].sourceTextureGUID = guid; } else { coll.spriteDefinitions[i].sourceTextureGUID = ""; } coll.spriteDefinitions[i].extractRegion = gen.textureParams[i].extractRegion; coll.spriteDefinitions[i].regionX = gen.textureParams[i].regionX; coll.spriteDefinitions[i].regionY = gen.textureParams[i].regionY; coll.spriteDefinitions[i].regionW = gen.textureParams[i].regionW; coll.spriteDefinitions[i].regionH = gen.textureParams[i].regionH; } coll.allowMultipleAtlases = gen.allowMultipleAtlases; coll.dataGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(coll)); float scale = 1.0f; if (gen.useTk2dCamera) { scale = 1.0f * gen.globalScale; } else { scale = (2.0f * gen.targetOrthoSize / gen.targetHeight) * gen.globalScale; } // Build fonts foreach (var font in fontInfoDict.Keys) { var fontInfo = fontInfoDict[font]; List<SpriteLut> fontSpriteLut = new List<SpriteLut>(); int fontId = 0; for (fontId = 0; fontId < gen.fonts.Length; ++fontId) if (gen.fonts[fontId] == font) break; foreach (var v in spriteLuts) { if (v.isFont && v.fontId == fontId) fontSpriteLut.Add(v); } fontInfo.scaleW = coll.textures[0].width; fontInfo.scaleH = coll.textures[0].height; // Set material if (font.useGradient && font.gradientTexture != null && font.gradientCount > 0) { font.editorData.gradientCount = font.gradientCount; font.editorData.gradientTexture = font.gradientTexture; } else { font.editorData.gradientCount = 1; font.editorData.gradientTexture = null; } // Build a local sprite lut only relevant to this font UpdateFontData(gen, scale, atlasData, fontSpriteLut, font, fontInfo); if (font.useGradient && font.gradientTexture != null) { font.data.gradientCount = font.editorData.gradientCount; font.data.gradientTexture = font.editorData.gradientTexture; font.data.textureGradients = true; } else { font.data.gradientCount = 1; font.data.gradientTexture = null; font.data.textureGradients = false; } font.data.spriteCollection = gen.spriteCollection; font.data.material = coll.materials[font.materialId]; font.editorData.material = coll.materials[font.materialId]; font.data.invOrthoSize = coll.invOrthoSize; font.data.halfTargetHeight = coll.halfTargetHeight; font.data.texelSize = new Vector3(scale, scale, 0.0f); // Managed? font.data.managedFont = gen.managedSpriteCollection; font.data.needMaterialInstance = gen.managedSpriteCollection; // Mark to save EditorUtility.SetDirty(font.editorData); EditorUtility.SetDirty(font.data); // Update font tk2dEditorUtility.GetOrCreateIndex().AddOrUpdateFont(font.editorData); tk2dEditorUtility.CommitIndex(); // Loadable? if (!tk2dSystemUtility.IsLoadableAsset(font.data)) tk2dSystemUtility.MakeLoadableAsset(font.data, ""); } // Build textures UpdateVertexCache(gen, scale, atlasData, coll, spriteLuts); // Free tmp textures foreach (var sprite in spriteLuts) { if (!sprite.isDuplicate) Object.DestroyImmediate(sprite.tex); } foreach (var tex in allocatedTextures) Object.DestroyImmediate(tex); // refresh existing RefreshExistingAssets(gen.spriteCollection); // save changes gen.spriteCollection.assetName = gen.assetName; gen.spriteCollection.managedSpriteCollection = gen.managedSpriteCollection; gen.spriteCollection.needMaterialInstance = gen.managedSpriteCollection; var index = tk2dEditorUtility.GetOrCreateIndex(); index.AddSpriteCollectionData(gen.spriteCollection); EditorUtility.SetDirty(gen.spriteCollection); EditorUtility.SetDirty(gen); sourceTextures = null; // need to clear, its static currentBuild = null; tk2dEditorUtility.GetOrCreateIndex().AddSpriteCollectionData(gen.spriteCollection); tk2dEditorUtility.CommitIndex(); Object.DestroyImmediate(blankTexture); // update resource system if (tk2dSystemUtility.IsLoadableAsset(gen.spriteCollection)) { tk2dSystemUtility.UpdateAssetName(gen.spriteCollection, gen.assetName); } return true; }
/// <summary> /// Generates the packed material map for an object /// </summary> public static void GeneratePackedMaterialMap(AlloyCustomImportObject settings, Texture2D source, string filePath) { int mipmapCount = 1; bool isEditorInLinearSpace = PlayerSettings.colorSpace == ColorSpace.Linear; Shader.SetGlobalFloat("_EditorIsLinear", isEditorInLinearSpace ? 1.0f : 0.0f); Vector2 size = settings.GetOutputSize(); int width = (int) size.x; int height = (int) size.y; // Pick output texture dimensions based on the largest input texture. for (int i = 0; i < 4; ++i) { if (settings.SelectedModes[i] != TextureValueChannelMode.Texture || settings.GetTexture(i) == null) { continue; } mipmapCount = Math.Max(mipmapCount, GetMipmapCount(settings.GetTexture(i))); } bool doMips; if (settings.NormalMapTexture != null) { var tex = settings.NormalMapTexture; var count = GetMipmapCount(tex); mipmapCount = Math.Max(mipmapCount, count); doMips = true; } else { mipmapCount = 1; doMips = false; } if (source.width != width || source.height != height) { source.Resize(width, height); } if (!Mathf.IsPowerOfTwo(width) || !Mathf.IsPowerOfTwo(height)) { Debug.LogWarning( "Alloy: Texture resolution is not power of 2; will have issues generating correct mip maps if custom sizing is specified in generated texture platform settings."); } var readableTextures = new Texture2D[settings.TexturesGUID.Length]; var linear = new bool[settings.TexturesGUID.Length]; for (int i = 0; i < settings.TexturesGUID.Length; ++i) { if (settings.SelectedModes[i] != TextureValueChannelMode.Texture) { continue; } var settingsTex = settings.GetTexture(i); if (settingsTex == null) { readableTextures[i] = null; linear[i] = false; } else { var texImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(settingsTex)) as TextureImporter; if (texImporter == null) { Debug.LogError("Couldn't find packed map texture in asset database!"); return; } readableTextures[i] = AlloyTextureReader.GetReadable(settingsTex, false); linear[i] = isEditorInLinearSpace && !texImporter.linearTexture; } } var normal = AlloyTextureReader.GetReadable(settings.NormalMapTexture, true); // Use renderer to sample mipmaps. for (int mipLevel = 0; mipLevel < mipmapCount; mipLevel++) { // CPU Method - more reliable/consistent across GPUs, but slower. EditorUtility.DisplayProgressBar("Calculating Mip Maps...", "MipLevel " + mipLevel, (float) mipLevel / mipmapCount); try { AlloyPackerCompositor.CompositeMips(source, settings, readableTextures, linear, normal, mipLevel); } finally { EditorUtility.ClearProgressBar(); } } foreach (var texture in readableTextures) { Object.DestroyImmediate(texture); } Object.DestroyImmediate(normal); int maxResolution = 0; settings.Width = width; settings.Height = height; settings.MaxResolution = maxResolution; EditorUtility.SetDirty(settings); // Tells Unity to save changes to the settings .asset object on disk source.Apply(!doMips, false); }
public override void CopyToTexture(Texture2D texture2D) { var format = ConvertPixelFormat(mPixelFormat); if (texture2D.width != mWidth || texture2D.height != mHeight || format != texture2D.format) { texture2D.Resize(mWidth, mHeight, format, false); } var channels = 1; switch (mPixelFormat) { case PIXEL_FORMAT.RGBA8888: channels = 4; break; case PIXEL_FORMAT.RGB565: case PIXEL_FORMAT.RGB888: channels = 3; break; } var colors = texture2D.GetPixels(); var c = 0; for (var i = 0; i < colors.Length; i++) { for (var j = 0; j < channels; j++) colors[i][j] = mData[c++]/255.0f; for (var j = channels; j < 4; j++) colors[i][j] = colors[i][j - 1]; } texture2D.SetPixels(colors); }
static void Resize(Texture src, Texture2D dst, YCgACoFormat format) { var width = src.width; var height = src.height; switch (format) { case YCgACoFormat.CgACo_RGB24_Half_6bpp: case YCgACoFormat.CgACo_RGB565_Half_4bpp: width /= 2; height /= 2; break; } if (dst.width != width || dst.height != height) dst.Resize(width, height); }
public static Rect[] PackTextures (Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize) { if (width > maxSize && height > maxSize) return null; if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } // Force square by sizing up if (NGUISettings.forceSquareAtlas) { if (width > height) height = width; else if (height > width) width = height; } UITexturePacker bp = new UITexturePacker(width, height, false); Storage[] storage = new Storage[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = new Rect(); int xPadding = 1; int yPadding = 1; for (xPadding = 1; xPadding >= 0; --xPadding) { for (yPadding = 1; yPadding >= 0; --yPadding) { rect = bp.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), UITexturePacker.FreeRectChoiceHeuristic.RectBestAreaFit); if (rect.width != 0 && rect.height != 0) break; // After having no padding if it still doesn't fit -- increase texture size. else if (xPadding == 0 && yPadding == 0) { return PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize); } } if (rect.width != 0 && rect.height != 0) break; } storage[i] = new Storage(); storage[i].rect = rect; storage[i].paddingX = (xPadding != 0); storage[i].paddingY = (yPadding != 0); } texture.Resize(width, height); texture.SetPixels(new Color[width * height]); // The returned rects Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = storage[i].rect; int xPadding = (storage[i].paddingX ? padding : 0); int yPadding = (storage[i].paddingY ? padding : 0); Color[] colors = tex.GetPixels(); // Would be used to rotate the texture if need be. if (rect.width != tex.width + xPadding) { Color[] newColors = tex.GetPixels(); for (int x = 0; x < rect.width; x++) { for (int y = 0; y < rect.height; y++) { int prevIndex = ((int)rect.height - (y + 1)) + x * (int)tex.width; newColors[x + y * (int)rect.width] = colors[prevIndex]; } } colors = newColors; } texture.SetPixels((int)rect.x, (int)rect.y, (int)rect.width - xPadding, (int)rect.height - yPadding, colors); rect.x /= width; rect.y /= height; rect.width = (rect.width - xPadding) / width; rect.height = (rect.height - yPadding) / height; rects[i] = rect; } texture.Apply(); return rects; }
public static bool readHDR(ref Texture2D tex, string path) { string fullPath = Application.dataPath + "/" + path.Substring(7); FileStream fs = new FileStream(fullPath, FileMode.Open); BinaryReader stream = new BinaryReader(fs); string properMagic = "#?RADIANCE"; char[] magic = stream.ReadChars(properMagic.Length); string magicStr = new string(magic,0,magic.Length); if( !magicStr.Equals(properMagic) ) { Debug.LogError("Invalid .hdr file, magic: " + magic); return false; } //read in our parameters bool xyz = false; float exposure = 1f; //bool flipX=false; //Yeah no we're not doing that. --Andres bool flipY=false; int width=-1; int height=-1; string name = ""; string val = ""; //HEADER - terminated by a blank line while( stream.PeekChar() != -1 && (width == -1 || height == -1) ) { readPair(ref stream, ref name, ref val); name = name.ToLowerInvariant(); val = val.ToLowerInvariant(); if( name.Equals("format") ) { if( val.Equals("32-bit_rle_rgbe") ) { xyz = false; } else if( val.Equals("32-bit_rle_xyze") ) { xyz = true; } } else if( name.Equals("exposure") ) { exposure = Convert.ToSingle(val); } if( name.Equals("+x") ) { //flipX = false; width = Convert.ToInt32(val); } else if( name.Equals("-x") ) { //flipX = true; width = Convert.ToInt32(val); } else if( name.Equals("+y") ) { flipY = false; height = Convert.ToInt32(val); } else if( name.Equals("-y") ) { flipY = true; height = Convert.ToInt32(val); } else { //do not want } } //Wat? some .HDR files do this and break everything. if( exposure <= 0f ) exposure = 1f; if( width <= 0 || height <= 0 ) { Debug.LogError("Invalid dimensions found in .hdr file (" + width + " x "+height+")"); return false; } tex.Resize(width, height,TextureFormat.ARGB32,false); Color[] pixels = tex.GetPixels(); byte[] rowHeader = null; for(int r=0; r<height; ++r) { int rowOffset = r*width; rowHeader = stream.ReadBytes(4); if( rowHeader[0] != 2 || rowHeader[1] != 2 || (256*rowHeader[2] + rowHeader[3]) != width ) { Debug.LogError("Invalid row header data found in .hdr file"); return false; } for( int c=0; c<4; ++c ) { int i=0; while( i < width ) { byte n = stream.ReadByte(); if( n > 128 ) { //run, duplicate the next byte 'n' times n -= 128; if( i+(int)n > width ) { Debug.LogError("invalid row size found in hdr file (corrupt or otherwise odd file?)"); return false; } byte b = stream.ReadByte(); float f = (float)b; for( byte run=0; run<n; ++run ) { pixels[rowOffset + i][c] = f; ++i; } } else { //dump, read the next 'n' components if( i+n > width ) { Debug.LogError("invalid row size found in hdr file (corrupt or otherwise odd file?)"); return false; } for( int dump=0; dump<n; ++dump ) { byte b = stream.ReadByte(); float f = (float)b; pixels[rowOffset + i][c] = f; ++i; } } } } } stream.Close(); fs.Close(); Color32[] dst = new Color32[pixels.Length]; //convert the row to real color for( int r=0; r<height; ++r ) { int rowOffset = r*width; int dstOffset = rowOffset; if( flipY ) dstOffset = (height-r-1)*width; int src_i, dst_i; float e, scale; for( int c=0; c<width; ++c ) { src_i = rowOffset + c; dst_i = dstOffset + c; e = pixels[src_i][3] - 128f; scale = exposure * Mathf.Pow(2f, e) / 255f; pixels[src_i][0] = pixels[src_i][0] * scale; pixels[src_i][1] = pixels[src_i][1] * scale; pixels[src_i][2] = pixels[src_i][2] * scale; pixels[src_i][3] = 1f; if(xyz) RGB.fromXYZ(ref pixels[src_i], pixels[src_i]); RGB.toRGBM(ref dst[dst_i], pixels[src_i], true); } } tex.SetPixels32(dst); tex.Apply(false); return true; }
public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize) { if(width > maxSize && height > maxSize) return null; if(width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } UITexturePacker bp = new UITexturePacker(width, height, false); Rect[] rects = new Rect[textures.Length]; for(int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = new Rect(); for (int xPadding = 1; xPadding >=0; --xPadding) { for (int yPadding = 1; yPadding >= 0; --yPadding) { rect = bp.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), UITexturePacker.FreeRectChoiceHeuristic.RectBestAreaFit); if (rect.width != 0 && rect.height != 0) { break; } // After having no padding if it still doesnt fit increase texture size. else if (xPadding == 0 && yPadding == 0) { return PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize); } } if (rect.width != 0 && rect.height != 0) { break; } } rects[i] = rect; } texture.Resize(width, height); texture.SetPixels(new Color[width * height]); for(int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; Rect rect = rects[i]; Color[] colors = tex.GetPixels(); if(rect.width != tex.width + padding) { Color[] newColors = tex.GetPixels(); for(int x = 0; x < rect.width; x++) { for(int y = 0; y < rect.height; y++) { int prevIndex = ((int)rect.height - (y + 1)) + x * (int)tex.width; newColors[x + y * (int)rect.width] = colors[prevIndex]; } } colors = newColors; } texture.SetPixels((int)rect.x, (int)rect.y, (int)rect.width - padding, (int)rect.height - padding, colors); rect.x /= width; rect.y /= height; rect.width = (rect.width- padding) / width ; rect.height = (rect.height - padding) / height; rects[i] = rect; } return rects; }
void OnPostprocessTexture(Texture2D texture) { var importer = assetImporter as TextureImporter; if (!assetPath.EndsWith("CP.png")) return; var hasAlpha = importer.DoesSourceTextureHaveAlpha(); var tw = texture.width; var th = texture.height; var source = texture.GetPixels(); texture.Resize(tw * 3 / 2, th, TextureFormat.Alpha8, false); var pixels = texture.GetPixels(); var i1 = 0; var i2 = 0; // int iCrCb = 0; // Texture2D texY = new Texture2D(tw,th, TextureFormat.Alpha8, false); // Texture2D texCr = new Texture2D(tw / 2, th / 2, TextureFormat.Alpha8, false); // Texture2D texCb = new Texture2D(tw / 2, th / 2, TextureFormat.Alpha8, false); // var pixelsY = texY.GetPixels(); // var pixelsCr = texture.GetPixels(); // var pixelsCb = texture.GetPixels(); // if (hasAlpha) { for (var iy = 0; iy < th; iy++) { for (var ix = 0; ix < tw; ix++) { // float aa = RGB_Ya(source[i1++]); // pixels[i2++].a = aa; // pixelsY[iCrCb++].a = aa; } i2 += tw / 2; } } else { for (var iy = 0; iy < th; iy++) { for (var ix = 0; ix < tw; ix++) { // float aa = RGB_Ya(source[i1++]); // pixels[i2++].a = aa; // pixelsY[iCrCb++].a = aa; } i2 += tw / 2; } } i1 = 0; i2 = tw; var i3 = (tw * 3 / 2) * th / 2 + tw; // iCrCb = 0; for (var iy = 0; iy < th / 2; iy++) { for (var ix = 0; ix < tw / 2; ix++) { var ws = (source[i1] + source[i1 + 1] + source[i1 + tw] + source[i1 + tw + 1]) / 4; pixels[i2++].a = RGB_Cr(ws) + 0.5f; pixels[i3++].a = RGB_Cb(ws) + 0.5f; i1 += 2; // pixelsCr[iCrCb].a = RGB_Cr(ws) + 0.5f; // pixelsCb[iCrCb].a = RGB_Cb(ws) + 0.5f; // ++iCrCb; } i1 += tw; i2 += tw; i3 += tw; } texture.SetPixels(pixels); importer.isReadable = false; // texCr.SetPixels(pixelsCr); // texCb.SetPixels(pixelsCb); // texY.SetPixels(pixelsY); //Debug.Log(assetImporter.assetPath); // System.IO.File.WriteAllBytes("C:\\texY.png", texY.EncodeToPNG()); // System.IO.File.WriteAllBytes("C:\\texCr.png", texCr.EncodeToPNG()); // System.IO.File.WriteAllBytes("C:\\texCb.png", texCb.EncodeToPNG()); }