Esempio n. 1
0
    private static Mesh GenerateMesh(MDLFile mdl, string destPath)
    {
        var geometry = mdl.geometry;

        var verts = geometry.frames[0].verts;

        Mesh mesh = new Mesh();

        var rotation = Quaternion.AngleAxis(-90, Vector3.up);

        Vector3[] vertices  = new Vector3[verts.Length];
        int[]     triangles = new int[verts.Length];
        for (int i = 0; i < verts.Length; i += 3)
        {
            vertices[i]      = rotation * BSPFile.TransformVector(verts[i]);
            vertices[i + 1]  = rotation * BSPFile.TransformVector(verts[i + 1]);
            vertices[i + 2]  = rotation * BSPFile.TransformVector(verts[i + 2]);
            triangles[i]     = i + 2;
            triangles[i + 1] = i + 1;
            triangles[i + 2] = i;
        }

        mesh.vertices  = vertices;
        mesh.triangles = triangles;
        mesh.uv        = geometry.uvs;
        mesh.RecalculateNormals();

        var meshPath = destPath + "/" + mdl.name + "_mesh.asset";

        AssetDatabase.CreateAsset(mesh, meshPath);

        return(AssetDatabase.LoadAssetAtPath <Mesh>(meshPath));
    }
        /// <summary>
        /// Create a clipping hull out of the visible hull
        /// </summary>
        /// <param name="bspFile"></param>
        /// <returns></returns>
        private Hull MakeHull0(BSPFile bspFile)
        {
            var clipNodes = new ClipNode[bspFile.Nodes.Count];

            for (var i = 0; i < bspFile.Nodes.Count; ++i)
            {
                var node = bspFile.Nodes[i];

                var clipNode = new ClipNode
                {
                    PlaneIndex = Array.FindIndex(bspFile.Planes, plane => ReferenceEquals(plane, node.Plane))
                };

                for (var j = 0; j < 2; ++j)
                {
                    var child = node.Children[j];

                    if (child.Contents >= Contents.Node)
                    {
                        clipNode.Children[j] = bspFile.Nodes.FindIndex(test => ReferenceEquals(test, child));
                    }
                    else
                    {
                        clipNode.Children[j] = (int)child.Contents;
                    }
                }

                clipNodes[i] = clipNode;
            }

            return(new Hull(0, bspFile.Nodes.Count - 1, Vector3.Zero, Vector3.Zero, clipNodes, bspFile.Planes));
        }
Esempio n. 3
0
    private static BSPTexture[] AdjustTextureSizes(BSPFile bsp)
    {
        var textures = bsp.textures;
        var sizes    = new Vector2[textures.Length];

        foreach (var geometry in bsp.models[0].geometries)
        {
            var g       = geometry.mesh;
            var tex_id  = geometry.tex_id;
            var texture = textures[tex_id];
            for (int i = 0; i < g.vertices.Length; ++i)
            {
                var   uv = g.uvs[i];
                float w  = texture.width * uv.x;
                float h  = texture.height * uv.y;

                if (w > sizes[tex_id].x || h > sizes[tex_id].y)
                {
                    sizes[tex_id] = new Vector2(w, h);
                }
            }
        }

        var result = new BSPTexture[textures.Length];

        for (int i = 0; i < sizes.Length; ++i)
        {
            result[i] = ResizeTextures(textures[i], sizes[i]);
        }
        return(result);
    }
Esempio n. 4
0
    static void GenerateCollision(BSPFile bsp, GameObject parent, BSPFace face)
    {
        GameObject levelCollision = PrefabCache.InstantiatePrefab("LevelCollision", "Assets/Prefabs");

        levelCollision.transform.parent = parent.transform;
        levelCollision.isStatic         = parent.isStatic;

        var verts = face.vertices;

        var collider = levelCollision.AddComponent <MeshCollider>();

        List <Vector3> vertices  = new List <Vector3>();
        List <int>     triangles = new List <int>();

        for (int vi = 0, ti = 0; vi < verts.Length; vi += 3, ti += 3)
        {
            vertices.Add(BSPFile.TransformVector(verts[vi + 0]));
            vertices.Add(BSPFile.TransformVector(verts[vi + 1]));
            vertices.Add(BSPFile.TransformVector(verts[vi + 2]));

            triangles.Add(ti + 2);
            triangles.Add(ti + 1);
            triangles.Add(ti + 0);
        }

        Mesh mesh = new Mesh();

        mesh.name      = "Collision Mesh";
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.RecalculateNormals();

        collider.sharedMesh = mesh;
    }
        /// <summary>
        /// Create the lightmap texture for a surface
        /// If the surface has no lightmaps, returns null
        /// </summary>
        /// <param name="bspFile"></param>
        /// <param name="face"></param>
        /// <param name="numLightmaps"></param>
        /// <param name="smax"></param>
        /// <param name="tmax"></param>
        /// <returns></returns>
        public static Image <Rgba32> CreateLightmapTexture(BSPFile bspFile, Face face, int numLightmaps, int smax, int tmax)
        {
            if (bspFile == null)
            {
                throw new ArgumentNullException(nameof(bspFile));
            }

            if (face == null)
            {
                throw new ArgumentNullException(nameof(face));
            }

            if (numLightmaps < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(numLightmaps));
            }

            if (smax <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(smax));
            }

            if (tmax <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(tmax));
            }

            return(InternalCreateLightmapTexture(bspFile, face, numLightmaps, smax, tmax));
        }
        private static Image <Rgba32> InternalGenerateLightmap(BSPFile bspFile, Face face, int smax, int tmax, int lightmapIndex)
        {
            var size = smax * tmax;

            var colorData = new Rgba32[size];

            if (bspFile.Lighting.Length > 0 && face.LightOffset != -1)
            {
                //Initialize from light data
                var lightmapData = new Span <Rgb24>(bspFile.Lighting, face.LightOffset + (size * lightmapIndex), size);

                for (var i = 0; i < size; ++i)
                {
                    //Lightmap data is passed directly to shaders; shaders will handle light styles and gamma correction
                    lightmapData[i].ToRgba32(ref colorData[i]);
                }
            }
            else
            {
                //Fill with fullbright
                for (var i = 0; i < size; ++i)
                {
                    colorData[i].R = byte.MaxValue;
                    colorData[i].G = byte.MaxValue;
                    colorData[i].B = byte.MaxValue;
                    colorData[i].A = byte.MaxValue;
                }
            }

            return(Image.LoadPixelData(colorData, smax, tmax));
        }
Esempio n. 7
0
    static Mesh GenerateMesh(BSPModelGeometry geometry)
    {
        List <Vector3> vertices  = new List <Vector3>();
        List <int>     triangles = new List <int>();
        List <Vector2> uvs       = new List <Vector2>();

        var g = geometry.mesh;

        for (int vi = 0, ti = 0; vi < g.vertices.Length; vi += 3, ti += 3)
        {
            vertices.Add(BSPFile.TransformVector(g.vertices[vi + 0]));
            vertices.Add(BSPFile.TransformVector(g.vertices[vi + 1]));
            vertices.Add(BSPFile.TransformVector(g.vertices[vi + 2]));

            uvs.Add(g.uvs[vi + 0]);
            uvs.Add(g.uvs[vi + 1]);
            uvs.Add(g.uvs[vi + 2]);

            triangles.Add(ti + 2);
            triangles.Add(ti + 1);
            triangles.Add(ti + 0);
        }

        Mesh mesh = new Mesh();

        mesh.name      = "Brush Mesh";
        mesh.vertices  = vertices.ToArray();
        mesh.uv        = uvs.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.RecalculateNormals();
        return(mesh);
    }
Esempio n. 8
0
    static void LoadBSP()
    {
        try
        {
            string path = EditorUtility.OpenFilePanelWithFilters("Open BSP", AssetUtils.GetAbsoluteAssetPath("Assets/Editor/Data/maps"), new string[] { "BSP files", "bsp" });
            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            using (FileStream stream = File.OpenRead(path))
            {
                DataStream ds  = new DataStream(stream);
                BSPFile    bsp = new BSPFile(ds);

                string name     = Path.GetFileNameWithoutExtension(path);
                string destPath = "Assets/Scenes/Maps/" + name;

                AssetUtils.CreateFolder(destPath);

                var materials = GenerateMaterials(bsp, destPath);
                if (materials == null) // cancelled
                {
                    return;
                }

                GenerateLevel(bsp, materials);
            }
        }
        finally
        {
            EditorUtility.ClearProgressBar();
        }
    }
Esempio n. 9
0
    public override void SetupInstance(BSPFile bsp, entity entity, SceneEntities entities)
    {
        base.SetupInstance(bsp, entity, entities);

        if (string.IsNullOrEmpty(this.message))
        {
            Debug.LogError("Can't set skill: message is null or empty");
            return;
        }

        int value;

        if (!int.TryParse(this.message, out value))
        {
            Debug.LogError("Can't set skill: invalid message '" + this.message + "'");
            return;
        }

        if (!Enum.IsDefined(typeof(GameSkill), value))
        {
            Debug.LogError("Can't set skill: invalid GameSkill value '" + value + "'");
            return;
        }

        var trigger = entity.GetComponent <trigger_setskill>();

        trigger.skill = (GameSkill)value;
    }
        private static Image <Rgba32> InternalCreateLightmapTexture(BSPFile bspFile, Face face, int numLightmaps, int smax, int tmax)
        {
            if (numLightmaps == 0)
            {
                //Let the user decide what to do
                return(null);
            }

            var lightmapData = new Image <Rgba32>(numLightmaps * smax, tmax);

            var graphicsOptions = GraphicsOptions.Default;

            graphicsOptions.BlenderMode = PixelBlenderMode.Src;

            //Generate lightmap data for every style
            for (var i = 0; i < numLightmaps; ++i)
            {
                using (var styleData = InternalGenerateLightmap(bspFile, face, smax, tmax, i))
                {
                    lightmapData.Mutate(context => context.DrawImage(graphicsOptions, styleData, new SixLabors.Primitives.Point(i * smax, 0)));
                }
            }

            return(lightmapData);
        }
Esempio n. 11
0
    public override void SetupInstance(BSPFile bsp, entity entity, SceneEntities entities)
    {
        base.SetupInstance(bsp, entity, entities);

        var door = entity as func_door;

        SetupTrigger(door);
        SetupItems(door);
        SetupMovement(door);
    }
Esempio n. 12
0
 public static bool LoadMap(string mapFile)
 {
     if (mapFile != null && File.Exists(mapFile) && Local.InGame)
     {
         loadedMap     = new BSPFile(mapFile);
         loadedMapFile = Local.MapFile;
         loadedMapName = Local.MapName;
         return(true);
     }
     return(false);
 }
Esempio n. 13
0
    static void GenerateBrush(BSPFile bsp, GameObject brush, BSPModelGeometry geometry, IList <Material> materials)
    {
        var mesh = GenerateMesh(geometry);

        var meshFilter = brush.GetComponent <MeshFilter>();

        meshFilter.sharedMesh = mesh;

        var meshRenderer = brush.GetComponent <MeshRenderer>();

        meshRenderer.material = materials[(int)geometry.tex_id];
    }
Esempio n. 14
0
    public override void SetupInstance(BSPFile bsp, entity entity, SceneEntities entities)
    {
        base.SetupInstance(bsp, entity, entities);

        if (angle >= 0 && angle < 360)
        {
            entity.transform.rotation = Quaternion.AngleAxis(90 - angle, Vector3.up);
        }
        else
        {
            Debug.LogError("Unexpected angle: " + angle);
        }
    }
Esempio n. 15
0
    static void GenerateModel(BSPFile bsp, Level level, BSPModel model, IList <Material> materials, bool[] used)
    {
        if (model.entity != null)
        {
            return;
        }

        GameObject modelObj = new GameObject("Model");

        modelObj.transform.parent = level.transform;
        modelObj.isStatic         = true;

        GenerateGeometries(bsp, model, modelObj, materials, used);
    }
Esempio n. 16
0
    public override void SetupInstance(BSPFile bsp, entity entity, SceneEntities entities)
    {
        base.SetupInstance(bsp, entity, entities);

        var collider = entity.GetComponent <BoxCollider>();

        var colliderSize = this.size;

        colliderSize.x += 0.4f;
        colliderSize.y += 0.4f;
        colliderSize.z += 0.4f;

        collider.size = colliderSize;
    }
Esempio n. 17
0
    public virtual void SetupInstance(BSPFile bsp, entity entity, SceneEntities entities)
    {
        if (this.target != -1)
        {
            var targetName = entities.FindTargetName(this.target);
            if (targetName == null)
            {
                Debug.LogError("Can't find entity with target name: " + this.target);
            }

            var target = entity.gameObject.AddComponent <EntityTarget>();
            target.targetName = targetName;
        }

        var instanceFields = ReflectionUtils.ListFields(entity);
        var dataFields     = ReflectionUtils.ListFields(this);

        foreach (var name in instanceFields.Keys)
        {
            FieldInfo dataField;
            if (dataFields.TryGetValue(name, out dataField))
            {
                object value = dataField.GetValue(this);
                if (dataField.GetCustomAttribute <BSPTransformAttribute>() != null)
                {
                    Type fieldType = dataField.FieldType;
                    if (fieldType == typeof(int))
                    {
                        value = BSPFile.Scale((int)value);
                    }
                    else if (fieldType == typeof(float))
                    {
                        value = BSPFile.Scale((float)value);
                    }
                    else if (fieldType == typeof(Vector3))
                    {
                        value = BSPFile.TransformVector((Vector3)value);
                    }
                    else
                    {
                        throw new NotImplementedException("Unexpected field type: " + fieldType);
                    }
                }

                FieldInfo instanceField = instanceFields[name];
                instanceField.SetValue(entity, value);
            }
        }
    }
Esempio n. 18
0
    public override void SetupInstance(BSPFile bsp, entity entity, SceneEntities entities)
    {
        base.SetupInstance(bsp, entity, entities);

        if (modelRef != null)
        {
            var collider = entity.GetComponent <BoxCollider>();
            collider.size = this.size;
        }

        if (health > 0)
        {
            entity.gameObject.layer = LayerMask.NameToLayer("ShootTrigger");
        }
    }
Esempio n. 19
0
    private static Mesh GenerateMesh(BSPFile bsp, string name, string destPath, TextureAtlas atlas)
    {
        List <Vector3> vertices  = new List <Vector3>();
        List <int>     triangles = new List <int>();
        List <Vector2> uvs       = new List <Vector2>();

        var textures = bsp.textures;

        int ti = 0;

        foreach (var geometry in bsp.models[0].geometries)
        {
            var g       = geometry.mesh;
            var tex_id  = geometry.tex_id;
            var texture = textures[tex_id];

            for (int vi = 0; vi < g.vertices.Length; vi += 3, ti += 3)
            {
                vertices.Add(BSPFile.TransformVector(g.vertices[vi + 0]));
                vertices.Add(BSPFile.TransformVector(g.vertices[vi + 1]));
                vertices.Add(BSPFile.TransformVector(g.vertices[vi + 2]));

                uvs.Add(atlas.TransformUV(tex_id, g.uvs[vi + 0], texture.width, texture.height));
                uvs.Add(atlas.TransformUV(tex_id, g.uvs[vi + 1], texture.width, texture.height));
                uvs.Add(atlas.TransformUV(tex_id, g.uvs[vi + 2], texture.width, texture.height));

                triangles.Add(ti + 2);
                triangles.Add(ti + 1);
                triangles.Add(ti + 0);
            }
        }

        Mesh mesh = new Mesh();

        mesh.name      = "Model Mesh";
        mesh.vertices  = vertices.ToArray();
        mesh.uv        = uvs.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.RecalculateNormals();

        var meshPath = destPath + "/" + name + "_mesh.asset";

        AssetDatabase.CreateAsset(mesh, meshPath);

        return(AssetDatabase.LoadAssetAtPath <Mesh>(meshPath));
    }
Esempio n. 20
0
    private static void GenerateGeometries(BSPFile bsp, BSPModel model, GameObject parent, IList <Material> materials, bool[] used)
    {
        foreach (var geometry in model.geometries)
        {
            GameObject brush = PrefabCache.InstantiatePrefab("LevelBrush", "Assets/Prefabs");
            brush.transform.parent = parent.transform;
            brush.isStatic         = parent.isStatic;
            GenerateBrush(bsp, brush, geometry, materials);

            foreach (var face in geometry.faces)
            {
                if (!used[face.id])
                {
                    used[face.id] = true;
                    GenerateCollision(bsp, brush.gameObject, face);
                }
            }
        }
    }
Esempio n. 21
0
        protected override void OnUpdate(TickEventArgs args)
        {
            base.OnUpdate(args);

            //Grab local player
            LocalPlayer.Reset();
            ViewMatrix.Reset();
            //GameRules.Reset();
            PlayerResources.Reset();
            ClientState.Reset();
            GameDirectory.Reset();

            BaseEntitites.Clear();
            PlayersOld.Clear();
            PlayersOld.CopyFrom(Players);
            Players.Clear();
            Weapons.Clear();

            //Load map
            if (ClientState.Value != null && ClientState.Value.Map.Value != null)
            {
                if (ClientState.Value.Map.Value != lastMap)
                {
                    var path = Path.Combine(GameDirectory.Value, ClientState.Value.Map.Value);
                    //try
                    //{
                    lastMap = ClientState.Value.Map.Value;
                    if (File.Exists(path))
                    {
                        using (var str = new FileStream(path, FileMode.Open, FileAccess.Read))
                        {
                            var bsp = new BSPFile(str);
                            Map = bsp;
                        }
                        //}catch(Exception ex)
                        //{
                        //    Program.Logger.Error("Failed to parse map \"{0}\": {1}", path, ex.Message);
                        //}
                    }
                }
            }
        }
Esempio n. 22
0
    public void LoadMap()
    {
        if (!Utils.IsGamePathValid())
        {
            Console.LogError("Gamepath must be fixed before loading a map.");
            return;
        }
        if (!Utils.IsModnameValid())
        {
            Console.LogError("Modname should be fixed before loading a map.");
        }

        ClearMap();

        //load a map file...
        StateManager.ChangeGameState(GameState.loading);

        StopAllCoroutines();
        StartCoroutine(BSPFile.LoadBspRoutine(Globals.map.Text));
    }
Esempio n. 23
0
    private static UnityEngine.Object CreateBSP(DataStream ds, string destPath, string name)
    {
        BSPFile bsp = new BSPFile(ds);

        if (bsp.models.Length != 1)
        {
            throw new ArgumentException("BSP should have 1 model only");
        }

        var textures = AdjustTextureSizes(bsp);
        var atlas    = new TextureAtlas(textures, 1024, 1024);
        var mesh     = GenerateMesh(bsp, name, destPath, atlas);
        var skins    = GenerateSkins(bsp, name, destPath, atlas);

        var asset = ScriptableObject.CreateInstance <MDL>(); // BSP is not quite MDL but who cares: it's a miracle I went this far with that budget

        asset.name      = name;
        asset.mesh      = mesh;
        asset.materials = skins;
        return(asset);
    }
Esempio n. 24
0
    void SetupMovement(func_door door)
    {
        Vector3 movedir;
        float   amount;

        if (angle == -1) // moving up
        {
            movedir = Vector3.up;
            amount  = this.size.y;
        }
        else if (angle == -2) // moving down
        {
            movedir = Vector2.down;
            amount  = this.size.y;
        }
        else if (angle == 0 || angle == 90 || angle == 180 || angle == 270)
        {
            movedir = Quaternion.AngleAxis(-angle, Vector3.up) * Vector3.right;
            amount  = angle == 0 || angle == 180 ? this.size.x : this.size.z;
        }
        else
        {
            movedir = Vector3.zero;
            amount  = 0.0f;
            Debug.LogError("Unexpected angle: " + angle);
        }
        door.pos1 = door.transform.position;
        door.pos2 = door.pos1 + movedir * (amount - BSPFile.Scale(lip));

        if ((this.spawnflags & DOOR_START_OPEN) != 0)
        {
            door.transform.position = door.pos2;

            // swap positions
            var temp = door.pos1;
            door.pos1 = door.pos2;
            door.pos2 = temp;
        }
    }
Esempio n. 25
0
    public override void SetupInstance(BSPFile bsp, entity entity, SceneEntities entities)
    {
        base.SetupInstance(bsp, entity, entities);

        if (this.spawnflags == 1) // not sure what this value means but it might be "crucified"
        {
            var rigidBoby = entity.GetComponent <Rigidbody>();
            if (rigidBoby != null)
            {
                GameObject.DestroyImmediate(rigidBoby);
            }

            var collider = entity.GetComponent <BoxCollider>();
            if (collider != null)
            {
                GameObject.DestroyImmediate(collider);
            }

            var zombie = entity as monster_zombie;
            zombie.crucified = true;
        }
    }
Esempio n. 26
0
        public BSPModel(string name, uint crc, BSPFile bspFile, Model subModel, Hull hull0)
            : base(name, crc, subModel.Mins, subModel.Maxs)
        {
            BSPFile  = bspFile ?? throw new ArgumentNullException(nameof(bspFile));
            SubModel = subModel ?? throw new ArgumentNullException(nameof(subModel));

            var hulls = new Hull[BSPConstants.MaxHulls];

            hulls[0] = new Hull(subModel.HeadNodes[0], bspFile.ClipNodes.Count - 1, hull0.ClipMins, hull0.ClipMaxs, hull0.ClipNodes, hull0.Planes);
            hulls[1] = new Hull(subModel.HeadNodes[1], bspFile.ClipNodes.Count - 1, PhysicsConstants.Hull1.ClipMins, PhysicsConstants.Hull1.ClipMaxs, hull0.ClipNodes, new Memory <SharpLife.Models.BSP.FileFormat.Plane>(BSPFile.Planes));
            hulls[2] = new Hull(subModel.HeadNodes[2], bspFile.ClipNodes.Count - 1, PhysicsConstants.Hull2.ClipMins, PhysicsConstants.Hull2.ClipMaxs, hull0.ClipNodes, new Memory <SharpLife.Models.BSP.FileFormat.Plane>(BSPFile.Planes));
            hulls[3] = new Hull(subModel.HeadNodes[3], bspFile.ClipNodes.Count - 1, PhysicsConstants.Hull3.ClipMins, PhysicsConstants.Hull3.ClipMaxs, hull0.ClipNodes, new Memory <SharpLife.Models.BSP.FileFormat.Plane>(BSPFile.Planes));

            Hulls = hulls;

            var radius = new Vector3(
                Math.Abs(subModel.Mins.X) > Math.Abs(subModel.Maxs.X) ? Math.Abs(subModel.Mins.X) : Math.Abs(subModel.Maxs.X),
                Math.Abs(subModel.Mins.Y) > Math.Abs(subModel.Maxs.Y) ? Math.Abs(subModel.Mins.Y) : Math.Abs(subModel.Maxs.Y),
                Math.Abs(subModel.Mins.Z) > Math.Abs(subModel.Maxs.Z) ? Math.Abs(subModel.Mins.Z) : Math.Abs(subModel.Maxs.Z)
                );

            Radius = radius.Length();
        }
Esempio n. 27
0
    private static Material[] GenerateSkins(BSPFile bsp, string name, string destPath, TextureAtlas atlas)
    {
        var skinsPath = destPath + "/skins";

        AssetUtils.CreateFolder(skinsPath);

        string textureName = FileUtilEx.FixFilename(name);
        var    texturePath = skinsPath + "/" + textureName + ".png";

        if (!AssetUtils.AssetPathExists(texturePath))
        {
            atlas.WriteTexture(texturePath);
            AssetDatabase.Refresh();
        }

        int    index        = texturePath.LastIndexOf('.');
        string materialPath = texturePath.Substring(0, index) + ".mat";

        if (!AssetUtils.AssetPathExists(materialPath))
        {
            TextureImporter importer = TextureImporter.GetAtPath(texturePath) as TextureImporter;
            importer.textureType    = TextureImporterType.Default;
            importer.wrapMode       = TextureWrapMode.Repeat;
            importer.filterMode     = FilterMode.Point;
            importer.maxTextureSize = 2048;
            importer.textureFormat  = TextureImporterFormat.DXT1;
            importer.SaveAndReimport();

            var material = new Material(Shader.Find("Standard"));
            material.mainTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(texturePath);
            material.SetFloat("_Glossiness", 0.0f);

            AssetDatabase.CreateAsset(material, materialPath);
        }

        return(new Material[] { AssetDatabase.LoadAssetAtPath <Material>(materialPath) });
    }
        public static Image <Rgba32> GenerateLightmap(BSPFile bspFile, Face face, int smax, int tmax, int lightmapIndex)
        {
            if (bspFile == null)
            {
                throw new ArgumentNullException(nameof(bspFile));
            }

            if (face == null)
            {
                throw new ArgumentNullException(nameof(face));
            }

            if (smax <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(smax));
            }

            if (tmax <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(tmax));
            }

            return(InternalGenerateLightmap(bspFile, face, smax, tmax, lightmapIndex));
        }
Esempio n. 29
0
    static GameObject GenerateEntity(BSPFile bsp, entity_t entity, IList <Material> materials, bool[] used)
    {
        var name = entity.GetType().Name;

        if (name.EndsWith(TYPE_PREFIX))
        {
            name = name.Substring(0, name.Length - TYPE_PREFIX.Length);
        }

        var entityInstance = PrefabCache.InstantiatePrefab(name, "Assets/Prefabs/Entities");

        if (entityInstance == null)
        {
            Debug.LogWarning("Can't load prefab: " + name);
            return(null);
        }

        entityInstance.isStatic = !entity.movable;

        if (entity.modelRef != null)
        {
            var model = entity.modelRef;
            entityInstance.transform.position = model.boundbox.center;

            if (entity.solid)
            {
                GenerateGeometries(bsp, model, entityInstance, materials, used);
            }
        }
        else
        {
            entityInstance.transform.position = BSPFile.TransformVector(entity.origin);
        }

        return(entityInstance);
    }
        /// <summary>
        /// Builds the vertices and indices buffers for the given faces
        /// </summary>
        /// <param name="bspFile"></param>
        /// <param name="faces"></param>
        /// <param name="texture"></param>
        /// <param name="textureResourceSet"></param>
        /// <param name="defaultLightmapTexture"></param>
        /// <param name="lightmapBuilders"></param>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        public static void BuildFacesBuffer(
            BSPFile bspFile,
            IReadOnlyList <Face> faces,
            MipTexture texture,
            ResourceSet textureResourceSet,
            Image <Rgba32> defaultLightmapTexture,
            List <LightmapBuilder> lightmapBuilders,
            List <BSPSurfaceData> vertices,
            List <uint> indices)
        {
            if (bspFile == null)
            {
                throw new ArgumentNullException(nameof(bspFile));
            }

            if (faces == null)
            {
                throw new ArgumentNullException(nameof(faces));
            }

            if (texture == null)
            {
                throw new ArgumentNullException(nameof(texture));
            }

            if (textureResourceSet == null)
            {
                throw new ArgumentNullException(nameof(textureResourceSet));
            }

            if (defaultLightmapTexture == null)
            {
                throw new ArgumentNullException(nameof(defaultLightmapTexture));
            }

            if (lightmapBuilders == null)
            {
                throw new ArgumentNullException(nameof(lightmapBuilders));
            }

            if (vertices == null)
            {
                throw new ArgumentNullException(nameof(vertices));
            }

            if (indices == null)
            {
                throw new ArgumentNullException(nameof(indices));
            }

            if (faces.Count == 0)
            {
                throw new ArgumentException("Cannot create a face buffer when no faces are provided", nameof(faces));
            }

            if (lightmapBuilders.Count == 0)
            {
                throw new ArgumentException("You must provide at least one lightmap builder", nameof(lightmapBuilders));
            }

            var lightmapBuilder = lightmapBuilders[lightmapBuilders.Count - 1];

            var firstVertex = vertices.Count;
            var firstIndex  = indices.Count;

            void AddTextureData()
            {
                lightmapBuilder.AddTextureData(new SingleTextureData
                {
                    Texture      = textureResourceSet,
                    FirstIndex   = (uint)firstIndex,
                    IndicesCount = (uint)(indices.Count - firstIndex)
                });
            }

            foreach (var face in faces)
            {
                var smax = (face.Extents[0] / 16) + 1;
                var tmax = (face.Extents[1] / 16) + 1;

                var numLightmaps = face.Styles.Count(style => style != BSPConstants.NoLightStyle);

                using (var lightmapTexture = CreateLightmapTexture(bspFile, face, numLightmaps, smax, tmax))
                {
                    var lightmap = lightmapTexture ?? defaultLightmapTexture;

                    var coordinates = lightmapBuilder.TryAllocate(lightmap);

                    if (!coordinates.HasValue)
                    {
                        //Lightmap is full

                        //Add the current vertices to the full one
                        AddTextureData();

                        //New starting point
                        firstIndex = indices.Count;

                        //Create a new one
                        lightmapBuilder = new LightmapBuilder(lightmapBuilder.Width, lightmapBuilder.Height);
                        lightmapBuilders.Add(lightmapBuilder);

                        //This can't fail without throwing an exception
                        coordinates = lightmapBuilder.TryAllocate(lightmap);
                    }

                    //Create triangles out of the face
                    foreach (var i in Enumerable.Range(vertices.Count + 1, face.Points.Count - 2))
                    {
                        indices.Add((uint)vertices.Count);
                        indices.Add((uint)i);
                        indices.Add((uint)i + 1);
                    }

                    var textureInfo = face.TextureInfo;

                    foreach (var point in face.Points)
                    {
                        var s = Vector3.Dot(point, textureInfo.SNormal) + textureInfo.SValue;
                        s /= texture.Width;

                        var t = Vector3.Dot(point, textureInfo.TNormal) + textureInfo.TValue;
                        t /= texture.Height;

                        var lightmapS = Vector3.Dot(point, textureInfo.SNormal) + textureInfo.SValue;
                        lightmapS -= face.TextureMins[0];
                        lightmapS += coordinates.Value.X * BSPConstants.LightmapScale;
                        lightmapS += 8;
                        lightmapS /= lightmapBuilder.Width * BSPConstants.LightmapScale;
                        //lightmapS /= numLightmaps != 0 ? numLightmaps : 1; //Rescale X so it covers one lightmap in the texture

                        var lightmapT = Vector3.Dot(point, textureInfo.TNormal) + textureInfo.TValue;
                        lightmapT -= face.TextureMins[1];
                        lightmapT += coordinates.Value.Y * BSPConstants.LightmapScale;
                        lightmapT += 8;
                        lightmapT /= lightmapBuilder.Height * BSPConstants.LightmapScale;

                        vertices.Add(new BSPSurfaceData
                        {
                            WorldTexture = new WorldTextureCoordinate
                            {
                                Vertex  = point,
                                Texture = new Vector2(s, t)
                            },
                            Lightmap        = new Vector2(lightmapS, lightmapT),
                            LightmapXOffset = smax / (float)lightmapBuilder.Width,
                            Style0          = face.Styles[0],
                            Style1          = face.Styles[1],
                            Style2          = face.Styles[2],
                            Style3          = face.Styles[3]
                        });
                    }
                }
            }

            AddTextureData();
        }