diff --git a/sandbox/embed_selfhost_fullscreen.html b/sandbox/embed_selfhost_fullscreen.html
index 628102d..0d3225c 100644
--- a/sandbox/embed_selfhost_fullscreen.html
+++ b/sandbox/embed_selfhost_fullscreen.html
@@ -44,6 +44,7 @@
+
diff --git a/sandbox/embed_selfhost_multiple.html b/sandbox/embed_selfhost_multiple.html
index e516f44..3868f7c 100644
--- a/sandbox/embed_selfhost_multiple.html
+++ b/sandbox/embed_selfhost_multiple.html
@@ -45,6 +45,7 @@
+
diff --git a/sandbox/embed_selfhost_single.html b/sandbox/embed_selfhost_single.html
index f25ee86..f227111 100644
--- a/sandbox/embed_selfhost_single.html
+++ b/sandbox/embed_selfhost_single.html
@@ -44,6 +44,7 @@
+
diff --git a/sandbox/embed_selfhost_single_scroll.html b/sandbox/embed_selfhost_single_scroll.html
index 1965107..e9944be 100644
--- a/sandbox/embed_selfhost_single_scroll.html
+++ b/sandbox/embed_selfhost_single_scroll.html
@@ -44,6 +44,7 @@
+
diff --git a/source/import/importer.js b/source/import/importer.js
index 592f843..7e5c156 100644
--- a/source/import/importer.js
+++ b/source/import/importer.js
@@ -265,7 +265,8 @@ OV.Importer = class
new OV.ImporterOff (),
new OV.ImporterPly (),
new OV.Importer3ds (),
- new OV.ImporterGltf ()
+ new OV.ImporterGltf (),
+ new OV.ImporterO3dv ()
];
this.fileList = new OV.FileList (this.importers);
this.model = null;
diff --git a/source/import/importero3dv.js b/source/import/importero3dv.js
new file mode 100644
index 0000000..38520e5
--- /dev/null
+++ b/source/import/importero3dv.js
@@ -0,0 +1,104 @@
+OV.ImporterO3dv = class extends OV.ImporterBase
+{
+ constructor ()
+ {
+ super ();
+ }
+
+ CanImportExtension (extension)
+ {
+ return extension === 'o3dv';
+ }
+
+ GetKnownFileFormats ()
+ {
+ return {
+ 'o3dv' : OV.FileFormat.Text
+ };
+ }
+
+ GetUpDirection ()
+ {
+ return OV.Direction.Z;
+ }
+
+ ClearContent ()
+ {
+
+ }
+
+ ResetContent ()
+ {
+
+ }
+
+ ImportContent (fileContent, onFinish)
+ {
+ let content = JSON.parse (fileContent);
+ if (content.materials !== undefined) {
+ for (let i = 0; i < content.materials.length; i++) {
+ const materialContent = content.materials[i];
+ this.ImportMaterial (materialContent);
+ }
+ }
+ if (content.meshes !== undefined) {
+ for (let i = 0; i < content.meshes.length; i++) {
+ const meshContent = content.meshes[i];
+ this.ImportMesh (meshContent);
+ }
+ }
+ onFinish ();
+ }
+
+ ImportMaterial (materialContent)
+ {
+ let material = new OV.Material ();
+ material.diffuse.Set (255, 255, 255);
+ if (materialContent.name !== undefined) {
+ material.name = materialContent.name;
+ }
+ if (materialContent.diffuse !== undefined) {
+ material.diffuse = OV.ArrayToColor (materialContent.diffuse);
+ }
+ this.model.AddMaterial (material);
+ }
+
+ ImportMesh (meshContent)
+ {
+ let genParams = new OV.GeneratorParams ();
+ if (meshContent.name !== undefined) {
+ genParams.SetName (meshContent.name);
+ }
+ if (meshContent.material !== undefined) {
+ genParams.SetMaterial (meshContent.material);
+ }
+ if (meshContent.transformation !== undefined) {
+ let translation = new OV.Coord3D (0.0, 0.0, 0.0);
+ let rotation = new OV.Quaternion (0.0, 0.0, 0.0, 1.0);
+ let scale = new OV.Coord3D (1.0, 1.0, 1.0);
+ if (meshContent.transformation.translation !== undefined) {
+ translation = OV.ArrayToCoord3D (meshContent.transformation.translation);
+ }
+ if (meshContent.transformation.rotation !== undefined) {
+ rotation = OV.ArrayToQuaternion (meshContent.transformation.rotation);
+ }
+ if (meshContent.transformation.scale !== undefined) {
+ scale = OV.ArrayToCoord3D (meshContent.transformation.scale);
+ }
+ genParams.SetTransformation (translation, rotation, scale);
+ }
+
+ let parameters = meshContent.parameters;
+ if (parameters === undefined) {
+ return;
+ }
+
+ if (meshContent.type === 'cuboid') {
+ if (parameters.size_x === undefined || parameters.size_y === undefined || parameters.size_z === undefined) {
+ return;
+ }
+ const mesh = OV.GenerateCuboid (genParams, parameters.size_x, parameters.size_y, parameters.size_z);
+ this.model.AddMesh (mesh);
+ }
+ }
+};
diff --git a/source/import/importeroff.js b/source/import/importeroff.js
index 30dbef4..9e7d9e6 100644
--- a/source/import/importeroff.js
+++ b/source/import/importeroff.js
@@ -24,7 +24,6 @@ OV.ImporterOff = class extends OV.ImporterBase
ClearContent ()
{
- this.model = null;
this.mesh = null;
this.status = null;
}
diff --git a/source/import/importerply.js b/source/import/importerply.js
index 9cf77d8..5230f08 100644
--- a/source/import/importerply.js
+++ b/source/import/importerply.js
@@ -110,7 +110,6 @@ OV.ImporterPly = class extends OV.ImporterBase
ClearContent ()
{
- this.model = null;
this.mesh = null;
}
diff --git a/source/model/generator.js b/source/model/generator.js
index 3d2a330..6d85660 100644
--- a/source/model/generator.js
+++ b/source/model/generator.js
@@ -2,10 +2,17 @@ OV.GeneratorParams = class
{
constructor ()
{
+ this.name = null;
this.material = null;
this.transformation = null;
}
+ SetName (name)
+ {
+ this.name = name;
+ return this;
+ }
+
SetMaterial (material)
{
this.material = material;
@@ -31,6 +38,9 @@ OV.Generator = class
{
this.params = params || new OV.GeneratorParams ();
this.mesh = new OV.Mesh ();
+ if (this.params.name !== null) {
+ this.mesh.SetName (this.params.name);
+ }
}
GetMesh ()
diff --git a/source/model/material.js b/source/model/material.js
index f10af99..cd8fd78 100644
--- a/source/model/material.js
+++ b/source/model/material.js
@@ -195,3 +195,8 @@ OV.ColorIsEqual = function (a, b)
{
return a.r === b.r && a.g === b.g && a.b === b.b;
};
+
+OV.ArrayToColor = function (arr)
+{
+ return new OV.Color (arr[0], arr[1], arr[2]);
+};
diff --git a/test/testfiles/o3dv/cube.o3dv b/test/testfiles/o3dv/cube.o3dv
new file mode 100644
index 0000000..5394032
--- /dev/null
+++ b/test/testfiles/o3dv/cube.o3dv
@@ -0,0 +1,12 @@
+{
+ "meshes" : [
+ {
+ "type" : "cuboid",
+ "parameters" : {
+ "size_x" : 1.0,
+ "size_y" : 1.0,
+ "size_z" : 1.0
+ }
+ }
+ ]
+}
diff --git a/test/testfiles/o3dv/cube_transformation.o3dv b/test/testfiles/o3dv/cube_transformation.o3dv
new file mode 100644
index 0000000..0bd08ce
--- /dev/null
+++ b/test/testfiles/o3dv/cube_transformation.o3dv
@@ -0,0 +1,74 @@
+{
+ "materials" : [
+ {
+ "name" : "Material 1",
+ "diffuse" : [200, 0, 0]
+ },
+ {
+ "name" : "Material 2",
+ "diffuse" : [0, 200, 0]
+ },
+ {
+ "name" : "Material 3",
+ "diffuse" : [0, 0, 200]
+ },
+ {
+ "name" : "Material 4",
+ "diffuse" : [200, 200, 0]
+ }
+ ],
+ "meshes" : [
+ {
+ "name" : "Cube",
+ "material" : 0,
+ "type" : "cuboid",
+ "parameters" : {
+ "size_x" : 1.0,
+ "size_y" : 1.0,
+ "size_z" : 1.0
+ }
+ },
+ {
+ "name" : "Cube T",
+ "material" : 1,
+ "transformation" : {
+ "translation" : [2.0, 0.0, 0.0]
+ },
+ "type" : "cuboid",
+ "parameters" : {
+ "size_x" : 1.0,
+ "size_y" : 1.0,
+ "size_z" : 1.0
+ }
+ },
+ {
+ "name" : "Cube TR",
+ "material" : 2,
+ "transformation" : {
+ "translation" : [4.0, 0.0, 0.0],
+ "rotation" : [0.0, 0.0, 0.3826834323650898, 0.9238795325112867]
+ },
+ "type" : "cuboid",
+ "parameters" : {
+ "size_x" : 1.0,
+ "size_y" : 1.0,
+ "size_z" : 1.0
+ }
+ },
+ {
+ "name" : "Cube TRS",
+ "material" : 3,
+ "transformation" : {
+ "translation" : [6.0, 0.0, 0.0],
+ "rotation" : [0.0, 0.0, 0.3826834323650898, 0.9238795325112867],
+ "scale" : [1.5, 2.0, 2.5]
+ },
+ "type" : "cuboid",
+ "parameters" : {
+ "size_x" : 1.0,
+ "size_y" : 1.0,
+ "size_z" : 1.0
+ }
+ }
+ ]
+}
diff --git a/test/testfiles/o3dv/cube_with_material.o3dv b/test/testfiles/o3dv/cube_with_material.o3dv
new file mode 100644
index 0000000..2cffbde
--- /dev/null
+++ b/test/testfiles/o3dv/cube_with_material.o3dv
@@ -0,0 +1,20 @@
+{
+ "materials" : [
+ {
+ "name" : "Material",
+ "diffuse" : [200, 0, 0]
+ }
+ ],
+ "meshes" : [
+ {
+ "name" : "Cube",
+ "material" : 0,
+ "type" : "cuboid",
+ "parameters" : {
+ "size_x" : 1.0,
+ "size_y" : 1.0,
+ "size_z" : 1.0
+ }
+ }
+ ]
+}
diff --git a/test/tests/importero3dv_test.js b/test/tests/importero3dv_test.js
new file mode 100644
index 0000000..0c45528
--- /dev/null
+++ b/test/tests/importero3dv_test.js
@@ -0,0 +1,119 @@
+var assert = require ('assert');
+var testFiles = require ('../utils/testfiles.js');
+var testUtils = require ('../utils/testutils.js');
+
+describe ('O3dv Importer', function () {
+ it ('cube.o3dv', function (done) {
+ testFiles.ImportO3dvFile ('cube.o3dv', function (model) {
+ assert (OV.CheckModel (model));
+ assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), {
+ name : '',
+ materials : [
+ { name : '' }
+ ],
+ meshes : [
+ {
+ name : '',
+ vertexCount : 8,
+ normalCount : 12,
+ uvCount : 0,
+ triangleCount : 12,
+ boundingBox : {
+ min : [0, 0, 0],
+ max : [1, 1, 1]
+ }
+ }
+ ]
+ });
+ done ();
+ });
+ });
+
+ it ('cube_with_material.o3dv', function (done) {
+ testFiles.ImportO3dvFile ('cube_with_material.o3dv', function (model) {
+ assert (OV.CheckModel (model));
+ assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), {
+ name : '',
+ materials : [
+ { name : 'Material' }
+ ],
+ meshes : [
+ {
+ name : 'Cube',
+ vertexCount : 8,
+ normalCount : 12,
+ uvCount : 0,
+ triangleCount : 12,
+ boundingBox : {
+ min : [0, 0, 0],
+ max : [1, 1, 1]
+ }
+ }
+ ]
+ });
+ done ();
+ });
+ });
+
+ it ('cube_transformation.o3dv', function (done) {
+ testFiles.ImportO3dvFile ('cube_transformation.o3dv', function (model) {
+ assert (OV.CheckModel (model));
+ assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), {
+ name : '',
+ materials : [
+ { name : 'Material 1' },
+ { name : 'Material 2' },
+ { name : 'Material 3' },
+ { name : 'Material 4' }
+ ],
+ meshes : [
+ {
+ name : 'Cube',
+ vertexCount : 8,
+ normalCount : 12,
+ uvCount : 0,
+ triangleCount : 12,
+ boundingBox : {
+ min : [0, 0, 0],
+ max : [1, 1, 1]
+ }
+ },
+ {
+ name : 'Cube T',
+ vertexCount : 8,
+ normalCount : 12,
+ uvCount : 0,
+ triangleCount : 12,
+ boundingBox : {
+ min : [2, 0, 0],
+ max : [3, 1, 1]
+ }
+ },
+ {
+ name : 'Cube TR',
+ vertexCount : 8,
+ normalCount : 12,
+ uvCount : 0,
+ triangleCount : 12,
+ boundingBox : {
+ min : [3.2928932188134525, 0, 0],
+ max : [4.707106781186548, 1.414213562373095, 1]
+ }
+ },
+ {
+ name : 'Cube TRS',
+ vertexCount : 8,
+ normalCount : 12,
+ uvCount : 0,
+ triangleCount : 12,
+ boundingBox : {
+ min : [4.585786437626905, 0, 0],
+ max : [7.060660171779821, 2.4748737341529163, 2.5]
+ }
+ }
+ ]
+ });
+ done ();
+ });
+ });
+});
diff --git a/test/utils/testfiles.js b/test/utils/testfiles.js
index 58f2a82..0470666 100644
--- a/test/utils/testfiles.js
+++ b/test/utils/testfiles.js
@@ -43,6 +43,12 @@ module.exports =
this.ImportFile (importer, format, 'gltf/' + folderName, fileName, onReady);
},
+ ImportO3dvFile : function (fileName, onReady)
+ {
+ var importer = new OV.ImporterO3dv ();
+ this.ImportFile (importer, OV.FileFormat.Text, 'o3dv', fileName, onReady);
+ },
+
ImportFile : function (importer, format, folder, fileName, onReady)
{
var content = null;
diff --git a/tools/config.json b/tools/config.json
index e508ca8..4031dc4 100644
--- a/tools/config.json
+++ b/tools/config.json
@@ -40,6 +40,7 @@
"source/import/importerply.js",
"source/import/importer3ds.js",
"source/import/importergltf.js",
+ "source/import/importero3dv.js",
"source/import/importer.js",
"source/export/exporterbase.js",
"source/export/exporterobj.js",
diff --git a/website/embed.html b/website/embed.html
index 81ab6e4..92f7595 100644
--- a/website/embed.html
+++ b/website/embed.html
@@ -53,6 +53,7 @@
+
diff --git a/website/index.html b/website/index.html
index 6ab603c..ca6a920 100644
--- a/website/index.html
+++ b/website/index.html
@@ -53,6 +53,7 @@
+