diff --git a/source/engine/import/importeroff.js b/source/engine/import/importeroff.js index ca717c3..e92a88d 100644 --- a/source/engine/import/importeroff.js +++ b/source/engine/import/importeroff.js @@ -1,10 +1,11 @@ import { Coord3D } from '../geometry/coord3d.js'; import { Direction } from '../geometry/geometry.js'; import { ArrayBufferToUtf8String } from '../io/bufferutils.js'; +import { Color, ColorComponentFromFloat } from '../model/color.js'; import { Mesh } from '../model/mesh.js'; import { Triangle } from '../model/triangle.js'; import { ImporterBase } from './importerbase.js'; -import { ParametersFromLine, ReadLines } from './importerutils.js'; +import { ColorToMaterialConverter, ParametersFromLine, ReadLines } from './importerutils.js'; export class ImporterOff extends ImporterBase { @@ -27,6 +28,7 @@ export class ImporterOff extends ImporterBase { this.mesh = null; this.status = null; + this.colorToMaterial = null; } ResetContent () @@ -39,6 +41,7 @@ export class ImporterOff extends ImporterBase foundVertex : 0, foundFace : 0 }; + this.colorToMaterial = new ColorToMaterialConverter (this.model); } ImportContent (fileContent, onFinish) @@ -54,6 +57,15 @@ export class ImporterOff extends ImporterBase ProcessLine (line) { + function CreateColorComponent (str) + { + if (str.indexOf ('.') !== -1) { + return ColorComponentFromFloat (parseFloat (str)); + } else { + return parseInt (str, 10); + } + } + if (line[0] === '#') { return; } @@ -84,20 +96,42 @@ export class ImporterOff extends ImporterBase )); this.status.foundVertex += 1; } + if (parameters.length >= 6) { + this.mesh.AddVertexColor (new Color ( + CreateColorComponent (parameters[3]), + CreateColorComponent (parameters[4]), + CreateColorComponent (parameters[5]) + )); + } return; } + let hasVertexColors = (this.mesh.VertexCount () ===this.mesh.VertexColorCount ()); if (this.status.foundFace < this.status.faceCount) { if (parameters.length >= 4) { let vertexCount = parseInt (parameters[0], 10); if (parameters.length < vertexCount + 1) { return; } + let materialIndex = null; + if (!hasVertexColors && parameters.length >= vertexCount + 4) { + let color = new Color ( + CreateColorComponent (parameters[vertexCount + 1]), + CreateColorComponent (parameters[vertexCount + 2]), + CreateColorComponent (parameters[vertexCount + 3]) + ); + materialIndex = this.colorToMaterial.GetMaterialIndex (color.r, color.g, color.b); + } for (let i = 0; i < vertexCount - 2; i++) { let v0 = parseInt (parameters[1]); let v1 = parseInt (parameters[i + 2]); let v2 = parseInt (parameters[i + 3]); let triangle = new Triangle (v0, v1, v2); + if (hasVertexColors) { + triangle.SetVertexColors (v0, v1, v2); + } else { + triangle.SetMaterial (materialIndex); + } this.mesh.AddTriangle (triangle); } this.status.foundFace += 1; diff --git a/test/testfiles/off/rectangle_face_colors_float.off b/test/testfiles/off/rectangle_face_colors_float.off new file mode 100644 index 0000000..8d45cab --- /dev/null +++ b/test/testfiles/off/rectangle_face_colors_float.off @@ -0,0 +1,10 @@ +OFF + +4 1 + +0.0 0.0 0.0 +1.0 0.0 0.0 +1.0 1.0 0.0 +0.0 1.0 0.0 + +4 0 1 2 3 1.0 0.0 0.0 diff --git a/test/testfiles/off/rectangle_face_colors_int.off b/test/testfiles/off/rectangle_face_colors_int.off new file mode 100644 index 0000000..429c654 --- /dev/null +++ b/test/testfiles/off/rectangle_face_colors_int.off @@ -0,0 +1,10 @@ +OFF + +4 1 + +0.0 0.0 0.0 +1.0 0.0 0.0 +1.0 1.0 0.0 +0.0 1.0 0.0 + +4 0 1 2 3 255 0 0 diff --git a/test/testfiles/off/rectangle_vertex_colors_float.off b/test/testfiles/off/rectangle_vertex_colors_float.off new file mode 100644 index 0000000..4a1f5c5 --- /dev/null +++ b/test/testfiles/off/rectangle_vertex_colors_float.off @@ -0,0 +1,10 @@ +OFF + +4 1 + +0.0 0.0 0.0 1.0 0.0 0.0 +1.0 0.0 0.0 0.0 1.0 0.0 +1.0 1.0 0.0 0.0 0.0 1.0 +0.0 1.0 0.0 1.0 0.0 0.0 + +4 0 1 2 3 diff --git a/test/testfiles/off/rectangle_vertex_colors_int.off b/test/testfiles/off/rectangle_vertex_colors_int.off new file mode 100644 index 0000000..64daf24 --- /dev/null +++ b/test/testfiles/off/rectangle_vertex_colors_int.off @@ -0,0 +1,10 @@ +OFF + +4 1 + +0.0 0.0 0.0 255 0 0 +1.0 0.0 0.0 0 255 0 +1.0 1.0 0.0 0 0 255 +0.0 1.0 0.0 255 0 0 + +4 0 1 2 3 diff --git a/test/tests/importeroff_test.js b/test/tests/importeroff_test.js index e17f916..a8beddc 100644 --- a/test/tests/importeroff_test.js +++ b/test/tests/importeroff_test.js @@ -121,7 +121,6 @@ describe ('Off Importer', function () { }); done (); }); - }); it ('cube.off', function (done) { @@ -150,6 +149,140 @@ describe ('Off Importer', function () { done (); }); }); + + it ('rectangle_vertex_colors_float.off', function (done) { + ImportOffFile ('rectangle_vertex_colors_float.off', function (model) { + assert.ok (OV.CheckModel (model)); + assert.strictEqual (model.GetMaterial (0).vertexColors, true); + assert.deepStrictEqual (ModelToObject (model), { + name : '', + materials : [ + { name : '' } + ], + meshes : [ + { + name : '', + triangles : [ + { + vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + }, + { + vertices : [0, 0, 0, 1, 1, 0, 0, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + } + ] + } + ] + }); + done (); + }); + }); + + it ('rectangle_vertex_colors_float.off', function (done) { + ImportOffFile ('rectangle_vertex_colors_float.off', function (model) { + assert.ok (OV.CheckModel (model)); + assert.strictEqual (model.GetMaterial (0).vertexColors, true); + assert.deepStrictEqual (ModelToObject (model), { + name : '', + materials : [ + { name : '' } + ], + meshes : [ + { + name : '', + triangles : [ + { + vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + }, + { + vertices : [0, 0, 0, 1, 1, 0, 0, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + } + ] + } + ] + }); + done (); + }); + }); + + it ('rectangle_face_colors_int.off', function (done) { + ImportOffFile ('rectangle_face_colors_int.off', function (model) { + assert.ok (OV.CheckModel (model)); + assert.ok (OV.ColorIsEqual (model.GetMaterial (0).color, new OV.Color (255, 0, 0))); + assert.strictEqual (model.GetMaterial (0).vertexColors, false); + assert.deepStrictEqual (ModelToObject (model), { + name : '', + materials : [ + { name : 'FF0000' } + ], + meshes : [ + { + name : '', + triangles : [ + { + vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + }, + { + vertices : [0, 0, 0, 1, 1, 0, 0, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + } + ] + } + ] + }); + done (); + }); + }); + + it ('rectangle_face_colors_int.off', function (done) { + ImportOffFile ('rectangle_face_colors_float.off', function (model) { + assert.ok (OV.CheckModel (model)); + assert.ok (OV.ColorIsEqual (model.GetMaterial (0).color, new OV.Color (255, 0, 0))); + assert.strictEqual (model.GetMaterial (0).vertexColors, false); + assert.deepStrictEqual (ModelToObject (model), { + name : '', + materials : [ + { name : 'FF0000' } + ], + meshes : [ + { + name : '', + triangles : [ + { + vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + }, + { + vertices : [0, 0, 0, 1, 1, 0, 0, 1, 0], + normals : [0, 0, 1, 0, 0, 1, 0, 0, 1], + uvs : [], + mat : 0 + } + ] + } + ] + }); + done (); + }); + }); }); }