diff --git a/sandbox/embed_edges.html b/sandbox/embed_edges.html
index 9219791..822e9ff 100644
--- a/sandbox/embed_edges.html
+++ b/sandbox/embed_edges.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_filehost.html b/sandbox/embed_filehost.html
index 078d28f..a89d2c5 100644
--- a/sandbox/embed_filehost.html
+++ b/sandbox/embed_filehost.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_selfhost_code.html b/sandbox/embed_selfhost_code.html
index 65c741a..3d013c5 100644
--- a/sandbox/embed_selfhost_code.html
+++ b/sandbox/embed_selfhost_code.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_selfhost_errors.html b/sandbox/embed_selfhost_errors.html
index 148a2ff..424e6f1 100644
--- a/sandbox/embed_selfhost_errors.html
+++ b/sandbox/embed_selfhost_errors.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_selfhost_externallibs.html b/sandbox/embed_selfhost_externallibs.html
index 0461ca5..45d7ee8 100644
--- a/sandbox/embed_selfhost_externallibs.html
+++ b/sandbox/embed_selfhost_externallibs.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_selfhost_fullscreen.html b/sandbox/embed_selfhost_fullscreen.html
index ce3ff17..974ac38 100644
--- a/sandbox/embed_selfhost_fullscreen.html
+++ b/sandbox/embed_selfhost_fullscreen.html
@@ -37,6 +37,7 @@
+
diff --git a/sandbox/embed_selfhost_manual.html b/sandbox/embed_selfhost_manual.html
index e620a55..11d95e5 100644
--- a/sandbox/embed_selfhost_manual.html
+++ b/sandbox/embed_selfhost_manual.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_selfhost_multiple.html b/sandbox/embed_selfhost_multiple.html
index d77b66a..4017fbb 100644
--- a/sandbox/embed_selfhost_multiple.html
+++ b/sandbox/embed_selfhost_multiple.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_selfhost_multiple_2.html b/sandbox/embed_selfhost_multiple_2.html
index 1c66a1e..0161412 100644
--- a/sandbox/embed_selfhost_multiple_2.html
+++ b/sandbox/embed_selfhost_multiple_2.html
@@ -38,6 +38,7 @@
+
diff --git a/sandbox/embed_selfhost_single.html b/sandbox/embed_selfhost_single.html
index 0024f93..62bcb67 100644
--- a/sandbox/embed_selfhost_single.html
+++ b/sandbox/embed_selfhost_single.html
@@ -37,6 +37,7 @@
+
diff --git a/sandbox/embed_selfhost_single_scroll.html b/sandbox/embed_selfhost_single_scroll.html
index 5691a6f..b54e8ff 100644
--- a/sandbox/embed_selfhost_single_scroll.html
+++ b/sandbox/embed_selfhost_single_scroll.html
@@ -37,6 +37,7 @@
+
diff --git a/source/model/meshutils.js b/source/model/meshutils.js
new file mode 100644
index 0000000..d941f9f
--- /dev/null
+++ b/source/model/meshutils.js
@@ -0,0 +1,80 @@
+OV.CalculateTriangleNormal = function (v0, v1, v2)
+{
+ let v = OV.SubCoord3D (v1, v0);
+ let w = OV.SubCoord3D (v2, v0);
+ let normal = OV.CrossVector3D (v, w);
+ normal.Normalize ();
+ return normal;
+};
+
+OV.TransformMesh = function (mesh, transformation)
+{
+ if (transformation.IsIdentity ()) {
+ return;
+ }
+
+ for (let i = 0; i < mesh.VertexCount (); i++) {
+ let vertex = mesh.GetVertex (i);
+ let transformed = transformation.TransformCoord3D (vertex);
+ vertex.x = transformed.x;
+ vertex.y = transformed.y;
+ vertex.z = transformed.z;
+ }
+
+ if (mesh.NormalCount () > 0) {
+ let trs = transformation.GetMatrix ().DecomposeTRS ();
+ let normalMatrix = new OV.Matrix ().ComposeTRS (new OV.Coord3D (0.0, 0.0, 0.0), trs.rotation, new OV.Coord3D (1.0, 1.0, 1.0));
+ let normalTransformation = new OV.Transformation (normalMatrix);
+ for (let i = 0; i < mesh.NormalCount (); i++) {
+ let normal = mesh.GetNormal (i);
+ let transformed = normalTransformation.TransformCoord3D (normal);
+ normal.x = transformed.x;
+ normal.y = transformed.y;
+ normal.z = transformed.z;
+ }
+ }
+};
+
+OV.FlipMeshTrianglesOrientation = function (mesh)
+{
+ for (let i = 0; i < mesh.TriangleCount (); i++) {
+ let triangle = mesh.GetTriangle (i);
+ let tmp = triangle.v1;
+ triangle.v1 = triangle.v2;
+ triangle.v2 = tmp;
+ }
+};
+
+OV.CloneMesh = function (mesh)
+{
+ let cloned = new OV.Mesh ();
+
+ cloned.SetName (mesh.GetName ());
+
+ for (let i = 0; i < mesh.VertexCount (); i++) {
+ let vertex = mesh.GetVertex (i);
+ cloned.AddVertex (vertex.Clone ());
+ }
+
+ for (let i = 0; i < mesh.VertexColorCount (); i++) {
+ let color = mesh.GetVertexColor (i);
+ cloned.AddVertexColor (color.Clone ());
+ }
+
+ for (let i = 0; i < mesh.NormalCount (); i++) {
+ let normal = mesh.GetNormal (i);
+ cloned.AddNormal (normal.Clone ());
+ }
+
+ for (let i = 0; i < mesh.TextureUVCount (); i++) {
+ let uv = mesh.GetTextureUV (i);
+ cloned.AddTextureUV (uv.Clone ());
+ }
+
+ for (let i = 0; i < mesh.TriangleCount (); i++) {
+ let triangle = mesh.GetTriangle (i);
+ cloned.AddTriangle (triangle.Clone ());
+ }
+
+ return cloned;
+};
diff --git a/source/model/modelutils.js b/source/model/modelutils.js
index 18ca3f5..7fa6c0b 100644
--- a/source/model/modelutils.js
+++ b/source/model/modelutils.js
@@ -1,50 +1,3 @@
-OV.CalculateTriangleNormal = function (v0, v1, v2)
-{
- let v = OV.SubCoord3D (v1, v0);
- let w = OV.SubCoord3D (v2, v0);
- let normal = OV.CrossVector3D (v, w);
- normal.Normalize ();
- return normal;
-};
-
-OV.TransformMesh = function (mesh, transformation)
-{
- if (transformation.IsIdentity ()) {
- return;
- }
-
- for (let i = 0; i < mesh.VertexCount (); i++) {
- let vertex = mesh.GetVertex (i);
- let transformed = transformation.TransformCoord3D (vertex);
- vertex.x = transformed.x;
- vertex.y = transformed.y;
- vertex.z = transformed.z;
- }
-
- if (mesh.NormalCount () > 0) {
- let trs = transformation.GetMatrix ().DecomposeTRS ();
- let normalMatrix = new OV.Matrix ().ComposeTRS (new OV.Coord3D (0.0, 0.0, 0.0), trs.rotation, new OV.Coord3D (1.0, 1.0, 1.0));
- let normalTransformation = new OV.Transformation (normalMatrix);
- for (let i = 0; i < mesh.NormalCount (); i++) {
- let normal = mesh.GetNormal (i);
- let transformed = normalTransformation.TransformCoord3D (normal);
- normal.x = transformed.x;
- normal.y = transformed.y;
- normal.z = transformed.z;
- }
- }
-};
-
-OV.FlipMeshTrianglesOrientation = function (mesh)
-{
- for (let i = 0; i < mesh.TriangleCount (); i++) {
- let triangle = mesh.GetTriangle (i);
- let tmp = triangle.v1;
- triangle.v1 = triangle.v2;
- triangle.v2 = tmp;
- }
-};
-
OV.IsModelEmpty = function (model)
{
let isEmpty = true;
@@ -56,40 +9,6 @@ OV.IsModelEmpty = function (model)
return isEmpty;
};
-OV.CloneMesh = function (mesh)
-{
- let cloned = new OV.Mesh ();
-
- cloned.SetName (mesh.GetName ());
-
- for (let i = 0; i < mesh.VertexCount (); i++) {
- let vertex = mesh.GetVertex (i);
- cloned.AddVertex (vertex.Clone ());
- }
-
- for (let i = 0; i < mesh.VertexColorCount (); i++) {
- let color = mesh.GetVertexColor (i);
- cloned.AddVertexColor (color.Clone ());
- }
-
- for (let i = 0; i < mesh.NormalCount (); i++) {
- let normal = mesh.GetNormal (i);
- cloned.AddNormal (normal.Clone ());
- }
-
- for (let i = 0; i < mesh.TextureUVCount (); i++) {
- let uv = mesh.GetTextureUV (i);
- cloned.AddTextureUV (uv.Clone ());
- }
-
- for (let i = 0; i < mesh.TriangleCount (); i++) {
- let triangle = mesh.GetTriangle (i);
- cloned.AddTriangle (triangle.Clone ());
- }
-
- return cloned;
-};
-
OV.GetBoundingBox = function (object3D)
{
let calculator = new OV.BoundingBoxCalculator3D ();
diff --git a/tools/config.json b/tools/config.json
index 2ae6fa3..6efb90b 100644
--- a/tools/config.json
+++ b/tools/config.json
@@ -28,6 +28,7 @@
"source/model/meshinstance.js",
"source/model/model.js",
"source/model/topology.js",
+ "source/model/meshutils.js",
"source/model/modelutils.js",
"source/model/modelfinalization.js",
"source/model/quantities.js",
diff --git a/website/embed.html b/website/embed.html
index 163a71b..0205247 100644
--- a/website/embed.html
+++ b/website/embed.html
@@ -44,6 +44,7 @@
+
diff --git a/website/index.html b/website/index.html
index aa4c6ef..e2eef97 100644
--- a/website/index.html
+++ b/website/index.html
@@ -46,6 +46,7 @@
+