Advertisement
Guest User

Untitled

a guest
Feb 16th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 5.56 KB | None | 0 0
  1. unit VXLHVAUnit;
  2.  
  3. {
  4.  VXL+HVA Unit
  5.  By Stuart "Stucuk" Carey
  6.  Started 2018/02/14
  7. }
  8.  
  9. interface
  10.  
  11. uses Classes;
  12.  
  13. type
  14. TStr16 = String[16];
  15. TM3x4  = Array [0..2,0..3] of Single;
  16.  
  17. THVASection = Record
  18.  Name   : TStr16;
  19.  Frames : Array of TM3x4;
  20. end;
  21. PHVASection = ^THVASection;
  22.  
  23. THVA = Class(TObject)
  24. private
  25.  FSection : Array of THVASection;
  26.  function GetSection(Index : Integer) : PHVASection;
  27. public
  28.  constructor Create(Stream : TStream);
  29.  destructor Destroy; override;
  30.  
  31.  function GetMatrix(Section,Frame : Integer) : TM3x4;
  32.  property Section[Index : Integer] : PHVASection read GetSection;
  33. end;
  34.  
  35. TVXLVoxel = Packed Record
  36.  XYZ    : Array [0..2] of Byte;
  37.  Normal,
  38.  Colour : Byte;
  39. end;
  40.  
  41. PVXLVoxel = ^TVXLVoxel;
  42.  
  43. TVXLSection = Record
  44.  Name       : TStr16;
  45.  Det        : Single;
  46.  Transform  : TM3x4;
  47.  MinB,
  48.  MaxB       : Array [0..2] of Single;
  49.  Size       : Array [0..2] of Byte;
  50.  NormalType : Byte;
  51.  Data       : PVXLVoxel;
  52.  VoxelCount : Integer;
  53. end;
  54. PVXLSection = ^TVXLSection;
  55.  
  56.  
  57. TVXL = Class(TObject)
  58. private
  59.  FHVA     : THVA;
  60.  FSection : Array of TVXLSection;
  61.  procedure AddVoxels(var SpanData : PByte; var Z : Integer; const X,Y,S : Integer);
  62.  function GetCount : Integer;
  63.  function GetSection(Index : Integer) : PVXLSection;
  64. public
  65.  constructor Create;
  66.  destructor Destroy; override;
  67.  
  68.  procedure LoadFromFile(Filename : AnsiString);
  69.  procedure LoadFromStream(Stream : TStream);
  70.  
  71.  property Count : Integer read GetCount;
  72.  property Section[Index : Integer] : PVXLSection read GetSection;
  73. end;
  74.  
  75. implementation
  76.  
  77. uses SysUtils;
  78.  
  79. constructor THVA.Create(Stream : TStream);
  80. var
  81.  C : Array [0..1] of Cardinal;
  82.  S,F : Integer;
  83. begin
  84.  Inherited Create();
  85.  
  86.  Stream.Seek(16,soFromCurrent); // Skip File Path.
  87.  Stream.Read(C[0],8);           // Frame Count + Section Count
  88.  
  89.  SetLength(FSection,C[1]);
  90.  
  91.  for S := 0 to C[1]-1 do
  92.  begin
  93.   Stream.Read(FSection[S].Name[1],16);
  94.   SetLength(FSection[S].Frames,C[0]);
  95.  end;
  96.  
  97.  for F := 0 to C[0]-1 do
  98.  for S := 0 to C[1]-1 do
  99.  Stream.Read(FSection[S].Frames[F][0,0],SizeOf(TM3x4));
  100. end;
  101.  
  102. destructor THVA.Destroy;
  103. begin
  104.  Inherited;
  105.  SetLength(FSection,0);
  106. end;
  107.  
  108. function THVA.GetSection(Index : Integer) : PHVASection;
  109. begin
  110.  Result := @FSection[Index];
  111. end;
  112.  
  113. function THVA.GetMatrix(Section,Frame : Integer) : TM3x4;
  114. begin
  115.  Result := FSection[Section].Frames[Frame];
  116. end;
  117.  
  118. //-- [TVXL] --//
  119.  
  120. constructor TVXL.Create;
  121. begin
  122.  Inherited Create;
  123. end;
  124.  
  125. destructor TVXL.Destroy;
  126. begin
  127.  Inherited Destroy;
  128. end;
  129.  
  130. procedure TVXL.AddVoxels(var SpanData : PByte; var Z : Integer; const X,Y,S : Integer);
  131. type
  132. TCNByte = Record
  133.  Colour,
  134.  Normal : Byte;
  135. end;
  136. PCNByte = ^TCNByte;
  137. var
  138.  Count,V : Integer;
  139.  D : PVXLVoxel;
  140. begin
  141.  Count := SpanData^;
  142.  Inc(Cardinal(SpanData),1);
  143.  
  144.  With FSection[S] do
  145.  begin
  146.   D := Pointer(Cardinal(Data)+(VoxelCount*SizeOf(TVXLVoxel)));
  147.  
  148.   for V := 0 to Count-1 do
  149.   begin
  150.    D^.Colour := PCNByte(SpanData)^.Colour;
  151.    D^.Normal := PCNByte(SpanData)^.Normal;
  152.    D^.XYZ[0]   := X;
  153.    D^.XYZ[1]   := Y;
  154.    D^.XYZ[2]   := Z;
  155.    Inc(Cardinal(SpanData),2);
  156.    Inc(Z);
  157.    Inc(Cardinal(D),SizeOf(TVXLVoxel));
  158.    Inc(VoxelCount);
  159.   end;
  160.  end;
  161.  
  162.  if Count <> SpanData^ then
  163.  asm nop end; //Break Point goes here.
  164.  Inc(Cardinal(SpanData),1);
  165. end;
  166.  
  167. procedure TVXL.LoadFromFile(Filename : AnsiString);
  168. var
  169.  Stream : TStream;
  170. begin
  171.  Stream := TFileStream.Create(Filename,fmOpenRead);
  172.   LoadFromStream(Stream);
  173.  Stream.Free;
  174. end;
  175.  
  176. procedure TVXL.LoadFromStream(Stream : TStream);
  177. var
  178.  S,X,Y,Z   : Integer;
  179.  BodySize  : Integer;
  180.  Name      : TStr16;
  181.  Span      : Array [0..2] of Integer;
  182.  SpanStart,
  183.  SpanEnd   : PInteger;
  184.  SpanData,
  185.  SpanDataD : PByte;
  186.  SS        : Integer;
  187.  BodyData  : Pointer;
  188. begin
  189.  // MAIN HEADER
  190.  Stream.Seek(16+4,soFromCurrent);
  191.  Stream.Read(S,4);
  192.  SetLength(FSection,S);
  193.  
  194.  Stream.Seek(4,soFromCurrent); // Skip
  195.  Stream.Read(BodySize,4);
  196.  Stream.Seek(2+(256*3),soFromCurrent); // Skip
  197.  // MAIN HEADER
  198.  
  199.  // SECTION HEADERS
  200.  for S := 0 to High(FSection) do
  201.  begin
  202.   Stream.Read(Name[1],16);
  203.   Stream.Seek(4*3,soFromCurrent); // Skip
  204.  end;
  205.  // SECTION HEADERS
  206.  
  207.  // BODY
  208.  GetMem(BodyData,BodySize);
  209.  Stream.Read(BodyData^,BodySize); // We use it below once we know the Tail Header
  210.  // BODY
  211.  
  212.  for S := 0 to High(FSection) do
  213.  begin
  214.   // TAIL HEADER
  215.   Stream.Read(Span[0],4*3);
  216.   Stream.Read(FSection[S].Det,4+SizeOf(TM3x4)+(3*4*2)+3+1);
  217.   // TAIL HEADER
  218.  
  219.   // VOXEL DATA (Reading BODYDATA)
  220.   With FSection[S] do
  221.   begin
  222.    GetMem(Data,Size[0]*Size[1]*Size[2]*Sizeof(TVXLVoxel)); //We make it the maximum size as we don't know how many voxels
  223.    VoxelCount := 0;
  224.  
  225.    SpanStart := Pointer(Cardinal(BodyData)+Span[0]);
  226.    SpanEnd   := Pointer(Cardinal(BodyData)+Span[1]);
  227.    SpanData  := Pointer(Cardinal(BodyData)+Span[2]);
  228.  
  229.    for Y := 0 to Size[1]-1 do
  230.    for X := 0 to Size[0]-1 do
  231.    begin
  232.     if (SpanStart^ > -1) and (SpanEnd^ > -1) then
  233.     begin
  234.      Z         := 0;
  235.      SpanDataD := Pointer(Cardinal(SpanData)+SpanStart^);
  236.  
  237.      while (Z < Size[2]) do
  238.      begin
  239.       Inc(Z,SpanDataD^);
  240.       Inc(SpanDataD,1);
  241.       AddVoxels(SpanDataD,Z,X,Y,S);
  242.      end;
  243.     end;
  244.  
  245.     Inc(Cardinal(SpanStart),4);
  246.     Inc(Cardinal(SpanEnd),4);
  247.    end;
  248.    // VOXEL DATA
  249.  
  250.    ReallocMem(Data,VoxelCount*Sizeof(TVXLVoxel)); //Resize to the correct size now we have it.
  251.   end;
  252.  end;
  253.  
  254.  FreeMem(BodyData);
  255. end;
  256.  
  257. function TVXL.GetCount : Integer;
  258. begin
  259.  Result := High(FSection)+1;
  260. end;
  261.  
  262. function TVXL.GetSection(Index : Integer) : PVXLSection;
  263. begin
  264.  Result := @FSection[Index];
  265. end;
  266.  
  267. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement