unit Unit3DS_11;
interface
uses Windows, Classes;
type point = record
k:integer;
x,y,z,nx,ny,nz:Single;
end;
type face = record
a,b,c:integer;
end;
type T3DObject = class(TObject)
private
// Nothing here at moment
public
PointCount, FaceCount: Integer;
ObjectName:String;
p:array of point;
f:array of face;
constructor Create;
destructor Destroy; override;
procedure Draw;
end;
type TChunk = class(TObject)
private
function ReadObjectString:String;
public
Id: word;
iBytesReaded, ChunkLength : Integer;
iFileHandle, iFileLength, ObjCount:Integer;
Objects:array of T3DObject;
function ReadChunk: Integer;
function ReadBuffer(var Buffer; Count:Integer):Integer;
procedure AddObject(ObjNr: Integer);
procedure Load3Data;
constructor Create;
destructor Destroy; override;
end;
type T3DModel = class(TObject)
private
ObjCount:Integer;
RootChunk:TChunk;
Objects:array of T3DObject;
public
constructor Create;
destructor Destroy; override;
procedure LoadFromFile(const FileName:string);
procedure Clone3Data;
procedure Draw;
end;
implementation
uses SysUtils, OpenGL;
constructor T3DObject.Create;
begin
inherited;
ObjectName:='';
PointCount:=0; FaceCount:=0;
p:=nil;
f:=nil;
end;
destructor T3DObject.Destroy;
begin
Finalize(p);
Finalize(f);
inherited;
end;
procedure T3Dobject.Draw;
var i:integer;
begin
for i:=0 to FaceCount-1 do begin
glBegin(GL_POLYGON);
glVertex3f(p[f[i].a].x,p[f[i].a].y,p[f[i].a].z);
glVertex3f(p[f[i].b].x,p[f[i].b].y,p[f[i].b].z);
glVertex3f(p[f[i].c].x,p[f[i].c].y,p[f[i].c].z);
glEnd();
end; end;
constructor TChunk.Create;
begin
inherited;
iFileHandle:=0; iFileLength:=0; iBytesReaded:=0; ObjCount:=0; ChunkLength:=0;
Id:=0;
Objects:=nil;
end;
destructor TChunk.Destroy;
begin
Finalize(Objects);
inherited;
end;
function TChunk.ReadChunk: Integer;
begin
iBytesReaded:=FileRead(iFileHandle, Id, 2);
iBytesReaded:=iBytesReaded + FileRead(iFileHandle, ChunkLength, 4);
Result:=iBytesReaded;
end;
function TChunk.ReadBuffer(var Buffer; Count: Integer): Integer;
begin
Result:=FileRead(iFileHandle, Buffer, Count);
iBytesReaded:=iBytesReaded + Result;
end;
function TChunk.ReadObjectString:String;
var //S:String;
C:Char;
i:integer;
SStr:ShortString;
begin
C:=#255; i:=0;
while (C<>#0) {and (i<=20)} do begin
iBytesReaded:=iBytesReaded+FileRead(iFileHandle, C, 1);
SStr[i+1]:=C;
Inc(i);
end;
SetLength(Result, I-1);
Move(SStr[1], Result[1], I-1);
end;
procedure TChunk.AddObject(ObjNr:Integer);
begin
SetLength(Objects,ObjNr);
Objects[ObjNr].Create;
end;
procedure TChunk.Load3Data;
var i,x: Integer;
begin
while (iBytesReaded < iFileLength) do begin
ReadChunk;
case Id of
$4D4D: begin
// MAIN CHUNK
// ShowMessage('Found $4D4D at: ' + IntToStr(iBytesReaded) + ' length: ' + IntToStr(ChunkLength));
end;
$3D3D: begin
// 3D EDITOR CHUNK
// ShowMessage('Found $3D3D at: ' + IntToStr(iBytesReaded) + ' length: ' + IntToStr(ChunkLength));
end;
$4000: begin
// OBJECT BLOCK
inc(ObjCount);
AddObject(ObjCount);
Objects[ObjCount].ObjectName:=ReadObjectString; // PROPERTY USE ???!!!
// ShowMessage(ObjectName);
end;
$4100: begin
// 3D Data Chunk (kb)
end;
$4110: begin // VERTICES LIST
with Objects[ObjCount] do begin
ReadBuffer(PointCount, 2);
SetLength(p,PointCount);
for i:=0 to PointCount-1 do begin
ReadBuffer(p[i].x,4);
ReadBuffer(p[i].y,4);
ReadBuffer(p[i].z,4);
end; end; end;
$4120: begin // FACES DESCRIPTION
with Objects[ObjCount] do begin
ReadBuffer(FaceCount, 2);
SetLength(f,FaceCount);
for i:=0 to FaceCount-1 do begin
ReadBuffer(f[i].a, 2);
ReadBuffer(f[i].b, 2);
ReadBuffer(f[i].c, 2);
ReadBuffer(x, 2);
end; end; end;
else
iBytesReaded:=FileSeek(iFileHandle,ChunkLength-6,1); end;
end; // while end;
end;
constructor T3DModel.Create;
begin
inherited;
ObjCount:=0;
//RootChunk:=nil;
Objects:=nil;
end;
destructor T3DModel.Destroy;
begin
Finalize(Objects);
inherited;
end;
procedure T3DModel.LoadFromFile(const FileName:string);
var iFileHandle, iFileLength: Integer;
begin
iFileHandle:=0; //iFileLength:=0;
try
iFileHandle := FileOpen(FileName, fmOpenRead);
finally
iFileLength := FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
RootChunk:=TChunk.Create;
RootChunk.iFileHandle:=iFileHandle;
RootChunk.iFileLength:=iFileLength;
RootChunk.Load3Data;
Clone3Data;
RootChunk.Free;
RootChunk.Destroy;
//ShowMessage('RootChunk Destroyed Successfully');
FileClose(iFileHandle);
end;
end;
procedure T3DModel.Clone3Data;
var i,j:integer;
begin
ObjCount:=RootChunk.ObjCount;
SetLength(Objects,ObjCount);
for i:=1 to ObjCount do begin
Objects[i].Create;
with Objects[i] do begin
PointCount:=RootChunk.Objects[i].PointCount;
FaceCount:=RootChunk.Objects[i].FaceCount;
SetLength(p,Objects[i].PointCount);
SetLength(f,Objects[i].FaceCount);
ObjectName:=RootChunk.Objects[i].ObjectName;
for j:=0 to PointCount-1 do p[j]:= RootChunk.Objects[i].p[j];
for j:=0 to FaceCount-1 do f[j]:= RootChunk.Objects[i].f[j];
end;
end;
end;
procedure T3DModel.Draw;
var i:integer;
begin
for i:=1 to ObjCount do Objects[i].Draw;
end;
end.