Add transformation option for exporter model.

This commit is contained in:
kovacsv 2021-12-28 09:18:29 +01:00
parent 0a1f158e01
commit f46ae4b88b
6 changed files with 81 additions and 23 deletions

View File

@ -74,7 +74,6 @@
"single" "single"
], ],
"block-scoped-var": "error", "block-scoped-var": "error",
"no-loop-func": "error",
"no-undef": "error", "no-undef": "error",
"no-extend-native": "error", "no-extend-native": "error",
"eqeqeq": "error", "eqeqeq": "error",

View File

@ -2,6 +2,7 @@ OV.ExporterSettings = class
{ {
constructor (settings) constructor (settings)
{ {
this.transformation = new OV.Transformation ();
this.isMeshVisible = (meshInstanceId) => { this.isMeshVisible = (meshInstanceId) => {
return true; return true;
}; };
@ -67,31 +68,47 @@ OV.ExporterModel = class
EnumerateTransformedMeshes (onMesh) EnumerateTransformedMeshes (onMesh)
{ {
this.EnumerateMeshInstances ((meshInstance) => { this.EnumerateMeshInstances ((meshInstance) => {
const transformed = meshInstance.GetTransformedMesh (); let transformation = meshInstance.GetTransformation ();
if (!this.settings.transformation.IsIdentity ()) {
transformation.Append (this.settings.transformation);
}
let mesh = meshInstance.GetMesh ();
let transformed = OV.CloneMesh (mesh);
if (!transformation.IsIdentity ()) {
OV.TransformMesh (transformed, transformation);
}
onMesh (transformed); onMesh (transformed);
}); });
} }
EnumerateVerticesAndTriangles (callbacks) EnumerateVerticesAndTriangles (callbacks)
{ {
this.EnumerateMeshInstances ((meshInstance) => { let transformedMeshes = [];
meshInstance.EnumerateVertices ((vertex) => { this.EnumerateTransformedMeshes ((mesh) => {
transformedMeshes.push (mesh);
});
for (let mesh of transformedMeshes) {
mesh.EnumerateVertices ((vertex) => {
callbacks.onVertex (vertex.x, vertex.y, vertex.z); callbacks.onVertex (vertex.x, vertex.y, vertex.z);
}); });
}); }
let vertexOffset = 0; let vertexOffset = 0;
this.EnumerateMeshInstances ((meshInstance) => { for (let mesh of transformedMeshes) {
meshInstance.EnumerateTriangleVertexIndices ((v0, v1, v2) => { mesh.EnumerateTriangleVertexIndices ((v0, v1, v2) => {
callbacks.onTriangle (v0 + vertexOffset, v1 + vertexOffset, v2 + vertexOffset); callbacks.onTriangle (v0 + vertexOffset, v1 + vertexOffset, v2 + vertexOffset);
}); });
vertexOffset += meshInstance.VertexCount (); vertexOffset += mesh.VertexCount ();
}); }
} }
EnumerateTrianglesWithNormals (onTriangle) EnumerateTrianglesWithNormals (onTriangle)
{ {
this.EnumerateMeshInstances ((meshInstance) => { this.EnumerateTransformedMeshes ((mesh) => {
meshInstance.EnumerateTriangleVertices ((v0, v1, v2) => { mesh.EnumerateTriangleVertices ((v0, v1, v2) => {
let normal = OV.CalculateTriangleNormal (v0, v1, v2); let normal = OV.CalculateTriangleNormal (v0, v1, v2);
onTriangle (v0, v1, v2, normal); onTriangle (v0, v1, v2, normal);
}); });

View File

@ -32,6 +32,16 @@ OV.MeshInstance = class extends OV.ModelObject3D
return this.id; return this.id;
} }
GetTransformation ()
{
return this.node.GetWorldTransformation ();
}
GetMesh ()
{
return this.mesh;
}
VertexCount () VertexCount ()
{ {
return this.mesh.VertexCount (); return this.mesh.VertexCount ();
@ -103,7 +113,7 @@ OV.MeshInstance = class extends OV.ModelObject3D
GetTransformedMesh () GetTransformedMesh ()
{ {
let transformation = this.node.GetWorldTransformation (); let transformation = this.node.GetWorldTransformation ();
const transformed = OV.CloneMesh (this.mesh); let transformed = OV.CloneMesh (this.mesh);
OV.TransformMesh (transformed, transformation); OV.TransformMesh (transformed, transformation);
return transformed; return transformed;
} }

View File

@ -135,8 +135,8 @@ OV.AddCheckbox = function (parentElement, id, text, isChecked, onChange)
label.setAttribute ('for', id); label.setAttribute ('for', id);
let check = OV.AddDomElement (label, 'input', 'ov_checkbox'); let check = OV.AddDomElement (label, 'input', 'ov_checkbox');
check.setAttribute ('type', 'checkbox'); check.setAttribute ('type', 'checkbox');
check.setAttribute ('checked', isChecked);
check.setAttribute ('id', id); check.setAttribute ('id', id);
check.checked = isChecked;
OV.AddDomElement (label, 'span', null, text); OV.AddDomElement (label, 'span', null, text);
if (onChange) { if (onChange) {
check.addEventListener ('change', onChange); check.addEventListener ('change', onChange);

View File

@ -60,4 +60,35 @@ describe ('Exporter Model', function () {
assert (OV.CoordIsEqual3D (boundingBox.min, new OV.Coord3D (0.0, 0.0, 0.0))); assert (OV.CoordIsEqual3D (boundingBox.min, new OV.Coord3D (0.0, 0.0, 0.0)));
assert (OV.CoordIsEqual3D (boundingBox.max, new OV.Coord3D (2.0, 1.0, 1.0))); assert (OV.CoordIsEqual3D (boundingBox.max, new OV.Coord3D (2.0, 1.0, 1.0)));
}); });
it ('Model transformation test', function () {
let rotation = OV.QuaternionFromAxisAngle (new OV.Coord3D (0.0, 1.0, 0.0), -Math.PI / 2.0);
let model = CreateTestModel ();
let settings = new OV.ExporterSettings ({
transformation : new OV.Transformation (new OV.Matrix ().CreateRotation (rotation.x, rotation.y, rotation.z, rotation.w))
});
let exporterModel = new OV.ExporterModel (model, settings);
assert.strictEqual (exporterModel.MeshInstanceCount (), 3);
let boundingBox = GetExporterModelBoundingBox (exporterModel);
assert (OV.CoordIsEqual3D (boundingBox.min, new OV.Coord3D (-1.0, 0.0, 0.0)));
assert (OV.CoordIsEqual3D (boundingBox.max, new OV.Coord3D (0.0, 1.0, 3.0)));
});
it ('Model filter and transformation test', function () {
let rotation = OV.QuaternionFromAxisAngle (new OV.Coord3D (0.0, 1.0, 0.0), -Math.PI / 2.0);
let model = CreateTestModel ();
let settings = new OV.ExporterSettings ({
transformation : new OV.Transformation (new OV.Matrix ().CreateRotation (rotation.x, rotation.y, rotation.z, rotation.w)),
isMeshVisible : (meshInstanceId) => {
return !meshInstanceId.IsEqual (new OV.MeshInstanceId (3, 2));
}
});
let exporterModel = new OV.ExporterModel (model, settings);
assert.strictEqual (exporterModel.MeshInstanceCount (), 2);
let boundingBox = GetExporterModelBoundingBox (exporterModel);
assert (OV.CoordIsEqual3D (boundingBox.min, new OV.Coord3D (-1.0, 0.0, 0.0)));
assert (OV.CoordIsEqual3D (boundingBox.max, new OV.Coord3D (0.0, 1.0, 2.0)));
});
}); });

View File

@ -52,6 +52,7 @@ OV.ModelExporterUI = class extends OV.ExporterUI
{ {
let visibleOnly = this.visibleOnlyCheckbox.checked; let visibleOnly = this.visibleOnlyCheckbox.checked;
let settings = new OV.ExporterSettings ({ let settings = new OV.ExporterSettings ({
transformation : new OV.Transformation (),
isMeshVisible : (meshInstanceId) => { isMeshVisible : (meshInstanceId) => {
if (visibleOnly) { if (visibleOnly) {
return callbacks.isMeshVisible (meshInstanceId); return callbacks.isMeshVisible (meshInstanceId);
@ -61,16 +62,16 @@ OV.ModelExporterUI = class extends OV.ExporterUI
} }
}); });
// TODO let exporterModel = new OV.ExporterModel (model, settings);
// if (exporterModel.MeshInstanceCount () === 0) { if (exporterModel.MeshInstanceCount () === 0) {
// let errorDialog = OV.ShowMessageDialog ( let errorDialog = OV.ShowMessageDialog (
// 'Export Failed', 'Export Failed',
// 'The model doesn\'t contain any meshes.', 'The model doesn\'t contain any meshes.',
// null null
// ); );
// callbacks.onDialog (errorDialog); callbacks.onDialog (errorDialog);
// return; return;
// } }
let progressDialog = new OV.ProgressDialog (); let progressDialog = new OV.ProgressDialog ();
progressDialog.Init ('Exporting Model'); progressDialog.Init ('Exporting Model');