diff --git a/gz3d/src/gzogre2json.js b/gz3d/src/gzogre2json.js index aadfce5b..d65f4f45 100644 --- a/gz3d/src/gzogre2json.js +++ b/gz3d/src/gzogre2json.js @@ -40,8 +40,12 @@ GZ3D.Ogre2Json.prototype.Parse = function(_str) { var str = _str; + // Remove leading and trailing whitespaces per line + str = str.replace(/^\s+/gm,''); + str = str.replace(/\s+$/gm,''); + // Remove "material " and properly add commas if more than one - str = str.replace(/material /g, function(match, offset) + str = str.replace(/^material /gm, function(match, offset) { if (offset === 0) { @@ -53,10 +57,44 @@ GZ3D.Ogre2Json.prototype.Parse = function(_str) } }); - // Remove leading and trailing whitespaces per line + // Handle vertex and fragment programs + str = str.replace(/^vertex_program .*$|^fragment_program .*$/gm, + function(match, offset) + { + var underscores = match.replace(/ /g, '_'); + if (offset === 0) + { + return underscores; + } + else + { + return '},{' + underscores; + } + }); + + // Handle vertex and fragment programs refs + str = str.replace(/^vertex_program_ref.*$|^fragment_program_ref.*$/gm, + function(match, offset) + { + return match.replace(/ /g, '_'); + }); + + // Strip name from named texture_unit + str = str.replace(/^texture_unit.*$/gm, function(match, offset) + { + return 'texture_unit'; + }); + + // Remove comments + str = str.replace(/(\/\*[\w\'\s\r\n\*]*\*\/)|(\/\/.*$)/gm, ''); + + // Remove leading and trailing whitespaces per line (again) str = str.replace(/^\s+/gm,''); str = str.replace(/\s+$/gm,''); + // Remove double-quotes + str = str.replace(/"/gm, ''); + // If line has more than one space, it has an array str = str.replace(/(.* .*){2,}/g, function(match) { @@ -120,7 +158,7 @@ GZ3D.Ogre2Json.prototype.Parse = function(_str) return false; } - // Arrange materials array so that GZ3d.SdfParser can consume it + // Arrange materials array so that GZ3D.SdfParser can consume it for (var material in this.materialObj) { for (var matName in this.materialObj[material]) diff --git a/gz3d/src/gzsdfparser.js b/gz3d/src/gzsdfparser.js index 4cbd741e..ef67121e 100644 --- a/gz3d/src/gzsdfparser.js +++ b/gz3d/src/gzsdfparser.js @@ -41,7 +41,7 @@ GZ3D.SdfParser = function(scene, gui, gziface) var that = this; this.emitter.on('material', function(mat) { - that.materials = mat; + that.materials = Object.assign(this.material, mat); }); }; diff --git a/gz3d/test/gzogre2json.js b/gz3d/test/gzogre2json.js index 2a383b3c..ec985c70 100644 --- a/gz3d/test/gzogre2json.js +++ b/gz3d/test/gzogre2json.js @@ -14,7 +14,7 @@ describe('GzOgre2Json tests', function() { depth_check off depth_write on - texture_unit + texture_unit tex { texture beer.png filtering anistropic @@ -284,6 +284,130 @@ material Dumpster/Specular expect(o2j.Parse("banana")).not.toBeTruthy(); expect(o2j.Parse("{}")).not.toBeTruthy(); }); + + it('should ignore comments', function() { + + let o2j = new GZ3D.Ogre2Json(); + const str = `material FireStation/Diffuse +{ + // inline comment + receive_shadows off // another comment + /* property value */ + transparency_casts_shadows on /* more comments */ +} +`; + + // Parse + expect(o2j.Parse(str)).toBeTruthy(); + + // Check materialObj + expect(o2j.materialObj).toBeDefined(); + expect(o2j.materialObj.length).toEqual(1); + + expect(o2j.materialObj + [0] + ['FireStation/Diffuse'] + ).toBeDefined(); + + expect(o2j.materialObj + [0] + ['FireStation/Diffuse'] + ['receive_shadows'] + ).toBeDefined(); + + expect(o2j.materialObj + [0] + ['FireStation/Diffuse'] + ['property'] + ).not.toBeDefined(); + + expect(o2j.materialObj + [0] + ['FireStation/Diffuse'] + ['transparency_casts_shadows'] + ).toBeDefined(); + }); + + it('should handle programs', function() { + + let o2j = new GZ3D.Ogre2Json(); + const str = `material OakTree/Branch +{ +} + +vertex_program caster_vp_glsl glsl +{ + source caster_vp.glsl +} + +material OakTree/Bark +{ +} + +fragment_program caster_fp_glsl glsl +{ + source caster_fp.glsl +} +`; + + // Parse + expect(o2j.Parse(str)).toBeTruthy(); + + // Check materialObj + expect(o2j.materialObj).toBeDefined(); + expect(o2j.materialObj.length).toEqual(4); + + // Check materials exist + expect(o2j.materialObj[0]['OakTree/Branch']).toBeDefined(); + expect(o2j.materialObj[2]['OakTree/Bark']).toBeDefined(); + + // Check programs exist + expect(o2j.materialObj[1]['vertex_program_caster_vp_glsl_glsl']) + .toBeDefined(); + expect(o2j.materialObj[3]['fragment_program_caster_fp_glsl_glsl']) + .toBeDefined(); + }); + + it('should handle program refs', function() { + + let o2j = new GZ3D.Ogre2Json(); + const str = `material OakTree/shadow_caster_alpha +{ + technique + { + pass + { + vertex_program_ref caster_vp_glsl + { + } + + fragment_program_ref caster_fp_glsl + { + } + } + } +} +`; + + // Parse + expect(o2j.Parse(str)).toBeTruthy(); + + // Check refs + expect(o2j.materialObj + [0]['OakTree/shadow_caster_alpha'] + ['technique'] + ['pass'] + ['vertex_program_ref_caster_vp_glsl'] + ).toBeDefined(); + + // Check refs + expect(o2j.materialObj + [0]['OakTree/shadow_caster_alpha'] + ['technique'] + ['pass'] + ['fragment_program_ref_caster_fp_glsl'] + ).toBeDefined(); + }); }); });