예제 #1
0
        public void BINReader(string file)
        {
            IO = File.OpenReader(file + ".bin");

            int aetSetsLength = IO.ReadInt32();
            int aetSetsOffset = IO.ReadInt32();
            int aetsLength    = IO.ReadInt32();
            int aetsOffset    = IO.ReadInt32();

            IO.Position = aetSetsOffset;
            AetSets     = new AetSet[aetSetsLength];
            for (i = 0; i < aetSetsLength; i++)
            {
                AetSets[i].Id       = IO.ReadInt32();
                AetSets[i].Name     = IO.ReadStringAtOffset();
                AetSets[i].FileName = IO.ReadStringAtOffset();
                IO.ReadInt32();
                AetSets[i].SpriteSetId = IO.ReadInt32();
            }

            int setIndex;
            AET aet = new AET();

            int[] AetCount = new int[aetSetsLength];

            IO.Position = aetsOffset;
            for (i = 0; i < aetsLength; i++)
            {
                IO.LongPosition += 10;
                setIndex         = IO.ReadInt16();
                AetCount[setIndex]++;
            }

            for (int i = 0; i < aetSetsLength; i++)
            {
                AetSets[i].Aets = new AET[AetCount[i]];
                AetCount[i]     = 0;
            }

            IO.Position = aetsOffset;
            for (i = 0; i < aetsLength; i++)
            {
                aet.Id   = IO.ReadInt32();
                aet.Name = IO.ReadStringAtOffset();
                IO.ReadInt16();
                setIndex = IO.ReadInt16();

                AetSets[setIndex].Aets[AetCount[setIndex]] = aet; AetCount[setIndex]++;
            }

            IO.Close();
        }
예제 #2
0
        public void BINReader(string file)
        {
            _IO = File.OpenReader(file + ".bin");

            int aetSetsLength = _IO.RI32();
            int aetSetsOffset = _IO.RI32();
            int aetsLength    = _IO.RI32();
            int aetsOffset    = _IO.RI32();

            _IO.P   = aetSetsOffset;
            AetSets = new AetSet[aetSetsLength];
            for (i = 0; i < aetSetsLength; i++)
            {
                AetSets[i].Id       = _IO.RI32();
                AetSets[i].Name     = _IO.RSaO();
                AetSets[i].FileName = _IO.RSaO();
                _IO.RI32();
                AetSets[i].SpriteSetId = _IO.RI32();
            }

            int setIndex;
            AET aet = new AET();

            int[] AetCount = new int[aetSetsLength];

            _IO.P = aetsOffset;
            for (i = 0; i < aetsLength; i++)
            {
                _IO.I64P += 10;
                setIndex  = _IO.RI16();
                AetCount[setIndex]++;
            }

            for (int i = 0; i < aetSetsLength; i++)
            {
                AetSets[i].Aets = new AET[AetCount[i]];
                AetCount[i]     = 0;
            }

            _IO.P = aetsOffset;
            for (i = 0; i < aetsLength; i++)
            {
                aet.Id   = _IO.RI32();
                aet.Name = _IO.RSaO();
                _IO.RI16();
                setIndex = _IO.RI16();

                AetSets[setIndex].Aets[AetCount[setIndex]] = aet; AetCount[setIndex]++;
            }

            _IO.C();
        }
예제 #3
0
        private void FillPolygonHybrid(Triangle triangle, double kd, double ks, double m)
        {
            List <Edge> edges = triangle.GetEdges();

            List <Edge>[] ET           = EdgeBucketSort(edges);
            int           edgesCounter = edges.Count;
            int           y            = 0;

            while (ET[y] == null)
            {
                y++;
            }

            List <(double yMax, double xMin, double m)> AET = new List <(double, double, double)>();

            List <(Point, Color, Vector3D)> triangle_vertex = new List <(Point, Color, Vector3D)>();

            for (int i = 0; i < 3; i++)
            {
                Point p;
                if (i == 0)
                {
                    p = triangle.p1;
                }
                else if (i == 1)
                {
                    p = triangle.p2;
                }
                else
                {
                    p = triangle.p3;
                }

                Color objectColor = constColor;
                if (isColorFromTexture)
                {
                    objectColor = photo[p.X, p.Y];
                }

                Vector3D normalVector = new Vector3D(0, 0, 1);
                if (isNormalVectorFromMap)
                {
                    normalVector = FromNormalMapToVector(normalMap[p.X, p.Y]);
                }
                else if (isNormalVectorFromBubble)
                {
                    normalVector = GetNormalVectorFromBubble(p.X, p.Y);
                }

                Vector3D newL = CalculateLVector(new Vector3D(p.X, p.Y, 0));

                int R = (int)GetLambertColor(((double)lightColor.R / (double)255), objectColor.R, newL, normalVector, ks, kd, m);
                int G = (int)GetLambertColor(((double)lightColor.G / (double)255), objectColor.G, newL, normalVector, ks, kd, m);
                int B = (int)GetLambertColor(((double)lightColor.B / (double)255), objectColor.B, newL, normalVector, ks, kd, m);

                FixRGB(ref R, ref G, ref B);

                Color newColor = Color.FromArgb(R, G, B);

                triangle_vertex.Add((p, newColor, normalVector));
            }

            double area = CalculateTriangleArea(triangle.p1, triangle.p2, triangle.p3);

            while (edgesCounter != 0 || AET.Any())
            {
                AET.RemoveAll(x => x.yMax == y);

                if (ET[y] != null)
                {
                    foreach (Edge edge in ET[y])
                    {
                        double mx = ((double)edge.p2.X - (double)edge.p1.X) / ((double)edge.p2.Y - (double)edge.p1.Y);

                        if (edge.p1.Y != edge.p2.Y)
                        {
                            AET.Add((edge.p2.Y, edge.p1.X, mx));
                        }

                        edgesCounter--;
                    }
                }

                AET.Sort((a, b) => a.xMin.CompareTo(b.xMin));

                for (int i = 0; i < AET.Count; i += 2)
                {
                    for (int j = (int)(AET[i].xMin); j < (int)(AET[i + 1].xMin); j++)
                    {
                        (Color color, Vector3D vector)interpolate_values = CalculateInterpolateColorAndVertex(area, triangle_vertex, j, y);

                        Vector3D newL = CalculateLVector(new Vector3D(j, y, 0));

                        int R = (int)GetLambertColor(((double)lightColor.R / (double)255), interpolate_values.color.R, newL, interpolate_values.vector, ks, kd, m);
                        int G = (int)GetLambertColor(((double)lightColor.G / (double)255), interpolate_values.color.G, newL, interpolate_values.vector, ks, kd, m);
                        int B = (int)GetLambertColor(((double)lightColor.B / (double)255), interpolate_values.color.B, newL, interpolate_values.vector, ks, kd, m);

                        FixRGB(ref R, ref G, ref B);

                        Color newColor = Color.FromArgb(R, G, B);

                        newPhoto[j, y] = newColor;
                    }
                }

                y++;

                for (int i = 0; i < AET.Count; i++)
                {
                    AET[i] = (AET[i].yMax, AET[i].xMin + AET[i].m, AET[i].m);
                }
            }
        }
예제 #4
0
        void FillTriangle(int i)
        {
            int[] Tab = new int[3];
            int   ymin;

            triangles[i].Vertex.CopyTo(Tab, 0);
            for (int j = 0; j < 2; j++)
            {
                ymin = Vertices[Tab[j]].Y;
                int ind = j;
                for (int k = j + 1; k < 3; k++)
                {
                    if (ymin > Vertices[Tab[k]].Y)
                    {
                        ind  = k;
                        ymin = Vertices[Tab[k]].Y;
                    }
                }
                int tmp = Tab[ind];
                Tab[ind] = Tab[j];
                Tab[j]   = tmp;
            }
            ymin = Vertices[Tab[0]].Y;
            int ymax = Vertices[Tab[2]].Y;
            List <(double, double, double)> AET = new List <(double, double, double)>();

            if (los)
            {
                Random rnd = new Random();
                Kd = (double)rnd.Next(0, 10) / 10;
                Ks = (double)rnd.Next(0, 10) / 10;
                m  = rnd.Next(0, 100);
            }
            if (DIH == 2)
            {
                Interpolation(triangles[i]);
            }
            if (DIH == 3)
            {
                Hybryda(triangles[i]);
            }
            for (int y = ymin; y <= ymax; y++)
            {
                for (int t = 0; t < Tab.Length; t++)
                {
                    if (y == Vertices[Tab[t]].Y)
                    {
                        int prev = t - 1;
                        if (prev == -1)
                        {
                            prev = Tab.Length - 1;
                        }

                        if (Vertices[Tab[prev]].Y >= Vertices[Tab[t]].Y)
                        {
                            if ((Vertices[Tab[prev]].Y - Vertices[Tab[t]].Y) != 0)
                            {
                                AET.Add((Vertices[Tab[prev]].Y, Vertices[Tab[t]].X, ((double)(Vertices[Tab[prev]].X - Vertices[Tab[t]].X) / (double)(Vertices[Tab[prev]].Y - Vertices[Tab[t]].Y))));
                            }
                        }
                        else
                        {
                            for (int z = 0; z < AET.Count(); z++)
                            {
                                if (AET[z].Item1 == y)
                                {
                                    FillPixel((int)AET[z].Item2, y, i);
                                    AET.RemoveAt(z);
                                }
                            }
                        }
                        int next = (t + 1) % Tab.Length;

                        if (Vertices[Tab[next]].Y >= Vertices[Tab[t]].Y)
                        {
                            if ((Vertices[Tab[next]].Y - Vertices[Tab[t]].Y) != 0)
                            {
                                double xd = (Vertices[Tab[next]].X - Vertices[Tab[t]].X);
                                double wx = (Vertices[Tab[next]].Y - Vertices[Tab[t]].Y);
                                double eq = xd / wx;
                                AET.Add((Vertices[Tab[next]].Y, Vertices[Tab[t]].X, ((double)(Vertices[Tab[next]].X - Vertices[Tab[t]].X) / (double)(Vertices[Tab[next]].Y - Vertices[Tab[t]].Y))));
                            }
                        }
                        else
                        {
                            for (int z = 0; z < AET.Count(); z++)
                            {
                                if (AET[z].Item1 == y)
                                {
                                    FillPixel((int)AET[z].Item2, y, i);
                                    AET.RemoveAt(z);
                                }
                            }
                        }
                    }
                }
                for (int j = 0; j < AET.Count() - 1; j++)
                {
                    double xmin = AET[j].Item2;
                    int    ind  = j;
                    for (int k = j + 1; k < AET.Count(); k++)
                    {
                        if (xmin > AET[k].Item2)
                        {
                            ind  = k;
                            xmin = AET[k].Item2;
                        }
                    }
                    List <(double, double, double)> tmp = new List <(double, double, double)>(AET);
                    AET[ind] = AET[j];
                    AET[j]   = tmp[ind];
                }

                for (int g = 0; g < AET.Count - 1; g += 2)
                {
                    for (int j = (int)AET[g].Item2; j <= (AET[g + 1].Item2); j++)
                    {
                        FillPixel(j, y, i);
                    }
                }
                for (int j = 0; j < AET.Count(); j++)
                {
                    AET[j] = (AET[j].Item1, AET[j].Item2 + AET[j].Item3, AET[j].Item3);
                }
            }
        }
예제 #5
0
        private void FillPolygonNormal(List <Edge> edges, double kd, double ks, double m)
        {
            List <Edge>[] ET           = EdgeBucketSort(edges);
            int           edgesCounter = edges.Count;
            int           y            = 0;

            while (ET[y] == null)
            {
                y++;
            }

            List <(double yMax, double xMin, double m)> AET = new List <(double, double, double)>();

            while (edgesCounter != 0 || AET.Any())
            {
                AET.RemoveAll(x => x.yMax == y);

                if (ET[y] != null)
                {
                    foreach (Edge edge in ET[y])
                    {
                        double mx = ((double)edge.p2.X - (double)edge.p1.X) / ((double)edge.p2.Y - (double)edge.p1.Y);

                        if (edge.p1.Y != edge.p2.Y)
                        {
                            AET.Add((edge.p2.Y, edge.p1.X, mx));
                        }

                        edgesCounter--;
                    }
                }

                AET.Sort((a, b) => a.xMin.CompareTo(b.xMin));

                for (int i = 0; i < AET.Count; i += 2)
                {
                    for (int j = (int)(AET[i].xMin); j < (int)(AET[i + 1].xMin); j++)
                    {
                        Color objectColor = constColor;
                        if (isColorFromTexture)
                        {
                            objectColor = photo[j, y];
                        }

                        Vector3D normalVector = new Vector3D(0, 0, 1);
                        if (isNormalVectorFromMap)
                        {
                            normalVector = FromNormalMapToVector(normalMap[j, y]);
                        }
                        else if (isNormalVectorFromBubble)
                        {
                            normalVector = GetNormalVectorFromBubble(j, y);
                        }

                        Vector3D newL = CalculateLVector(new Vector3D(j, y, 0));

                        int R = (int)GetLambertColor(((double)lightColor.R / (double)255), objectColor.R, newL, normalVector, ks, kd, m);
                        int G = (int)GetLambertColor(((double)lightColor.G / (double)255), objectColor.G, newL, normalVector, ks, kd, m);
                        int B = (int)GetLambertColor(((double)lightColor.B / (double)255), objectColor.B, newL, normalVector, ks, kd, m);

                        FixRGB(ref R, ref G, ref B);

                        Color newColor = Color.FromArgb(R, G, B);

                        newPhoto[j, y] = newColor;
                    }
                }

                y++;

                for (int i = 0; i < AET.Count; i++)
                {
                    AET[i] = (AET[i].yMax, AET[i].xMin + AET[i].m, AET[i].m);
                }
            }
        }
예제 #6
0
        //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);
                }
            }
        }