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"
],
"block-scoped-var": "error",
"no-loop-func": "error",
"no-undef": "error",
"no-extend-native": "error",
"eqeqeq": "error",

View File

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

View File

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

View File

@ -135,8 +135,8 @@ OV.AddCheckbox = function (parentElement, id, text, isChecked, onChange)
label.setAttribute ('for', id);
let check = OV.AddDomElement (label, 'input', 'ov_checkbox');
check.setAttribute ('type', 'checkbox');
check.setAttribute ('checked', isChecked);
check.setAttribute ('id', id);
check.checked = isChecked;
OV.AddDomElement (label, 'span', null, text);
if (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.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 settings = new OV.ExporterSettings ({
transformation : new OV.Transformation (),
isMeshVisible : (meshInstanceId) => {
if (visibleOnly) {
return callbacks.isMeshVisible (meshInstanceId);
@ -61,16 +62,16 @@ OV.ModelExporterUI = class extends OV.ExporterUI
}
});
// TODO
// if (exporterModel.MeshInstanceCount () === 0) {
// let errorDialog = OV.ShowMessageDialog (
// 'Export Failed',
// 'The model doesn\'t contain any meshes.',
// null
// );
// callbacks.onDialog (errorDialog);
// return;
// }
let exporterModel = new OV.ExporterModel (model, settings);
if (exporterModel.MeshInstanceCount () === 0) {
let errorDialog = OV.ShowMessageDialog (
'Export Failed',
'The model doesn\'t contain any meshes.',
null
);
callbacks.onDialog (errorDialog);
return;
}
let progressDialog = new OV.ProgressDialog ();
progressDialog.Init ('Exporting Model');