コード例 #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 world into the SabreCSG model.
        /// </summary>
        /// <param name="model">The model to import into.</param>
        /// <param name="world">The world to be imported.</param>
        /// <param name="scale">The scale modifier.</param>
        public static void Import(CSGModelBase model, MapWorld world)
        {
            try
            {
                model.BeginUpdate();

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

                // group all the brushes together.
                GroupBrush groupBrush = new GameObject("Quake 1 Map").AddComponent <GroupBrush>();
                groupBrush.transform.SetParent(model.transform);

                // iterate through all entities.
                for (int e = 0; e < world.Entities.Count; e++)
                {
#if UNITY_EDITOR
                    UnityEditor.EditorUtility.DisplayProgressBar("SabreCSG: Importing Quake 1 Map", "Converting Quake 1 Entities To SabreCSG Brushes (" + (e + 1) + " / " + world.Entities.Count + ")...", e / (float)world.Entities.Count);
#endif
                    MapEntity entity = world.Entities[e];

                    // iterate through all entity solids.
                    for (int i = 0; i < entity.Brushes.Count; i++)
                    {
                        MapBrush brush = entity.Brushes[i];
#if UNITY_EDITOR
                        if (world.Entities[e].ClassName == "worldspawn")
                        {
                            UnityEditor.EditorUtility.DisplayProgressBar("SabreCSG: Importing Quake 1 Map", "Converting Quake 1 Brushes To SabreCSG Brushes (" + (i + 1) + " / " + entity.Brushes.Count + ")...", i / (float)entity.Brushes.Count);
                        }
#endif
                        // don't add triggers to the scene.
                        if (brush.Sides.Count > 0 && IsSpecialMaterial(brush.Sides[0].Material))
                        {
                            continue;
                        }

                        // build a very large cube brush.
                        var go = model.CreateBrush(PrimitiveBrushType.Cube, Vector3.zero);
                        var pr = go.GetComponent <PrimitiveBrush>();
                        BrushUtility.Resize(pr, new Vector3(8192, 8192, 8192));

                        // clip all the sides out of the brush.
                        for (int j = brush.Sides.Count; j-- > 0;)
                        {
                            MapBrushSide side = brush.Sides[j];
                            Plane        clip = new Plane(pr.transform.InverseTransformPoint(new Vector3(side.Plane.P1.X, side.Plane.P1.Z, side.Plane.P1.Y) / (float)s_Scale), pr.transform.InverseTransformPoint(new Vector3(side.Plane.P2.X, side.Plane.P2.Z, side.Plane.P2.Y) / (float)s_Scale), pr.transform.InverseTransformPoint(new Vector3(side.Plane.P3.X, side.Plane.P3.Z, side.Plane.P3.Y) / (float)s_Scale));
                            ClipUtility.ApplyClipPlane(pr, clip, false);

                            // find the polygons associated with the clipping plane.
                            // the normal is unique and can never occur twice as that wouldn't allow the solid to be convex.
                            var polygons = pr.GetPolygons().Where(p => p.Plane.normal.EqualsWithEpsilonLower3(clip.normal));
                            foreach (var polygon in polygons)
                            {
                                // detect excluded polygons.
                                if (IsExcludedMaterial(side.Material))
                                {
                                    polygon.UserExcludeFromFinal = true;
                                }
                                // detect collision-only brushes.
                                if (IsInvisibleMaterial(side.Material))
                                {
                                    pr.IsVisible = false;
                                }
                                // find the material in the unity project automatically.
                                Material material;
                                // try finding the texture name with '*' replaced by '#' so '#teleport'.
                                string materialName = side.Material.Replace("*", "#");
                                material = materialSearcher.FindMaterial(new string[] { materialName });
                                if (material == null)
                                {
                                    Debug.Log("SabreCSG: Tried to find material '" + materialName + "' but it couldn't be found in the project.");
                                }
                                polygon.Material = material;
                                // calculate the texture coordinates.
                                int w = 256;
                                int h = 256;
                                if (polygon.Material != null && polygon.Material.mainTexture != null)
                                {
                                    w = polygon.Material.mainTexture.width;
                                    h = polygon.Material.mainTexture.height;
                                }
                                CalculateTextureCoordinates(pr, polygon, w, h, new Vector2(side.Offset.X, -side.Offset.Y), new Vector2(side.Scale.X, side.Scale.Y), side.Rotation);
                            }
                        }

                        // add the brush to the group.
                        pr.transform.SetParent(groupBrush.transform);
                    }
                }

#if UNITY_EDITOR
                UnityEditor.EditorUtility.ClearProgressBar();
#endif
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                model.EndUpdate();
            }
        }
コード例 #3
0
        private const float inchesInMeters = 0.03125f; // 1/32

        /// <summary>
        /// Imports the specified world into the SabreCSG model.
        /// </summary>
        /// <param name="model">The model to import into.</param>
        /// <param name="world">The world to be imported.</param>
        /// <param name="scale">The scale modifier.</param>
        public static void Import(CSGModelBase model, VmfWorld world)
        {
            try
            {
                model.BeginUpdate();

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

                // group all the brushes together.
                GroupBrush groupBrush = new GameObject("Source Engine Map").AddComponent <GroupBrush>();
                groupBrush.transform.SetParent(model.transform);

                // iterate through all world solids.
                for (int i = 0; i < world.Solids.Count; i++)
                {
#if UNITY_EDITOR
                    UnityEditor.EditorUtility.DisplayProgressBar("SabreCSG: Importing Source Engine Map", "Converting Hammer Solids To SabreCSG Brushes (" + (i + 1) + " / " + world.Solids.Count + ")...", i / (float)world.Solids.Count);
#endif
                    VmfSolid solid = world.Solids[i];

                    // don't add triggers to the scene.
                    if (solid.Sides.Count > 0 && IsSpecialMaterial(solid.Sides[0].Material))
                    {
                        continue;
                    }

                    // build a very large cube brush.
                    var go = model.CreateBrush(PrimitiveBrushType.Cube, Vector3.zero);
                    var pr = go.GetComponent <PrimitiveBrush>();
                    BrushUtility.Resize(pr, new Vector3(8192, 8192, 8192));

                    // clip all the sides out of the brush.
                    for (int j = solid.Sides.Count; j-- > 0;)
                    {
                        VmfSolidSide side = solid.Sides[j];
                        Plane        clip = new Plane(pr.transform.InverseTransformPoint(new Vector3(side.Plane.P1.X, side.Plane.P1.Z, side.Plane.P1.Y) * inchesInMeters), pr.transform.InverseTransformPoint(new Vector3(side.Plane.P2.X, side.Plane.P2.Z, side.Plane.P2.Y) * inchesInMeters), pr.transform.InverseTransformPoint(new Vector3(side.Plane.P3.X, side.Plane.P3.Z, side.Plane.P3.Y) * inchesInMeters));
                        ClipUtility.ApplyClipPlane(pr, clip, false);

                        // find the polygons associated with the clipping plane.
                        // the normal is unique and can never occur twice as that wouldn't allow the solid to be convex.
                        var polygons = pr.GetPolygons().Where(p => p.Plane.normal == clip.normal);
                        foreach (var polygon in polygons)
                        {
                            // detect excluded polygons.
                            if (IsExcludedMaterial(side.Material))
                            {
                                polygon.UserExcludeFromFinal = true;
                            }
                            // detect collision-only brushes.
                            if (IsInvisibleMaterial(side.Material))
                            {
                                pr.IsVisible = false;
                            }
                            // find the material in the unity project automatically.
                            Material material;
                            // try finding the fully qualified texture name with '/' replaced by '.' so 'BRICK.BRICKWALL052D'.
                            string materialName = side.Material.Replace("/", ".");
                            if (materialName.Contains('.'))
                            {
                                // try finding both 'BRICK.BRICKWALL052D' and 'BRICKWALL052D'.
                                string tiny = materialName.Substring(materialName.LastIndexOf('.') + 1);
                                material = materialSearcher.FindMaterial(new string[] { materialName, tiny });
                                if (material == null)
                                {
                                    Debug.Log("SabreCSG: Tried to find material '" + materialName + "' and also as '" + tiny + "' but it couldn't be found in the project.");
                                }
                            }
                            else
                            {
                                // only try finding 'BRICKWALL052D'.
                                material = materialSearcher.FindMaterial(new string[] { materialName });
                                if (material == null)
                                {
                                    Debug.Log("SabreCSG: Tried to find material '" + materialName + "' but it couldn't be found in the project.");
                                }
                            }
                            polygon.Material = material;
                            // calculate the texture coordinates.
                            int w = 256;
                            int h = 256;
                            if (polygon.Material != null && polygon.Material.mainTexture != null)
                            {
                                w = polygon.Material.mainTexture.width;
                                h = polygon.Material.mainTexture.height;
                            }
                            CalculateTextureCoordinates(pr, polygon, w, h, side.UAxis, side.VAxis);
                        }
                    }

                    // add the brush to the group.
                    pr.transform.SetParent(groupBrush.transform);
                }

                // iterate through all entities.
                for (int e = 0; e < world.Entities.Count; e++)
                {
#if UNITY_EDITOR
                    UnityEditor.EditorUtility.DisplayProgressBar("SabreCSG: Importing Source Engine Map", "Converting Hammer Entities To SabreCSG Brushes (" + (e + 1) + " / " + world.Entities.Count + ")...", e / (float)world.Entities.Count);
#endif
                    VmfEntity entity = world.Entities[e];

                    // skip entities that sabrecsg can't handle.
                    switch (entity.ClassName)
                    {
                    case "func_areaportal":
                    case "func_areaportalwindow":
                    case "func_capturezone":
                    case "func_changeclass":
                    case "func_combine_ball_spawner":
                    case "func_dustcloud":
                    case "func_dustmotes":
                    case "func_nobuild":
                    case "func_nogrenades":
                    case "func_occluder":
                    case "func_precipitation":
                    case "func_proprespawnzone":
                    case "func_regenerate":
                    case "func_respawnroom":
                    case "func_smokevolume":
                    case "func_viscluster":
                        continue;
                    }

                    // iterate through all entity solids.
                    for (int i = 0; i < entity.Solids.Count; i++)
                    {
                        VmfSolid solid = entity.Solids[i];

                        // don't add triggers to the scene.
                        if (solid.Sides.Count > 0 && IsSpecialMaterial(solid.Sides[0].Material))
                        {
                            continue;
                        }

                        // build a very large cube brush.
                        var go = model.CreateBrush(PrimitiveBrushType.Cube, Vector3.zero);
                        var pr = go.GetComponent <PrimitiveBrush>();
                        BrushUtility.Resize(pr, new Vector3(8192, 8192, 8192));

                        // clip all the sides out of the brush.
                        for (int j = solid.Sides.Count; j-- > 0;)
                        {
                            VmfSolidSide side = solid.Sides[j];
                            Plane        clip = new Plane(pr.transform.InverseTransformPoint(new Vector3(side.Plane.P1.X, side.Plane.P1.Z, side.Plane.P1.Y) * inchesInMeters), pr.transform.InverseTransformPoint(new Vector3(side.Plane.P2.X, side.Plane.P2.Z, side.Plane.P2.Y) * inchesInMeters), pr.transform.InverseTransformPoint(new Vector3(side.Plane.P3.X, side.Plane.P3.Z, side.Plane.P3.Y) * inchesInMeters));
                            ClipUtility.ApplyClipPlane(pr, clip, false);

                            // find the polygons associated with the clipping plane.
                            // the normal is unique and can never occur twice as that wouldn't allow the solid to be convex.
                            var polygons = pr.GetPolygons().Where(p => p.Plane.normal == clip.normal);
                            foreach (var polygon in polygons)
                            {
                                // detect excluded polygons.
                                if (IsExcludedMaterial(side.Material))
                                {
                                    polygon.UserExcludeFromFinal = true;
                                }
                                // detect collision-only brushes.
                                if (IsInvisibleMaterial(side.Material))
                                {
                                    pr.IsVisible = false;
                                }
                                // find the material in the unity project automatically.
                                Material material;
                                // try finding the fully qualified texture name with '/' replaced by '.' so 'BRICK.BRICKWALL052D'.
                                string materialName = side.Material.Replace("/", ".");
                                if (materialName.Contains('.'))
                                {
                                    // try finding both 'BRICK.BRICKWALL052D' and 'BRICKWALL052D'.
                                    string tiny = materialName.Substring(materialName.LastIndexOf('.') + 1);
                                    material = materialSearcher.FindMaterial(new string[] { materialName, tiny });
                                    if (material == null)
                                    {
                                        Debug.Log("SabreCSG: Tried to find material '" + materialName + "' and also as '" + tiny + "' but it couldn't be found in the project.");
                                    }
                                }
                                else
                                {
                                    // only try finding 'BRICKWALL052D'.
                                    material = materialSearcher.FindMaterial(new string[] { materialName });
                                    if (material == null)
                                    {
                                        Debug.Log("SabreCSG: Tried to find material '" + materialName + "' but it couldn't be found in the project.");
                                    }
                                }
                                polygon.Material = material;
                                // calculate the texture coordinates.
                                int w = 256;
                                int h = 256;
                                if (polygon.Material != null && polygon.Material.mainTexture != null)
                                {
                                    w = polygon.Material.mainTexture.width;
                                    h = polygon.Material.mainTexture.height;
                                }
                                CalculateTextureCoordinates(pr, polygon, w, h, side.UAxis, side.VAxis);
                            }
                        }

                        // detail brushes that do not affect the CSG world.
                        if (entity.ClassName == "func_detail")
                        {
                            pr.IsNoCSG = true;
                        }
                        // collision only brushes.
                        if (entity.ClassName == "func_vehicleclip")
                        {
                            pr.IsVisible = false;
                        }

                        // add the brush to the group.
                        pr.transform.SetParent(groupBrush.transform);
                    }
                }

#if UNITY_EDITOR
                UnityEditor.EditorUtility.ClearProgressBar();
#endif
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                model.EndUpdate();
            }
        }
コード例 #4
0
    void CreateRoom()
    {
        if (level != null)
        {
            Destroy(level);
        }
        level = new GameObject("Level");
        level.transform.parent = gameObject.transform;

        BSPDungeon bspDungeon = new BSPDungeon(binarySpacePartitionSettings, roomSettings, connectionSettings);

        bspDungeon.GenerateDungeon();
        List <Partition> finalPartitions = bspDungeon.GenerateFinalPartitionList();
        List <Partition> allPartitions   = bspDungeon.GeneratePartitionList();

        Vector3 position;
        Vector3 size;

        csgModel = level.AddComponent <CSGModelBase>();

        //Debug.Log("drawing rooms and partitions");
        foreach (Partition partition in finalPartitions)
        {
            if (drawPartitions)
            {
                position    = (Vector2)(partition.start + partition.end) / 2;
                size        = (Vector2)(partition.end - partition.start);
                position.z += 5;
                size.x     -= 0.5f;
                size.y     -= 0.5f;
                size.z      = 1;
                //Debug.Log("Position: " + position + ", Size: " + size);
                csgModel.CreateBrush(PrimitiveBrushType.Cube, position, size, Quaternion.identity, partitionMaterial);
            }

            if (drawRooms)
            {
                if (partition.room != null)
                {
                    foreach (Shape shape in partition.room)
                    {
                        if (shape.GetType() == typeof(Rectangle))
                        {
                            Rectangle rectangle = (Rectangle)shape;
                            position    = (Vector2)(rectangle.start + rectangle.end) / 2;
                            position.z -= 0;
                            size        = (Vector2)(rectangle.end - rectangle.start);
                            size.z      = 1;
                            //Debug.Log("Position: " + position + ", Size: " + size);
                            csgModel.CreateBrush(PrimitiveBrushType.Cube, position, size, Quaternion.identity, roomMaterial);
                        }
                    }
                }
            }
        }

        foreach (Partition partition in allPartitions)
        {
            if (drawConnections)
            {
                foreach (Shape shape in partition.connection)
                {
                    if (shape.GetType() == typeof(Rectangle))
                    {
                        Rectangle rectangle = (Rectangle)shape;
                        position    = (Vector2)(rectangle.start + rectangle.end) / 2;
                        position.z -= 5;
                        size        = (Vector2)(rectangle.end - rectangle.start);
                        size.z      = 1;
                        //Debug.Log("Position: " + position + ", Size: " + size);
                        csgModel.CreateBrush(PrimitiveBrushType.Cube, position, size, Quaternion.identity, connectionMaterial);
                    }
                }
            }
        }
        Debug.Log(finalPartitions.Count);

        csgModel.Build(true, false);
    }