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

model viewer: export current object

This commit is contained in:
dpethes 2020-07-28 14:08:33 +02:00
parent aa723776ba
commit c98faf8fb5

View File

@ -30,8 +30,6 @@ type
TVertexList = specialize TVector<TVertex>; TVertexList = specialize TVector<TVertex>;
TTriangleList = specialize TVector<TTriangle>; TTriangleList = specialize TVector<TTriangle>;
TTriangleListList = specialize TVector<TTriangleList>;
TTriangleListListList = specialize TVector<TTriangleListList>;
TMaterialArray = array of TMaterial; TMaterialArray = array of TMaterial;
TRenderOpts = record TRenderOpts = record
@ -65,10 +63,9 @@ type
TModel = class TModel = class
private private
_vertices: TVertexList;
_triangles: TTriangleListListList;
_materials: TMaterialArray; _materials: TMaterialArray;
_objects: TRenderObjectList; _objects: TRenderObjectList;
_current_robject: TRenderObject;
_hmt: THmtFile; _hmt: THmtFile;
_hmt_loaded: boolean; _hmt_loaded: boolean;
@ -115,7 +112,6 @@ var
triangle: TTriangle; triangle: TTriangle;
fg_idx: integer; fg_idx: integer;
tris: TTriangleList; tris: TTriangleList;
mesh_tris: TTriangleListList;
function InitVertex(face: THobFace; offset: integer): TTriangle; function InitVertex(face: THobFace; offset: integer): TTriangle;
var var
@ -137,7 +133,6 @@ var
begin begin
current_block_vertices := TVertexList.Create; //todo just offset to vertex list current_block_vertices := TVertexList.Create; //todo just offset to vertex list
mesh_tris := TTriangleListList.Create;
fg_idx := 0; fg_idx := 0;
robject.parts := TObjectPartList.Create; robject.parts := TObjectPartList.Create;
@ -177,13 +172,11 @@ begin
robjpart.triangles.PushBack(triangle); robjpart.triangles.PushBack(triangle);
end; end;
end; end;
mesh_tris.PushBack(tris);
fg_idx += 1; fg_idx += 1;
robject.parts.PushBack(robjpart); robject.parts.PushBack(robjpart);
end; end;
current_block_vertices.Free; current_block_vertices.Free;
_triangles.PushBack(mesh_tris);
_objects.PushBack(robject); _objects.PushBack(robject);
end; end;
@ -253,28 +246,17 @@ begin
end; end;
destructor TModel.Destroy; destructor TModel.Destroy;
var
t: TTriangleListList;
tt: TTriangleList;
begin begin
inherited Destroy; inherited Destroy;
for t in _triangles do begin
for tt in t do
tt.Free;
t.Free;
end;
_triangles := nil;
if _hmt_loaded then
DeallocHmt(_hmt);
_vertices.Free;
_materials := nil; _materials := nil;
_objects.Free; _objects.Free;
end; end;
procedure TModel.Load(hob, hmt: TMemoryStream); procedure TModel.Load(hob, hmt: TMemoryStream);
begin begin
_vertices := TVertexList.Create; if _hmt_loaded then
_triangles := TTriangleListListList.Create; DeallocHmt(_hmt);
WriteLn('Loading mesh file'); WriteLn('Loading mesh file');
HobRead(hob); HobRead(hob);
WriteLn('Loading material file'); WriteLn('Loading material file');
@ -382,12 +364,17 @@ var
part_idx, i: integer; part_idx, i: integer;
begin begin
if _triangles.Size = 0 then if _objects.Size = 0 then begin
exit; ImGui.Begin_('Mesh');
ImGui.Text('no objects');
ImGui.End_;
exit;
end;
//clip selected object/part //clip selected object/part
opts.obj_to_draw := min(integer(opts.obj_to_draw), integer(_objects.Size - 1)); opts.obj_to_draw := min(integer(opts.obj_to_draw), integer(_objects.Size - 1));
robject := _objects[opts.obj_to_draw]; robject := _objects[opts.obj_to_draw];
_current_robject := robject;
opts.part_to_draw := min(integer(opts.part_to_draw), integer(robject.parts.Size - 1)); opts.part_to_draw := min(integer(opts.part_to_draw), integer(robject.parts.Size - 1));
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
@ -425,12 +412,12 @@ begin
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
ImGui.Begin_('Mesh'); ImGui.Begin_('Mesh');
ImGui.Text('triangles: %d (vertices: %d)', [triangle_count, _vertices.Size]); ImGui.Text('triangles: %d', [triangle_count]);
ImGui.Text('object: %d / %d', [opts.obj_to_draw + 1, _triangles.Size]); ImGui.Text('object: %d / %d', [opts.obj_to_draw + 1, _objects.Size]);
if opts.show_all_parts then if opts.show_all_parts then
ImGui.Text('parts: %d', [_triangles[opts.obj_to_draw].Size]) ImGui.Text('parts: %d', [robject.parts.Size])
else else
ImGui.Text('facegroup: %d / %d', [opts.part_to_draw + 1, _triangles[opts.obj_to_draw].Size]); ImGui.Text('part: %d / %d', [opts.part_to_draw + 1, robject.parts.Size]);
ImGui.End_; ImGui.End_;
end; end;
@ -442,6 +429,8 @@ const
procedure TModel.ExportObj(const obj_name: string; const png_textures: boolean); procedure TModel.ExportObj(const obj_name: string; const png_textures: boolean);
const const
DesiredUnitSize = 2; DesiredUnitSize = 2;
type
TOutputPass = (OutPassVertex, OutPassUV, OutPassFaces);
var var
objfile: TextFile; objfile: TextFile;
vt: TVertex; vt: TVertex;
@ -455,29 +444,20 @@ var
uv_counter: integer; uv_counter: integer;
last_material_index: integer; last_material_index: integer;
i,j,k: integer; i,j: integer;
vertex_counter: Integer; vertex_counter, part_idx: Integer;
mat: TMaterial; mat: TMaterial;
mtl_name: string; mtl_name: string;
function GetMaxCoord: double; robject: TRenderObject;
var part: TObjectPart;
vt: TVertex; outpass: TOutputPass;
i: integer;
begin
result := 0;
for i := 0 to _vertices.Size - 1 do begin
vt := _vertices[i];
x := abs(vt.x);
y := abs(vt.y);
z := abs(vt.z);
coord_max := Max(z, Max(x, y));
if coord_max > result then
result := coord_max;
end;
end;
begin begin
robject := _current_robject;
if (robject.parts = nil) or (robject.parts.Size = 0) then
exit;
AssignFile(objfile, obj_name); AssignFile(objfile, obj_name);
Rewrite(objfile); Rewrite(objfile);
@ -485,70 +465,65 @@ begin
mtl_name := obj_name + '.mtl'; mtl_name := obj_name + '.mtl';
writeln(objfile, 'mtllib ', mtl_name); writeln(objfile, 'mtllib ', mtl_name);
//scale pass
scaling_factor := 1; scaling_factor := 1;
//scaling_factor := DesiredUnitSize / GetMaxCoord;
// just export first object for now -- TODO: allow object selection later
//vertex pass
for k := 0 to _triangles[0].Size - 1 do
for i := 0 to _triangles[0][k].Size - 1 do begin
face := _triangles[0][k][i];
for vt in face.vertices do begin
x := (vt.x) * scaling_factor;
y := (vt.y) * scaling_factor;
z := (vt.z) * scaling_factor;
writeln(objfile, 'v ', x:10:6, ' ', y:10:6, ' ', z:10:6);
end;
end;
//uv pass
for k := 0 to _triangles[0].Size - 1 do
for i := 0 to _triangles[0][k].Size - 1 do begin
face := _triangles[0][k][i];
for j := 0 to 2 do begin
u := face.tex_coords[j, 0];
v := face.tex_coords[j, 1];
writeln(objfile, 'vt ', u:10:6, ' ', v:10:6);
end;
end;
//face / material pass
uv_counter := 1; uv_counter := 1;
vertex_counter := 1; vertex_counter := 1;
last_material_index := -1; last_material_index := -1;
part_idx := 0;
for k := 0 to _triangles[0].Size - 1 do begin for outpass := Low(TOutputPass) to High(TOutputPass) do
if _triangles[0][k].Size = 0 then for part in robject.parts do begin
continue; if part.triangles.Size = 0 then
continue;
writeln(objfile, 'g ', k); if outpass = OutPassFaces then begin
writeln(objfile, 'g ', part_idx);
part_idx += 1;
end;
for i := 0 to _triangles[0][k].Size - 1 do begin for i := 0 to part.triangles.Size - 1 do begin
face := _triangles[0][k][i]; face := part.triangles[i];
if face.material_index <> last_material_index then begin case outpass of
if face.material_index = -1 then OutPassVertex: begin
writeln(objfile, 'usemtl ' + DefaultMaterial) for vt in face.vertices do begin
else begin x := (vt.x) * scaling_factor;
mat := _materials[face.material_index]; y := (vt.y) * scaling_factor;
writeln(objfile, 'usemtl ' + mat.name); z := (vt.z) * scaling_factor;
writeln(objfile, 'v ', x:10:6, ' ', y:10:6, ' ', z:10:6);
end;
end;
OutPassUV: begin
for j := 0 to 2 do begin
u := face.tex_coords[j, 0];
v := face.tex_coords[j, 1];
writeln(objfile, 'vt ', u:10:6, ' ', v:10:6);
end;
end;
OutPassFaces: begin
if face.material_index <> last_material_index then begin
if face.material_index = -1 then
writeln(objfile, 'usemtl ' + DefaultMaterial)
else begin
mat := _materials[face.material_index];
writeln(objfile, 'usemtl ' + mat.name);
end;
last_material_index := face.material_index;
end;
write(objfile, 'f ');
for vt in face.vertices do begin
write(objfile, vertex_counter);
write(objfile, '/', uv_counter);
write(objfile, ' ');
vertex_counter += 1;
uv_counter += 1;
end;
writeln(objfile);
end;
end; end;
last_material_index := face.material_index;
end; end;
write(objfile, 'f ');
for vt in face.vertices do begin
write(objfile, vertex_counter);
write(objfile, '/', uv_counter);
write(objfile, ' ');
vertex_counter += 1;
uv_counter += 1;
end;
writeln(objfile);
end; end;
end;
CloseFile(objfile); CloseFile(objfile);
SaveMaterials(mtl_name, png_textures); SaveMaterials(mtl_name, png_textures);