gltfjsx icon indicating copy to clipboard operation
gltfjsx copied to clipboard

Unexpected token g in JSON when using GLTFStructureLoader

Open dottodot opened this issue 2 years ago • 9 comments

I was hoping I'd be able to use the GLTFStructureLoader in a node js app using the following

const { GLTFStructureLoader } = require("@react-three/gltfjsx");
const fs = require("fs/promises");
const loader = new GLTFStructureLoader();

async function loadModel() {
  const data = await fs.readFile("./model.glb");

  const { scene } = await new Promise((res) =>
    loader.parse(data, "", res)
  );
  console.log(scene);
}

but this causes an error of

SyntaxError: Unexpected token g in JSON at position 0
    at JSON.parse (<anonymous>)
    at GLTFLoader.parse (/nodejs/node_modules/@react-three/gltfjsx/src/bin/GLTFLoader.js:145:23)
    at /nodejs/index.js:10:12
    at new Promise (<anonymous>)
    at loadModel (/nodejs/index.js:9:27)

however using npx gltfjsx on the same model is fine.

dottodot avatar Jun 24 '22 15:06 dottodot

+1

hannesuw avatar Jul 15 '22 19:07 hannesuw

+1

ajitStephen avatar Oct 05 '22 16:10 ajitStephen

+1

ashleymvanduzer avatar Nov 29 '22 04:11 ashleymvanduzer

The problem here may be passing a Buffer or Uint8Array into the parse() method, when an ArrayBuffer is required. To do the conversion:

const arrayBuffer = data.buffer.slice( data.byteOffset, data.byteLength );

loader.parse( arrayBuffer, '', callback );

donmccurdy avatar Jan 29 '23 01:01 donmccurdy

@donmccurdy thanks for the suggestion! excited to give that a shot.

ashleymvanduzer avatar Jan 29 '23 03:01 ashleymvanduzer

@donmccurdy thanks so much, that did the trick.

ashleymvanduzer avatar Feb 02 '23 05:02 ashleymvanduzer

@donmccurdy The solution works as you suggested with non gltfjsx transformed models, again so many thanks for the tip. Though I recently used gltfjsx with the transform flag on a big chunk of the models I am using to bring bundle size down for the project I am working on. But now, when I try to pass one of these transformed models, I run into the error: ` THREE.GLTFLoader: No DRACOLoader instance provided.

  91 |   //@ts-ignore
  92 |   const {scene} = await new Promise((resolve) => {
> 93 |     loader.parse(arrayBuffer, '', resolve);
     |            ^
  94 |   }
  95 | );

`

So I followed the error message and passed a draco loader to the GLTFStructureLoader, and the output becomes:

` ReferenceError: Request is not defined

  at FileLoader.load (node_modules/three/build/three.cjs:28302:15)
  at node_modules/three-stdlib/index.cjs.js:1:1223275
  at vh._loadLibrary (node_modules/three-stdlib/index.cjs.js:1:1223252)
  at vh._initDecoder (node_modules/three-stdlib/index.cjs.js:1:1223553)
  at vh._getWorker (node_modules/three-stdlib/index.cjs.js:1:1223995)
  at vh.decodeGeometry (node_modules/three-stdlib/index.cjs.js:1:1222541)
  at vh.decodeDracoFile (node_modules/three-stdlib/index.cjs.js:1:1222076)
  at node_modules/@react-three/gltfjsx/src/bin/GLTFLoader.js:612:21
  at node_modules/@react-three/gltfjsx/src/bin/GLTFLoader.js:611:14
      at async Promise.all (index 0)
      at async Promise.all (index 1)
      at async Promise.all (index 0)
      at async Promise.all (index 0)

`

Sorry to bother you further, but if you happen to have some time and any insight into why this may be happening, I'd really appreciate hearing your thoughts on this.

ashleymvanduzer avatar Feb 02 '23 08:02 ashleymvanduzer

It might be best to file a bug, attach a model that demonstrates the issue, and share any other details like the version of Node.js you're using. Using gltfjsx on a Draco-compressed model does seem to be working correctly for me.

donmccurdy avatar Feb 12 '23 20:02 donmccurdy

@donmccurdy Much appreciated, I'll go ahead and do that.

ashleymvanduzer avatar Feb 13 '23 00:02 ashleymvanduzer