private static void FuncRotatingSpawn(GameModel model) { model.clipTest = true; BSPEnt e = model.Ent; e.SetThinkAndTouch(EntityThink.FuncRotatingThink, null); }
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); } }
/// <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; } }