bsptexinfo[] ReadTexInfos() { br.BaseStream.Seek(header.lumps [SourceBSPStructs.LUMP_TEXINFO].fileofs, SeekOrigin.Begin); int numTexinfos = header.lumps [SourceBSPStructs.LUMP_TEXINFO].filelen / 72; bsptexinfo[] temp = new bsptexinfo[numTexinfos]; for (int i = 0; i < numTexinfos; i++) { bsptexinfo texinfo = new bsptexinfo(); texinfo.texvecs = ConvertUtils.FlipVector(ConvertUtils.ReadVector3(br)); texinfo.texoffs = br.ReadSingle(); texinfo.texvect = ConvertUtils.FlipVector(ConvertUtils.ReadVector3(br)); texinfo.texofft = br.ReadSingle(); texinfo.lightvecs = ConvertUtils.FlipVector(ConvertUtils.ReadVector3(br)); texinfo.lightoffs = br.ReadSingle(); texinfo.lightvect = ConvertUtils.FlipVector(ConvertUtils.ReadVector3(br)); texinfo.lightofft = br.ReadSingle(); texinfo.flags = br.ReadInt32(); texinfo.texdata = br.ReadInt32(); temp[i] = texinfo; } tempLog += ("Load: " + numTexinfos + " TexInfos \n"); return(temp); }
surface BuildDispFace(int faceIndex, int model, short dispinfoId) { Vector3[] vertices = new Vector3[4]; List <Vector3> disp_verts = new List <Vector3>(); List <Vector2> UVs = new List <Vector2>(); List <Color32> cols = new List <Color32>(); List <int> indices = new List <int>(); bspface curFace = map.facesLump[faceIndex]; bsptexinfo curTexInfo = map.texinfosLump[curFace.texinfo]; bsptexdata curTexData = map.texdataLump[curTexInfo.texdata]; int fEdge = curFace.firstedge; for (int i = 0; i < curFace.numedges; i++) { vertices[i] = (map.surfedgesLump[fEdge + i] > 0 ? map.vertexesLump[map.edgesLump[Mathf.Abs(map.surfedgesLump[fEdge + i])][0]] : map.vertexesLump[map.edgesLump[Mathf.Abs(map.surfedgesLump[fEdge + i])][1]]); } bspdispinfo curDisp = map.dispinfoLump [dispinfoId]; Vector3 startPos = curDisp.startPosition; float dist; float minDist = 0.1f; int minIndex = 0; for (int i = 0; i < 4; i++) { dist = Vector3.Distance(startPos, vertices[i]); if (dist < minDist) { minDist = dist; minIndex = i; } } Vector3 temp; for (int i = 0; i < minIndex; i++) { temp = vertices[0]; vertices[0] = vertices[1]; vertices[1] = vertices[2]; vertices[2] = vertices[3]; vertices[3] = temp; } Vector3 leftEdge = vertices[1] - vertices[0]; Vector3 rightEdge = vertices[2] - vertices[3]; int numEdgeVertices = (1 << curDisp.power) + 1; float subdivideScale = 1.0f / (float)(numEdgeVertices - 1); Vector3 leftEdgeStep = leftEdge * subdivideScale; Vector3 rightEdgeStep = rightEdge * subdivideScale; int firstVertex = 0; Vector3 leftEnd; Vector3 rightEnd; Vector3 leftRightSeg; Vector3 leftRightStep; int dispVertIndex; bspDispVert dispVert; Vector3 flatVertex; Vector3 dispVertex; float scaleU = (float)1f / curTexData.width; float scaleV = (float)1f / curTexData.height; for (int i = 0; i < numEdgeVertices; i++) { leftEnd = leftEdgeStep * (float)i; leftEnd += vertices[0]; rightEnd = rightEdgeStep * (float)i; rightEnd += vertices[3]; leftRightSeg = rightEnd - leftEnd; leftRightStep = leftRightSeg * subdivideScale; for (int j = 0; j < numEdgeVertices; j++) { dispVertIndex = curDisp.DispVertStart; dispVertIndex += i * numEdgeVertices + j; dispVert = map.dispVertsLump[dispVertIndex]; flatVertex = leftEnd + (leftRightStep * (float)j); dispVertex = dispVert.vec * (dispVert.dist /* *scale*/); dispVertex += flatVertex; disp_verts.Add(dispVertex); float tU = Vector3.Dot(flatVertex, curTexInfo.texvecs) + (curTexInfo.texoffs); float tV = Vector3.Dot(flatVertex, curTexInfo.texvect) + (curTexInfo.texofft); UVs.Add(new Vector2(tU * scaleU, tV * scaleV)); cols.Add(new Color32((byte)(dispVert.alpha), 0, 0, 0)); } } int curIndex; for (int i = 0; i < numEdgeVertices - 1; i++) { for (int j = 0; j < numEdgeVertices - 1; j++) { curIndex = i * numEdgeVertices + j; if ((curIndex % 2) == 1) { curIndex += firstVertex; indices.Add(curIndex + 1); indices.Add(curIndex); indices.Add(curIndex + numEdgeVertices); indices.Add(curIndex + numEdgeVertices + 1); indices.Add(curIndex + 1); indices.Add(curIndex + numEdgeVertices); } else { curIndex += firstVertex; indices.Add(curIndex); indices.Add(curIndex + numEdgeVertices); indices.Add(curIndex + numEdgeVertices + 1); indices.Add(curIndex + 1); indices.Add(curIndex); indices.Add(curIndex + numEdgeVertices + 1); } } } for (int i = 0; i < disp_verts.Count; i++) { disp_verts[i] *= uSrcSettings.Inst.worldScale; } surface f = new surface(); f.index = faceIndex; //f.flags = flags; f.dispinfo = dispinfoId; f.points = disp_verts.ToArray(); f.uv = UVs.ToArray(); //f.uv2 = UV2s; f.cols = cols.ToArray(); f.triangles = indices.ToArray(); //f.lightMapW = lightmapW; //f.lightMapH = lightmapH; return(f); }
bool BuildFace(int index, ref Vector3[] verts, ref Vector2[] UVs, ref Vector2[] UV2s, ref int[] tris, int vertOffs, int triOffs) { bspface curface = map.facesLump[index]; int startEdge = curface.firstedge; int nEdges = curface.numedges; bsptexinfo texInfo = map.texinfosLump[curface.texinfo]; //Debug.Log("texinfo "+curface.texinfo+"/"+map.texinfosLump.Length); int tiFlags = texInfo.flags; int lightmapW = curface.LightmapTextureSizeInLuxels[0] + 1; int lightmapH = curface.LightmapTextureSizeInLuxels[1] + 1; int lmx = 0, lmy = 0; if (uSrcSettings.Inst.lightmaps && (tiFlags & SourceBSPStructs.SURF_NOLIGHT) == 0) { if (!LM_AllocBlock(lightmapW, lightmapH, out lmx, out lmy)) { Debug.LogWarning("LM_AllocBlock failed on face " + index); return(false); } } for (int i = 0; i < nEdges; i++) { //verts.Add( map.surfedgesLump[i]>0 ? verts[vertOffs + i] = (map.vertexesLump[map.edgesLump[Math.Abs(map.surfedgesLump[startEdge + i])][map.surfedgesLump[startEdge + i] > 0?0:1]]); } int j = triOffs; for (int i = 0; i < nEdges - 2; i++) { tris[j] = vertOffs; tris[j + 1] = vertOffs + i + 1; tris[j + 2] = vertOffs + i + 2; j += 3; } float scales = map.texdataLump[texInfo.texdata].width * uSrcSettings.Inst.worldScale; float scalet = map.texdataLump[texInfo.texdata].height * uSrcSettings.Inst.worldScale; for (int i = 0; i < nEdges; i++) { float tU = Vector3.Dot(verts[vertOffs + i] * uSrcSettings.Inst.worldScale, texInfo.texvecs) + (texInfo.texoffs * uSrcSettings.Inst.worldScale); float tV = Vector3.Dot(verts[vertOffs + i] * uSrcSettings.Inst.worldScale, texInfo.texvect) + (texInfo.texofft * uSrcSettings.Inst.worldScale); UVs[vertOffs + i] = new Vector2(tU / scales, tV / scalet); } for (int i = 0; i < nEdges; i++) { float U, V; if ((tiFlags & SourceBSPStructs.SURF_NOLIGHT) == 0) { U = Vector3.Dot(verts[vertOffs + i], texInfo.lightvecs) + texInfo.lightoffs + 0.5f - curface.LightmapTextureMinsInLuxels[0] + lmx; V = Vector3.Dot(verts[vertOffs + i], texInfo.lightvect) + texInfo.lightofft + 0.5f - curface.LightmapTextureMinsInLuxels[1] + lmy; } else { U = BLOCK_SIZE - 2; V = BLOCK_SIZE - 2; } UV2s[vertOffs + i] = new Vector2(U / BLOCK_SIZE, V / BLOCK_SIZE); } for (int i = 0; i < nEdges; i++) { verts[vertOffs + i] *= uSrcSettings.Inst.worldScale; } if (uSrcSettings.Inst.lightmaps && (tiFlags & SourceBSPStructs.SURF_NOLIGHT) == 0) { CreateLightmapTex(lightmapW, lightmapH, lmx, lmy, index); } return(true); }
surface BuildFace(int index) { List <Vector3> verts = new List <Vector3>(); List <Vector2> UVs = new List <Vector2>(); List <Vector2> UV2s = new List <Vector2>(); List <int> tris = new List <int>(); bspface curface = map.facesLump[index]; int startEdge = curface.firstedge; int nEdges = curface.numedges; //Debug.Log("texinfo "+curface.texinfo+"/"+map.texinfosLump.Length); int flags = map.texinfosLump [curface.texinfo].flags; for (int i = startEdge; i < startEdge + nEdges; i++) { verts.Add(map.surfedgesLump[i] > 0 ? map.vertexesLump[map.edgesLump[Mathf.Abs(map.surfedgesLump[i])][0]] : map.vertexesLump[map.edgesLump[Mathf.Abs(map.surfedgesLump[i])][1]]); } for (int i = 1; i < verts.Count - 1; i++) { tris.Add(0); tris.Add(i); tris.Add(i + 1); } bsptexinfo texInfo = map.texinfosLump [map.facesLump [index].texinfo]; float scales = map.texdataLump[texInfo.texdata].width * uSrcSettings.Inst.worldScale; float scalet = map.texdataLump[texInfo.texdata].height * uSrcSettings.Inst.worldScale; for (int i = 0; i < verts.Count; i++) { float tU = Vector3.Dot(verts[i] * uSrcSettings.Inst.worldScale, texInfo.texvecs) + (texInfo.texoffs * uSrcSettings.Inst.worldScale); float tV = Vector3.Dot(verts[i] * uSrcSettings.Inst.worldScale, texInfo.texvect) + (texInfo.texofft * uSrcSettings.Inst.worldScale); UVs.Add(new Vector2(tU / scales, tV / scalet)); } int lightmapW = (map.facesLump[index].LightmapTextureSizeInLuxels[0] + 1); int lightmapH = (map.facesLump[index].LightmapTextureSizeInLuxels[1] + 1); for (int i = 0; i < verts.Count; i++) { float U = Vector3.Dot(verts[i], texInfo.lightvecs) + texInfo.lightoffs + 0.5f - map.facesLump[index].LightmapTextureMinsInLuxels[0]; float V = Vector3.Dot(verts[i], texInfo.lightvect) + texInfo.lightofft + 0.5f - map.facesLump[index].LightmapTextureMinsInLuxels[1]; //U=(U*(float)((float)lightmapW/((float)lightmapW+2f)))+(1f/((float)lightmapW+2f)); //V=(V*(float)((float)lightmapH/((float)lightmapH+2f)))+(1f/((float)lightmapH+2f)); UV2s.Add(new Vector2(U / (lightmapW), V / (lightmapH))); } for (int i = 0; i < verts.Count; i++) { verts[i] *= uSrcSettings.Inst.worldScale; } int texID = map.texdataLump [map.texinfosLump [map.facesLump [index].texinfo].texdata].nameStringTableID; surface f = new surface(); f.index = index; f.flags = flags; f.texID = texID; f.dispinfo = curface.dispinfo; f.points = verts.ToArray(); f.uv = UVs.ToArray(); f.uv2 = UV2s.ToArray(); f.triangles = tris.ToArray(); f.lightMapW = lightmapW; f.lightMapH = lightmapH; return(f); }