public void Planef_Distance() { Planef plane = new Planef(Vertex3f.UnitZ, 10.0f); Assert.AreEqual(-10.0f, plane.GetDistance(new Vertex3f(0.0f, 0.0f, 0.0f))); Assert.AreEqual(0.0f, plane.GetDistance(new Vertex3f(0.0f, 0.0f, 10.0f))); Assert.AreEqual(+10.0f, plane.GetDistance(new Vertex3f(0.0f, 0.0f, 20.0f))); }
public SceneGraphContext(SceneGraph sceneGraph) { if (sceneGraph == null) { throw new ArgumentNullException("sceneGraph"); } Scene = sceneGraph; ViewFrustumPlanes = Planef.GetFrustumPlanes(Scene.ProjectionMatrix); }
public void Planef_PosYPlane() { Planef plane = new Planef(Vertex3f.UnitY, 0.0f); // Positive half-space Vertex3f[] pointsPosY = { new Vertex3f(+1.0f, 1.0f, +1.0f), new Vertex3f(+1.0f, 1.0f, -1.0f), new Vertex3f(-1.0f, 1.0f, +1.0f), new Vertex3f(-1.0f, 1.0f, -1.0f), }; foreach (Vertex3f v in pointsPosY) { Assert.IsTrue(plane.GetDistance(v) > 0.0f); } // Negative half-space Vertex3f[] pointsNegY = { new Vertex3f(+1.0f, -1.0f, +1.0f), new Vertex3f(+1.0f, -1.0f, -1.0f), new Vertex3f(-1.0f, -1.0f, +1.0f), new Vertex3f(-1.0f, -1.0f, -1.0f), }; foreach (Vertex3f v in pointsNegY) { Assert.IsTrue(plane.GetDistance(v) < 0.0f); } // On-plane Vertex3f[] pointsZero = { new Vertex3f(+1.0f, 0.0f, +1.0f), new Vertex3f(+1.0f, 0.0f, -1.0f), new Vertex3f(-1.0f, 0.0f, +1.0f), new Vertex3f(-1.0f, 0.0f, -1.0f), }; foreach (Vertex3f v in pointsZero) { Assert.AreEqual(0.0f, plane.GetDistance(v)); } }
// [Test] public void Planef_ProjectionFrustum() { Matrix4x4f projectionMatrix = Matrix4x4f.Perspective(90.0f, 1.0f, 1.0f, 10.0f); Matrix4x4f modelMatrix = Matrix4x4f.Identity; Matrix4x4f frustumMatrix = projectionMatrix * modelMatrix; Planef planeL = Planef.GetFrustumLeftPlane(frustumMatrix); Planef planeR = Planef.GetFrustumRightPlane(frustumMatrix); Planef planeB = Planef.GetFrustumBottomPlane(frustumMatrix); Planef planeT = Planef.GetFrustumTopPlane(frustumMatrix); Planef planeN = Planef.GetFrustumNearPlane(frustumMatrix); Assert.IsTrue(planeN.GetDistance(new Vertex3f(0.0f, 0.0f, -5.0f)) > 0.0f); Planef planeF = Planef.GetFrustumFarPlane(frustumMatrix); // Assert.IsTrue(planeF.GetDistance(new Vertex3f(0.0f, 0.0f, -5.0f)) > 0.0f); }
public Bsp(Stream stream, IEnumerable<Package.Wad> wads) { if (!stream.CanSeek || !stream.CanRead) throw new ArgumentException("stream must be seekable and readable.", "stream"); if (wads == null) wads = System.Linq.Enumerable.Empty<Package.Wad>(); Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); if (Reader.ReadUInt32() != 30) throw new InvalidDataException("Version is not 30."); long entitiesOffset = Reader.ReadUInt32(); long entitiesCount = Reader.ReadUInt32(); long planesOffset = Reader.ReadUInt32(); long planesCount = Reader.ReadUInt32(); long texturesOffset = Reader.ReadUInt32(); long texturesCount = Reader.ReadUInt32(); long vertexesOffset = Reader.ReadUInt32(); long vertexesCount = Reader.ReadUInt32(); long visibilityOffset = Reader.ReadUInt32(); long visibilityCount = Reader.ReadUInt32(); long nodesOffset = Reader.ReadUInt32(); long nodesCount = Reader.ReadUInt32(); long texinfoOffset = Reader.ReadUInt32(); long texinfoCount = Reader.ReadUInt32(); long facesOffset = Reader.ReadUInt32(); long facesCount = Reader.ReadUInt32(); long lightingOffset = Reader.ReadUInt32(); long lightingCount = Reader.ReadUInt32(); long clipnodesOffset = Reader.ReadUInt32(); long clipnodesCount = Reader.ReadUInt32(); long leafsOffset = Reader.ReadUInt32(); long leafsCount = Reader.ReadUInt32(); long marksurfacesOffset = Reader.ReadUInt32(); long marksurfacesCount = Reader.ReadUInt32(); long edgesOffset = Reader.ReadUInt32(); long edgesCount = Reader.ReadUInt32(); long surfedgesOffset = Reader.ReadUInt32(); long surfedgesCount = Reader.ReadUInt32(); long modelsOffset = Reader.ReadUInt32(); long modelsCount = Reader.ReadUInt32(); //Entities Reader.Seek(entitiesOffset, SeekOrigin.Begin); Entities = Encoding.ASCII.GetString(Reader.ReadBytes((int)entitiesCount)); //Planes Reader.Seek(planesOffset, SeekOrigin.Begin); Planes = new Planef[planesCount / 20]; for (int i = 0; i < Planes.Length; ++i) { Planes[i] = new Planef( Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); uint type = Reader.ReadUInt32(); } //Textures { Reader.Seek(texturesOffset, SeekOrigin.Begin); long[] offsets = new long[Reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = Reader.ReadUInt32(); } Textures = new Resource[offsets.Length]; for (int i = 0; i < offsets.Length; ++i) { Reader.Seek(texturesOffset + offsets[i], SeekOrigin.Begin); string name = Encoding.ASCII.GetString(Reader.ReadBytes(16)); int nullbyte = name.IndexOf('\0'); name = nullbyte == -1 ? name : name.Substring(0, nullbyte); int width = Reader.ReadInt32(); int height = Reader.ReadInt32(); long[] dataoffsets = new long[4]; dataoffsets[0] = Reader.ReadUInt32(); dataoffsets[1] = Reader.ReadUInt32(); dataoffsets[2] = Reader.ReadUInt32(); dataoffsets[3] = Reader.ReadUInt32(); Resource resource = null; if (dataoffsets.All(o => o == 0)) { foreach (var wad in wads) { resource = wad[name]; if (resource != null) { break; } } } else { resource = new Resource(new Size3i(width, height, 1), 4, 1, Format.R8G8B8A8UNorm); byte[][] images = new byte[4][]; for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { Reader.Seek(texturesOffset + offsets[i] + dataoffsets[mipSlice], SeekOrigin.Begin); images[mipSlice] = Reader.ReadBytes(width * height); width >>= 1; height >>= 1; } Reader.Seek(2, SeekOrigin.Current); byte[] pallet = Reader.ReadBytes(256 * 3); for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { byte[] data = resource[mipSlice, 0]; byte[] image = images[mipSlice]; for (int j = 0; j < image.Length; ++j) { int palletIndex = image[j] * 3; int dataIndex = j * 3; data[dataIndex + 0] = pallet[palletIndex + 0]; data[dataIndex + 1] = pallet[palletIndex + 1]; data[dataIndex + 2] = pallet[palletIndex + 2]; } } } Textures[i] = resource; } } //Vertices Reader.Seek(vertexesOffset, SeekOrigin.Begin); Vertices = new Vector3f[vertexesCount / 12]; for (int i = 0; i < Vertices.Length; ++i) { Vertices[i] = new Vector3f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); } //Visibility Reader.Seek(visibilityOffset, SeekOrigin.Begin); Visibility = Reader.ReadBytes((int)visibilityCount); //Nodes //Surfaces Reader.Seek(texinfoOffset, SeekOrigin.Begin); Surfaces = new Surface[texinfoCount / 24]; for (int i = 0; i < Surfaces.Length; ++i) { Surfaces[i] = new Surface( new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), Reader.ReadInt32(), Reader.ReadInt32()); } //Faces Reader.Seek(facesOffset, SeekOrigin.Begin); Faces = new Face[facesCount / 20]; for (int i = 0; i < Faces.Length; ++i) { Faces[i] = new Face( Reader.ReadUInt16(), Reader.ReadInt16(), Reader.ReadInt32(), Reader.ReadInt16(), Reader.ReadInt16(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadInt32()); } //Lighting Reader.Seek(facesOffset, SeekOrigin.Begin); Lighting = Reader.ReadBytes((int)lightingCount); //#define clipnodes 9 //#define leafs 10 //#define marksurfaces 11 //#define edges 12 //#define surfedges 13 //#define models 14 //Edges Reader.Seek(edgesOffset, SeekOrigin.Begin); Edges = new Edge[edgesCount / 4]; for (int i = 0; i < Edges.Length; ++i) { Edges[i] = new Edge(Reader.ReadUInt16(), Reader.ReadUInt16()); } //SurfaceEdges Reader.Seek(surfedgesOffset, SeekOrigin.Begin); SurfaceEdges = new int[surfedgesCount / 4]; for (int i = 0; i < Planes.Length; ++i) { SurfaceEdges[i] = Reader.ReadInt32(); } }
public Bsp(Stream stream, IEnumerable <Package.Wad> wads) { if (!stream.CanSeek || !stream.CanRead) { throw new ArgumentException("stream must be seekable and readable.", "stream"); } if (wads == null) { wads = System.Linq.Enumerable.Empty <Package.Wad>(); } Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); if (Reader.ReadUInt32() != 30) { throw new InvalidDataException("Version is not 30."); } long entitiesOffset = Reader.ReadUInt32(); long entitiesCount = Reader.ReadUInt32(); long planesOffset = Reader.ReadUInt32(); long planesCount = Reader.ReadUInt32(); long texturesOffset = Reader.ReadUInt32(); long texturesCount = Reader.ReadUInt32(); long vertexesOffset = Reader.ReadUInt32(); long vertexesCount = Reader.ReadUInt32(); long visibilityOffset = Reader.ReadUInt32(); long visibilityCount = Reader.ReadUInt32(); long nodesOffset = Reader.ReadUInt32(); long nodesCount = Reader.ReadUInt32(); long texinfoOffset = Reader.ReadUInt32(); long texinfoCount = Reader.ReadUInt32(); long facesOffset = Reader.ReadUInt32(); long facesCount = Reader.ReadUInt32(); long lightingOffset = Reader.ReadUInt32(); long lightingCount = Reader.ReadUInt32(); long clipnodesOffset = Reader.ReadUInt32(); long clipnodesCount = Reader.ReadUInt32(); long leafsOffset = Reader.ReadUInt32(); long leafsCount = Reader.ReadUInt32(); long marksurfacesOffset = Reader.ReadUInt32(); long marksurfacesCount = Reader.ReadUInt32(); long edgesOffset = Reader.ReadUInt32(); long edgesCount = Reader.ReadUInt32(); long surfedgesOffset = Reader.ReadUInt32(); long surfedgesCount = Reader.ReadUInt32(); long modelsOffset = Reader.ReadUInt32(); long modelsCount = Reader.ReadUInt32(); //Entities Reader.Seek(entitiesOffset, SeekOrigin.Begin); Entities = Encoding.ASCII.GetString(Reader.ReadBytes((int)entitiesCount)); //Planes Reader.Seek(planesOffset, SeekOrigin.Begin); Planes = new Planef[planesCount / 20]; for (int i = 0; i < Planes.Length; ++i) { Planes[i] = new Planef( Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); uint type = Reader.ReadUInt32(); } //Textures { Reader.Seek(texturesOffset, SeekOrigin.Begin); long[] offsets = new long[Reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = Reader.ReadUInt32(); } Textures = new Resource[offsets.Length]; for (int i = 0; i < offsets.Length; ++i) { Reader.Seek(texturesOffset + offsets[i], SeekOrigin.Begin); string name = Encoding.ASCII.GetString(Reader.ReadBytes(16)); int nullbyte = name.IndexOf('\0'); name = nullbyte == -1 ? name : name.Substring(0, nullbyte); int width = Reader.ReadInt32(); int height = Reader.ReadInt32(); long[] dataoffsets = new long[4]; dataoffsets[0] = Reader.ReadUInt32(); dataoffsets[1] = Reader.ReadUInt32(); dataoffsets[2] = Reader.ReadUInt32(); dataoffsets[3] = Reader.ReadUInt32(); Resource resource = null; if (dataoffsets.All(o => o == 0)) { foreach (var wad in wads) { resource = wad[name]; if (resource != null) { break; } } } else { resource = new Resource(new Size3i(width, height, 1), 4, 1, Format.R8G8B8A8UNorm); byte[][] images = new byte[4][]; for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { Reader.Seek(texturesOffset + offsets[i] + dataoffsets[mipSlice], SeekOrigin.Begin); images[mipSlice] = Reader.ReadBytes(width * height); width >>= 1; height >>= 1; } Reader.Seek(2, SeekOrigin.Current); byte[] pallet = Reader.ReadBytes(256 * 3); for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { byte[] data = resource[mipSlice, 0]; byte[] image = images[mipSlice]; for (int j = 0; j < image.Length; ++j) { int palletIndex = image[j] * 3; int dataIndex = j * 3; data[dataIndex + 0] = pallet[palletIndex + 0]; data[dataIndex + 1] = pallet[palletIndex + 1]; data[dataIndex + 2] = pallet[palletIndex + 2]; } } } Textures[i] = resource; } } //Vertices Reader.Seek(vertexesOffset, SeekOrigin.Begin); Vertices = new Vector3f[vertexesCount / 12]; for (int i = 0; i < Vertices.Length; ++i) { Vertices[i] = new Vector3f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); } //Visibility Reader.Seek(visibilityOffset, SeekOrigin.Begin); Visibility = Reader.ReadBytes((int)visibilityCount); //Nodes //Surfaces Reader.Seek(texinfoOffset, SeekOrigin.Begin); Surfaces = new Surface[texinfoCount / 24]; for (int i = 0; i < Surfaces.Length; ++i) { Surfaces[i] = new Surface( new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), Reader.ReadInt32(), Reader.ReadInt32()); } //Faces Reader.Seek(facesOffset, SeekOrigin.Begin); Faces = new Face[facesCount / 20]; for (int i = 0; i < Faces.Length; ++i) { Faces[i] = new Face( Reader.ReadUInt16(), Reader.ReadInt16(), Reader.ReadInt32(), Reader.ReadInt16(), Reader.ReadInt16(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadInt32()); } //Lighting Reader.Seek(facesOffset, SeekOrigin.Begin); Lighting = Reader.ReadBytes((int)lightingCount); //#define clipnodes 9 //#define leafs 10 //#define marksurfaces 11 //#define edges 12 //#define surfedges 13 //#define models 14 //Edges Reader.Seek(edgesOffset, SeekOrigin.Begin); Edges = new Edge[edgesCount / 4]; for (int i = 0; i < Edges.Length; ++i) { Edges[i] = new Edge(Reader.ReadUInt16(), Reader.ReadUInt16()); } //SurfaceEdges Reader.Seek(surfedgesOffset, SeekOrigin.Begin); SurfaceEdges = new int[surfedgesCount / 4]; for (int i = 0; i < Planes.Length; ++i) { SurfaceEdges[i] = Reader.ReadInt32(); } }