123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- //
- // The graphics engine GXScene
- //
- unit Formatx.MD3;
- (* File loading methods for the MD3 file format *)
- interface
- uses
- System.Classes,
- Stage.VectorTypes;
- type
- // Quake3 MD3 structure types
- TMD3Tag = record
- strName: array [0 .. 63] of AnsiChar;
- vPosition: TVector3f;
- rotation: TMatrix3f;
- end;
- (* This part of the MD3 structure called 2 things:
- A frame and a bone. It doesn't matter because we don't use it *)
- (*
- TMD3Frame = record
- min_bound,max_bounds,
- local_origin : TVector3f;
- radius : single;
- name : array[0..15] of char;
- end;
- *)
- TMD3Bone = record
- mins, maxs, position: TVector3f;
- scale: single;
- creator: array [0 .. 15] of AnsiChar;
- end;
- TMD3Triangle = record
- vertex: TVector3s; // value/64 to get real number position
- normal: TVector2b; // Latitude,Longitude
- end;
- TMD3Face = record
- vertexIndices: TVector3i;
- end;
- TMD3TexCoord = record
- textureCoord: TVector2f;
- end;
- TMD3Skin = record
- strName: array [0 .. 63] of AnsiChar;
- shaderIndex: Integer;
- end;
- TMD3Header = record
- fileID: array [0 .. 3] of AnsiChar;
- version: Integer;
- strFile: array [0 .. 63] of AnsiChar;
- flags, numFrames, numTags, numMeshes, numMaxSkins, headerSize, tagStart,
- tagEnd, fileSize: Integer;
- end;
- TMD3MeshHeader = record
- meshID: array [0 .. 3] of AnsiChar;
- strName: array [0 .. 63] of AnsiChar;
- flags, numMeshFrames, numSkins, numVertices, numTriangles, triStart,
- headerSize, uvStart, vertexStart, meshSize: Integer;
- end;
- TMD3MeshData = record
- MeshHeader: TMD3MeshHeader;
- Skins: array of TMD3Skin;
- Triangles: array of TMD3Face;
- TexCoords: array of TMD3TexCoord;
- Vertices: array of TMD3Triangle;
- end;
- // MD3 Main file class
- TFileMD3 = class
- public
- ModelHeader: TMD3Header;
- Bones: array of TMD3Bone;
- Tags: array of TMD3Tag;
- MeshData: array of TMD3MeshData;
- procedure LoadFromStream(aStream: TStream);
- end;
- implementation // ------------------------------------------------------------
- // ------------------
- // ------------------ TFileMD3 ------------------
- // ------------------
- procedure TFileMD3.LoadFromStream(aStream: TStream);
- var
- i: Integer;
- meshOffset: LongInt;
- begin
- aStream.Read(ModelHeader, sizeof(ModelHeader));
- // Test for correct file ID and version
- Assert(ModelHeader.fileID = 'IDP3', 'Incorrect MD3 file ID');
- Assert(ModelHeader.version = 15, 'Incorrect MD3 version number');
- // Read in the bones
- SetLength(Bones, ModelHeader.numFrames);
- aStream.Read(Bones[0], sizeof(TMD3Bone) * ModelHeader.numFrames);
- // Read in the Tags
- SetLength(Tags, ModelHeader.numFrames * ModelHeader.numTags);
- if ModelHeader.numTags > 0 then
- aStream.Read(Tags[0], sizeof(TMD3Tag) * ModelHeader.numFrames *
- ModelHeader.numTags);
- // Read in the Mesh data
- meshOffset := aStream.position;
- SetLength(MeshData, ModelHeader.numMeshes);
- for i := 0 to ModelHeader.numMeshes - 1 do
- begin
- with MeshData[i] do
- begin
- aStream.position := meshOffset;
- aStream.Read(MeshHeader, sizeof(MeshHeader));
- // Set up the dynamic arrays
- SetLength(Skins, MeshHeader.numSkins);
- SetLength(Triangles, MeshHeader.numTriangles);
- SetLength(TexCoords, MeshHeader.numVertices);
- SetLength(Vertices, MeshHeader.numVertices * MeshHeader.numMeshFrames);
- // Skins
- aStream.Read(Skins[0], sizeof(TMD3Skin) * MeshHeader.numSkins);
- // Face data
- aStream.position := meshOffset + MeshHeader.triStart;
- aStream.Read(Triangles[0], sizeof(TMD3Face) * MeshHeader.numTriangles);
- // Texture coordinates
- aStream.position := meshOffset + MeshHeader.uvStart;
- aStream.Read(TexCoords[0], sizeof(TMD3TexCoord) * MeshHeader.numVertices);
- // Vertices
- aStream.position := meshOffset + MeshHeader.vertexStart;
- aStream.Read(Vertices[0], sizeof(TMD3Triangle) * MeshHeader.numMeshFrames
- * MeshHeader.numVertices);
- // Increase the offset
- meshOffset := meshOffset + MeshHeader.meshSize;
- end;
- end;
- end;
- // ------------------------------------------------------------------
- end.
|