2
0
mirror of https://github.com/dpethes/rerogue.git synced 2025-06-07 18:58:32 +02:00

hob parser: parse files with multiple objects / meshes

This commit is contained in:
dpethes 2014-10-14 03:30:42 +02:00
parent 02029c9da6
commit 650a8f8f89
2 changed files with 85 additions and 55 deletions

View File

@ -1,11 +1,13 @@
4B entity_count. 0 in empty files, 1 for most single objects, N>1 in opkg.hob files 4B object count OF. 0 in empty files
4B simple offset to vertices/faces - doesn't work all the time. Probably useless? 4B simple offset to vertices/faces - doesn't work all the time. Probably useless?
OF * object header 116B
{
16B name 16B name
4B facegroups offset 4B int facegroups offset
4B int ? 0x7C, 4B int facegroup header offset
4B int ? 0x88, 0xA8 4B int facegroup header 2 offset
12B zero? 12B zero
4B int ? 94, 0xD4 4B int ? 94, 0xD4
4B int ? 98, 0x100 4B int ? 98, 0x100
4B int ? 9C, 0x104 4B int ? 9C, 0x104
@ -15,9 +17,12 @@
-wmvwing: 1.25 -wmvwing: 1.25
12B zero 12B zero
5x4B floats ? 5x4B floats ?
4B int ? -bark_moon, e_cor, towc: 0xA = 10 4B int offset before 0xFFFFFFFF header end marker
6x 4B float ? 6x 4B float ?
}
OF * facegroup header
{
2B number of facegroups? NOF 2B number of facegroups? NOF
2B number of facegroups? NOF 2B number of facegroups? NOF
facegoup definitions facegoup definitions
@ -26,8 +31,10 @@ facegoup definitions
} }
4B 0xFFFFFFFF header end marker 4B 0xFFFFFFFF header end marker
}
NOF * facegroup/meshdef0 132B { NOF * facegroup/meshdef0 132B
{
4B int 4B int
4B int 4B int
4B int 4B int
@ -44,7 +51,8 @@ NOF * facegroup/meshdef0 132B {
28B zero 28B zero
} }
NOF * facegroup/meshdef1 96B { NOF * facegroup/meshdef1 96B
{
4B int facedef end offset 4B int facedef end offset
20B zero 20B zero
4B int vertices used 4B int vertices used

View File

@ -32,16 +32,23 @@ type
end; end;
end; end;
THobFile = record THobObject = record
obj_count: integer;
name: array[0..15] of byte; name: array[0..15] of byte;
face_group_offset: integer; face_group_offset: integer;
face_group_header_offset: integer;
face_group_header2_offset: integer;
face_group_count: integer; face_group_count: integer;
face_group_count0: integer; face_group_count0: integer;
face_groups: array of THobFaceGroup; face_groups: array of THobFaceGroup;
end; end;
THobFile = record
obj_count: integer;
objects: array of THobObject;
end;
function ParseHobFile(const fname: string): THobFile; function ParseHobFile(const fname: string): THobFile;
//************************************************************************************************** //**************************************************************************************************
@ -178,48 +185,63 @@ begin
end; end;
procedure ReadObject(var mesh: THobObject; var f: TMemoryStream);
var
i: integer;
begin
f.ReadBuffer(mesh.name, 16);
mesh.face_group_offset := f.ReadDWord;
mesh.face_group_header_offset := f.ReadDWord;
mesh.face_group_header2_offset := f.ReadDWord;
writeln('object: ', NameToString(mesh.name));
writeln('face group offset: ', mesh.face_group_offset);
//get face group count
f.Seek(mesh.face_group_header_offset, fsFromBeginning); //16B zero
mesh.face_group_count := f.ReadWord; //which?
mesh.face_group_count0 := f.ReadWord;
if mesh.face_group_count <> mesh.face_group_count0 then begin
writeln('facegroup counts don''t match!: ', mesh.face_group_count, mesh.face_group_count0:5);
end;
//read face group defs
SetLength(mesh.face_groups, mesh.face_group_count);
f.Seek(mesh.face_group_offset, fsFromBeginning);
for i := 0 to mesh.face_group_count - 1 do begin
ReadFaceGroup(mesh.face_groups[i], f);
end;
end;
function ParseHobFile(const fname: string): THobFile; function ParseHobFile(const fname: string): THobFile;
var var
f: TMemoryStream; f: TMemoryStream;
hob: THobFile; hob: THobFile;
i: integer; i: integer;
unknown: integer; filepos: int64;
begin begin
f := TMemoryStream.Create; f := TMemoryStream.Create;
f.LoadFromFile(fname); f.LoadFromFile(fname);
hob.obj_count := f.ReadDWord; //object count hob.obj_count := f.ReadDWord;
unknown := f.ReadDWord; //sometimes face block start, but useless in general f.ReadDWord; //sometimes face block start, but useless in general
writeln('objects: ', hob.obj_count);
if hob.obj_count = 0 then begin if hob.obj_count = 0 then begin
result := hob;
writeln('hob file is empty!'); writeln('hob file is empty!');
result := hob;
exit; exit;
end; end;
f.ReadBuffer(hob.name, 16); SetLength(hob.objects, hob.obj_count);
hob.face_group_offset := f.ReadDWord; for i := 0 to hob.obj_count - 1 do begin
filepos := f.Position;
ReadObject(hob.objects[i], f);
writeln(NameToString(hob.name)); //seek to next object header
writeln('objects: ', hob.obj_count); if i + 1 < hob.obj_count then
writeln('face group offset: ', hob.face_group_offset); f.Seek(filepos + 116, fsFromBeginning);
if hob.obj_count > 1 then begin
writeln('reading failed: cannot read multiple objects yet!');
halt;
end;
//get face group count
f.Seek(124, fsFromBeginning); //16B zero
hob.face_group_count := f.ReadWord; //which?
hob.face_group_count0 := f.ReadWord;
if hob.face_group_count <> hob.face_group_count0 then begin
writeln('reading failed: facegroup counts don''t match!: ', hob.face_group_count, hob.face_group_count0:5);
end;
//read face group defs
SetLength(hob.face_groups, hob.face_group_count);
f.Seek(hob.face_group_offset, fsFromBeginning);
for i := 0 to hob.face_group_count - 1 do begin
ReadFaceGroup(hob.face_groups[i], f);
end; end;
f.Free; f.Free;