Esempio n. 1
0
        private void LoadVisgroups(MapFile map, SerialisedObject so)
        {
            var vis = new Visgroup();

            LoadVisgroupsRecursive(so, vis);
            map.Visgroups.AddRange(vis.Children);
        }
Esempio n. 2
0
 private void LoadVisgroups(Map map, SerialisedObject visgroups)
 {
     if (visgroups == null)
     {
         return;
     }
     foreach (var vg in visgroups.Children.Where(x => x.Name?.ToLower() == "visgroup"))
     {
         var v = new Visgroup
         {
             Name    = vg.Get("name", ""),
             ID      = vg.Get("visgroupid", -1),
             Colour  = vg.GetColor("color"),
             Visible = true
         };
         if (v.Colour.GetBrightness() < 0.001f)
         {
             v.Colour = Colour.GetRandomBrushColour();
         }
         if (v.ID < 0)
         {
             continue;
         }
         map.Data.Add(v);
     }
 }
Esempio n. 3
0
        private void ReadVisgroups(Map map, BinaryReader br)
        {
            var list         = new List <Visgroup>();
            var numVisgroups = br.ReadInt32();

            for (var i = 0; i < numVisgroups; i++)
            {
                var vis = new Visgroup
                {
                    Name    = br.ReadFixedLengthString(Encoding.ASCII, 128),
                    Colour  = br.ReadRGBAColour(),
                    ID      = br.ReadInt32(),
                    Visible = br.ReadBoolean()
                };
                vis.Colour = Color.FromArgb(255, vis.Colour);
                map.NumberGenerator.Seed("Visgroup", vis.ID);
                br.ReadBytes(3);
                list.Add(vis);
            }

            // Get rid of zero groups
            foreach (var vg in list.Where(x => x.ID == 0))
            {
                vg.ID = map.NumberGenerator.Next("Visgroup");
            }

            map.Data.AddRange(list);
        }
Esempio n. 4
0
        private void AddNode(TreeNode parent, Visgroup visgroup, Func <Visgroup, string> getCheckState)
        {
            if (!ShowHidden && visgroup is AutoVisgroup && ((AutoVisgroup)visgroup).IsHidden)
            {
                return;
            }
            if (HideAutomatic && visgroup.IsAutomatic)
            {
                return;
            }
            var node = new TreeNode(visgroup.Name)
            {
                StateImageKey = getCheckState(visgroup) + (DisableAutomatic && visgroup.IsAutomatic ? "Disabled" : ""),
                BackColor     = visgroup.Colour,
                Tag           = visgroup.ID
            };

            if (parent == null)
            {
                VisgroupTree.Nodes.Add(node);
            }
            else
            {
                parent.Nodes.Add(node);
            }

            foreach (var vg in Sort(visgroup.Children))
            {
                AddNode(node, vg, getCheckState);
            }
        }
Esempio n. 5
0
        private static IEnumerable <Visgroup> ReadVisgroups(BinaryReader br)
        {
            var list         = new List <Visgroup>();
            var numVisgroups = br.ReadInt32();

            for (var i = 0; i < numVisgroups; i++)
            {
                var vis = new Visgroup
                {
                    Name    = br.ReadFixedLengthString(Encoding.UTF8, 128),
                    Colour  = br.ReadRGBAColour(),
                    ID      = br.ReadInt32(),
                    Visible = br.ReadBoolean()
                };
                vis.Colour = Color.FromArgb(255, vis.Colour);
                br.ReadBytes(3);
                list.Add(vis);
            }
            // Get rid of zero groups
            foreach (var vg in list.Where(x => x.ID == 0))
            {
                vg.ID = list.Max(x => x.ID) + 1;
            }
            return(list);
        }
Esempio n. 6
0
        public void VisgroupCreateNew()
        {
            using (var qf = new QuickForm("Create New Visgroup")
            {
                UseShortcutKeys = true
            }.TextBox("Name").CheckBox("Add selection to visgroup", true).OkCancel()) {
                if (qf.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                var ids = _document.Map.Visgroups.Where(x => !x.IsAutomatic).Select(x => x.ID).ToList();
                var id  = Math.Max(1, ids.Any() ? ids.Max() + 1 : 1);

                var name = qf.String("Name");
                if (String.IsNullOrWhiteSpace(name))
                {
                    name = "Visgroup " + id.ToString();
                }

                var vg = new Visgroup {
                    ID      = id,
                    Colour  = Colour.GetRandomLightColour(),
                    Name    = name,
                    Visible = true
                };
                IAction action = new CreateEditDeleteVisgroups(new[] { vg }, new Visgroup[0], new Visgroup[0]);
                if (qf.Bool("Add selection to visgroup") && !_document.Selection.IsEmpty())
                {
                    action = new ActionCollection(action, new EditObjectVisgroups(_document.Selection.GetSelectedObjects(), new[] { id }, new int[0]));
                }
                _document.PerformAction("Create visgroup", action);
            }
        }
Esempio n. 7
0
        private static GenericStructure WriteVisgroup(Visgroup visgroup)
        {
            var ret = new GenericStructure("visgroup");

            ret["name"]       = visgroup.Name;
            ret["visgroupid"] = visgroup.ID.ToString(CultureInfo.InvariantCulture);
            ret["color"]      = FormatColor(visgroup.Colour);
            return(ret);
        }
Esempio n. 8
0
        private static Visgroup ReadVisgroup(GenericStructure visgroup)
        {
            var v = new Visgroup {
                Name    = visgroup["name"],
                ID      = visgroup.PropertyInteger("visgroupid"),
                Colour  = visgroup.PropertyColour("color", Colour.GetRandomBrushColour()),
                Visible = true
            };

            return(v);
        }
Esempio n. 9
0
 private void LoadVisgroupsRecursive(SerialisedObject so, Visgroup parent)
 {
     foreach (var vg in so.Children.Where(x => string.Equals(x.Name, "visgroup", StringComparison.InvariantCultureIgnoreCase)))
     {
         var v = new Visgroup
         {
             Name    = vg.Get("name", ""),
             ID      = vg.Get("visgroupid", -1),
             Color   = vg.GetColor("color"),
             Visible = true
         };
         LoadVisgroupsRecursive(vg, v);
         parent.Children.Add(v);
     }
 }
        static void ReadVisgroups(MapFile map, BinaryReader br)
        {
            int numVisgroups = br.ReadInt32();

            for (int i = 0; i < numVisgroups; i++)
            {
                Visgroup vis = new Visgroup
                {
                    Name    = ReadString(br),
                    ID      = br.ReadInt32(),
                    Color   = br.ReadRGBAColour(),
                    Visible = br.ReadBoolean()
                };
                map.Visgroups.Add(vis);
            }
        }
Esempio n. 11
0
        private void AddGroup(object sender, EventArgs e)
        {
            var newGroup = new Visgroup
            {
                ID      = GetNewID(),
                Colour  = Colour.GetRandomLightColour(),
                Name    = "New Group",
                Visible = true
            };

            _visgroups.Add(newGroup);
            UpdateVisgroups();
            VisgroupPanel.SetSelectedVisgroup(newGroup.ID);
            GroupName.SelectAll();
            GroupName.Focus();
        }
        static void ReadVisgroups(MapFile map, BinaryReader br)
        {
            int numVisgroups = br.ReadInt32();

            for (int i = 0; i < numVisgroups; i++)
            {
                Visgroup vis = new Visgroup
                {
                    Name    = br.ReadFixedLengthString(Encoding.ASCII, 128),
                    Color   = br.ReadRGBAColour(),
                    ID      = br.ReadInt32(),
                    Visible = br.ReadBoolean()
                };
                br.ReadBytes(3);
                map.Visgroups.Add(vis);
            }
        }
Esempio n. 13
0
        private static IEnumerable <Visgroup> ReadVisgroups(BinaryReader br)
        {
            var numVisgroups = br.ReadInt32();

            for (var i = 0; i < numVisgroups; i++)
            {
                var vis = new Visgroup
                {
                    Name    = br.ReadFixedLengthString(Encoding.UTF8, 128),
                    Colour  = br.ReadRGBAColour(),
                    ID      = br.ReadInt32(),
                    Visible = br.ReadBoolean()
                };
                vis.Colour = Color.FromArgb(255, vis.Colour);
                br.ReadBytes(3);
                yield return(vis);
            }
        }
Esempio n. 14
0
        protected override DataStructures.MapObjects.Map GetFromStream(Stream stream, IEnumerable <string> modelDirs, out Image[] lightmaps)
        {
            lightmaps = null;
            var map = new DataStructures.MapObjects.Map();

            map.CordonBounds = new Box(Coordinate.One * -16384, Coordinate.One * 16384);
            BinaryReader br = new BinaryReader(stream);

            //header
            UInt16 mapVersion   = br.ReadUInt16();
            byte   mapFlags     = br.ReadByte();
            Int32  nameCount    = br.ReadInt32();
            Int32  nameOffset   = br.ReadInt32();
            Int32  objectCount  = br.ReadInt32();
            Int32  objectOffset = br.ReadInt32();

            //get names, needed to understand the objects
            List <string> names = new List <string>();

            br.BaseStream.Seek(nameOffset, SeekOrigin.Begin);
            for (int i = 0; i < nameCount; i++)
            {
                string name = br.ReadNullTerminatedString();
                names.Add(name);
            }

            //now we can parse the object table
            List <string> materials = new List <string>();
            List <Tuple <int, string> > meshReferences = new List <Tuple <int, string> >();
            Dictionary <int, Group>     groups         = new Dictionary <int, Group>();
            Dictionary <int, int>       visgroups      = new Dictionary <int, int>();

            br.BaseStream.Seek(objectOffset, SeekOrigin.Begin);
            long objectStartPos = br.BaseStream.Position;

            for (int i = 0; i < objectCount; i++)
            {
                int    index = br.ReadInt32() - 1;
                int    size  = br.ReadInt32();
                string name  = null;
                if (index >= 0 && index < names.Count)
                {
                    name = names[index];
                }

                if (name == "group")
                {
                    byte  flags      = br.ReadByte();
                    Int32 groupIndex = br.ReadInt32();

                    Group newGroup = new Group(map.IDGenerator.GetNextObjectID());
                    newGroup.SetParent(map.WorldSpawn);

                    groups.Add(i, newGroup);
                }
                else if (name == "visgroup")
                {
                    byte   flags = br.ReadByte();
                    string groupName = names[br.ReadInt32() - 1];
                    byte   colorR = br.ReadByte(); byte colorG = br.ReadByte(); byte colorB = br.ReadByte();

                    Visgroup newGroup = new Visgroup()
                    {
                        Name = groupName, ID = visgroups.Count + 1
                    };
                    newGroup.Colour = System.Drawing.Color.FromArgb(colorR, colorG, colorB);
                    map.Visgroups.Add(newGroup);
                    visgroups.Add(i, newGroup.ID);
                }
                else if (name == "meshreference")
                {
                    byte flags = br.ReadByte();

                    Int32 groupNameInd  = br.ReadInt32() - 1;
                    Int32 objectNameInd = br.ReadInt32() - 1;

                    byte limbCount = br.ReadByte();

                    meshReferences.Add(new Tuple <int, string>(i, names[objectNameInd]));
                }
                else if (name == "material")
                {
                    byte   materialFlags      = br.ReadByte();
                    Int32  groupIndex         = br.ReadInt32();
                    string objectName         = names[br.ReadInt32() - 1];
                    Int32  extensionNameIndex = -1;
                    if ((materialFlags & 2) != 0)
                    {
                        extensionNameIndex = br.ReadInt32(); //TODO: what the heck is this
                    }
                    materials.Add(objectName);
                }
                else
                {
                    br.BaseStream.Seek(size, SeekOrigin.Current);
                }
            }
            br.BaseStream.Position = objectStartPos;
            for (int i = 0; i < objectCount; i++)
            {
                int    index = br.ReadInt32() - 1;
                int    size  = br.ReadInt32();
                string name  = null;
                if (index >= 0 && index < names.Count)
                {
                    name = names[index];
                }

                if (name == "mesh")
                {
                    Property newProperty;

                    long startPos = br.BaseStream.Position;

                    byte flags = br.ReadByte();

                    Entity entity = new Entity(map.IDGenerator.GetNextObjectID());
                    entity.ClassName       = "model";
                    entity.EntityData.Name = "model";
                    entity.Colour          = Colour.GetDefaultEntityColour();

                    Int32 keyCount = br.ReadInt32();
                    for (int j = 0; j < keyCount; j++)
                    {
                        Int32 keyNameInd  = br.ReadInt32() - 1;
                        Int32 keyValueInd = br.ReadInt32() - 1;
                        if (names[keyNameInd] != "classname")
                        {
                            newProperty       = new Property();
                            newProperty.Key   = names[keyNameInd];
                            newProperty.Value = names[keyValueInd];

                            if (newProperty.Key == "file")
                            {
                                newProperty.Value = System.IO.Path.GetFileNameWithoutExtension(newProperty.Value);
                            }

                            entity.EntityData.Properties.Add(newProperty);
                        }
                    }

                    Int32 groupIndex    = br.ReadInt32() - 1;
                    Int32 visgroupIndex = br.ReadInt32() - 1;
                    if (visgroups.ContainsKey(visgroupIndex))
                    {
                        entity.Visgroups.Add(visgroups[visgroupIndex]);
                    }

                    byte red = br.ReadByte(); byte green = br.ReadByte(); byte blue = br.ReadByte();

                    Int32 meshRefIndex = br.ReadInt32() - 1;

                    float x = br.ReadSingle();
                    float z = br.ReadSingle();
                    float y = br.ReadSingle();
                    if (entity != null)
                    {
                        entity.Origin = new Coordinate((decimal)x, (decimal)y, (decimal)z);
                    }

                    if (entity.EntityData.GetPropertyValue("file") == null)
                    {
                        newProperty       = new Property();
                        newProperty.Key   = "file";
                        newProperty.Value = meshReferences.Find(q => q.Item1 == meshRefIndex).Item2;

                        entity.EntityData.Properties.Add(newProperty);
                    }

                    float pitch = br.ReadSingle();
                    float yaw   = br.ReadSingle();
                    float roll  = br.ReadSingle();
                    newProperty       = new Property();
                    newProperty.Key   = "angles";
                    newProperty.Value = pitch.ToString() + " " + yaw.ToString() + " " + roll.ToString();

                    entity.EntityData.Properties.Add(newProperty);

                    float xScale = 1.0f;
                    float yScale = 1.0f;
                    float zScale = 1.0f;

                    if ((flags & 1) == 0)
                    {
                        xScale = br.ReadSingle();
                        yScale = br.ReadSingle();
                        zScale = br.ReadSingle();
                    }

                    newProperty       = new Property();
                    newProperty.Key   = "scale";
                    newProperty.Value = xScale.ToString() + " " + yScale.ToString() + " " + zScale.ToString();

                    entity.EntityData.Properties.Add(newProperty);

                    br.BaseStream.Position += size - (br.BaseStream.Position - startPos);

                    entity.UpdateBoundingBox();

                    if (groups.ContainsKey(groupIndex))
                    {
                        entity.SetParent(groups[groupIndex]);
                    }
                    else
                    {
                        entity.SetParent(map.WorldSpawn);
                    }
                }
                else if (name == "entity")
                {
                    byte  flags = br.ReadByte();
                    float x     = br.ReadSingle();
                    float z     = br.ReadSingle();
                    float y     = br.ReadSingle();

                    Entity entity = new Entity(map.IDGenerator.GetNextObjectID());
                    entity.Colour = Colour.GetDefaultEntityColour();
                    entity.Origin = new Coordinate((decimal)x, (decimal)y, (decimal)z);

                    Int32 keyCount = br.ReadInt32();
                    for (int j = 0; j < keyCount; j++)
                    {
                        Int32 keyNameInd  = br.ReadInt32() - 1;
                        Int32 keyValueInd = br.ReadInt32() - 1;
                        if (names[keyNameInd] == "classname")
                        {
                            entity.ClassName       = names[keyValueInd];
                            entity.EntityData.Name = names[keyValueInd];
                        }
                        else
                        {
                            Property newProperty = new Property();
                            newProperty.Key   = names[keyNameInd];
                            newProperty.Value = names[keyValueInd];
                            entity.EntityData.Properties.Add(newProperty);
                        }
                    }

                    Int32 groupIndex    = br.ReadInt32() - 1;
                    Int32 visgroupIndex = br.ReadInt32() - 1;
                    if (visgroups.ContainsKey(visgroupIndex))
                    {
                        entity.Visgroups.Add(visgroups[visgroupIndex]);
                    }

                    entity.UpdateBoundingBox();
                    if (groups.ContainsKey(groupIndex))
                    {
                        entity.SetParent(groups[groupIndex]);
                    }
                    else
                    {
                        entity.SetParent(map.WorldSpawn);
                    }
                }
                else if (name == "brush")
                {
                    bool invisibleCollision = false;

                    byte  brushFlags = br.ReadByte(); //TODO: ???
                    Int32 keys       = br.ReadInt32();
                    for (int j = 0; j < keys; j++)
                    {
                        Int32  keyNameInd  = br.ReadInt32();
                        Int32  keyValueInd = br.ReadInt32();
                        string keyName     = names[keyNameInd - 1];
                        if (keyName.Equals("classname", StringComparison.OrdinalIgnoreCase))
                        {
                            string keyValue = names[keyValueInd - 1];
                            if (keyValue.Equals("field_hit", StringComparison.OrdinalIgnoreCase))
                            {
                                invisibleCollision = true;
                            }
                        }
                    }
                    Int32 groupIndex    = br.ReadInt32() - 1;
                    Int32 visgroupIndex = br.ReadInt32() - 1;

                    byte red = br.ReadByte(); byte green = br.ReadByte(); byte blue = br.ReadByte();

                    List <Coordinate> vertices = new List <Coordinate>();
                    byte vertexCount           = br.ReadByte();
                    for (int j = 0; j < vertexCount; j++)
                    {
                        decimal x = (decimal)br.ReadSingle(); decimal z = (decimal)br.ReadSingle(); decimal y = (decimal)br.ReadSingle();
                        vertices.Add(new Coordinate(x, y, z));
                    }
                    List <Face> faces     = new List <Face>();
                    byte        faceCount = br.ReadByte();
                    for (int j = 0; j < faceCount; j++)
                    {
                        byte faceFlags = br.ReadByte();

                        //TODO: maybe we need these unused bits for something idk
                        decimal planeEq0 = (decimal)br.ReadSingle(); decimal planeEq1 = (decimal)br.ReadSingle(); decimal planeEq2 = (decimal)br.ReadSingle(); decimal planeEq3 = (decimal)br.ReadSingle();

                        decimal texPosX = (decimal)br.ReadSingle(); decimal texPosY = (decimal)br.ReadSingle();
                        decimal texScaleX = (decimal)br.ReadSingle(); decimal texScaleY = (decimal)br.ReadSingle();
                        float   texRotX = br.ReadSingle(); float texRotY = br.ReadSingle();

                        decimal uTexPlane0 = (decimal)br.ReadSingle(); decimal uTexPlane1 = (decimal)br.ReadSingle(); decimal uTexPlane2 = (decimal)br.ReadSingle(); decimal uTexPlane3 = (decimal)br.ReadSingle();
                        decimal vTexPlane0 = (decimal)br.ReadSingle(); decimal vTexPlane1 = (decimal)br.ReadSingle(); decimal vTexPlane2 = (decimal)br.ReadSingle(); decimal vTexPlane3 = (decimal)br.ReadSingle();

                        float luxelSize = br.ReadSingle();

                        Int32 smoothGroupInd = br.ReadInt32();
                        Int32 materialInd    = br.ReadInt32() - 1;

                        Int32 lightmapInd = -1;
                        if ((faceFlags & 16) != 0)
                        {
                            lightmapInd = br.ReadInt32();
                        }

                        byte        indexCount  = br.ReadByte();
                        List <byte> vertsInFace = new List <byte>();
                        for (int k = 0; k < indexCount; k++)
                        {
                            byte vertIndex = br.ReadByte();
                            vertsInFace.Add(vertIndex);

                            float texCoordX = br.ReadSingle(); float texCoordY = br.ReadSingle();

                            float lmCoordX = 0.0f; float lmCoordY = 0.0f;
                            if ((faceFlags & 16) != 0)
                            {
                                lmCoordX = br.ReadSingle(); lmCoordY = br.ReadSingle();
                            }
                        }

                        Coordinate norm = new Coordinate(planeEq0, planeEq2, planeEq1);

                        if (Math.Abs((float)norm.LengthSquared()) > 0.001f)
                        {
                            if (Math.Abs((double)norm.LengthSquared() - 1) > 0.001)
                            {
                                throw new Exception(norm.LengthSquared().ToString());
                            }

                            Face newFace = new Face(map.IDGenerator.GetNextFaceID());

                            foreach (byte vertInd in vertsInFace)
                            {
                                newFace.Vertices.Insert(0, new Vertex(vertices[vertInd], newFace));
                            }

                            newFace.Plane = new Plane(newFace.Vertices[0].Location, newFace.Vertices[1].Location, newFace.Vertices[2].Location);

                            newFace.UpdateBoundingBox();

                            Coordinate uNorm = new Coordinate(uTexPlane0, uTexPlane2, uTexPlane1).Normalise();
                            Coordinate vNorm = new Coordinate(vTexPlane0, vTexPlane2, vTexPlane1).Normalise();
                            if (Math.Abs((double)(uNorm.LengthSquared() - vNorm.LengthSquared())) > 0.001)
                            {
                                throw new Exception(uNorm.LengthSquared().ToString() + " " + vNorm.LengthSquared().ToString());
                            }

                            newFace.Texture.Name = (faceFlags & 4) != 0 ? "tooltextures/remove_face" :
                                                   invisibleCollision ? "tooltextures/invisible_collision" :
                                                   materials[materialInd];
                            newFace.AlignTextureToWorld();

                            newFace.Texture.UAxis = uNorm * (decimal)Math.Cos(-texRotX * Math.PI / 180.0) + vNorm * (decimal)Math.Sin(-texRotX * Math.PI / 180.0);
                            newFace.Texture.VAxis = vNorm * (decimal)Math.Cos(-texRotX * Math.PI / 180.0) - uNorm * (decimal)Math.Sin(-texRotX * Math.PI / 180.0);

                            //huh?????
                            if (Math.Abs(texScaleX) < 0.0001m)
                            {
                                if (Math.Abs(texScaleY) < 0.0001m)
                                {
                                    texScaleX = 1m;
                                    texScaleY = 1m;
                                }
                                else
                                {
                                    texScaleX = texScaleY;
                                }
                            }
                            else if (Math.Abs(texScaleY) < 0.0001m)
                            {
                                texScaleY = texScaleX;
                            }
                            newFace.Texture.XScale   = texScaleX / 2;
                            newFace.Texture.YScale   = texScaleY / 2;
                            newFace.Texture.XShift   = -texPosX * 2 / texScaleX;
                            newFace.Texture.YShift   = texPosY * 2 / texScaleY;
                            newFace.Texture.Rotation = (decimal)texRotX;

                            //seriously, what the F**K???????????
                            if ((texRotX - texRotY) > 120.0f)
                            {
                                newFace.Texture.XScale   *= -1m;
                                newFace.Texture.YScale   *= -1m;
                                newFace.Texture.Rotation -= 180m;
                                newFace.Texture.UAxis     = -newFace.Texture.UAxis;
                            }
                            else if ((texRotY - texRotX) > 120.0f)
                            {
                                newFace.Texture.XScale   *= -1m;
                                newFace.Texture.YScale   *= -1m;
                                newFace.Texture.Rotation -= 180m;
                                newFace.Texture.VAxis     = -newFace.Texture.VAxis;
                            }

                            newFace.Transform(new UnitScale(Coordinate.One, newFace.BoundingBox.Center), TransformFlags.None);

                            faces.Add(newFace);
                        }
                    }

                    Solid newSolid = new Solid(map.IDGenerator.GetNextObjectID());
                    foreach (Face face in faces)
                    {
                        face.Parent = newSolid;
                        newSolid.Faces.Add(face);
                    }
                    if (visgroups.ContainsKey(visgroupIndex))
                    {
                        newSolid.Visgroups.Add(visgroups[visgroupIndex]);
                    }
                    newSolid.Colour = Colour.GetRandomBrushColour();
                    newSolid.UpdateBoundingBox();

                    MapObject parent = map.WorldSpawn;
                    if (groups.ContainsKey(groupIndex))
                    {
                        parent = groups[groupIndex];
                    }

                    if (newSolid.IsValid())
                    {
                        newSolid.SetParent(parent);

                        newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None);
                    }
                    else
                    {
                        var offset = newSolid.BoundingBox.Center;
                        // Not a valid solid, decompose into tetrahedrons/etc
                        foreach (var face in faces)
                        {
                            var polygon = new Polygon(face.Vertices.Select(x => x.Location));
                            if (!polygon.IsValid() || !polygon.IsConvex())
                            {
                                // tetrahedrons
                                foreach (var triangle in face.GetTrianglesReversed())
                                {
                                    var tf = new Face(map.IDGenerator.GetNextFaceID());
                                    tf.Plane = new Plane(triangle[0].Location, triangle[1].Location, triangle[2].Location);
                                    tf.Vertices.AddRange(triangle.Select(x => new Vertex(x.Location, tf)));
                                    tf.Texture = face.Texture.Clone();
                                    tf.UpdateBoundingBox();
                                    newSolid = SolidifyFace(map, tf, offset);
                                    newSolid.SetParent(parent);
                                    newSolid.UpdateBoundingBox();

                                    newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None);
                                }
                            }
                            else
                            {
                                // cone/pyramid/whatever
                                newSolid = SolidifyFace(map, face, offset);
                                newSolid.SetParent(parent);
                                newSolid.UpdateBoundingBox();

                                newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None);
                            }
                        }
                    }
                }
                else
                {
                    if (name == "terrain")
                    {
                        MapProvider.warnings = "This map contains displacements, which are currently not supported. The map will appear incomplete.";
                    }
                    br.BaseStream.Seek(size, SeekOrigin.Current);
                }
            }

            return(map);
        }
Esempio n. 15
0
        protected override DataStructures.MapObjects.Map GetFromStream(Stream stream, IEnumerable <string> modelDirs, out Image[] lightmaps)
        {
            BinaryReader reader = new BinaryReader(stream);

            if (reader.ReadFixedLengthString(Encoding.ASCII, 3) != "CBR")
            {
                throw new ProviderException("CBR file is corrupted/invalid!");
            }
            uint revision = reader.ReadUInt32();

            // Lightmaps
            bool lightmapped = reader.ReadByte() > (byte)Lightmapped.No;

            if (lightmapped)
            {
                lightmaps = new Image[4];
                for (int i = 0; i < 4; i++)
                {
                    lightmaps[i] = Image.FromStream(new MemoryStream(reader.ReadBytes(reader.ReadInt32())));
                }
            }
            else
            {
                lightmaps = null;
            }

            // Texture dictionary
            int texSize = reader.ReadInt32();

            string[] textures = new string[texSize];
            for (int i = 0; i < texSize; i++)
            {
                textures[i] = reader.ReadNullTerminatedString();
            }

            DataStructures.MapObjects.Map map = new DataStructures.MapObjects.Map();
            map.WorldSpawn = new World(map.IDGenerator.GetNextObjectID());

            // Solids
            List <MapObject> solids = new List <MapObject>();
            int solidCount          = reader.ReadInt32();

            for (int i = 0; i < solidCount; i++)
            {
                Solid s = new Solid(map.IDGenerator.GetNextObjectID());
                s.Colour = Colour.GetRandomBrushColour();
                int faceCount = reader.ReadInt32();
                for (int j = 0; j < faceCount; j++)
                {
                    Face f = new Face(map.IDGenerator.GetNextFaceID());
                    f.Colour           = s.Colour;
                    f.Texture.Name     = textures[reader.ReadInt32()];
                    f.Texture.UAxis    = reader.ReadCoordinate();
                    f.Texture.VAxis    = reader.ReadCoordinate();
                    f.Texture.XShift   = reader.ReadDecimal();
                    f.Texture.YShift   = reader.ReadDecimal();
                    f.Texture.XScale   = reader.ReadDecimal();
                    f.Texture.YScale   = reader.ReadDecimal();
                    f.Texture.Rotation = reader.ReadDecimal();
                    int vertexCount = reader.ReadInt32();
                    for (int k = 0; k < vertexCount; k++)
                    {
                        Vertex v = new Vertex(reader.ReadCoordinate(), f);
                        if (lightmapped)
                        {
                            v.LMU      = reader.ReadSingle();
                            v.LMV      = reader.ReadSingle();
                            v.TextureU = (decimal)reader.ReadSingle();
                            v.TextureV = (decimal)reader.ReadSingle();
                        }
                        f.Vertices.Add(v);
                    }
                    f.Plane  = new Plane(f.Vertices[0].Location, f.Vertices[1].Location, f.Vertices[2].Location);
                    f.Parent = s;
                    s.Faces.Add(f);
                    f.UpdateBoundingBox();
                }
                s.SetParent(map.WorldSpawn, false);
                s.UpdateBoundingBox(false);
                solids.Add(s);
            }

            // Entities
            List <MapObject> entities = new List <MapObject>(0);
            string           read;
            bool             isStillSolid = true;

            for (int i = 0; i < 2; i++)
            {
                while ((read = reader.ReadNullTerminatedString()) != "")
                {
                    List <Property> properties = new List <Property>();
                    byte            propertyType;
                    while ((propertyType = reader.ReadByte()) != 255)
                    {
                        properties.Add(new Property()
                        {
                            name = reader.ReadNullTerminatedString(),
                            type = (VariableType)propertyType
                        });
                    }

                    // Entries
                    int entitiesOfType = reader.ReadInt32();
                    entities.Capacity += entitiesOfType;
                    for (int j = 0; j < entitiesOfType; j++)
                    {
                        Entity e = new Entity(map.IDGenerator.GetNextObjectID());
                        e.Colour          = Colour.GetDefaultEntityColour();
                        e.ClassName       = read;
                        e.EntityData.Name = read;
                        if (isStillSolid)
                        {
                            int entitySolids = reader.ReadInt32();
                            for (int k = 0; k < entitySolids; k++)
                            {
                                solids[reader.ReadInt32()].SetParent(e);
                            }
                        }
                        e.SetParent(map.WorldSpawn);
                        foreach (Property property in properties)
                        {
                            string propertyVal;
                            switch (property.type)
                            {
                            case VariableType.Bool:
                                propertyVal = reader.ReadBoolean() ? "Yes" : "No";
                                break;

                            case VariableType.Color255:
                                propertyVal = DataStructures.MapObjects.Property.FromColor(reader.ReadRGBAColour());
                                break;

                            case VariableType.Float:
                                propertyVal = reader.ReadSingle().ToString();
                                break;

                            case VariableType.Integer:
                                propertyVal = reader.ReadInt32().ToString();
                                break;

                            case VariableType.String:
                                propertyVal = reader.ReadNullTerminatedString();
                                break;

                            case VariableType.Vector:
                                propertyVal = DataStructures.MapObjects.Property.FromCoordinate(reader.ReadCoordinate());
                                break;

                            case VariableType.Choices:
                                // TODO: Bullshit
                                throw new NotImplementedException();

                            default:
                                propertyVal = "";
                                break;
                            }
                            e.EntityData.SetPropertyValue(property.name, propertyVal);
                        }
                        e.UpdateBoundingBox();
                        entities.Add(e);
                    }
                }
                isStillSolid = false;
            }

            // CBRE ONLY

            // Visgroup dictionary
            Visgroup currentParentVisgroup = null;

            while (true)
            {
                byte     hierarchyControl;
                Visgroup newGroup = null;
                while ((hierarchyControl = reader.ReadByte()) == HIERARCHY_PROCCEED)
                {
                    newGroup        = new Visgroup();
                    newGroup.Colour = Colour.GetRandomBrushColour();
                    newGroup.ID     = reader.ReadInt32();
                    newGroup.Name   = reader.ReadNullTerminatedString();
                    if (currentParentVisgroup != null)
                    {
                        newGroup.Parent = currentParentVisgroup;
                        currentParentVisgroup.Children.Add(newGroup);
                    }
                    else
                    {
                        map.Visgroups.Add(newGroup);
                    }
                }
                if (hierarchyControl == HIERARCHY_DOWN)
                {
                    currentParentVisgroup = newGroup;
                }
                else if (currentParentVisgroup != null)
                {
                    currentParentVisgroup = currentParentVisgroup.Parent;
                }
                else
                {
                    break;
                }
            }

            // Solid visgroups
            foreach (Solid mo in solids)
            {
                ReadVisgroups(reader, mo);
            }

            // Entity visgroups
            foreach (Entity e in entities)
            {
                ReadVisgroups(reader, e);
            }

            // Groups
            int directWorldGroups = reader.ReadInt32();

            for (int i = 0; i < directWorldGroups; i++)
            {
                Group currentParentGroup = new Group(map.IDGenerator.GetNextObjectID());
                currentParentGroup.SetParent(map.WorldSpawn);
                while (true)
                {
                    byte hierarchyControl;
                    while ((hierarchyControl = reader.ReadByte()) > HIERARCHY_UP)
                    {
                        if (hierarchyControl == IDENTIFIER_ENTITY)
                        {
                            entities[reader.ReadInt32()].SetParent(currentParentGroup);
                        }
                        else
                        {
                            solids[reader.ReadInt32()].SetParent(currentParentGroup);
                        }
                    }
                    if (hierarchyControl == HIERARCHY_DOWN)
                    {
                        Group newGroup = new Group(map.IDGenerator.GetNextObjectID());
                        newGroup.SetParent(currentParentGroup);
                        currentParentGroup = newGroup;
                    }
                    else if (currentParentGroup.Parent != map.WorldSpawn)
                    {
                        currentParentGroup = (Group)currentParentGroup.Parent;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            stream.Close();
            return(map);
        }