Issues loading JSON

I’m trying to load JSON into THREE.
I have the JSON just hardcoded into the project atm so from what I gather I should be using ObjectLoader and .parse, but I’m getting an error

TypeError: Materials[json.type] is not a constructor

My code is

    const loader = new ObjectLoader()
    loader.parse(json, (theObj) => {
        /*...*/
    })

and the json is (shortened the faces and vertices arrays for brevity)

{
  "metadata" :
  {
      "formatVersion" : 3,
      "generatedBy"   : "ParametricParts",
      "vertices"      : 3426,
      "faces"         : 3776,
      "normals"       : 0,
      "colors"        : 0,
      "uvs"           : 0,
      "materials"     : 1,
      "morphTargets"  : 0
  },

  "scale" : 1.0,

  "materials": [    {
  "DbgColor" : 15658734,
  "DbgIndex" : 0,
  "DbgName" : "Material",
  "colorAmbient" : [0.0, 0.0, 0.0],
  "colorDiffuse" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746],
  "colorSpecular" : [0.5, 0.5, 0.5],
  "shading" : "Lambert",
  "specularCoef" : 50,
  "transparency" : 1.0,
  "vertexColors" : false
  }],

  "vertices": ["..."],

  "morphTargets": [],

  "normals": [],

  "colors": [],

  "uvs": [[]],

  "faces": ["..."]
}

So I think the probably is either the JSON is misformed, or that I’m doing something wrong, with the latter when I search about json and Three.js, I get lot of out-of-date results show up so I’m not sure if the ObjectLoader is what I should be using?

If it’s the former, the JSON is produced by this project, so I’ll raise it with them

but I wanted to double check it’s not my fault first.

Any insights would be appreciated.

The JSON you have shared uses an outdated three.js standard that can’t be loaded anymore. The JSON has to follow the JSON Object Scene Format 4.

This JSON is produced if you call Ojbect3D.toJSON() with a current three.js release like in the following example: https://jsfiddle.net/woub49xf/

Cool, thanks @Mugen87 that clears things up.

Hi, I have an issue with loading geometry from JSON. I have prepared a simple JSON with a similar approach as above. Trying to add loaded geometry with two approaches - scene.add(obj) and scene.add(obj.scene) - got me an error that objects are not Three.Objecct3d types. Therefore I decided to take only mesh from JSON and add to a new scene:

loader.load(
	// resource URL
	"../../../threeJsBox.json",
  /* error
	function ( obj ) {
		// Add the loaded object to the scene
		scene.add( obj.scene );
	},
*/
function ( object ) {
  object.traverse( function ( child ) {
    if ( child instanceof THREE.Mesh ) {
    //add only meshes
    const importMaterial = new MeshBasicMaterial( {color: 0x0000ff} );
    const importedCube = new Mesh( child.geometry, importMaterial );
    scene.add(importedCube);}});},

	function ( xhr ) {
		console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
	},
	function ( err ) {
		console.error( error );
	});

This approach kind of worked and the new scene contains a new ThreeBufferGeometry object with the same parameters as my initial geometry. However, it doesn’t appear on the screen. What did I get wrong? :smiley:

Json is used to load:

{
	"metadata": {
		"version": 4.3,
		"type": "Object",
		"generator": "ObjectExporter"
	},
	"textures": [],
	"images": [],
	"geometries": [
		{
			"uuid": "0A8F2988-626F-411C-BD6A-AC656C4E6878",
			"type": "BufferGeometry",
			"data": {
				"attributes": {
					"position": {
						"itemSize": 3,
						"type": "Float32Array",
						"array": [1,1,0,1,-1,0,-1,-1,0,-1,1,0],
						"normalized": false
					},
					"normal": {
						"itemSize": 3,
						"type": "Float32Array",
						"array": [0,0,1,0,0,1,0,0,1,0,0,1],
						"normalized": false
					},
					"uv": {
						"itemSize": 2,
						"type": "Float32Array",
						"array": [1,1,1,0,0,0,0,1],
						"normalized": false
					}
				},
				"index": {
					"type": "Uint16Array",
					"array": [0,1,2,0,2,3]
				},
				"boundingSphere": {
					"center": [0,0,0],
					"radius": 1
				}
			}
		}
	],
	"materials": [],
	"object": {
		"uuid": "378FAA8D-0888-4249-8701-92D1C1F37C51",
		"type": "Scene",
		"matrix": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ],
		"children": [
			{
				"uuid": "E7B44C44-DD75-4C29-B571-21AD6AEF0CA9",
				"name": "SharedVertexTest",
				"type": "Mesh",
				"geometry": "0A8F2988-626F-411C-BD6A-AC656C4E6878",
				"matrix": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]
			}
		]
	}
}

Loading the JSON into the three.js editor works as expected. Since it is a plane, you maybe look from the wrong direction to it.

BTW: Adding the loaded object to the scene should be something like:

There is no need to traverse through the object and only select meshes.

Thanks a lot for response. I have tried:

async function Fetch(){
    const loader = new THREE.ObjectLoader();
    const object = await loader.loadAsync( '../../../simpleScene.json', function(progress){ console.log(progress)} );
    scene.add( object );
}
await Fetch();

But end up with error:
Uncaught TypeError: loader.loadAsync is not a function

I will double check saved json. But it should be a cube geometry. I also tried geometry.computeVertexNormals() but didn’t worked.

You probably use and outdated version of three.js.

Thx I had a double-check and upgraded from 143 to 146. Unfortunately still same error. Could it be the node version? I use 16.13.0 for this project.