123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- //
- // The multimedia graphics platform GLScene https://github.com/glscene
- //
- unit Formats.MD3;
- (* File loading methods for the MD3 file format *)
- interface
- uses
- System.Classes,
- GLS.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.
|