Пример #1
0
    private static void FuncRotatingSpawn(GameModel model)
    {
        model.clipTest = true;

        BSPEnt e = model.Ent;

        e.SetThinkAndTouch(EntityThink.FuncRotatingThink, null);
    }
Пример #2
0
    private static void DebugEntityStrings(BSPEnt e)
    {
#if DEBUG
        Console.DebugLog("Logging entity strings for " + e.Classname);
        foreach (var s in e.strings)
        {
            Console.Log("> " + s.Key + " = " + s.Value);
        }
    }
Пример #3
0
    /// <summary>
    /// Creates the model.s
    /// </summary>
    /// <param name="model">BSP model</param>
    /// <param name="entity">Entity data.</param>
    public void CreateModel(BSPModel model, BSPEnt entity)
    {
        MeshFilter     meshFilter;
        MeshRenderer   meshRenderer;
        LightmapAtlas  newAtlas;
        Color          col;
        List <BSPFace> fs;
        float          transparency;
        bool           depthMask;
        bool           hasTexture;
        bool           hasLightmap;

        //set gameobject's name
        gameObject.name = "GM(" + entity.Classname + ")";
        Ent             = entity;
        Bmodel          = model;

        if (model == null || model.numfaces == 0)
        {
            //entity with no bmodel - run spawn and return
            EntitySpawn.Instance.SpawnEntity(this);
            return;
        }

        BSPFace[] faces = model.Faces;

        //group faces by texture and its contents
        var groupsByTexture = faces.GroupBy(i => new {
            i.BSPTexInfo.texfile_guid,
            i.BSPTexInfo.flags,
            c = Utils.GetPointContents(i.Center - (i.Normal * 0.5f)).HasFlag(BrushContents.CONTENTS_WATER) && i.Normal.y == 1
        }).Select(group => group.ToList()).ToList();

        //limit group size to maxgroup
        faceGroups = new List <List <BSPFace> >();
        foreach (List <BSPFace> list in groupsByTexture)
        {
            if (list.Count > maxgroup)
            {
                faceGroups.AddRange(list.Select((x, i) => new { Index = i, Value = x }).GroupBy(x => x.Index / maxgroup).Select(x => x.Select(v => v.Value).ToList()).ToList());
            }
            else
            {
                faceGroups.Add(list);
            }
        }

        //create Bmodel geometry
        for (int a = 0; a < faceGroups.Count; a++)
        {
            fs = faceGroups[a];

            //nodraw brushes can only have a collider mesh
            //TODO: should this only happen to clip brushes?
            if (fs[0].BSPTexInfo.flags.HasFlag(SurfFlags.SURF_NODRAW))
            {
                tris.Clear();
                verts.Clear();

                foreach (BSPFace f in fs)
                {
                    AddFaceToMeshData(f, false, false);
                }

                collisionVerts.AddRange(verts);
                collisionTris.AddRange(tris);

                continue;
            }

            //is this a depth mask?
            depthMask = fs[0].BSPTexInfo.flags.HasFlag(SurfFlags.SURF_SKY);

            //create a lightmap atlas for the group
            if (fs[0].lightmap != null && !depthMask)
            {
                Texture2D[] texs = new Texture2D[fs.Count];

                for (int g = 0; g < texs.Length; g++)
                {
                    if (fs[g].lightmap != null)
                    {
                        texs[g] = fs[g].lightmap.tex;
                    }
                }

                newAtlas = new LightmapAtlas
                {
                    tex = new Texture2D(512, 512)
                };

                //pack the atlas
                newAtlas.rect = newAtlas.tex.PackTextures(texs, 2, 512);

                newAtlas.tex.filterMode = FilterMode.Trilinear;

                for (int b = 0; b < fs.Count; b++)
                {
                    fs[b].atlas       = newAtlas;
                    fs[b].atlas_index = b;
                }

                hasLightmap = true;
            }
            else
            {
                hasLightmap = false;
            }

            GameObject o;

            //if group is made out of sky brushes make it a depth mask
            if (depthMask)
            {
                o            = Instantiate(depthMaskObject, transform);
                hasTexture   = false;
                transparency = -1;

                meshRenderer = o.GetComponent <MeshRenderer>();
            }
            else
            {
                //check object transparency
                if (fs[0].BSPTexInfo.flags.HasFlag(SurfFlags.SURF_TRANS33))
                {
                    transparency = 0.33f;
                }
                else if (fs[0].BSPTexInfo.flags.HasFlag(SurfFlags.SURF_TRANS66))
                {
                    transparency = 0.66f;
                }
                else
                {
                    transparency = -1; //solid
                }

                //instantiate object and set its transparency
                if (transparency > 0)
                {
                    o            = Instantiate(waterObject, transform);
                    meshRenderer = o.GetComponent <MeshRenderer>();

                    col   = Color.white;
                    col.a = transparency;
                    meshRenderer.material.color = col;
                }
                else
                {
                    o            = Instantiate(mapObject, transform);
                    meshRenderer = o.GetComponent <MeshRenderer>();
                }
            }

            //clear lists
            tris.Clear();
            verts.Clear();
            uvs.Clear();
            uvs2.Clear();

            meshFilter = o.GetComponent <MeshFilter>();

            //set object's name
            o.name = entity.Classname + " " + a.ToString();

            //create mesh
            Mesh mesh = new Mesh()
            {
                name = entity.Classname
            };

            //check if a texture has been successfully loaded
            hasTexture = TextureLoader.HasTexture(fs[0].BSPTexInfo.texfile_guid);

            //read all faces into mesh arrays
            foreach (BSPFace f in fs)
            {
                AddFaceToMeshData(f, hasTexture, hasLightmap);
            }

            //add mesh data to collision mesh
            collisionVerts.AddRange(verts);
            collisionTris.AddRange(tris);

            //fill the mesh
            mesh.vertices = verts.ToArray();
            if (hasTexture)
            {
                mesh.uv = uvs.ToArray();
            }
            mesh.triangles = tris.ToArray();
            if (hasLightmap)
            {
                mesh.uv2 = uvs2.ToArray();
            }

            //calculate normals and bounds
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            meshFilter.mesh = mesh;

            //set textures
            if (hasTexture)
            {
                meshRenderer.material.mainTexture = TextureLoader.GetTexture(fs[0].BSPTexInfo.texfile_guid);
            }

            //set lightmap textures
            if (hasLightmap)
            {
                meshRenderer.material.SetTexture("_LightmapTex", fs[0].atlas.tex);
            }

            //add object to list
            faceObjects.Add(o);
        }

        //spawn bmodel entity at the very end!
        EntitySpawn.Instance.SpawnEntity(this);

        //generate collision mesh
        MeshCollider meshCollider = GetComponent <MeshCollider>();

        if (meshCollider)
        {
            Mesh collisionMesh = new Mesh
            {
                vertices  = collisionVerts.ToArray(),
                triangles = collisionTris.ToArray()
            };

            collisionMesh.RecalculateNormals();
            collisionMesh.RecalculateBounds();
            collisionMesh.name = entity.Classname;

            meshCollider.sharedMesh = collisionMesh;
        }
    }