예제 #1
0
        /// <summary>
        /// Imports the specified map into the SabreCSG model.
        /// </summary>
        /// <param name="model">The model to import into.</param>
        /// <param name="map">The map to be imported.</param>
        /// <param name="scale">The scale modifier.</param>
        public static void Import(CSGModelBase model, T3dMap map, int scale = 64)
        {
            try
            {
                model.BeginUpdate();

                // create a material searcher to associate materials automatically.
                MaterialSearcher materialSearcher = new MaterialSearcher();

                List <T3dActor> brushes      = map.Brushes;
                Brush[]         sabreBrushes = new Brush[brushes.Count];

                // iterate through all brush actors.
                for (int k = 0; k < brushes.Count; k++)
                {
                    // get the underlying brush data.
                    T3dActor tactor = brushes[k];
                    T3dBrush tbrush = tactor.Brush;
#if UNITY_EDITOR
                    UnityEditor.EditorUtility.DisplayProgressBar("SabreCSG: Importing Unreal Gold Map", "Converting Unreal Brushes To SabreCSG Brushes (" + (k + 1) + " / " + brushes.Count + ")...", k / (float)brushes.Count);
#endif
                    // iterate through the brush polygons.
                    Polygon[] polygons = new Polygon[tbrush.Polygons.Count];
                    for (int i = 0; i < tbrush.Polygons.Count; i++)
                    {
                        T3dPolygon tpolygon = tbrush.Polygons[i];

                        // find the material in the unity project automatically.
                        Material material = null;
                        if (!string.IsNullOrEmpty(tpolygon.Texture))
                        {
                            if (tpolygon.Texture.Contains('.'))
                            {
                                // try finding both 'PlayrShp.Ceiling.Hullwk' and 'Hullwk'.
                                string tiny = tpolygon.Texture.Substring(tpolygon.Texture.LastIndexOf('.') + 1);
                                material = materialSearcher.FindMaterial(new string[] { tpolygon.Texture, tiny });
                                if (material == null)
                                {
                                    Debug.Log("SabreCSG: Tried to find material '" + tpolygon.Texture + "' and also as '" + tiny + "' but it couldn't be found in the project.");
                                }
                            }
                            else
                            {
                                // only try finding 'Hullwk'.
                                material = materialSearcher.FindMaterial(new string[] { tpolygon.Texture });
                                if (material == null)
                                {
                                    Debug.Log("SabreCSG: Tried to find material '" + tpolygon.Texture + "' but it couldn't be found in the project.");
                                }
                            }
                        }

                        Vertex[] vertices = new Vertex[tpolygon.Vertices.Count];
                        for (int j = 0; j < tpolygon.Vertices.Count; j++)
                        {
                            // main-scale
                            // scale around pivot point.
                            Vector3 vertexPosition = ToVector3(tpolygon.Vertices[j]);
                            Vector3 pivot          = ToVector3(tactor.PrePivot);
                            Vector3 difference     = vertexPosition - pivot;
                            vertexPosition = difference.Multiply(ToVector3Raw(tactor.MainScale)) + pivot;

                            // post-scale
                            vertices[j] = new Vertex(vertexPosition.Multiply(ToVector3Raw(tactor.PostScale)) / (float)scale, ToVector3(tpolygon.Normal), GenerateUV(tpolygon, j, material));
                        }

                        // detect the polygon flags.
                        bool userExcludeFromFinal = false;
                        if ((tpolygon.Flags & T3dPolygonFlags.Invisible) > 0)
                        {
                            userExcludeFromFinal = true;
                        }

                        polygons[i] = new Polygon(vertices, material, false, userExcludeFromFinal);
                    }

                    // position and rotate the brushes around their pivot point.
                    Transform transform = model.CreateCustomBrush(polygons).transform;
                    transform.position = (ToVector3(tactor.Location) / (float)scale) - (ToVector3(tactor.PrePivot) / (float)scale);
                    Vector3 axis;
                    float   angle;
                    T3dRotatorToQuaternion(tactor.Rotation).ToAngleAxis(out angle, out axis);
                    transform.RotateAround(transform.position + (ToVector3(tactor.PrePivot) / (float)scale), axis, angle);

                    PrimitiveBrush brush = transform.GetComponent <PrimitiveBrush>();
                    sabreBrushes[k] = brush;

                    object value;
                    // detect the brush mode (additive, subtractive).
                    if (tactor.Properties.TryGetValue("CsgOper", out value))
                    {
                        brush.Mode = (string)value == "CSG_Add" ? CSGMode.Add : CSGMode.Subtract;
                    }
                    // detect special brush flags.
                    if (tactor.Properties.TryGetValue("PolyFlags", out value))
                    {
                        T3dBrushFlags flags = (T3dBrushFlags)value;
                        if ((flags & T3dBrushFlags.Invisible) > 0)
                        {
                            brush.IsVisible = false;
                        }
                        if ((flags & T3dBrushFlags.NonSolid) > 0)
                        {
                            brush.HasCollision = false;
                        }
                        if ((flags & T3dBrushFlags.SemiSolid) > 0)
                        {
                            brush.IsNoCSG = true;
                        }
                    }
                    // detect single polygons.
                    if (polygons.Length == 1)
                    {
                        brush.IsNoCSG = true;
                    }
                }

                // add all new brushes to a group.
                string title = "Unreal Gold Map";
                if (map.Title != "")
                {
                    title += " '" + map.Title + "'";
                }
                if (map.Author != "")
                {
                    title += " (" + map.Author + ")";
                }

                GroupBrush groupBrush = new GameObject(title).AddComponent <GroupBrush>();
                groupBrush.transform.SetParent(model.transform);
                for (int i = 0; i < sabreBrushes.Length; i++)
                {
                    sabreBrushes[i].transform.SetParent(groupBrush.transform);
                }

#if UNITY_EDITOR
                UnityEditor.EditorUtility.ClearProgressBar();
#endif
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                model.EndUpdate();
            }
        }
예제 #2
0
        /// <summary>
        /// Imports the specified Unreal Text file.
        /// </summary>
        /// <param name="path">The file path.</param>
        /// <returns>A <see cref="T3dMap"/> containing the imported map data.</returns>
        public T3dMap Import(string path)
        {
            // create a new map.
            T3dMap map = new T3dMap();

            // open the file for reading. we use streams for additional performance.
            // it's faster than File.ReadAllLines() as that requires two iterations.
            using (FileStream stream = new FileStream(path, FileMode.Open))
                using (StreamReader reader = new StreamReader(stream))
                {
                    // read all the lines from the file.
                    bool   inActor = false; T3dActor actor = null;
                    bool   inBrush = false; T3dBrush brush = null;
                    bool   inPolygon = false; T3dPolygon polygon = null;
                    string line;
                    while (!reader.EndOfStream)
                    {
                        line = reader.ReadLine().Trim();

                        // if we currently parsing an actor:
                        if (inActor)
                        {
                            if (!inBrush)
                            {
                                // if we done parsing the actor:
                                if (line == "End Actor")
                                {
                                    inActor = false;
                                    continue;
                                }

                                // try parsing an actor property.
                                string key;
                                object value;
                                if (TryParseProperty(line, out key, out value))
                                {
                                    actor.Properties.Add(key, value);
                                }

                                // make sure we detect brush declarations:
                                if (line.StartsWith("Begin Brush"))
                                {
                                    // read the properties of the brush.
                                    var properties = ParseKeyValuePairs(line);
                                    if (properties.ContainsKey("Name"))
                                    {
                                        // this is a valid brush model that can be parsed further.
                                        inBrush = true;
                                        // create a new brush model and add it to the map.
                                        brush = new T3dBrush(properties["Name"]);
                                        map.BrushModels.Add(brush);
                                        continue;
                                    }
                                }
                            }
                            // we are currently parsing a brush:
                            else
                            {
                                // if we done parsing the brush:
                                if (line == "End Brush")
                                {
                                    inBrush = false;
                                    continue;
                                }

                                if (!inPolygon)
                                {
                                    // make sure we detect brush polygon declarations:
                                    if (line.StartsWith("Begin Polygon"))
                                    {
                                        inPolygon = true;
                                        // create a new brush polygon and add it to the brush.
                                        polygon = new T3dPolygon();
                                        brush.Polygons.Add(polygon);
                                        // read the properties of the brush polygon.
                                        var properties = ParseKeyValuePairs(line);
                                        if (properties.ContainsKey("Item"))
                                        {
                                            polygon.Item = properties["Item"];
                                        }
                                        if (properties.ContainsKey("Texture"))
                                        {
                                            polygon.Texture = properties["Texture"];
                                        }
                                        if (properties.ContainsKey("Flags"))
                                        {
                                            polygon.Flags = (T3dPolygonFlags)Int32.Parse(properties["Flags"]);
                                        }
                                    }
                                }
                                // we are currently parsing a brush polygon:
                                else
                                {
                                    // if we done parsing the brush polygon:
                                    if (line == "End Polygon")
                                    {
                                        inPolygon = false;
                                        continue;
                                    }

                                    if (line.StartsWith("Origin"))
                                    {
                                        polygon.Origin = ParsePolygonVector(line);
                                    }
                                    if (line.StartsWith("Normal"))
                                    {
                                        polygon.Normal = ParsePolygonVector(line);
                                    }
                                    if (line.StartsWith("TextureU"))
                                    {
                                        polygon.TextureU = ParsePolygonVector(line);
                                    }
                                    if (line.StartsWith("TextureV"))
                                    {
                                        polygon.TextureV = ParsePolygonVector(line);
                                    }
                                    if (line.StartsWith("Pan"))
                                    {
                                        int u, v;
                                        ParsePolygonUV(line, out u, out v);
                                        polygon.PanU = u;
                                        polygon.PanV = v;
                                    }
                                    if (line.StartsWith("Vertex"))
                                    {
                                        polygon.Vertices.Add(ParsePolygonVector(line));
                                    }
                                }
                            }
                        }
                        // if we are looking for another begin declaration:
                        else
                        {
                            // if we are going to parse an actor:
                            if (line.StartsWith("Begin Actor"))
                            {
                                // read the properties of the actor.
                                var properties = ParseKeyValuePairs(line);
                                if (properties.ContainsKey("Class") && properties.ContainsKey("Name"))
                                {
                                    // this is a valid actor that can be parsed further.
                                    inActor = true;
                                    // create a new actor and add it to the map.
                                    actor = new T3dActor(map, properties["Class"], properties["Name"]);
                                    map.Actors.Add(actor);
                                    continue;
                                }
                            }
                        }
                    }
                }

            // return the map data.
            return(map);
        }
예제 #3
0
        /// <summary>
        /// Imports the specified map into the SabreCSG model.
        /// </summary>
        /// <param name="model">The model to import into.</param>
        /// <param name="map">The map to be imported.</param>
        /// <param name="scale">The scale modifier.</param>
        public static void Import(CSGModel model, T3dMap map, int scale = 64)
        {
            try
            {
                model.BeginUpdate();

                List <T3dActor> brushes      = map.Brushes;
                Brush[]         sabreBrushes = new Brush[brushes.Count];

                // iterate through all brush actors.
                for (int k = 0; k < brushes.Count; k++)
                {
                    // get the underlying brush data.
                    T3dActor tactor = brushes[k];
                    T3dBrush tbrush = tactor.Brush;
#if UNITY_EDITOR
                    UnityEditor.EditorUtility.DisplayProgressBar("SabreCSG: Importing Unreal Gold Map", "Converting Unreal Brushes To SabreCSG Brushes (" + (k + 1) + " / " + brushes.Count + ")...", k / (float)brushes.Count);
#endif
                    // iterate through the brush polygons.
                    Polygon[] polygons = new Polygon[tbrush.Polygons.Count];
                    for (int i = 0; i < tbrush.Polygons.Count; i++)
                    {
                        T3dPolygon tpolygon = tbrush.Polygons[i];

                        // find the material in the unity project automatically.
                        Material material = FindMaterial(tpolygon.Texture);

                        Vertex[] vertices = new Vertex[tpolygon.Vertices.Count];
                        for (int j = 0; j < tpolygon.Vertices.Count; j++)
                        {
                            vertices[j] = new Vertex(ToVector3(tpolygon.Vertices[j]) / (float)scale, ToVector3(tpolygon.Normal), GenerateUV(tpolygon, j, material));
                        }

                        // detect the polygon flags.
                        bool userExcludeFromFinal = false;
                        if ((tpolygon.Flags & T3dPolygonFlags.Invisible) > 0)
                        {
                            userExcludeFromFinal = true;
                        }

                        polygons[i] = new Polygon(vertices, material, false, userExcludeFromFinal);
                    }

                    // position and rotate the brushes.
                    Transform transform = model.CreateCustomBrush(polygons).transform;
                    transform.position = (ToVector3(tactor.Location) / (float)scale) - (ToVector3(tactor.PrePivot) / (float)scale);
                    Vector3 axis;
                    float   angle;
                    T3dRotatorToQuaternion(tactor.Rotation).ToAngleAxis(out angle, out axis);
                    transform.RotateAround(transform.position + (ToVector3(tactor.PrePivot) / (float)scale), axis, angle);

                    PrimitiveBrush brush = transform.GetComponent <PrimitiveBrush>();
                    sabreBrushes[k] = brush;

                    object value;
                    // detect the brush mode (additive, subtractive).
                    if (tactor.Properties.TryGetValue("CsgOper", out value))
                    {
                        brush.Mode = (string)value == "CSG_Add" ? CSGMode.Add : CSGMode.Subtract;
                    }
                    // detect special brush flags.
                    if (tactor.Properties.TryGetValue("PolyFlags", out value))
                    {
                        T3dBrushFlags flags = (T3dBrushFlags)value;
                        if ((flags & T3dBrushFlags.Invisible) > 0)
                        {
                            brush.IsVisible = false;
                        }
                        if ((flags & T3dBrushFlags.NonSolid) > 0)
                        {
                            brush.HasCollision = false;
                        }
                        if ((flags & T3dBrushFlags.SemiSolid) > 0)
                        {
                            brush.IsNoCSG = true;
                        }
                    }
                    // detect single polygons.
                    if (polygons.Length == 1)
                    {
                        brush.IsNoCSG = true;
                    }
                }

                // add all new brushes to a group.
                string title = "Unreal Gold Map";
                if (map.Title != "")
                {
                    title += " '" + map.Title + "'";
                }
                if (map.Author != "")
                {
                    title += " (" + map.Author + ")";
                }

                GroupBrush groupBrush = new GameObject(title).AddComponent <GroupBrush>();
                groupBrush.transform.SetParent(model.transform);
                for (int i = 0; i < sabreBrushes.Length; i++)
                {
                    sabreBrushes[i].transform.SetParent(groupBrush.transform);
                }

#if UNITY_EDITOR
                UnityEditor.EditorUtility.ClearProgressBar();
#endif
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                model.EndUpdate();
            }
        }