123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- //
- // The graphics engine GXScene
- //
- unit Formatx.MD2;
- (* Loading methods for MD2 file format *)
- interface
- {$R-}
- {$I Stage.Defines.inc}
- uses
- System.Classes,
- System.SysUtils,
-
- Stage.VectorTypes;
- const
- MAX_MD2_TRIANGLES = 4096;
- MAX_MD2_VERTICES = 2048;
- MAX_MD2_FRAMES = 512;
- MAX_MD2_SKINS = 32;
- MAX_MD2_SKINNAME = 64;
- type
- PMD2VertexIndex = ^TMD2VertexIndex;
- TMD2VertexIndex = record
- A, B, C: integer;
- A_S, A_T,
- B_S, B_T,
- C_S, C_T: single;
- end;
- TMD2Triangle = record
- VertexIndex: TVector3s;
- TextureCoordIndex: TVector3s;
- end;
- TMD2TriangleVertex = record
- Vert: array[0..2] of byte;
- LightnormalIndex: byte;
- end;
- PMD2AliasFrame = ^TMD2AliasFrame;
- TMD2AliasFrame = record
- Scale: TVector3f;
- Translate: TVector3f;
- Name: array[0..15] of AnsiChar;
- Vertices: array[0..0] of TMD2TriangleVertex;
- end;
- TMD2Header = record
- Ident: integer;
- Version: integer;
- SkinWidth: integer;
- SkinHeight: integer;
- FrameSize: integer;
- Num_Skins: integer;
- Num_Vertices: integer;
- Num_TextureCoords: integer;
- Num_VertexIndices: integer;
- Num_GLCommdands: integer;
- Num_Frames: integer;
- Offset_skins: integer;
- Offset_st: integer;
- Offset_tris: integer;
- Offset_frames: integer;
- Offset_glcmds: integer;
- Offset_end: integer;
- end;
- TIndexList = array of TMD2VertexIndex;
- TGLVertexList = array of array of TVector3f;
- type
- TFileMD2 = class
- private
- FiFrames: longint;
- FiVertices: longint;
- FiTriangles: longint;
- procedure FreeLists;
- public
- fIndexList : TIndexList;
- fVertexList : TGLVertexList;
- FrameNames : TStrings;
- constructor Create; virtual;
- destructor Destroy; override;
- procedure LoadFromStream(aStream : TStream);
- property iFrames: longInt read FiFrames;
- property iVertices: longInt read FiVertices;
- property iTriangles: longInt read FiTriangles;
- property IndexList: TIndexList read fIndexList;
- property VertexList: TGLVertexList read fVertexList;
- end;
- implementation // ------------------------------------------------------------
- // ------------------
- // ------------------ TFileMD2 ------------------
- // ------------------
- constructor TFileMD2.Create;
- begin
- inherited;
- FreeLists;
- FrameNames := TStringList.Create;
- end;
- destructor TFileMD2.Destroy;
- begin
- FreeLists;
- FrameNames.Free;
- inherited;
- end;
- procedure TFileMD2.FreeLists;
- begin
- SetLength(fIndexList,0);
- SetLength(fVertexList,0,0);
- FiFrames := 0;
- FiVertices := 0;
- FiTriangles := 0;
- end;
- procedure TFileMD2.LoadFromStream(aStream : TStream);
- var
- Skins: array[0..MAX_MD2_SKINS - 1, 0..63] of AnsiChar;
- TextureCoords: array[0..MAX_MD2_VERTICES - 1] of TVector2s;
- Buffer: array[0..MAX_MD2_VERTICES * 4 + 127] of byte;
- Header: TMD2Header;
- Triangle: TMD2Triangle;
- I: integer;
- J: integer;
- Frame: PMD2AliasFrame;
- FrameName : String;
- begin
- FreeLists;
- // read the modelinfo
- aStream.Read(Header, SizeOf(Header));
- FiFrames := Header.Num_Frames;
- FiVertices := Header.Num_Vertices;
- FiTriangles := Header.Num_VertexIndices;
- SetLength(fIndexList, FiTriangles);
- SetLength(fVertexList, FiFrames, FiVertices);
- // get the skins...
- aStream.Read(Skins, Header.Num_Skins * MAX_MD2_SKINNAME);
- // ...and the texcoords
- aStream.Read(TextureCoords, Header.Num_TextureCoords * SizeOf(TVector2s));
- for I := 0 to Header.Num_VertexIndices - 1 do begin
- aStream.Read(Triangle, SizeOf(TMD2Triangle));
- with fIndexList[I] do begin
- A := Triangle.VertexIndex.Z;
- B := Triangle.VertexIndex.Y;
- C := Triangle.VertexIndex.X;
- A_S := TextureCoords[Triangle.TextureCoordIndex.Z].X / Header.SkinWidth;
- A_T := TextureCoords[Triangle.TextureCoordIndex.Z].Y / Header.SkinHeight;
- B_S := TextureCoords[Triangle.TextureCoordIndex.Y].X / Header.SkinWidth;
- B_T := TextureCoords[Triangle.TextureCoordIndex.Y].Y / Header.SkinHeight;
- C_S := TextureCoords[Triangle.TextureCoordIndex.X].X / Header.SkinWidth;
- C_T := TextureCoords[Triangle.TextureCoordIndex.X].Y / Header.SkinHeight;
- end;
- end;
- for I := 0 to Header.Num_Frames - 1 do begin
- Frame := PMD2AliasFrame(@Buffer);
- // read animation / frame info
- aStream.Read(Frame^, Header.FrameSize);
- FrameName := Trim(String(Frame^.Name));
- if CharInSet(Copy(FrameName, Length(FrameName) - 1, 1)[1], ['0'..'9']) then
- FrameName := Copy(FrameName, 1, Length(FrameName) - 2)
- else
- FrameName := Copy(FrameName, 1, Length(FrameName) - 1);
- if FrameNames.IndexOf(FrameName) < 0 then
- FrameNames.AddObject(FrameName, TObject(Cardinal(I)));
- // fill the vertices list
- for J := 0 to FiVertices - 1 do begin
- fVertexList[i][J].X := Frame^.Vertices[J].Vert[0] * Frame^.Scale.X + Frame^.Translate.X;
- fVertexList[i][J].Y := Frame^.Vertices[J].Vert[1] * Frame^.Scale.Y + Frame^.Translate.Y;
- fVertexList[i][J].Z := Frame^.Vertices[J].Vert[2] * Frame^.Scale.Z + Frame^.Translate.Z;
- end;
- end;
- end;
- //---------------------------------------------------------------------------
- end.
|