Ejemplo n.º 1
0
        public Poly CopyPoly()
        {
            Poly p = new Poly();

            p.TextureID        = TextureID;
            p.NumberOfVertices = NumberOfVertices;
            p.plane            = plane;
            p.verts            = new Vertex[NumberOfVertices];
            Array.Copy(verts, p.verts, NumberOfVertices);
            return(p);
        }
Ejemplo n.º 2
0
        public Poly CopyList()
        {
            Poly p = CopyPoly();

            if (!IsLast)
            {
                p.AddPoly(Next.CopyList());
            }

            return(p);
        }
Ejemplo n.º 3
0
        public int GetNumberOfPolys()
        {
            Poly p       = Polys;
            int  uiCount = 0;

            while (p != null)
            {
                p = p.Next;
                uiCount++;
            }

            return(uiCount);
        }
Ejemplo n.º 4
0
        public void AddPoly(Poly poly)
        {
            if (Polys == null)
            {
                Polys = poly;
                return;
            }

            Poly p = Polys;
            while (!p.IsLast)
            {
                p = p.Next;
            }

            p.SetNext(poly);
        }
Ejemplo n.º 5
0
        public void CalculateAABB()
        {
            min = Polys.verts[0].p;
            max = Polys.verts[0].p;

            Poly p = Polys;

            for (int i = 0; i < GetNumberOfPolys; i++)
            {
                for (int j = 0; j < p.NumberOfVertices; j++)
                {
                    // Calculate min
                    if (p.verts[j].p.x < min.x)
                    {
                        min.x = p.verts[j].p.x;
                    }

                    if (p.verts[j].p.y < min.y)
                    {
                        min.y = p.verts[j].p.y;
                    }

                    if (p.verts[j].p.z < min.z)
                    {
                        min.z = p.verts[j].p.z;
                    }

                    // Calculate max
                    if (p.verts[j].p.x > max.x)
                    {
                        max.x = p.verts[j].p.x;
                    }

                    if (p.verts[j].p.y > max.y)
                    {
                        max.y = p.verts[j].p.y;
                    }

                    if (p.verts[j].p.z > max.z)
                    {
                        max.z = p.verts[j].p.z;
                    }
                }

                p = p.Next;
            }
        }
Ejemplo n.º 6
0
        public void SetNext(Poly poly)
        {
            if (IsLast)
            {
                Next = poly;
                return;
            }

            Poly p = poly;

            while (!p.IsLast)
            {
                p = p.Next;
            }

            p.SetNext(Next);
            Next = poly;
        }
Ejemplo n.º 7
0
        public void AddPoly(Poly pPoly_)
        {
            if (pPoly_ != null)
            {
                if (IsLast)
                {
                    Next = pPoly_;
                    return;
                }

                Poly p = Next;
                while (!p.IsLast)
                {
                    p = p.Next;
                }

                p.Next = pPoly_;
            }
        }
Ejemplo n.º 8
0
        public eCP ClassifyPoly(Poly poly)
        {
            bool  front = false, back = false;
            float dist;

            for (int i = 0; i < poly.NumberOfVertices; i++)
            {
                dist = Vector3.Dot(plane.n, poly.verts[i].p) + plane.d;

                if (dist > 0.001f)
                {
                    if (back)
                    {
                        return(eCP.SPLIT);
                    }

                    front = true;
                }
                else if (dist < -0.001f)
                {
                    if (front)
                    {
                        return(eCP.SPLIT);
                    }

                    back = true;
                }
            }

            if (front)
            {
                return(eCP.FRONT);
            }
            else if (back)
            {
                return(eCP.BACK);
            }

            return(eCP.ONPLANE);
        }
Ejemplo n.º 9
0
        public void ClipToBrush(Brush brush, bool clipOnPlane)
        {
            Poly polyList = null;
            Poly p = Polys;

            for (int i = 0; i < GetNumberOfPolys; i++)
            {
                Poly clippedPoly = brush.Polys.ClipToList(p, clipOnPlane);

                if (polyList == null)
                {
                    polyList = clippedPoly;
                }
                else
                {
                    polyList.AddPoly(clippedPoly);
                }

                p = p.Next;
            }

            Polys = polyList;
        }
Ejemplo n.º 10
0
        public void Load(Tokenizer tokenizer)
        {
            entityList.Clear();
            entities = 0;
            polygons = 0;
            textures = 0;

            while (tokenizer.PeekNextToken().Type != Tokenizer.TokenType.EndOfStream)
            {
                var token = tokenizer.GetNextToken();
                if (token.Type == Tokenizer.TokenType.StartBlock)
                {
                    Entity e         = new Entity();
                    Brush  brushList = null;

                    token = tokenizer.GetNextToken();
                    while (token.Type != Tokenizer.TokenType.EndBlock)
                    {
                        switch (token.Type)
                        {
                        case Tokenizer.TokenType.Value:     // Key/value pair
                            var value = tokenizer.GetNextToken();
                            if (value.Type == Tokenizer.TokenType.Value)
                            {
                                e.Properties.Add(token.Contents, value.Contents);
                            }
                            else
                            {
                                throw new FormatException(String.Format("Expected a value, received a {0}", value));
                            }
                            break;

                        case Tokenizer.TokenType.StartBlock:     // Brush

                            Brush b       = new Brush();
                            Face  faces   = null;
                            int   uiFaces = 0;

                            while (tokenizer.PeekNextToken().Type != Tokenizer.TokenType.EndBlock)
                            {
                                Face face = new Face();

                                Vector3 v1 = Vector3Extension.FromToken(tokenizer);
                                Vector3 v2 = Vector3Extension.FromToken(tokenizer);
                                Vector3 v3 = Vector3Extension.FromToken(tokenizer);
                                face.plane = new Plane(v1, v3, v2);

                                // TODO: read texture maybe?
                                string textureName = tokenizer.GetNextValue();

                                // parsing
                                int   xOffset  = Convert.ToInt32(tokenizer.GetNextValue());
                                int   yOffset  = Convert.ToInt32(tokenizer.GetNextValue());
                                int   rotation = Convert.ToInt32(tokenizer.GetNextValue());
                                float xScale   = Convert.ToSingle(tokenizer.GetNextValue());
                                float yScale   = Convert.ToSingle(tokenizer.GetNextValue());

                                face.texAxis = new Plane[]
                                {
                                    new Plane {
                                        d = xOffset
                                    },
                                    new Plane {
                                        d = yOffset
                                    }
                                };

                                face.texRotation = rotation;
                                face.texScale    = new float[] { xScale, yScale };

                                if (faces == null)
                                {
                                    // assign as the fist face
                                    faces = face;
                                }
                                else
                                {
                                    // add face to the list
                                    faces.AddFace(face);
                                }
                                uiFaces++;

                                //var newFace = new Face(v1, v2, v3, textureName, xOffset, yOffset, rotation, xScale, yScale);
                                //b.AddFace(newFace);
                            }

                            Poly polyList = faces.GetPolys();

                            // Sort vertices and calculate texture coordinates for every polygon
                            Poly pi = polyList;
                            Face f  = faces;

                            for (int c = 0; c < uiFaces; c++)
                            {
                                pi.plane     = f.plane;
                                pi.TextureID = f.texture.ID;

                                pi.SortVerticesCW();

                                //pi.CalculateTextureCoordinates(
                                //    f.texture.GetWidth,
                                //    f.texture.GetHeight,
                                //    f.texAxis[0], f.texAxis[1],
                                //    f.texScale[0], f.texScale[1]);

                                f  = f.Next;
                                pi = pi.Next;
                            }

                            b.AddPoly(polyList);
                            b.CalculateAABB();

                            if (brushList == null)
                            {
                                brushList = b;
                            }
                            else
                            {
                                Brush temp = brushList;
                                while (!temp.IsLast)
                                {
                                    temp = temp.Next;
                                }
                                temp.SetNext(b);
                            }

                            tokenizer.GetNextToken();     // Brush end block
                            break;

                        default:
                            throw new FormatException(String.Format("Expected either a block start or a value, received a {0}", token));
                        }
                        token = tokenizer.GetNextToken();
                    }

                    // End of entity

                    // Perform CSG union
                    if (brushList != null)
                    {
                        e.AddPoly(brushList.MergeList());
                        brushList = null;
                        polygons += e.GetNumberOfPolys();
                    }

                    entityList.Add(e);
                }
            }

            Console.WriteLine("Map created.");
            Console.WriteLine(" -" + entities + " entities loaded.");
            Console.WriteLine(" -" + polygons + " polygons loaded.");
        }
Ejemplo n.º 11
0
        public Poly MergeList()
        {
            Brush clippedList = CopyList();
            Brush clip = clippedList;
            Brush brush = null;
            Poly polyList = null;

            bool clipOnPlane = false;


            for (int i = 0; i < GetNumberOfBrushes; i++)
            {
                brush = this;
                clipOnPlane = false;

                for (int j = 0; j < GetNumberOfBrushes; j++)
                {
                    if (i == j)
                    {
                        clipOnPlane = true;
                    }
                    else
                    {
                        if (clip.AABBIntersect(brush))
                        {
                            clip.ClipToBrush(brush, clipOnPlane);
                        }
                    }

                    brush = brush.Next;
                }

                clip = clip.Next;
            }

            clip = clippedList;

            while (clip != null)
            {
                if (clip.GetNumberOfPolys != 0)
                {
                    // Extract brushes left over polygons and add them to the list
                    Poly p = clip.Polys.CopyList();

                    if (polyList == null)
                    {
                        polyList = p;
                    }
                    else
                    {
                        polyList.AddPoly(p);
                    }

                    clip = clip.Next;
                }
                else
                {
                    // Brush has no polygons and should be deleted
                    if (clip == clippedList)
                    {
                        clip = clippedList.Next;
                        clippedList.SetNext(null);
                        clippedList = clip;
                    }
                    else
                    {
                        Brush temp = clippedList;
                        while (temp != null)
                        {
                            if (temp.Next == clip)
                                break;

                            temp = temp.Next;
                        }

                        temp.Next = clip.Next;
                        clip.SetNext(null);
                        clip = temp.Next;
                    }
                }
            }

            return polyList;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Create the polygons from the faces
        /// </summary>
        public Poly GetPolys()
        {
            int  nFaces = 0;
            Face face   = this;

            while (face != null)
            {
                face = face.Next;
                nFaces++;
            }

            Poly polyList = null;
            Face lfi      = null;
            Face lfj      = null;
            Face lfk      = null;

            // Create polygons
            face = this;

            for (int c = 0; c < nFaces; c++)
            {
                if (polyList == null)
                {
                    polyList = new Poly();
                }
                else
                {
                    polyList.AddPoly(new Poly());
                }

                if (c == nFaces - 3)
                {
                    lfi = face.Next;
                }
                else if (c == nFaces - 2)
                {
                    lfj = face.Next;
                }
                else if (c == nFaces - 1)
                {
                    lfk = face.Next;
                }

                face = face.Next;
            }

            // Loop through faces and create polygons
            Poly pi = polyList;

            for (Face fi = this; fi != lfi; fi = fi.Next)
            {
                Poly pj = pi.Next;

                for (Face fj = fi.Next; fj != lfj; fj = fj.Next)
                {
                    Poly pk = pj.Next;

                    for (Face fk = fj.Next; fk != lfk; fk = fk.Next)
                    {
                        Vector3 p = Vector3.zero;

                        if (fi.plane.GetIntersection(fj.plane, fk.plane, ref p))
                        {
                            Face f = this;

                            while (true)
                            {
                                if (f.plane.ClassifyPoints(p) == Plane.eCP.FRONT)
                                {
                                    break;
                                }

                                if (!f.IsLast)
                                {
                                    Vertex v = new Vertex {
                                        p = p
                                    };

                                    pi.AddVertex(v);
                                    pj.AddVertex(v);
                                    pk.AddVertex(v);

                                    break;
                                }

                                f = f.Next;
                            }
                        }

                        pk = pk.Next;
                    }

                    pj = pj.Next;
                }

                pi = pi.Next;
            }

            return(polyList);
        }
Ejemplo n.º 13
0
        public Poly ClipToList(Poly poly, bool clipOnPlane)
        {
            switch (ClassifyPoly(poly))
            {
            case eCP.FRONT:
                return(poly.CopyPoly());

            case eCP.BACK:
                if (IsLast)
                {
                    return(null);
                }

                return(Next.ClipToList(poly, clipOnPlane));

            case eCP.ONPLANE:
                float angle = Vector3.Dot(plane.n, poly.plane.n) - 1;

                if (angle < Mathf.EPSILON && angle > -Mathf.EPSILON)
                {
                    if (!clipOnPlane)
                    {
                        return(poly.CopyPoly());
                    }
                }

                if (IsLast)
                {
                    return(null);
                }

                return(Next.ClipToList(poly, clipOnPlane));

            case eCP.SPLIT:
                Poly front = null;
                Poly back  = null;

                SplitPoly(poly, ref front, ref back);

                if (IsLast)
                {
                    return(front);
                }

                Poly backFrags = Next.ClipToList(back, clipOnPlane);

                if (backFrags == null)
                {
                    return(front);
                }

                if (backFrags == back)
                {
                    return(poly.CopyPoly());
                }

                front.AddPoly(backFrags);

                return(front);
            }

            return(null);
        }
Ejemplo n.º 14
0
        public void SplitPoly(Poly poly, ref Poly front, ref Poly back)
        {
            Plane.eCP[] cp = new Plane.eCP[poly.NumberOfVertices];

            // classify all points
            for (int i = 0; i < poly.NumberOfVertices; i++)
            {
                cp[i] = plane.ClassifyPoints(poly.verts[i].p);
            }

            // builds fragments
            Poly newFront = new Poly();
            Poly newBack  = new Poly();

            newFront.TextureID = poly.TextureID;
            newBack.TextureID  = poly.TextureID;
            newFront.plane     = poly.plane;
            newBack.plane      = poly.plane;

            for (int i = 0; i < poly.NumberOfVertices; i++)
            {
                // Add point to appropriate list
                switch (cp[i])
                {
                case Plane.eCP.FRONT:
                    newFront.AddVertex(poly.verts[i]);
                    break;

                case Plane.eCP.BACK:
                    newBack.AddVertex(poly.verts[i]);
                    break;

                case Plane.eCP.ONPLANE:
                    newFront.AddVertex(poly.verts[i]);
                    newBack.AddVertex(poly.verts[i]);
                    break;
                }

                // Check if edges should be split
                int  iNext  = i + 1;
                bool ignore = false;

                if (i == (poly.NumberOfVertices - 1))
                {
                    iNext = 0;
                }

                if (cp[i] == Plane.eCP.ONPLANE && cp[iNext] != Plane.eCP.ONPLANE)
                {
                    ignore = true;
                }
                else if (cp[iNext] == Plane.eCP.ONPLANE && cp[i] != Plane.eCP.ONPLANE)
                {
                    ignore = true;
                }

                if (!ignore && (cp[i] != cp[iNext]))
                {
                    Vertex v = new Vertex();    // New vertex created by splitting
                    float  p = 0f;              // Percentage between the two points

                    plane.GetIntersection(poly.verts[i].p, poly.verts[iNext].p, v.p, p);

                    v.tex[0] = poly.verts[iNext].tex[0] - poly.verts[i].tex[0];
                    v.tex[1] = poly.verts[iNext].tex[1] - poly.verts[i].tex[1];

                    v.tex[0] = poly.verts[i].tex[0] + (p * v.tex[0]);
                    v.tex[1] = poly.verts[i].tex[1] + (p * v.tex[1]);

                    newFront.AddVertex(v);
                    newBack.AddVertex(v);
                }
            }

            newFront.CalculatePlane();
            newBack.CalculatePlane();

            front = newFront;
            back  = newBack;
        }