public TriangleFillingMode(FillingMode fm, bool randomfactors, bool vectorL, VectorNMode vectorN, bool textureFill, bool lightcolor) { this.fillingMode = fm; this.RandomFactors = randomfactors; this.IsDefaultVectorL = vectorL; this.vectorNMode = vectorN; this.IsTextureFill = textureFill; this.IsDefaulLightColor = lightcolor; VectorL = Globals.DefaultVectorL.Normalize(); //NonTexturedVectorN = Globals.DefaultVectorN; LightVector = new SimpleColor(Globals.LightColor).ConvertColorToVector(); ViewVector = Globals.ViewVector; KdFactor = 100d; MFactor = 1; }
private void SetNormalVectorBitmap(WriteableBitmap vectorNbitmap = null, IntPoint mousePosition = null) { //if (timer.IsEnabled == true) //{ // IsDefaultVectorL = true; //} if (IsTexturedVectorN == VectorNMode.Default) { NormalBitmapVector = new Vector3[heightBitmap, widthBitmap]; for (int i = 0; i < NormalBitmapVector.GetLength(0); i++) { for (int j = 0; j < NormalBitmapVector.GetLength(1); j++) { NormalBitmapVector[i, j] = Globals.DefaultVectorN; } } NormalWriteableBitmap = null; } else if (IsTexturedVectorN == VectorNMode.NormalMap) { NormalWriteableBitmap = vectorNbitmap; var NormalBitmapColor = new SimpleColor[heightBitmap, widthBitmap]; if (vectorNbitmap.PixelHeight != heightBitmap || vectorNbitmap.PixelWidth != widthBitmap) { var TMPBitmapColor = new SimpleColor[vectorNbitmap.PixelHeight, vectorNbitmap.PixelWidth]; Paint.ReadColorsFromBitmap(vectorNbitmap, TMPBitmapColor); for (int y = 0; y < heightBitmap; y++) { for (int x = 0; x < widthBitmap; x++) { NormalBitmapColor[y, x] = TMPBitmapColor[y % vectorNbitmap.PixelHeight, x % vectorNbitmap.PixelWidth]; } } } else { Paint.ReadColorsFromBitmap(vectorNbitmap, NormalBitmapColor); } NormalBitmapVector = SimpleColor.ConvertColorsToVectorsN(NormalBitmapColor); } else { //assumming Vector Table is ProperSize for (int y = 0; y < NormalBitmapVector.GetLength(0); y++) { for (int x = 0; x < NormalBitmapVector.GetLength(1); x++) { if (mousePosition.SquareLength(ref x, ref y) <= BubbleSquareRadius) { int dx = x - mousePosition.X; int dy = mousePosition.Y - y; double h = Math.Sqrt(dx * dx + dy * dy + BubbleSquareRadius); NormalBitmapVector[y, x].X = dx; NormalBitmapVector[y, x].Y = dy; NormalBitmapVector[y, x].Z = h; NormalBitmapVector[y, x].NormalizeInPlace(); } else { NormalBitmapVector[y, x].X = 0; NormalBitmapVector[y, x].Y = 0; NormalBitmapVector[y, x].Z = 1; } } } } triangleFillingMode.NormalBitmapVector = NormalBitmapVector; }
//paint polygon public static void PaintPolygon(List <SimplePoint> points, TriangleFillingMode fillingMode, ref double KdFactor, ref double KsFactor, ref int MFactor) { IntPoint[] pointsArray = new IntPoint[points.Count]; int[] indexes = new int[points.Count]; int i = 0; //fast (byte R, byte G, byte B)p0Fast = (0, 0, 0); (byte R, byte G, byte B)p1Fast = (0, 0, 0); (byte R, byte G, byte B)p2Fast = (0, 0, 0); int triangleField = 0; //hybrid SimpleColor c0Hybrid = new SimpleColor(); SimpleColor c1Hybrid = new SimpleColor(); SimpleColor c2Hybrid = new SimpleColor(); Vector3 v0Hybrid = new Vector3(); Vector3 v1Hybrid = new Vector3(); Vector3 v2Hybrid = new Vector3(); foreach (var item in points) { pointsArray[i] = new IntPoint(item.X, item.Y); if (pointsArray[i].X >= fillingMode.PictureBitmapColor.GetLength(1)) { pointsArray[i].X = fillingMode.PictureBitmapColor.GetLength(1) - 1; } if (pointsArray[i].Y >= fillingMode.PictureBitmapColor.GetLength(0)) { pointsArray[i].Y = fillingMode.PictureBitmapColor.GetLength(0) - 1; } indexes[i] = i; i++; } if (fillingMode.fillingMode == FillingMode.Fast) { p0Fast = CalculateResultColorInPoint(pointsArray[0].X, pointsArray[0].Y, fillingMode, ref KdFactor, ref KsFactor, ref MFactor); p1Fast = CalculateResultColorInPoint(pointsArray[1].X, pointsArray[1].Y, fillingMode, ref KdFactor, ref KsFactor, ref MFactor); p2Fast = CalculateResultColorInPoint(pointsArray[2].X, pointsArray[2].Y, fillingMode, ref KdFactor, ref KsFactor, ref MFactor); triangleField = IntPoint.CalculateTriangleField(pointsArray); } else if (fillingMode.fillingMode == FillingMode.Hybrid) { c0Hybrid = fillingMode.PictureBitmapColor[pointsArray[0].Y, pointsArray[0].X]; c1Hybrid = fillingMode.PictureBitmapColor[pointsArray[1].Y, pointsArray[1].X]; c2Hybrid = fillingMode.PictureBitmapColor[pointsArray[2].Y, pointsArray[2].X]; v0Hybrid = fillingMode.NormalBitmapVector[pointsArray[0].Y, pointsArray[0].X]; v1Hybrid = fillingMode.NormalBitmapVector[pointsArray[1].Y, pointsArray[1].X]; v2Hybrid = fillingMode.NormalBitmapVector[pointsArray[2].Y, pointsArray[2].X]; triangleField = IntPoint.CalculateTriangleField(pointsArray); } Array.Sort(indexes, (p1, p2) => { if (pointsArray[p1].Y > pointsArray[p2].Y) { return(1); } else if (pointsArray[p1].Y < pointsArray[p2].Y) { return(-1); } else if (pointsArray[p1].X > pointsArray[p2].X) { return(1); } else if (pointsArray[p1].X < pointsArray[p2].X) { return(-1); } return(0); }); List <(int ymax, double x, double m)> AET = new List <(int, double, double)>(); int ymin = pointsArray[indexes[0]].Y; int ymax = pointsArray[indexes[indexes.Length - 1]].Y; int startingIndex = 0; bool removeEdgesFromAET = false; for (int scanLineY = ymin; scanLineY <= ymax; scanLineY++) { for (int j = startingIndex; j < indexes.Length; j++) { if (pointsArray[indexes[j]].Y > scanLineY - 1) { break; } if (pointsArray[indexes[j]].Y == scanLineY - 1) { startingIndex++; int index = indexes[j]; int previousIndex = (indexes[j] - 1 + pointsArray.Length) % pointsArray.Length; int nextIndex = (indexes[j] + 1) % pointsArray.Length; if (pointsArray[previousIndex].Y >= pointsArray[indexes[j]].Y) { //dodaj krawedz Pi-1 Pi do AET int x = pointsArray[index].X; if (pointsArray[index].Y != pointsArray[previousIndex].Y) { double m = (double)(pointsArray[index].X - pointsArray[previousIndex].X) / (double)(pointsArray[index].Y - pointsArray[previousIndex].Y); AET.Add((pointsArray[previousIndex].Y, x, m)); } } else { //usun krawedz Pi-1 Pi z AET removeEdgesFromAET = true; } if (pointsArray[nextIndex].Y >= pointsArray[indexes[j]].Y) { //dodaj krawedz Pi+1 Pi do AET int x = pointsArray[index].X; if (pointsArray[nextIndex].Y != pointsArray[index].Y) { double m = (double)(pointsArray[nextIndex].X - pointsArray[index].X) / (double)(pointsArray[nextIndex].Y - pointsArray[index].Y); AET.Add((pointsArray[nextIndex].Y, x, m)); } } else { //usun krawedz Pi+1 Pi z AET removeEdgesFromAET = true; } if (removeEdgesFromAET == true) { AET.RemoveAll((aet) => { return(aet.ymax == scanLineY - 1); }); removeEdgesFromAET = false; } } } //uaktualnij AET //posortuj AET.Sort((p1, p2) => { if (p1.x > p2.x) { return(1); } else if (p1.x < p2.x) { return(-1); } else { return(0); } }); //wypelnij if (fillingMode.fillingMode == FillingMode.Direct) { FillScanLineDirect(scanLineY, AET, fillingMode, ref KdFactor, ref KsFactor, ref MFactor); } else if (fillingMode.fillingMode == FillingMode.Fast) { //policz kolory w wierzcholkach trojkat FillScanLineFast(scanLineY, AET, fillingMode, ref triangleField, pointsArray, ref p0Fast, ref p1Fast, ref p2Fast); } else//hybrid mode { FillScanLineHybrid(scanLineY, AET, fillingMode, ref triangleField, pointsArray, ref v0Hybrid, ref c0Hybrid, ref v1Hybrid, ref c1Hybrid, ref v2Hybrid, ref c2Hybrid, ref KdFactor, ref KsFactor, ref MFactor); } //uaktualnij x for (int k = 0; k < AET.Count; k++) { var aet = AET[k]; AET[k] = (aet.ymax, aet.x += aet.m, aet.m); } } }