// Use this for initialization void Awake() { steps = new Stack <UStep>(); redoSteps = new Stack <UStep>(); undoSnapshots = new Stack <string>(); if (paintEngine == null) { if (gameObject.GetComponent <AdvancedMobilePaint>() != null) { paintEngine = gameObject.GetComponent <AdvancedMobilePaint>(); paintEngine.undoEnabled = true; paintEngine.undoController = gameObject.GetComponent <PaintUndoManager>(); } else { Debug.LogError("AMP: PaintUndoManger Cant find paint engine!"); } } if (!Directory.Exists(Application.persistentDataPath + "/AMP_cashe")) { Directory.CreateDirectory(Application.persistentDataPath + "/AMP_cashe"); } else { string[] files = Directory.GetFiles(Application.persistentDataPath + "/AMP_cashe"); for (int i = 0; i < files.Length; i++) { File.Delete(files[i]); } } }
public static void DrawLineWithBrush(Vector2 start, Vector2 end, AdvancedMobilePaint paintEngine) { int x0 = (int)start.x; int y0 = (int)start.y; int x1 = (int)end.x; int y1 = (int)end.y; int dx = Mathf.Abs(x1 - x0); // TODO: try these? http://stackoverflow.com/questions/6114099/fast-integer-abs-function int dy = Mathf.Abs(y1 - y0); int sx, sy; if (x0 < x1) { sx = 1; } else { sx = -1; } if (y0 < y1) { sy = 1; } else { sy = -1; } int err = dx - dy; bool loop = true; // int minDistance=paintEngine.brushSize-1; // int minDistance=(int)(paintEngine.brushSize>>1); // divide by 2, you might want to set mindistance to smaller value, to avoid gaps between brushes when moving fast int minDistance = (int)((paintEngine.brushSize >> 1) / 2); //FIXME Cackano! int pixelCount = 0; int e2; while (loop) { pixelCount++; if (pixelCount > minDistance) { pixelCount = 0; DrawCustomBrush2(x0, y0, paintEngine); } if ((x0 == x1) && (y0 == y1)) { loop = false; } e2 = 2 * err; if (e2 > -dy) { err = err - dy; x0 = x0 + sx; } if (e2 < dx) { err = err + dx; y0 = y0 + sy; } } }
/// <summary> /// Sets the step properties from engine. /// </summary> /// <param name="paintEngine">Paint engine.</param> public void SetStepPropertiesFromEngine(AdvancedMobilePaint paintEngine) { this.brushMode = paintEngine.brushMode; this.drawMode = paintEngine.drawMode; this.brushSize = paintEngine.brushSize; this.brushTexture = paintEngine.customBrush; this.patternTexture = paintEngine.pattenTexture; this.useAdditiveColors = paintEngine.useAdditiveColors; this.canDrawOnBlack = paintEngine.canDrawOnBlack; this.paintColor = paintEngine.paintColor; this.useLockArea = paintEngine.useLockArea; this.useCustomBrushAlpha = paintEngine.useCustomBrushAlpha; this.connectBrushStrokes = paintEngine.connectBrushStokes; //this.interpolation=paintEngine.doInterpolation; this.useMaskLayerOnly = paintEngine.useMaskLayerOnly; this.useTreshold = paintEngine.useThreshold; this.useMaskImage = paintEngine.useMaskImage; this.brushAlphaStrength = paintEngine.brushAlphaStrength; this.vectorBrushType = paintEngine.vectorBrushType; this.brushHeight = paintEngine.customBrushHeight; this.brushWidth = paintEngine.customBrushWidth; this.isLine = paintEngine.isLinePaint; this.isPatternLine = paintEngine.isPatternLine; this.lineEgdeSize = paintEngine.lineEdgeSize; }
} //DrawRectabgle() end // main painting function, http://stackoverflow.com/a/24453110 /// <summary> /// Draws the circle. /// </summary> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> public static void DrawCircle(int x, int y, AdvancedMobilePaint paintEngine) { if (!paintEngine.canDrawOnBlack) { if (paintEngine.pixels[(paintEngine.texWidth * y + x) * 4] == 0 && paintEngine.pixels[(paintEngine.texWidth * y + x) * 4 + 1] == 0 && paintEngine.pixels[(paintEngine.texWidth * y + x) * 4 + 2] == 0 && paintEngine.pixels[(paintEngine.texWidth * y + x) * 4 + 3] != 0) { return; } } int pixel = 0; // draw fast circle: int r2 = paintEngine.brushSize * paintEngine.brushSize; int area = r2 << 2; int rr = paintEngine.brushSize << 1; float lerpVal = 1f; lerpVal = paintEngine.paintColor.a / 255f * paintEngine.brushAlphaStrength; for (int i = 0; i < area; i++) { int tx = (i % rr) - paintEngine.brushSize; int ty = (i / rr) - paintEngine.brushSize; if (tx * tx + ty * ty < r2) { if (x + tx < 0 || y + ty < 0 || x + tx >= paintEngine.texWidth || y + ty >= paintEngine.texHeight) { continue; // temporary fix for corner painting } pixel = (paintEngine.texWidth * (y + ty) + x + tx) * 4; //pixel = ( texWidth*( (y+ty) % texHeight )+ (x+tx) % texWidth )*4; if (paintEngine.useAdditiveColors) { // additive over white also if (!paintEngine.useLockArea || (paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1)) { //toLerpVal= paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.paintColor.r, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.paintColor.g, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.paintColor.b, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.paintColor.a, lerpVal /*paintEngine.paintColor.a/255*paintEngine.brushAlphaStrength*/); } } else // no additive, just paint my colors { if (!paintEngine.useLockArea || (paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1)) { paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; } } // if additive } // if in circle } // for area } // DrawCircle()
public static void FillIndexes(List <int> indexes, AdvancedMobilePaint paintEngine, Color32 newColor) { for (int i = 0; i < indexes.Count; i++) { int num = indexes[i] * 4; paintEngine.pixels[num] = newColor.r; paintEngine.pixels[num + 1] = newColor.g; paintEngine.pixels[num + 2] = newColor.b; paintEngine.pixels[num + 3] = newColor.a; } }
public void Init(AdvancedMobilePaint paintData, PaletteData data, Texture2D drawTexture) { this.drawImg.gameObject.SetActive(true); this.pd = data; this.paintEngine = paintData; this.highlightEngine = new AdvancedMobilePaint(); this.highlightEngine.pixels = new byte[this.paintEngine.pixels.Length]; this.highlightEngine.source = this.paintEngine.source; this.highlightEngine.texWidth = this.paintEngine.texWidth; this.highlightEngine.texHeight = this.paintEngine.texHeight; this.drawText = new Texture2D(drawTexture.width, drawTexture.height, TextureFormat.RGBA32, false); this.drawText.LoadRawTextureData(this.highlightEngine.pixels); this.drawText.Apply(); this.drawImg.texture = this.drawText; }
// Use this for initialization void Awake() { steps = new Stack <UStep> (); redoSteps = new Stack <UStep> (); if (paintEngine == null) { if (gameObject.GetComponent <AdvancedMobilePaint>() != null) { paintEngine = gameObject.GetComponent <AdvancedMobilePaint>(); paintEngine.undoEnabled = true; paintEngine.undoController = gameObject.GetComponent <PaintUndoManager>(); } else { Debug.LogError("AMP: PaintUndoManger Cant find paint engine!"); } } }
} //DrawRectabgle() end public static void DrawPatternRectangle(int px, int py, AdvancedMobilePaint paintEngine) { Debug.Log("DrawPatternRectangle"); int startX = /*(int)*/ (px - paintEngine.customBrushWidth / 2); int startY = /*(int)*/ (py - paintEngine.customBrushHeight / 2); int pixel = (paintEngine.texWidth * startY + startX) * 4; //int brushPixel = 0; bool skip = false; float yy = 0; float xx = 0; int pixel2 = 0; for (int y = 0; y < paintEngine.customBrushHeight; y++) { for (int x = 0; x < paintEngine.customBrushWidth; x++) { skip = false; if ((startX + x) > (paintEngine.texWidth - 2) || (startX + x) < -1) { skip = true; } if (pixel < 0 || pixel >= paintEngine.pixels.Length) { skip = true; // } if (!skip) { //TODO: add more modes /*float*/ yy = Mathf.Repeat(y + startY, paintEngine.customPatternWidth); /*float*/ xx = Mathf.Repeat(x + startX, paintEngine.customPatternWidth); //Debug.Log ("P"+xx+","+yy); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, paintEngine.patternBrushBytes.Length); paintEngine.pixels[pixel] = paintEngine.patternBrushBytes[pixel2]; //r paintEngine.pixels[pixel + 1] = paintEngine.patternBrushBytes[pixel2 + 1]; //g paintEngine.pixels[pixel + 2] = paintEngine.patternBrushBytes[pixel2 + 2]; //b paintEngine.pixels[pixel + 3] = paintEngine.patternBrushBytes[pixel2 + 3]; //a } pixel += 4; } //za x pixel = (paintEngine.texWidth * (startY == 0?-1:startY + y) + startX + 1) * 4; } //za y } //DrawRectabgle() end
public static void DrawRectangle(int px, int py, AdvancedMobilePaint paintEngine) { //Debug.Log ("DrawRectangle"); int startX = /*(int)*/ (px - paintEngine.customBrushWidth / 2); int startY = /*(int)*/ (py - paintEngine.customBrushHeight / 2); int pixel = (paintEngine.texWidth * startY + startX) * 4; //int brushPixel = 0; bool skip = false; //float yy =0; //float xx =0; //int pixel2 = 0; for (int y = 0; y < paintEngine.customBrushHeight; y++) { for (int x = 0; x < paintEngine.customBrushWidth; x++) { skip = false; if ((startX + x) > (paintEngine.texWidth - 2) || (startX + x) < -1) { skip = true; } if (pixel < 0 || pixel >= paintEngine.pixels.Length) { skip = true; // } if (!skip) { //TODO: add more modes paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; } pixel += 4; } //za x pixel = (paintEngine.texWidth * (startY == 0?-1:startY + y) + startX + 1) * 4; } //za y } //DrawRectabgle() end
} // DrawPatternCircle() //DRAW PROPER LINE ON TEXTURE public static void DrawLineBrush(Vector2 start, Vector2 end, int size, bool isPattern, byte[] patternSource, AdvancedMobilePaint paintEngine) { // int x0 = (int)start.x; int y0 = (int)start.y; int x1 = (int)end.x; int y1 = (int)end.y; // int dx= Mathf.Abs(x1-x0); // int dy= Mathf.Abs(y1-y0); int dy = (int)(y1 - y0); int dx = (int)(x1 - x0); int pixel = 0; //<--pixel cordinates on texture int y = 0; int x = 0; int pixel2 = 0; //<---pixel coordinate on pattern texture //draw "size" pixels wide vector line between points, uses current pattern bytes if "isPattern" is true { int stepx, stepy; if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; } if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } dy <<= 1; dx <<= 1; float fraction = 0; // // if (dx > dy) { fraction = dy - (dx >> 1); while (Mathf.Abs(x0 - x1) > 1) { if (fraction >= 0) { y0 += stepy; fraction -= dx; } x0 += stepx; fraction += dy; //tex.SetPixel(x0, y0, paintColor); if (x0 < paintEngine.texWidth && x0 >= 0 && y0 < paintEngine.texHeight && y0 >= 0) { pixel = paintEngine.texWidth * 4 * y0 + x0 * 4; if (!isPattern) { paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; } else { float yy = Mathf.Repeat(/*py+y*/ y0 /*+(y0-customBrushHeight/2f)*/, paintEngine.customPatternHeight); float xx = Mathf.Repeat(/*px+x*/ x0 /*+(x0-customBrushWidth/2f)*/, paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, /*patternBrushBytes*/ patternSource.Length); paintEngine.pixels[pixel] = /*patternBrushBytes*/ patternSource[pixel2]; paintEngine.pixels[pixel + 1] = /*patternBrushBytes*/ patternSource[pixel2 + 1]; paintEngine.pixels[pixel + 2] = /*patternBrushBytes*/ patternSource[pixel2 + 2]; paintEngine.pixels[pixel + 3] = /*patternBrushBytes*/ patternSource[pixel2 + 3]; } } for (int i = 0; i < size; i++) { //tex.SetPixel(x0,y0-(size/2)+i,paintColor); y = y0 - (size / 2) + i; pixel = paintEngine.texWidth * 4 * y + x0 * 4; if (x0 < paintEngine.texWidth && x0 >= 0 && y < paintEngine.texHeight && y >= 0) { //try{ if (!isPattern) { paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; } else { float yy = Mathf.Repeat(/*py+y*/ y /*+(y0-customBrushHeight/2f)*/, paintEngine.customPatternHeight); float xx = Mathf.Repeat(/*px+x*/ x0 /*+(x0-customBrushWidth/2f)*/, paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, /*patternBrushBytes*/ patternSource.Length); paintEngine.pixels[pixel] = /*patternBrushBytes*/ patternSource[pixel2]; paintEngine.pixels[pixel + 1] = /*patternBrushBytes*/ patternSource[pixel2 + 1]; paintEngine.pixels[pixel + 2] = /*patternBrushBytes*/ patternSource[pixel2 + 2]; paintEngine.pixels[pixel + 3] = /*patternBrushBytes*/ patternSource[pixel2 + 3]; } //} // catch(Exception e) // { // Debug.Log ("ERROR ON PIXEL " + pixel.ToString() + " WITH ( "+y.ToString()+" , "+x0.ToString()+" )"); // } } } } } else { fraction = dx - (dy >> 1); while (Mathf.Abs(y0 - y1) > 1) { if (fraction >= 0) { x0 += stepx; fraction -= dy; } y0 += stepy; fraction += dx; //tex.SetPixel(x0, y0, paintColor); if (x0 < paintEngine.texWidth && x0 >= 0 && y0 < paintEngine.texHeight && y0 >= 0) { pixel = paintEngine.texWidth * 4 * y0 + x0 * 4; if (!isPattern) { paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; } else { float yy = Mathf.Repeat(/*py+y*/ y0 /*+(y0-customBrushHeight/2f)*/, paintEngine.customPatternHeight); float xx = Mathf.Repeat(/*px+x*/ x0 /*+(x0-customBrushWidth/2f)*/, paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, /*patternBrushBytes*/ patternSource.Length); paintEngine.pixels[pixel] = /*patternBrushBytes*/ patternSource[pixel2]; paintEngine.pixels[pixel + 1] = /*patternBrushBytes*/ patternSource[pixel2 + 1]; paintEngine.pixels[pixel + 2] = /*patternBrushBytes*/ patternSource[pixel2 + 2]; paintEngine.pixels[pixel + 3] = /*patternBrushBytes*/ patternSource[pixel2 + 3]; } } for (int i = 0; i < size; i++) { //tex.SetPixel(x0,y0-(size/2)+i,paintColor); x = x0 - (size / 2) + i; pixel = paintEngine.texWidth * 4 * y0 + x * 4; if (x < paintEngine.texWidth && x >= 0 && y0 < paintEngine.texHeight && y0 >= 0) { if (!isPattern) { paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; } else { float yy = Mathf.Repeat(/*py+y*/ y0 /*+(y0-customBrushHeight/2f)*/, paintEngine.customPatternHeight); float xx = Mathf.Repeat(/*px+x*/ x /*+(x0-customBrushWidth/2f)*/, paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, /*patternBrushBytes*/ patternSource.Length); paintEngine.pixels[pixel] = /*patternBrushBytes*/ patternSource[pixel2]; paintEngine.pixels[pixel + 1] = /*patternBrushBytes*/ patternSource[pixel2 + 1]; paintEngine.pixels[pixel + 2] = /*patternBrushBytes*/ patternSource[pixel2 + 2]; paintEngine.pixels[pixel + 3] = /*patternBrushBytes*/ patternSource[pixel2 + 3]; } } } } } } //tex.LoadRawTextureData(pixels); //tex.Apply(); }
} //end of function : DrawCustomBrush2 /// <summary> /// Draws the pattern circle. /// </summary> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> public static void DrawPatternCircle(int x, int y, byte[] patternSource, int size, AdvancedMobilePaint paintEngine) { //Debug.Log ("DrawPatternCircle "+ x +" ,"+y); if (!paintEngine.canDrawOnBlack) { if (paintEngine.pixels[(paintEngine.texWidth * y + x) * 4] == 0 && paintEngine.pixels[(paintEngine.texWidth * y + x) * 4 + 1] == 0 && paintEngine.pixels[(paintEngine.texWidth * y + x) * 4 + 2] == 0 && paintEngine.pixels[(paintEngine.texWidth * y + x) * 4 + 3] != 0) { return; } } int pixel = 0; // draw fast circle: int r2 = size * size; //povrsina kruga int area = r2 << 2; //sve rgb vrednosti koje cine povrsinu kruga -piksela u krugu int rr = size << 1; //precnik kruga int tx = 0; int ty = 0; float yy = 0; float xx = 0; int pixel2 = 0; float lerpVal = 1f; for (int i = 0; i < area; i++) { /*int*/ tx = (i % rr) - size; /*int*/ ty = (i / rr) - size; if (tx * tx + ty * ty < r2) //(if in circle) { if (x + tx < 0 || y + ty < 0 || x + tx >= paintEngine.texWidth || y + ty >= paintEngine.texHeight) { continue; // temporary fix for corner painting } pixel = (paintEngine.texWidth * (y + ty) + x + tx) * 4; // << 2 //if(pixel<0 || pixel>pixels.Length) continue; if (paintEngine.useAdditiveColors) { // additive over white also if (!paintEngine.useLockArea || (paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1)) { /*float*/ yy = Mathf.Repeat(y + ty, paintEngine.customPatternWidth); /*float*/ xx = Mathf.Repeat(x + tx, paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, paintEngine.patternBrushBytes.Length); lerpVal = patternSource[pixel2 + 3] / 255f * paintEngine.brushAlphaStrength; paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], patternSource[pixel2], lerpVal /*patternSource[pixel2+3]/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], patternSource[pixel2 + 1], lerpVal /*patternSource[pixel2+3]/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], patternSource[pixel2 + 2], lerpVal /*patternSource[pixel2+3]/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], patternSource[pixel2 + 3], lerpVal /*patternSource[pixel2+3]/255f*paintEngine.brushAlphaStrength*/); } } else // no additive, just paint my colors { if (!paintEngine.useLockArea || (paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1)) { // TODO: pattern dynamic scalar value? /*float*/ yy = Mathf.Repeat(y + ty, paintEngine.customPatternWidth); /*float*/ xx = Mathf.Repeat(x + tx, paintEngine.customPatternWidth); //Debug.Log ("P"+xx+","+yy); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, paintEngine.patternBrushBytes.Length); paintEngine.pixels[pixel] = patternSource[pixel2]; //r paintEngine.pixels[pixel + 1] = patternSource[pixel2 + 1]; //g paintEngine.pixels[pixel + 2] = patternSource[pixel2 + 2]; //b paintEngine.pixels[pixel + 3] = patternSource[pixel2 + 3]; //a //} } } // if additive } // if in circle } // for area } // DrawPatternCircle()
/// <summary> /// Draws the custom brush (v2). /// </summary> /// <param name="px">Px.</param> /// <param name="py">Py.</param> public static void DrawCustomBrush2(int px, int py, AdvancedMobilePaint paintEngine) { // TODO: this function needs comments/info.. //Debug.Log ("DrawCustomBrush2"); // get position where we paint int startX = /*(int)*/ (px - paintEngine.customBrushWidth / 2); int startY = /*(int)*/ (py - paintEngine.customBrushHeight / 2); int pixel = (paintEngine.texWidth * startY + startX) * 4; int brushPixel = 0; bool skip = false; float yy = 0; float xx = 0; int pixel2 = 0; float lerpVal = 1f; lerpVal = paintEngine.paintColor.a / 255f * paintEngine.brushAlphaStrength; for (int y = 0; y < paintEngine.customBrushHeight; y++) { for (int x = 0; x < paintEngine.customBrushWidth; x++) { //brushColor = (customBrushPixels[x*customBrushWidth+y]); //FIX brushPixel = (paintEngine.customBrushWidth * (y) + x) * 4; skip = false; if ((startX + x) > (paintEngine.texWidth - 2) || (startX + x) < -1) { skip = true; } //if((startY+y)>(texWidth+2) || (startY+y)<-1 ) skip=true; if (pixel < 0 || pixel >= paintEngine.pixels.Length) { skip = true; // } if (brushPixel < 0 || brushPixel > paintEngine.customBrushBytes.Length) { skip = true; } if (!paintEngine.canDrawOnBlack && !skip) { if (paintEngine.pixels[pixel + 3] != 0 && paintEngine.pixels[pixel] == 0 && paintEngine.pixels[pixel + 1] == 0 && paintEngine.pixels[pixel + 2] == 0) { skip = true; } } // FIXME Cackano! Dodata provera da se ne iscrtavaju pikseli nisu transparentni na masci if (!paintEngine.canDrawOnBlack && !skip && paintEngine.useMaskLayerOnly) { if (paintEngine.maskPixels[pixel + 3] != 0) { skip = true; } } // brush alpha is over 0 in this pixel? if (paintEngine.customBrushBytes[brushPixel + 3] != 0 && !skip) //END FIX { // take alpha from brush? if (paintEngine.useCustomBrushAlpha) { if (paintEngine.useAdditiveColors) { // additive over white also if ((paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1) || !paintEngine.useLockArea) //this enables custom brushes using lock mask { lerpVal = paintEngine.customBrushBytes[brushPixel + 3] / 255f; switch (paintEngine.brushMode) { case BrushProperties.Clear: //TODO paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.clearColor.r, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.clearColor.g, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.clearColor.b, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.clearColor.a, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); break; case BrushProperties.Default: //TODO paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.paintColor.r, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.paintColor.g, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.paintColor.b, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.paintColor.a, lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); break; case BrushProperties.Simple: paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.customBrushBytes[brushPixel], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.customBrushBytes[brushPixel + 1], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.customBrushBytes[brushPixel + 2], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.customBrushBytes[brushPixel + 3], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); break; case BrushProperties.Pattern: //TODO /*float*/ yy = Mathf.Repeat(/*py+y*/ py + (y - paintEngine.customBrushHeight / 2f), paintEngine.customPatternHeight); /*float*/ xx = Mathf.Repeat(/*px+x*/ px + (x - paintEngine.customBrushWidth / 2f), paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, paintEngine.patternBrushBytes.Length); paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.patternBrushBytes[pixel2], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.patternBrushBytes[pixel2 + 1], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.patternBrushBytes[pixel2 + 2], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.patternBrushBytes[pixel2 + 3], lerpVal /*paintEngine.customBrushBytes[brushPixel+3]/255f*/); break; } } } else { //TODO // no additive colors if ((paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1) || !paintEngine.useLockArea) { switch (paintEngine.brushMode) { case BrushProperties.Clear: paintEngine.pixels[pixel] = paintEngine.clearColor.r; paintEngine.pixels[pixel + 1] = paintEngine.clearColor.g; paintEngine.pixels[pixel + 2] = paintEngine.clearColor.b; paintEngine.pixels[pixel + 3] = paintEngine.clearColor.a; break; case BrushProperties.Default: paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; break; case BrushProperties.Simple: paintEngine.pixels[pixel] = paintEngine.customBrushBytes[brushPixel]; paintEngine.pixels[pixel + 1] = paintEngine.customBrushBytes[brushPixel + 1]; paintEngine.pixels[pixel + 2] = paintEngine.customBrushBytes[brushPixel + 2]; paintEngine.pixels[pixel + 3] = paintEngine.customBrushBytes[brushPixel + 3]; break; case BrushProperties.Pattern: /*float*/ yy = Mathf.Repeat(/*py+y*/ py + (y - paintEngine.customBrushHeight / 2f), paintEngine.customPatternHeight); /*float*/ xx = Mathf.Repeat(/*px+x*/ px + (x - paintEngine.customBrushWidth / 2f), paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, paintEngine.patternBrushBytes.Length); //OVDE TODO //add ignore transparent pixels paintEngine.pixels[pixel] = paintEngine.patternBrushBytes[pixel2]; paintEngine.pixels[pixel + 1] = paintEngine.patternBrushBytes[pixel2 + 1]; paintEngine.pixels[pixel + 2] = paintEngine.patternBrushBytes[pixel2 + 2]; paintEngine.pixels[pixel + 3] = paintEngine.patternBrushBytes[pixel2 + 3]; break; } } } } else // use paint color alpha { if (paintEngine.useAdditiveColors) { if ((paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1) || !paintEngine.useLockArea) { switch (paintEngine.brushMode) { case BrushProperties.Clear: paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.clearColor.r, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.clearColor.g, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.clearColor.b, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.clearColor.a, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); break; case BrushProperties.Default: paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.paintColor.r, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.paintColor.g, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.paintColor.b, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.paintColor.a, lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); break; case BrushProperties.Simple: paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.customBrushBytes[brushPixel], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.customBrushBytes[brushPixel + 1], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.customBrushBytes[brushPixel + 2], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.customBrushBytes[brushPixel + 3], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); break; case BrushProperties.Pattern: /*float*/ yy = Mathf.Repeat(/*py+y*/ py + (y - paintEngine.customBrushHeight / 2f), paintEngine.customPatternHeight); /*float*/ xx = Mathf.Repeat(/*px+x*/ px + (x - paintEngine.customBrushWidth / 2f), paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, paintEngine.patternBrushBytes.Length); paintEngine.pixels[pixel] = (byte)Mathf.Lerp(paintEngine.pixels[pixel], paintEngine.patternBrushBytes[pixel2], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 1] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 1], paintEngine.patternBrushBytes[pixel2 + 1], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 2] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 2], paintEngine.patternBrushBytes[pixel2 + 2], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); paintEngine.pixels[pixel + 3] = (byte)Mathf.Lerp(paintEngine.pixels[pixel + 3], paintEngine.patternBrushBytes[pixel2 + 3], lerpVal /*paintEngine.paintColor.a/255f*paintEngine.brushAlphaStrength*/); break; } } } else // no additive colors { if ((paintEngine.useLockArea && paintEngine.lockMaskPixels[pixel] == 1) || !paintEngine.useLockArea) { switch (paintEngine.brushMode) { case BrushProperties.Clear: paintEngine.pixels[pixel] = paintEngine.clearColor.r; paintEngine.pixels[pixel + 1] = paintEngine.clearColor.g; paintEngine.pixels[pixel + 2] = paintEngine.clearColor.b; paintEngine.pixels[pixel + 3] = paintEngine.clearColor.a; break; case BrushProperties.Default: paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; break; case BrushProperties.Simple: paintEngine.pixels[pixel] = paintEngine.customBrushBytes[brushPixel]; paintEngine.pixels[pixel + 1] = paintEngine.customBrushBytes[brushPixel + 1]; paintEngine.pixels[pixel + 2] = paintEngine.customBrushBytes[brushPixel + 2]; paintEngine.pixels[pixel + 3] = paintEngine.customBrushBytes[brushPixel + 3]; break; case BrushProperties.Pattern: /*float*/ yy = Mathf.Repeat(/*py+y*/ py + (y - paintEngine.customBrushHeight / 2f), paintEngine.customPatternHeight); /*float*/ xx = Mathf.Repeat(/*px+x*/ px + (x - paintEngine.customBrushWidth / 2f), paintEngine.customPatternWidth); /*int*/ pixel2 = (int)Mathf.Repeat((paintEngine.customPatternWidth * xx + yy) * 4, paintEngine.patternBrushBytes.Length); paintEngine.pixels[pixel] = paintEngine.patternBrushBytes[pixel2]; paintEngine.pixels[pixel + 1] = paintEngine.patternBrushBytes[pixel2 + 1]; paintEngine.pixels[pixel + 2] = paintEngine.patternBrushBytes[pixel2 + 2]; paintEngine.pixels[pixel + 3] = paintEngine.patternBrushBytes[pixel2 + 3]; break; } } } } } // if alpha>0 pixel += 4; } // for x // pixel = (texWidth*(startY==0?1:startY+y)+startX+1)*4; pixel = (paintEngine.texWidth * (startY == 0?-1:startY + y) + startX + 1) * 4; //pixel = (texWidth*(startY==0?1:startY+y)+(startX==0?1:startX)+1)*4; } // for y } //end of function : DrawCustomBrush2
public static void FloodFillCopy(int x, int y, AdvancedMobilePaint paintEngine, byte[] pixels, byte newMark) { byte b = paintEngine.source[paintEngine.texWidth * y + x]; Queue <int> queue = new Queue <int>(); Queue <int> queue2 = new Queue <int>(); queue.Enqueue(x); queue2.Enqueue(y); while (queue.Count > 0) { int num = queue.Dequeue(); int num2 = queue2.Dequeue(); if (num2 - 1 > -1) { int num3 = paintEngine.texWidth * (num2 - 1) + num; int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num); queue2.Enqueue(num2 - 1); pixels[num4] = paintEngine.paintColor.r; pixels[num4 + 1] = paintEngine.paintColor.g; pixels[num4 + 2] = paintEngine.paintColor.b; pixels[num4 + 3] = paintEngine.paintColor.a; paintEngine.source[num3] = newMark; } } if (num + 1 < paintEngine.texWidth) { int num3 = paintEngine.texWidth * num2 + (num + 1); int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num + 1); queue2.Enqueue(num2); pixels[num4] = paintEngine.paintColor.r; pixels[num4 + 1] = paintEngine.paintColor.g; pixels[num4 + 2] = paintEngine.paintColor.b; pixels[num4 + 3] = paintEngine.paintColor.a; paintEngine.source[num3] = newMark; } } if (num - 1 > -1) { int num3 = paintEngine.texWidth * num2 + (num - 1); int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num - 1); queue2.Enqueue(num2); pixels[num4] = paintEngine.paintColor.r; pixels[num4 + 1] = paintEngine.paintColor.g; pixels[num4 + 2] = paintEngine.paintColor.b; pixels[num4 + 3] = paintEngine.paintColor.a; paintEngine.source[num3] = newMark; } } if (num2 + 1 < paintEngine.texHeight) { int num3 = paintEngine.texWidth * (num2 + 1) + num; int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num); queue2.Enqueue(num2 + 1); pixels[num4] = paintEngine.paintColor.r; pixels[num4 + 1] = paintEngine.paintColor.g; pixels[num4 + 2] = paintEngine.paintColor.b; pixels[num4 + 3] = paintEngine.paintColor.a; paintEngine.source[num3] = newMark; } } } }
public static List <int> FloodFillExtended(int x, int y, AdvancedMobilePaint paintEngine, Color32 newColor, byte newMark) { byte b = paintEngine.source[paintEngine.texWidth * y + x]; List <int> list = new List <int>(); Queue <int> queue = new Queue <int>(); Queue <int> queue2 = new Queue <int>(); queue.Enqueue(x); queue2.Enqueue(y); while (queue.Count > 0) { int num = queue.Dequeue(); int num2 = queue2.Dequeue(); if (num2 - 1 > -1) { int num3 = paintEngine.texWidth * (num2 - 1) + num; int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num); queue2.Enqueue(num2 - 1); paintEngine.pixels[num4] = newColor.r; paintEngine.pixels[num4 + 1] = newColor.g; paintEngine.pixels[num4 + 2] = newColor.b; paintEngine.pixels[num4 + 3] = newColor.a; paintEngine.source[num3] = newMark; list.Add(num3); } } if (num + 1 < paintEngine.texWidth) { int num3 = paintEngine.texWidth * num2 + (num + 1); int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num + 1); queue2.Enqueue(num2); paintEngine.pixels[num4] = newColor.r; paintEngine.pixels[num4 + 1] = newColor.g; paintEngine.pixels[num4 + 2] = newColor.b; paintEngine.pixels[num4 + 3] = newColor.a; paintEngine.source[num3] = newMark; list.Add(num3); } } if (num - 1 > -1) { int num3 = paintEngine.texWidth * num2 + (num - 1); int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num - 1); queue2.Enqueue(num2); paintEngine.pixels[num4] = newColor.r; paintEngine.pixels[num4 + 1] = newColor.g; paintEngine.pixels[num4 + 2] = newColor.b; paintEngine.pixels[num4 + 3] = newColor.a; paintEngine.source[num3] = newMark; list.Add(num3); } } if (num2 + 1 < paintEngine.texHeight) { int num3 = paintEngine.texWidth * (num2 + 1) + num; int num4 = num3 * 4; if (paintEngine.source[num3] == b) { queue.Enqueue(num); queue2.Enqueue(num2 + 1); paintEngine.pixels[num4] = newColor.r; paintEngine.pixels[num4 + 1] = newColor.g; paintEngine.pixels[num4 + 2] = newColor.b; paintEngine.pixels[num4 + 3] = newColor.a; paintEngine.source[num3] = newMark; list.Add(num3); } } } return(list); }
public IEnumerator SlowFill(int x, int y, AdvancedMobilePaint paintEngine, byte newMark) { UnityEngine.Debug.Log("FloodFill"); int scanBeforeUpdate = 1000; int index = 0; byte hitColorA = paintEngine.source[paintEngine.texWidth * y + x]; Queue <int> fillPointX = new Queue <int>(); Queue <int> fillPointY = new Queue <int>(); fillPointX.Enqueue(x); fillPointY.Enqueue(y); int pixel = 0; int sourceA = 0; while (fillPointX.Count > 0) { int ptsx = fillPointX.Dequeue(); int ptsy = fillPointY.Dequeue(); if (ptsy - 1 > -1) { sourceA = paintEngine.texWidth * (ptsy - 1) + ptsx; pixel = sourceA * 4; if (paintEngine.source[sourceA] == hitColorA) { fillPointX.Enqueue(ptsx); fillPointY.Enqueue(ptsy - 1); paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; paintEngine.source[sourceA] = newMark; } } if (ptsx + 1 < paintEngine.texWidth) { sourceA = paintEngine.texWidth * ptsy + (ptsx + 1); pixel = sourceA * 4; if (paintEngine.source[sourceA] == hitColorA) { fillPointX.Enqueue(ptsx + 1); fillPointY.Enqueue(ptsy); paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; paintEngine.source[sourceA] = newMark; } } if (ptsx - 1 > -1) { sourceA = paintEngine.texWidth * ptsy + (ptsx - 1); pixel = sourceA * 4; if (paintEngine.source[sourceA] == hitColorA) { fillPointX.Enqueue(ptsx - 1); fillPointY.Enqueue(ptsy); paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; paintEngine.source[sourceA] = newMark; } } if (ptsy + 1 < paintEngine.texHeight) { sourceA = paintEngine.texWidth * (ptsy + 1) + ptsx; pixel = sourceA * 4; if (paintEngine.source[sourceA] == hitColorA) { fillPointX.Enqueue(ptsx); fillPointY.Enqueue(ptsy + 1); paintEngine.pixels[pixel] = paintEngine.paintColor.r; paintEngine.pixels[pixel + 1] = paintEngine.paintColor.g; paintEngine.pixels[pixel + 2] = paintEngine.paintColor.b; paintEngine.pixels[pixel + 3] = paintEngine.paintColor.a; paintEngine.source[sourceA] = newMark; } } index++; if (index > scanBeforeUpdate) { index = 0; this.drawText.LoadRawTextureData(paintEngine.pixels); this.drawText.Apply(false); yield return(0); } } this.drawText.LoadRawTextureData(paintEngine.pixels); this.drawText.Apply(false); TLogger.Instance.Log(Time.realtimeSinceStartup - this.time); yield return(0); yield break; }