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

hob parser: distinguish face/vertex color, update hob description

This commit is contained in:
dpethes 2014-10-26 16:22:25 +01:00
parent 4670ca2807
commit 1a75a3abab
2 changed files with 75 additions and 42 deletions

View File

@ -70,25 +70,36 @@ NOF * face block
FC * face FC * face
{ {
4B int face flags 4B int face flags
- if bit 3 is set, the face is a quad, otherwise triangle - bits 0, 1 unknown
- if bit 2 is set, face has texture coordinates (uv-s) - if bit 2 is set, face has texture coordinates (uv-s)
- if bit 3 is set, the face is a quad, otherwise it's a triangle
- if bit 4 is set, face has separate colors for each vertex
- if bit 5 is set, face has color
- if bit 6 is set, face has extra 8 bytes before vertex colors - if bit 6 is set, face has extra 8 bytes before vertex colors
1B int 46/49/4B - bits 7-10 unknown. higher bits don't seem to be set
1B int 51/71 1B int ? 46/49/4B
1B int 0C 1B int ? 51/71
1B int block size / 4: A = 40B, 9 = 36, etc. 1B int ? 0C
2B int zero? 1B int face block size divided by 4
2B int material index? - A = 40B, 9 = 36, etc.
2B int zero
2B int material index
4x 2B vertex indices, relative to the face group. The last index is zero in triangle faces 4x 2B vertex indices, relative to the face group. The last index is zero in triangle faces
if (face has extra 8 bytes) { if (face has extra 8 bytes) {
8B extra bytes 8B extra bytes
}
if (face has color) {
if (face has vertex colors) {
3/4 * 4B RGBA vertex color
} else {
4B RGBA color
}
} }
3/4 * 4B RGBA vertex color
if (face has texture coordinates) { if (face has texture coordinates) {
3/4 * { 3/4 * {
2B int u 2B int horizontal texture coord
2B int v 2B int vertical texture coord
} }
} }
} }
} }

View File

@ -20,7 +20,6 @@ type
b1, b2, b3: byte; b1, b2, b3: byte;
bsize: byte; bsize: byte;
ftype: byte; //3 - tri, 4 - quad ftype: byte; //3 - tri, 4 - quad
has_uv: boolean;
material_index: word; material_index: word;
indices: array[0..3] of word; indices: array[0..3] of word;
vertex_colors: array[0..3] of TRGBA; vertex_colors: array[0..3] of TRGBA;
@ -80,17 +79,24 @@ begin
end; end;
procedure ReadFaces(var group: THobFaceGroup; var f: TMemoryStream); procedure ReadFaces(var group: THobFaceGroup; var f: TMemoryStream);
const
FACE_UV = %100;
FACE_QUAD = %1000;
FACE_VCOLORS = %10000;
FACE_COLOR = %100000;
FACE_EXT = %1000000;
var var
i, k: integer; i, k: integer;
face: THobFace; face: THobFace;
unknown: integer; zero: integer;
file_pos: integer; file_pos: integer;
color: integer;
begin begin
unknown := f.ReadDWord; zero := f.ReadDWord;
if (unknown <> 0) then if (zero <> 0) then
writeln('unusual file: zero'); writeln('unusual file: zero');
unknown := f.ReadDWord; zero := f.ReadDWord;
if (unknown <> 0) then if (zero <> 0) then
writeln('unusual file: zero'); writeln('unusual file: zero');
file_pos := f.ReadDWord; file_pos := f.ReadDWord;
if file_pos <> f.Position + 4 then if file_pos <> f.Position + 4 then
@ -101,21 +107,20 @@ begin
SetLength(group.faces, group.face_count); SetLength(group.faces, group.face_count);
for i := 0 to group.face_count - 1 do begin for i := 0 to group.face_count - 1 do begin
file_pos := f.Position; file_pos := f.Position;
face.flags := f.ReadDWord; //? face.flags := f.ReadDWord;
face.b1 := f.ReadByte; //46/49/4B face.b1 := f.ReadByte; //46/49/4B
face.b2 := f.ReadByte; //51/71 face.b2 := f.ReadByte; //51/71
face.b3 := f.ReadByte; //0C face.b3 := f.ReadByte; //0C
face.bsize := f.ReadByte * 4; //block size: A = 40B, 9 = 36 face.bsize := f.ReadByte * 4; //block size
zero := f.ReadWord;
unknown := f.ReadWord; if (zero <> 0) then
if (unknown <> 0) then writeln('unusual file: face header separator');
writeln('unusual file: unknown');
//material index //material index
face.material_index := f.ReadWord; face.material_index := f.ReadWord;
//face type: quad or triangle //face type: quad or triangle
if face.flags and %1000 > 0 then if face.flags and FACE_QUAD > 0 then
face.ftype := 4 face.ftype := 4
else else
face.ftype := 3; face.ftype := 3;
@ -125,43 +130,59 @@ begin
face.indices[k] := f.ReadWord; face.indices[k] := f.ReadWord;
//ext0 //ext0
if face.flags and %1000000 > 0 then begin if face.flags and FACE_EXT > 0 then begin
f.ReadDWord; f.ReadDWord;
f.ReadDWord; f.ReadDWord;
end; end;
//vertex colors //vertex colors - either per vertex, or the same for all vertices
for k := 0 to face.ftype - 1 do if face.flags and FACE_COLOR > 0 then begin
face.vertex_colors[k].color := f.ReadDWord; if face.flags and FACE_VCOLORS > 0 then begin
for k := 0 to face.ftype - 1 do
face.vertex_colors[k].color := f.ReadDWord;
end else begin
color := f.ReadDWord;
for k := 0 to face.ftype - 1 do
face.vertex_colors[k].color := color;
end;
end;
//uv coords //uv coords
face.has_uv := face.flags and %100 > 0; if face.flags and FACE_UV > 0 then begin
if face.has_uv then begin
for k := 0 to face.ftype - 1 do begin for k := 0 to face.ftype - 1 do begin
face.tex_coords[k].u := f.ReadWord; face.tex_coords[k].u := f.ReadWord;
face.tex_coords[k].v := f.ReadWord; face.tex_coords[k].v := f.ReadWord;
end; end;
end; end;
group.faces[i] := face;
if DumpFaces then begin if DumpFaces then begin
if face.ftype = 3 then write('t') else write('q'); if (face.flags and FACE_QUAD) = 0 then write('t') else write('q');
write(face.flags:5, face.b1:3, face.b2:3, face.b3:3, face.bsize:3); write(face.flags:5, face.b1:3, face.b2:4, face.b3:3, face.bsize:3);
write(' mat: ', face.material_index); write(' mt: ', face.material_index);
write(' verts: '); write(' verts: ');
for k := 0 to 3 do for k := 0 to face.ftype - 1 do
write(face.indices[k]:4); write(face.indices[k]:4);
write(' colors: '); write(' colors: ');
for k := 0 to face.ftype - 1 do for k := 0 to face.ftype - 1 do
write(IntToHex(face.vertex_colors[k].color, 8), ' '); write(IntToHex(face.vertex_colors[k].color, 8), ' ');
if face.has_uv then begin if (face.flags and FACE_UV) > 0 then begin
write(' uvs: '); write(' uvs: ');
for k := 0 to face.ftype - 1 do for k := 0 to face.ftype - 1 do
write('(', face.tex_coords[k].u, ', ', face.tex_coords[k].v, ') '); write('(', face.tex_coords[k].u, ', ', face.tex_coords[k].v, ') ');
end; end;
writeln;
end; end;
//hack for awing.hob
if f.Position <> (file_pos + face.bsize) then begin
write(' rest:');
for k := f.Position to file_pos + face.bsize - 1 do
write(IntToHex(f.ReadByte, 2):3);
end;
if DumpFaces then
writeln;
group.faces[i] := face;
end; end;
end; end;
@ -243,6 +264,7 @@ begin
for i := 0 to mesh.face_group_count - 1 do begin for i := 0 to mesh.face_group_count - 1 do begin
ReadFaceGroup(mesh.face_groups[i], f); ReadFaceGroup(mesh.face_groups[i], f);
end; end;
writeln;
end; end;