Example #1
0
        /// <summary>
        /// Recursively draws the BSP tree, beginning at the specified node. SLOW!!
        /// </summary>
        private void drawBspNode(int nodeIndex, Effect effect, LightmapResource lightmaps, Camera camera)
        {
            if (_boundingSpheres[nodeIndex].W > 100.0f &&
                camera.Frustum.IsSphereOutside(_boundingSpheres[nodeIndex]))
            {
                return;
            }

            BspNode node = _nodes[nodeIndex];

            if (node.Left < 0 && node.Right < 0)
            {
                // draw the polygon
                for (int i = node.PolygonStartIndex; i < node.PolygonStartIndex + node.NumPolygons; i++)
                {
                    //drawSurface(_surfaces[_polygons[i].surfaceIndex], lightmaps[_polygons[i].surfaceIndex], effect, camera);
                }
            }
            else
            {
                if (node.Left >= 0)
                {
                    drawBspNode(node.Left, effect, lightmaps, camera);
                }
                if (node.Right >= 0)
                {
                    drawBspNode(node.Right, effect, lightmaps, camera);
                }

                // draw the polygon
                for (int i = node.PolygonStartIndex; i < node.PolygonStartIndex + node.NumPolygons; i++)
                {
                    //drawSurface(_surfaces[_polygons[i].surfaceIndex], lightmaps[_polygons[i].surfaceIndex], effect, camera);
                }
            }
        }
Example #2
0
        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);
        }