public dDispVert[] GetDispVerts() { lump_t lump = lumps[33]; dDispVert[] displacementVertices = new dDispVert[lump.filelen / 20]; stream.Position = lump.fileofs; for (int i = 0; i < displacementVertices.Length; i++) { displacementVertices[i].vec = new Vector3(FileReader.readFloat(stream), FileReader.readFloat(stream), FileReader.readFloat(stream)); displacementVertices[i].dist = FileReader.readFloat(stream); displacementVertices[i].alpha = FileReader.readFloat(stream); } lumpData[33] = displacementVertices; return(displacementVertices); }
static void LoadDisplacement(BinaryReader br, Header header) { // Read DispInfo br.BaseStream.Seek(header.lumps[26].fileofs, SeekOrigin.Begin); int nDispInfo = header.lumps[26].filelen / 176; world.DispIndexToFaceIndex = new int[nDispInfo]; ddispinfo_t[] ddispinfos = new ddispinfo_t[nDispInfo]; for (int i = 0; i < nDispInfo; i++) { br.BaseStream.Seek(header.lumps[26].fileofs + (i * 176), SeekOrigin.Begin); ddispinfo_t info = new ddispinfo_t(); info.startPosition = SwapZY(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle())); info.DispVertStart = (int)br.ReadUInt32(); info.DispTriStart = br.ReadInt32(); info.power = br.ReadInt32(); info.minTess = br.ReadInt32(); info.smoothingAngle = br.ReadSingle(); info.contents = br.ReadInt32(); info.MapFace = br.ReadUInt16(); info.LightmapAlphaStart = br.ReadInt32(); info.LightmapSamplePositionStart = br.ReadInt32(); info.EdgeNeighbors = new DisplaceNeighbor[4]; for (int j = 0; j < 4; j++) { DisplaceNeighbor dispNei = new DisplaceNeighbor(); dispNei.sub_neighbors = new DisplaceSubNeighbor[2]; for (int h = 0; h < 2; h++) { DisplaceSubNeighbor subNei = new DisplaceSubNeighbor(); subNei.neighbor_index = br.ReadUInt16(); subNei.neighbor_orient = br.ReadByte(); subNei.local_span = br.ReadByte(); subNei.neighbor_span = br.ReadByte(); dispNei.sub_neighbors[h] = subNei; } info.EdgeNeighbors[j] = dispNei; } info.CornerNeighbors = new DisplaceCornerNeighbor[4]; for (int j = 0; j < 4; j++) { DisplaceCornerNeighbor corner = new DisplaceCornerNeighbor(); corner.neighbor_indices = new ushort[] { br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16() }; // 4 corner.neighbor_count = br.ReadByte(); info.CornerNeighbors[j] = corner; } info.AllowedVerts = new ulong[10]; for (int j = 0; j < info.AllowedVerts.Length; j++) { info.AllowedVerts[j] = br.ReadUInt64(); } ddispinfos[i] = info; } world.ddispinfos = ddispinfos; // Read DispLIghtmapSamples br.BaseStream.Seek(header.lumps[34].fileofs, SeekOrigin.Begin); int nSamples = header.lumps[34].filelen; byte[] dispLightmapSamples = new byte[nSamples]; for (int i = 0; i < nSamples; i++) { dispLightmapSamples[i] = br.ReadByte(); } world.dispLightmapSamples = dispLightmapSamples; // Read DispVerts br.BaseStream.Seek(header.lumps[33].fileofs, SeekOrigin.Begin); int nDispVerts = header.lumps[33].filelen / 20; dDispVert[] dispVerts = new dDispVert[nDispVerts]; for (int i = 0; i < nDispVerts; i++) { dDispVert vert = new dDispVert(); vert.vec = SwapZY(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle())); vert.dist = br.ReadSingle(); vert.alpha = br.ReadSingle(); dispVerts[i] = vert; } world.dispVerts = dispVerts; // Read DispTris br.BaseStream.Seek(header.lumps[48].fileofs, SeekOrigin.Begin); int nDispTris = header.lumps[48].filelen / 2; dDispTri[] dispTris = new dDispTri[nDispTris]; for (int i = 0; i < nDispTris; i++) { dDispTri vert = new dDispTri(); vert.Tags = br.ReadUInt16(); dispTris[i] = vert; } world.dispTris = dispTris; }
public dDispVert[] GetDispVerts() { lump_t lump = lumps[33]; dDispVert[] displacementVertices = new dDispVert[lump.filelen / 20]; stream.Position = lump.fileofs; for (int i = 0; i < displacementVertices.Length; i++) { displacementVertices[i].vec = new Vector3(FileReader.readFloat(stream), FileReader.readFloat(stream), FileReader.readFloat(stream)); displacementVertices[i].dist = FileReader.readFloat(stream); displacementVertices[i].alpha = FileReader.readFloat(stream); } lumpData[33] = displacementVertices; return displacementVertices; }
static void CreateDispFaces() { BSP_CDisp = new Face[BSP_DispInfo.Length]; for (Int32 Index = 0; Index < BSP_DispInfo.Length; Index++) { Face MapFace = BSP_CFaces[BSP_DispInfo[Index].MapFace]; Vector3[] FaceVertices = MapFace.Vertices; List <Color32> VertColors = new List <Color32>(); List <Vector3> DispVertices = new List <Vector3>(); List <Int32> DispIndices = new List <Int32>(); List <Vector2> TextureCoordinates = new List <Vector2>(); List <Vector2> LightmapCoordinates = new List <Vector2>(); for (Int32 i = 0; i < FaceVertices.Length; i++) { FaceVertices[i] = MathUtils.UnSwapZY(FaceVertices[i]); } Vector3 tS = new Vector3(MapFace.TexInfo.TextureVecs[0].x, MapFace.TexInfo.TextureVecs[0].y, MapFace.TexInfo.TextureVecs[0].z); Vector3 tT = new Vector3(MapFace.TexInfo.TextureVecs[1].x, MapFace.TexInfo.TextureVecs[1].y, MapFace.TexInfo.TextureVecs[1].z); Int32 MinIndex = 0; Single MinDist = 1.0e9f; for (Int32 i = 0; i < 4; i++) { Single Distance = Vector3.Distance(FaceVertices[i], BSP_DispInfo[Index].StartPosition * ConfigLoader.WorldScale); if (Distance < MinDist) { MinDist = Distance; MinIndex = i; } } for (Int32 i = 0; i < MinIndex; i++) { Vector3 Temp = FaceVertices[0]; FaceVertices[0] = FaceVertices[1]; FaceVertices[1] = FaceVertices[2]; FaceVertices[2] = FaceVertices[3]; FaceVertices[3] = Temp; } Vector3 LeftEdge = FaceVertices[1] - FaceVertices[0]; Vector3 RightEdge = FaceVertices[2] - FaceVertices[3]; Int32 NumEdgeVertices = (1 << BSP_DispInfo[Index].Power) + 1; Single SubdivideScale = 1.0f / (NumEdgeVertices - 1); Single LightDeltaU = (1f) / (NumEdgeVertices - 1); Single LightDeltaV = (1f) / (NumEdgeVertices - 1); Vector3 LeftEdgeStep = LeftEdge * SubdivideScale; Vector3 RightEdgeStep = RightEdge * SubdivideScale; for (Int32 i = 0; i < NumEdgeVertices; i++) { Vector3 LeftEnd = LeftEdgeStep * i; LeftEnd += FaceVertices[0]; Vector3 RightEnd = RightEdgeStep * i; RightEnd += FaceVertices[3]; Vector3 LeftRightSeg = RightEnd - LeftEnd; Vector3 LeftRightStep = LeftRightSeg * SubdivideScale; for (Int32 j = 0; j < NumEdgeVertices; j++) { Int32 DispVertIndex = BSP_DispInfo[Index].DispVertStart + (i * NumEdgeVertices + j); dDispVert DispVertInfo = BSP_DispVerts[DispVertIndex]; Vector3 FlatVertex = LeftEnd + (LeftRightStep * j); Vector3 DispVertex = DispVertInfo.Vec * (DispVertInfo.Dist * ConfigLoader.WorldScale); DispVertex += FlatVertex; Single s = (Vector3.Dot(FlatVertex, tS) + MapFace.TexInfo.TextureVecs[0].w * ConfigLoader.WorldScale) / (MapFace.TexData.View_Width * ConfigLoader.WorldScale); Single t = (Vector3.Dot(FlatVertex, tT) + MapFace.TexInfo.TextureVecs[1].w * ConfigLoader.WorldScale) / (MapFace.TexData.View_Height * ConfigLoader.WorldScale); TextureCoordinates.Add(new Vector2(s, t)); Single l_s = (LightDeltaU * j * MapFace.LightMapW + 0.5f) / (MapFace.LightMapW + 1); Single l_t = (LightDeltaV * i * MapFace.LightMapH + 0.5f) / (MapFace.LightMapH + 1); LightmapCoordinates.Add(new Vector2(l_s, l_t)); VertColors.Add(new Color32(0, 0, 0, (Byte)(DispVertInfo.Alpha))); DispVertices.Add(new Vector3(-DispVertex.x, DispVertex.z, DispVertex.y)); } } for (Int32 i = 0; i < NumEdgeVertices - 1; i++) { for (Int32 j = 0; j < NumEdgeVertices - 1; j++) { Int32 vIndex = i * NumEdgeVertices + j; if ((vIndex % 2) == 1) { DispIndices.Add(vIndex); DispIndices.Add(vIndex + 1); DispIndices.Add(vIndex + NumEdgeVertices); DispIndices.Add(vIndex + 1); DispIndices.Add(vIndex + NumEdgeVertices + 1); DispIndices.Add(vIndex + NumEdgeVertices); } else { DispIndices.Add(vIndex); DispIndices.Add(vIndex + NumEdgeVertices + 1); DispIndices.Add(vIndex + NumEdgeVertices); DispIndices.Add(vIndex); DispIndices.Add(vIndex + 1); DispIndices.Add(vIndex + NumEdgeVertices + 1); } } } BSP_CDisp[Index] = new Face { Vertices = DispVertices.ToArray(), Triangles = DispIndices.ToArray(), Colors = VertColors.ToArray(), UV = TextureCoordinates.ToArray(), UV2 = LightmapCoordinates.ToArray(), LightOfs = MapFace.LightOfs, LightMapW = MapFace.LightMapW, LightMapH = MapFace.LightMapH }; } }
// I'm not the author of this method. I translated it on ะก#. // http://trac.openscenegraph.org/projects/osg/browser/OpenSceneGraph/branches/OpenSceneGraph-osgWidget-dev/src/osgPlugins/bsp/VBSPGeometry.cpp?rev=9236 private static face CreateDispSurface(int dispIndex) { List <Vector3> faceVertices = new List <Vector3>(); List <Vector3> dispVertices = new List <Vector3>(); List <Int32> dispIndices = new List <int>(); List <Vector2> textureCoordinates = new List <Vector2>(); // List<Vector2> lightmapCoordinates = new List<Vector2>(); dface_t faceInfo = BSP_Faces[BSP_DispInfo[dispIndex].MapFace]; int minIndex = 0; for (int i = faceInfo.firstedge; i < (faceInfo.firstedge + faceInfo.numedges); i++) { faceVertices.Add((BSP_Surfedges[i] > 0 ? BSP_Vertices[BSP_Edges[Mathf.Abs(BSP_Surfedges[i])].v[0]] : BSP_Vertices[BSP_Edges[Mathf.Abs(BSP_Surfedges[i])].v[1]]) * WorldController.WorldScale); } float minDist = 1.0e9f; for (int i = 0; i < 4; i++) { float dist = (faceVertices[i] - BSP_DispInfo[dispIndex].startPosition * WorldController.WorldScale).magnitude; if (dist < minDist) { minDist = dist; minIndex = i; } } for (int i = 0; i < minIndex; i++) { Vector3 temp = faceVertices[0]; faceVertices[0] = faceVertices[1]; faceVertices[1] = faceVertices[2]; faceVertices[2] = faceVertices[3]; faceVertices[3] = temp; } Vector3 leftEdge = faceVertices[1] - faceVertices[0]; Vector3 rightEdge = faceVertices[2] - faceVertices[3]; int numEdgeVertices = (1 << BSP_DispInfo[dispIndex].power) + 1; float subdivideScale = 1.0f / (numEdgeVertices - 1); Vector3 leftEdgeStep = leftEdge * subdivideScale; Vector3 rightEdgeStep = rightEdge * subdivideScale; for (int i = 0; i < numEdgeVertices; i++) { Vector3 leftEnd = leftEdgeStep * i; leftEnd += faceVertices[0]; Vector3 rightEnd = rightEdgeStep * i; rightEnd += faceVertices[3]; Vector3 leftRightSeg = rightEnd - leftEnd; Vector3 leftRightStep = leftRightSeg * subdivideScale; for (int j = 0; j < numEdgeVertices; j++) { int dispVertIndex = BSP_DispInfo[dispIndex].DispVertStart; dispVertIndex += i * numEdgeVertices + j; dDispVert dispVertInfo = BSP_DispVerts[dispVertIndex]; Vector3 flatVertex = leftEnd + (leftRightStep * j); Vector3 dispVertex = dispVertInfo.vec * (dispVertInfo.dist * WorldController.WorldScale); dispVertex += flatVertex; texinfo_t faceTexinfo = BSP_Texinfo[faceInfo.texinfo]; float fU = Vector3.Dot(new Vector3(faceTexinfo.textureVecs[0].x, faceTexinfo.textureVecs[0].y, faceTexinfo.textureVecs[0].z), flatVertex) + faceTexinfo.textureVecs[0].w * WorldController.WorldScale; float fV = Vector3.Dot(new Vector3(faceTexinfo.textureVecs[1].x, faceTexinfo.textureVecs[1].y, faceTexinfo.textureVecs[1].z), flatVertex) + faceTexinfo.textureVecs[1].w * WorldController.WorldScale; fU /= (BSP_Texdata[faceTexinfo.texdata].width * WorldController.WorldScale); fV /= (BSP_Texdata[faceTexinfo.texdata].height * WorldController.WorldScale); textureCoordinates.Add(new Vector2(fU, fV)); dispVertices.Add(new Vector3(-dispVertex.x, dispVertex.z, dispVertex.y)); } } for (int i = 0; i < numEdgeVertices - 1; i++) { for (int j = 0; j < numEdgeVertices - 1; j++) { int index = i * numEdgeVertices + j; if ((index % 2) == 1) { dispIndices.Add(index); dispIndices.Add(index + 1); dispIndices.Add(index + numEdgeVertices); dispIndices.Add(index + 1); dispIndices.Add(index + numEdgeVertices + 1); dispIndices.Add(index + numEdgeVertices); } else { dispIndices.Add(index); dispIndices.Add(index + numEdgeVertices + 1); dispIndices.Add(index + numEdgeVertices); dispIndices.Add(index); dispIndices.Add(index + 1); dispIndices.Add(index + numEdgeVertices + 1); } } } return(new face() { index = BSP_DispInfo[dispIndex].MapFace, points = dispVertices.ToArray(), triangles = dispIndices.ToArray(), uv = textureCoordinates.ToArray() }); }