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:
parent
aa723776ba
commit
c98faf8fb5
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user