public void FinalizeVertices(LightmapResource lightmap, bool regen) { _lightmapcoords = new float[_bspVertices.Count * 2]; for (int i = 0; i < _surfaces.Length; i++) { if (i == 45) { i = i; } for (int j = 0; j < _surfaces[i].indices.Length; j++) { float u = (_surfaces[i].uCoord + _texcoords[_surfaces[i].indices[j] * 2 + 0]) * _surfaces[i].uScale; float v = (_surfaces[i].vCoord + _texcoords[_surfaces[i].indices[j] * 2 + 1]) * _surfaces[i].vScale; //_lightmapcoords[_surfaces[i].indices[j] * 2 + 0] = u; //_lightmapcoords[_surfaces[i].indices[j] * 2 + 1] = v; _lightmapcoords[(_surfaces[i].VertexIndex + j) * 2 + 0] = u; _lightmapcoords[(_surfaces[i].VertexIndex + j) * 2 + 1] = v; if (lightmap != null) { Rect lightmapRect = lightmap.PackedLightmaps.GetPackedTextureRect(i); //_lightmapcoords[_surfaces[i].indices[j] * 2 + 0] += 1.0f / lightmapRect.Width * 0.5f; //_lightmapcoords[_surfaces[i].indices[j] * 2 + 1] += 1.0f / lightmapRect.Height * 0.5f; float lu = (lightmapRect.X + 0.5f) / lightmap.PackedLightmapTexture.Width; float lv = (lightmapRect.Y + 0.5f) / lightmap.PackedLightmapTexture.Height; float lw = (lightmapRect.Width - 1.0f) / lightmap.PackedLightmapTexture.Width; float lh = (lightmapRect.Height - 1.0f) / lightmap.PackedLightmapTexture.Height; BspVertex vertex = _bspVertices[_surfaces[i].VertexIndex + j]; vertex.LU = lu + u * lw; vertex.LV = lv + v * lh; _bspVertices[_surfaces[i].VertexIndex + j] = vertex; } else { BspVertex vertex = _bspVertices[_surfaces[i].VertexIndex + j]; vertex.LU = u; vertex.LV = v; _bspVertices[_surfaces[i].VertexIndex + j] = vertex; } } } _allVertices = RendererManager.CurrentRenderer.CreateVertexBuffer(VertexBufferUsage.Static, _bspVertices.ToArray(), _bspVertices.Count, _vertexDeclaration); }
public BspResource(string name, System.IO.Stream stream, Resource.ResourceManager content) : base(name, true) { System.IO.BinaryReader reader = new System.IO.BinaryReader(stream); // read the header BspHeader header = new BspHeader(); header.heading = reader.ReadBytes(4); header.minorVersion = reader.ReadUInt16(); header.majorVersion = reader.ReadUInt16(); header.dataSectionSize = reader.ReadUInt32(); header.rootIndex = reader.ReadUInt32(); header.numModels = reader.ReadUInt32(); header.numVertices = reader.ReadUInt32(); header.numTexCoords = reader.ReadUInt32(); header.numVertexIndices = reader.ReadUInt32(); header.numTexIndices = reader.ReadUInt32(); header.numSurfaces = reader.ReadUInt32(); header.numPlanes = reader.ReadUInt32(); header.numNodes = reader.ReadUInt32(); header.numPolygons = reader.ReadUInt32(); // read the model names byte[] buffer32 = new byte[32]; BspModel[] models = new BspModel[header.numModels]; _modelsNames = new string[header.numModels]; for (uint i = 0; i < header.numModels; i++) { models[i] = new BspModel(); models[i].name = Gk3Main.Utils.ConvertAsciiToString(reader.ReadBytes(32)); _modelsNames[i] = models[i].name; } // read the surfaces Random randomGenerator = new Random(); _surfaces = new BspSurface[header.numSurfaces]; for (uint i = 0; i < header.numSurfaces; i++) { if (i == 134) { i = i; } _surfaces[i] = new BspSurface(); _surfaces[i].modelIndex = reader.ReadUInt32(); _surfaces[i].texture = Gk3Main.Utils.ConvertAsciiToString(reader.ReadBytes(32)); _surfaces[i].uCoord = reader.ReadSingle(); _surfaces[i].vCoord = reader.ReadSingle(); _surfaces[i].uScale = reader.ReadSingle(); _surfaces[i].vScale = reader.ReadSingle(); _surfaces[i].size1 = reader.ReadUInt16(); _surfaces[i].size2 = reader.ReadUInt16(); _surfaces[i].flags = (BspSurfaceFlags)reader.ReadUInt32(); _surfaces[i].r = (float)randomGenerator.NextDouble(); _surfaces[i].g = (float)randomGenerator.NextDouble(); _surfaces[i].b = (float)randomGenerator.NextDouble(); _surfaces[i].index = i; } // read the BSP nodes (for now throw them away) _nodes = new BspNode[header.numNodes]; for (uint i = 0; i < header.numNodes; i++) { _nodes[i].Left = reader.ReadInt16(); _nodes[i].Right = reader.ReadInt16(); _nodes[i].PlaneIndex = reader.ReadInt16(); _nodes[i].PolygonStartIndex = reader.ReadInt16(); reader.ReadInt16(); _nodes[i].NumPolygons = reader.ReadInt16(); uint i3 = reader.ReadUInt16(); uint i4 = reader.ReadUInt16(); } // TEMP: validate the BSP foreach (BspNode node in _nodes) { if (node.Left >= _nodes.Length || node.Right >= _nodes.Length) { throw new Exception("OH NO!"); } } int parent = findParent(_nodes, 0); // read all the polygons _polygons = new BspPolygon[header.numPolygons]; for (uint i = 0; i < header.numPolygons; i++) { _polygons[i] = new BspPolygon(); _polygons[i].vertexIndex = reader.ReadUInt16(); _polygons[i].flags = reader.ReadUInt16(); _polygons[i].numVertices = reader.ReadUInt16(); _polygons[i].surfaceIndex = reader.ReadUInt16(); if (_polygons[i].surfaceIndex == 134) { i = i; } } // read all the planes (thow them away) for (uint i = 0; i < header.numPlanes; i++) { reader.ReadBytes(16); } // read the vertices _vertices = new float[header.numVertices * 3]; for (uint i = 0; i < header.numVertices; i++) { _vertices[i * 3 + 0] = reader.ReadSingle(); _vertices[i * 3 + 1] = reader.ReadSingle(); _vertices[i * 3 + 2] = reader.ReadSingle(); } // read the texture vertices _texcoords = new float[header.numTexCoords * 2]; for (uint i = 0; i < header.numTexCoords; i++) { _texcoords[i * 2 + 0] = reader.ReadSingle(); _texcoords[i * 2 + 1] = reader.ReadSingle(); } // read all the vertex indices ushort[] indices = new ushort[header.numVertexIndices]; for (uint i = 0; i < header.numVertexIndices; i++) { indices[i] = reader.ReadUInt16(); } // read all the texcoord indices ushort[] texindices = new ushort[header.numTexIndices]; for (uint i = 0; i < header.numTexIndices; i++) { texindices[i] = reader.ReadUInt16(); } // read the bounding spheres _boundingSpheres = new Math.Vector4[header.numNodes]; for (uint i = 0; i < header.numNodes; i++) { _boundingSpheres[i].Z = reader.ReadSingle(); _boundingSpheres[i].Y = reader.ReadSingle(); _boundingSpheres[i].X = reader.ReadSingle(); _boundingSpheres[i].W = reader.ReadSingle(); } // load the "thingies", whatever that means _bspVertices = new List <BspVertex>(); for (int i = 0; i < header.numSurfaces; i++) { // throw junk away _surfaces[i].boundingSphere.X = reader.ReadSingle(); _surfaces[i].boundingSphere.Y = reader.ReadSingle(); _surfaces[i].boundingSphere.Z = reader.ReadSingle(); _surfaces[i].boundingSphere.W = reader.ReadSingle(); reader.ReadBytes(12); uint numIndices = reader.ReadUInt32(); _surfaces[i].numTriangles = reader.ReadUInt32(); UInt16[] myindices = new UInt16[numIndices]; for (uint j = 0; j < numIndices; j++) { myindices[j] = reader.ReadUInt16(); } _surfaces[i].VertexIndex = _bspVertices.Count; _surfaces[i].indices = new ushort[_surfaces[i].numTriangles * 3]; for (uint j = 0; j < _surfaces[i].numTriangles; j++) { ushort x = reader.ReadUInt16(); ushort y = reader.ReadUInt16(); ushort z = reader.ReadUInt16(); _surfaces[i].indices[j * 3 + 0] = myindices[x]; _surfaces[i].indices[j * 3 + 1] = myindices[y]; _surfaces[i].indices[j * 3 + 2] = myindices[z]; // TODO: since we aren't using indices the hardware can't cache vertices, // so there's some performance loss. Figure out a good way to still use indices. // vertex 1 BspVertex vertex = new BspVertex(); vertex.X = _vertices[myindices[x] * 3 + 0]; vertex.Y = _vertices[myindices[x] * 3 + 1]; vertex.Z = _vertices[myindices[x] * 3 + 2]; vertex.U = _texcoords[myindices[x] * 2 + 0]; vertex.V = _texcoords[myindices[x] * 2 + 1]; _bspVertices.Add(vertex); // vertex 2 vertex.X = _vertices[myindices[y] * 3 + 0]; vertex.Y = _vertices[myindices[y] * 3 + 1]; vertex.Z = _vertices[myindices[y] * 3 + 2]; vertex.U = _texcoords[myindices[y] * 2 + 0]; vertex.V = _texcoords[myindices[y] * 2 + 1]; _bspVertices.Add(vertex); // vertex 3 vertex.X = _vertices[myindices[z] * 3 + 0]; vertex.Y = _vertices[myindices[z] * 3 + 1]; vertex.Z = _vertices[myindices[z] * 3 + 2]; vertex.U = _texcoords[myindices[z] * 2 + 0]; vertex.V = _texcoords[myindices[z] * 2 + 1]; _bspVertices.Add(vertex); } _surfaces[i].VertexCount = _bspVertices.Count - _surfaces[i].VertexIndex; } reader.Close(); loadTextures(content); }