private bool collideRayWithSurface(BspSurface surface, Math.Vector3 origin, Math.Vector3 direction, float length, out float distance) { Math.Vector3?collisionPoint; for (int i = 0; i < surface.indices.Length / 3; i++) { Math.Vector3 v1 = new Math.Vector3( _vertices[surface.indices[i * 3 + 0] * 3 + 0], _vertices[surface.indices[i * 3 + 0] * 3 + 1], _vertices[surface.indices[i * 3 + 0] * 3 + 2]); Math.Vector3 v2 = new Math.Vector3( _vertices[surface.indices[i * 3 + 1] * 3 + 0], _vertices[surface.indices[i * 3 + 1] * 3 + 1], _vertices[surface.indices[i * 3 + 1] * 3 + 2]); Math.Vector3 v3 = new Math.Vector3( _vertices[surface.indices[i * 3 + 2] * 3 + 0], _vertices[surface.indices[i * 3 + 2] * 3 + 1], _vertices[surface.indices[i * 3 + 2] * 3 + 2]); if (Gk3Main.Utils.TestRayTriangleCollision(origin, direction, v1, v2, v3, out distance, out collisionPoint) == true) { return(true); } } distance = float.NaN; return(false); }
private void drawSurface(BspSurface surface, Effect effect, Camera camera) { if (camera.Frustum.IsSphereOutside(surface.boundingSphere)) { return; } effect.SetParameter("Diffuse", surface.textureResource, 0); effect.CommitParams(); RendererManager.CurrentRenderer.Draw(PrimitiveType.Triangles, surface.VertexIndex, surface.VertexCount); }
public bool CollideRayWithSurfaces(Math.Vector3 origin, Math.Vector3 direction, float length, out BspSurface surface) { if (_surfaces == null) { surface = null; return(false); } surface = null; float distance = float.MaxValue, minDistance = float.MaxValue; foreach (BspSurface isurface in _surfaces) { if (collideRayWithSurface(isurface, origin, direction, length, out distance) == true) { if (distance < minDistance && distance > 0) { minDistance = distance; surface = isurface; } } } if (surface == null) { return(false); } return(true); }
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); }