public void InitQuake3Patches(Quake3Level q3lvl, VertexDeclaration decl) { int face; patchVertexCount = 0; patchIndexCount = 0; // We're just building the patch here to get a hold on the size of the mesh // although we'll reuse this information later face = q3lvl.NumFaces; while (face-- > 0) { InternalBspFace src = q3lvl.Faces[face]; if (src.type == BspFaceType.Patch) { // Seems to be some crap in the Q3 level where vertex count = 0 or num control points = 0? if ((src.vertCount == 0) || (src.meshCtrl[0] == 0)) { continue; } PatchSurface ps = new PatchSurface(); // Set up control points & format. // Reuse the vertex declaration. // Copy control points into a buffer so we can convert their format. BspVertex[] controlPoints = new BspVertex[src.vertCount]; TextureLightMap texLightMap; for (int v = 0; v < src.vertCount; v++) { QuakeVertexToBspVertex(q3lvl.Vertices[src.vertStart + v], out controlPoints[v], out texLightMap); } // Define the surface, but don't build it yet (no vertex / index buffer) ps.DefineSurface( controlPoints, decl, src.meshCtrl[0], src.meshCtrl[1] ); // Get stats patchVertexCount += ps.RequiredVertexCount; patchIndexCount += ps.RequiredIndexCount; // Save the surface for later patches.Add(face, ps); } } }
private void ReadFaces(InternalBspLump lump, BinaryReader reader) { reader.BaseStream.Seek(lump.offset, SeekOrigin.Begin); faces = new InternalBspFace[lump.size / Marshal.SizeOf(typeof(InternalBspFace))]; for (int i = 0; i < faces.Length; i++) { faces[i] = new InternalBspFace(); faces[i].shader = reader.ReadInt32(); faces[i].unknown = reader.ReadInt32(); faces[i].type = (BspFaceType)Enum.Parse(typeof(BspFaceType), reader.ReadInt32().ToString()); faces[i].vertStart = reader.ReadInt32(); faces[i].vertCount = reader.ReadInt32(); faces[i].elemStart = reader.ReadInt32(); faces[i].elemCount = reader.ReadInt32(); faces[i].lmTexture = reader.ReadInt32(); faces[i].lmOffset = new int[] { reader.ReadInt32(), reader.ReadInt32() }; faces[i].lmSize = new int[] { reader.ReadInt32(), reader.ReadInt32() }; faces[i].org = new float[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }; faces[i].bbox = new float[6]; for (int j = 0; j < faces[i].bbox.Length; j++) { faces[i].bbox[j] = reader.ReadSingle(); } faces[i].normal = new float[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }; faces[i].meshCtrl = new int[] { reader.ReadInt32(), reader.ReadInt32() }; TransformBoundingBox(faces[i].bbox); TransformVector(faces[i].org); TransformVector(faces[i].normal, true); } }
private void ReadFaces( InternalBspLump lump, BinaryReader reader ) { reader.BaseStream.Seek( lump.offset, SeekOrigin.Begin ); for ( int i = 0; i < faces.Length; i++ ) { faces[ i ] = new InternalBspFace(); faces[ i ].shader = reader.ReadInt32(); faces[ i ].unknown = reader.ReadInt32(); faces[ i ].type = (BspFaceType)Enum.Parse( typeof( BspFaceType ), reader.ReadInt32().ToString() ); faces[ i ].vertStart = reader.ReadInt32(); faces[ i ].vertCount = reader.ReadInt32(); faces[ i ].elemStart = reader.ReadInt32(); faces[ i ].elemCount = reader.ReadInt32(); faces[ i ].lmTexture = reader.ReadInt32(); faces[ i ].lmOffset = new int[] { reader.ReadInt32(), reader.ReadInt32() }; faces[ i ].lmSize = new int[] { reader.ReadInt32(), reader.ReadInt32() }; faces[ i ].org = new float[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }; faces[ i ].bbox = new float[ 6 ]; for ( int j = 0; j < faces[ i ].bbox.Length; j++ ) faces[ i ].bbox[ j ] = reader.ReadSingle(); faces[ i ].normal = new float[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }; faces[ i ].meshCtrl = new int[] { reader.ReadInt32(), reader.ReadInt32() }; TransformBoundingBox( faces[ i ].bbox ); TransformVector( faces[ i ].org ); TransformVector( faces[ i ].normal, true ); } }
private BspStaticFaceGroup CopyShaderFaceData(Quake3Level q3lvl, int face, Material shadMat, int shadIdx) { BspStaticFaceGroup dest = new BspStaticFaceGroup(); InternalBspFace src = q3lvl.Faces[face]; if ((q3lvl.Shaders[src.shader].surfaceFlags & SurfaceFlags.Sky) == SurfaceFlags.Sky) { dest.isSky = true; } else { dest.isSky = false; } dest.materialHandle = shadMat.Handle; dest.elementStart = src.elemStart; dest.numElements = src.elemCount; dest.numVertices = src.vertCount; dest.vertexStart = src.vertStart; dest.plane = new Plane(); if (Quake3ShaderManager.Instance.GetByName(q3lvl.Shaders[shadIdx].name) != null) { // it's a quake shader dest.isQuakeShader = true; } if (src.type == BspFaceType.Normal) { dest.type = FaceGroup.FaceList; // Assign plane dest.plane.Normal = new Vector3( src.normal[0], src.normal[1], src.normal[2] ); dest.plane.D = -dest.plane.Normal.Dot( new Vector3( src.org[0], src.org[1], src.org[2] ) ); // Don't rebase indexes here - Quake3 re-uses some indexes for multiple vertex // groups eg repeating small details have the same relative vertex data but // use the same index data. } else if (src.type == BspFaceType.Patch) { // Seems to be some crap in the Q3 level where vertex count = 0 or num control points = 0? if ((dest.numVertices == 0) || (src.meshCtrl[0] == 0)) { dest.type = FaceGroup.Unknown; } else { // Set up patch surface dest.type = FaceGroup.Patch; // Locate the patch we already built if (!patches.ContainsKey(face)) { throw new AxiomException("Patch not found from previous built state."); } dest.patchSurf = (PatchSurface)patches[face]; } } else if (src.type == BspFaceType.Mesh) { dest.type = FaceGroup.FaceList; // Assign plane dest.plane.Normal = new Vector3(src.normal[0], src.normal[1], src.normal[2]); dest.plane.D = -dest.plane.Normal.Dot(new Vector3(src.org[0], src.org[1], src.org[2])); } else { LogManager.Instance.Write("!!! Unknown face type !!!"); } return(dest); }