Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit VXLHVAUnit;
- {
- VXL+HVA Unit
- By Stuart "Stucuk" Carey
- Started 2018/02/14
- }
- interface
- uses Classes;
- type
- TStr16 = String[16];
- TM3x4 = Array [0..2,0..3] of Single;
- THVASection = Record
- Name : TStr16;
- Frames : Array of TM3x4;
- end;
- PHVASection = ^THVASection;
- THVA = Class(TObject)
- private
- FSection : Array of THVASection;
- function GetSection(Index : Integer) : PHVASection;
- public
- constructor Create(Stream : TStream);
- destructor Destroy; override;
- function GetMatrix(Section,Frame : Integer) : TM3x4;
- property Section[Index : Integer] : PHVASection read GetSection;
- end;
- TVXLVoxel = Packed Record
- XYZ : Array [0..2] of Byte;
- Normal,
- Colour : Byte;
- end;
- PVXLVoxel = ^TVXLVoxel;
- TVXLSection = Record
- Name : TStr16;
- Det : Single;
- Transform : TM3x4;
- MinB,
- MaxB : Array [0..2] of Single;
- Size : Array [0..2] of Byte;
- NormalType : Byte;
- Data : PVXLVoxel;
- VoxelCount : Integer;
- end;
- PVXLSection = ^TVXLSection;
- TVXL = Class(TObject)
- private
- FHVA : THVA;
- FSection : Array of TVXLSection;
- procedure AddVoxels(var SpanData : PByte; var Z : Integer; const X,Y,S : Integer);
- function GetCount : Integer;
- function GetSection(Index : Integer) : PVXLSection;
- public
- constructor Create;
- destructor Destroy; override;
- procedure LoadFromFile(Filename : AnsiString);
- procedure LoadFromStream(Stream : TStream);
- property Count : Integer read GetCount;
- property Section[Index : Integer] : PVXLSection read GetSection;
- end;
- implementation
- uses SysUtils;
- constructor THVA.Create(Stream : TStream);
- var
- C : Array [0..1] of Cardinal;
- S,F : Integer;
- begin
- Inherited Create();
- Stream.Seek(16,soFromCurrent); // Skip File Path.
- Stream.Read(C[0],8); // Frame Count + Section Count
- SetLength(FSection,C[1]);
- for S := 0 to C[1]-1 do
- begin
- Stream.Read(FSection[S].Name[1],16);
- SetLength(FSection[S].Frames,C[0]);
- end;
- for F := 0 to C[0]-1 do
- for S := 0 to C[1]-1 do
- Stream.Read(FSection[S].Frames[F][0,0],SizeOf(TM3x4));
- end;
- destructor THVA.Destroy;
- begin
- Inherited;
- SetLength(FSection,0);
- end;
- function THVA.GetSection(Index : Integer) : PHVASection;
- begin
- Result := @FSection[Index];
- end;
- function THVA.GetMatrix(Section,Frame : Integer) : TM3x4;
- begin
- Result := FSection[Section].Frames[Frame];
- end;
- //-- [TVXL] --//
- constructor TVXL.Create;
- begin
- Inherited Create;
- end;
- destructor TVXL.Destroy;
- begin
- Inherited Destroy;
- end;
- procedure TVXL.AddVoxels(var SpanData : PByte; var Z : Integer; const X,Y,S : Integer);
- type
- TCNByte = Record
- Colour,
- Normal : Byte;
- end;
- PCNByte = ^TCNByte;
- var
- Count,V : Integer;
- D : PVXLVoxel;
- begin
- Count := SpanData^;
- Inc(Cardinal(SpanData),1);
- With FSection[S] do
- begin
- D := Pointer(Cardinal(Data)+(VoxelCount*SizeOf(TVXLVoxel)));
- for V := 0 to Count-1 do
- begin
- D^.Colour := PCNByte(SpanData)^.Colour;
- D^.Normal := PCNByte(SpanData)^.Normal;
- D^.XYZ[0] := X;
- D^.XYZ[1] := Y;
- D^.XYZ[2] := Z;
- Inc(Cardinal(SpanData),2);
- Inc(Z);
- Inc(Cardinal(D),SizeOf(TVXLVoxel));
- Inc(VoxelCount);
- end;
- end;
- if Count <> SpanData^ then
- asm nop end; //Break Point goes here.
- Inc(Cardinal(SpanData),1);
- end;
- procedure TVXL.LoadFromFile(Filename : AnsiString);
- var
- Stream : TStream;
- begin
- Stream := TFileStream.Create(Filename,fmOpenRead);
- LoadFromStream(Stream);
- Stream.Free;
- end;
- procedure TVXL.LoadFromStream(Stream : TStream);
- var
- S,X,Y,Z : Integer;
- BodySize : Integer;
- Name : TStr16;
- Span : Array [0..2] of Integer;
- SpanStart,
- SpanEnd : PInteger;
- SpanData,
- SpanDataD : PByte;
- SS : Integer;
- BodyData : Pointer;
- begin
- // MAIN HEADER
- Stream.Seek(16+4,soFromCurrent);
- Stream.Read(S,4);
- SetLength(FSection,S);
- Stream.Seek(4,soFromCurrent); // Skip
- Stream.Read(BodySize,4);
- Stream.Seek(2+(256*3),soFromCurrent); // Skip
- // MAIN HEADER
- // SECTION HEADERS
- for S := 0 to High(FSection) do
- begin
- Stream.Read(Name[1],16);
- Stream.Seek(4*3,soFromCurrent); // Skip
- end;
- // SECTION HEADERS
- // BODY
- GetMem(BodyData,BodySize);
- Stream.Read(BodyData^,BodySize); // We use it below once we know the Tail Header
- // BODY
- for S := 0 to High(FSection) do
- begin
- // TAIL HEADER
- Stream.Read(Span[0],4*3);
- Stream.Read(FSection[S].Det,4+SizeOf(TM3x4)+(3*4*2)+3+1);
- // TAIL HEADER
- // VOXEL DATA (Reading BODYDATA)
- With FSection[S] do
- begin
- GetMem(Data,Size[0]*Size[1]*Size[2]*Sizeof(TVXLVoxel)); //We make it the maximum size as we don't know how many voxels
- VoxelCount := 0;
- SpanStart := Pointer(Cardinal(BodyData)+Span[0]);
- SpanEnd := Pointer(Cardinal(BodyData)+Span[1]);
- SpanData := Pointer(Cardinal(BodyData)+Span[2]);
- for Y := 0 to Size[1]-1 do
- for X := 0 to Size[0]-1 do
- begin
- if (SpanStart^ > -1) and (SpanEnd^ > -1) then
- begin
- Z := 0;
- SpanDataD := Pointer(Cardinal(SpanData)+SpanStart^);
- while (Z < Size[2]) do
- begin
- Inc(Z,SpanDataD^);
- Inc(SpanDataD,1);
- AddVoxels(SpanDataD,Z,X,Y,S);
- end;
- end;
- Inc(Cardinal(SpanStart),4);
- Inc(Cardinal(SpanEnd),4);
- end;
- // VOXEL DATA
- ReallocMem(Data,VoxelCount*Sizeof(TVXLVoxel)); //Resize to the correct size now we have it.
- end;
- end;
- FreeMem(BodyData);
- end;
- function TVXL.GetCount : Integer;
- begin
- Result := High(FSection)+1;
- end;
- function TVXL.GetSection(Index : Integer) : PVXLSection;
- begin
- Result := @FSection[Index];
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement