GLTF Animation - Unexpected End of JSON

I have exported a short GLTF animation from Houdini 19 using the ROP GLTF Output. The animation plays back fine in a GLTF viewer like https://gltf-viewer.donmccurdy.com/ (albeit looks a bit silly given its just a 10 frame test)
However, importing into Studio I get a Unexpected End of JSON error. I’ve tried a bunch of different settings, GLBs, different models. Keep getting the same problem. Have attached the file for reference and the JSON below. Any ideas what the issue is here?

As an aside, would also love to hear any suggestions from anybody who has successfully brought simple animation into Studio from Houdini, because FBX doesn’t seem to be working either.

Thanks for the advice

{
	"asset":{
		"version":"2.0",
		"generator":"Houdini GLTF 2.0 Exporter"
	},
	"animations":[
		{
			"channels":[
				{
					"target":{
						"node":0,
						"path":"weights"
					},
					"sampler":0
				}
			],
			"samplers":[
				{
					"input":13,
					"interpolation":"LINEAR",
					"output":12
				}
			]
		}
	],
	"accessors":[
		{
			"bufferView":0,
			"componentType":5123,
			"count":1728,
			"type":"SCALAR",
			"min":[0
			],
			"max":[287
			]
		},
		{
			"bufferView":1,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[-0.75,-0.25,-0.75
			],
			"max":[0.75,0.25,0.75
			]
		},
		{
			"bufferView":2,
			"componentType":5126,
			"count":288,
			"type":"VEC2",
			"min":[1.37868213e-07,0.333333313
			],
			"max":[0.958333313,0.666666627
			]
		},
		{
			"bufferView":3,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[-1,-0.999767661,-1
			],
			"max":[1,0.999767601,1
			]
		},
		{
			"bufferView":4,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[0,-0.080646053,-0.0297809839
			],
			"max":[0,0.080646053,0.0297809839
			]
		},
		{
			"bufferView":5,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[-1.85783222e-07,-0.107528113,-0.107628092
			],
			"max":[2.00765768e-07,0.10752812,0.107628033
			]
		},
		{
			"bufferView":6,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[0,-0.28962335,-0.135326117
			],
			"max":[0,0.28962335,0.135326117
			]
		},
		{
			"bufferView":7,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[-1.45490901e-07,-0.386164576,-0.387746871
			],
			"max":[1.57673298e-07,0.386164516,0.387747079
			]
		},
		{
			"bufferView":8,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[0,-0.560387611,-0.353579998
			],
			"max":[0,0.560387611,0.353579998
			]
		},
		{
			"bufferView":9,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[-1.74767791e-07,-0.787723243,-0.788405597
			],
			"max":[2.28081277e-07,0.787723243,0.788405418
			]
		},
		{
			"bufferView":10,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[0,-0.785069108,-0.673077941
			],
			"max":[0,0.785069108,0.673077881
			]
		},
		{
			"bufferView":11,
			"componentType":5126,
			"count":288,
			"type":"VEC3",
			"min":[-1.29031562e-07,-1.20956075,-1.21059752
			],
			"max":[1.68370491e-07,1.20956075,1.21059752
			]
		},
		{
			"componentType":5126,
			"count":20,
			"type":"SCALAR",
			"sparse":{
				"count":4,
				"values":{
					"bufferView":13
				},
				"indices":{
					"bufferView":12,
					"componentType":5125
				}
			},
			"min":[0
			],
			"max":[1
			]
		},
		{
			"bufferView":14,
			"componentType":5126,
			"count":5,
			"type":"SCALAR",
			"min":[0
			],
			"max":[0.13333334
			]
		}
	],
	"buffers":[
		{
			"uri":"SpinningTorus_data.bin",
			"byteLength":40372,
			"name":"main_buffer"
		}
	],
	"bufferViews":[
		{
			"buffer":0,
			"byteLength":3456,
			"target":34963
		},
		{
			"buffer":0,
			"byteOffset":3456,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":6912,
			"byteLength":2304,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":9216,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":12672,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":16128,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":19584,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":23040,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":26496,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":29952,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":33408,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":36864,
			"byteLength":3456,
			"target":34962
		},
		{
			"buffer":0,
			"byteOffset":40320,
			"byteLength":16
		},
		{
			"buffer":0,
			"byteOffset":40336,
			"byteLength":16
		},
		{
			"buffer":0,
			"byteOffset":40352,
			"byteLength":20
		}
	],
	"nodes":[
		{
			"name":"torus",
			"mesh":0
		}
	],
	"meshes":[
		{
			"primitives":[
				{
					"attributes":{
						"NORMAL":3,
						"TEXCOORD_0":2,
						"POSITION":1
					},
					"indices":0,
					"material":0,
					"targets":[
						{
							"NORMAL":5,
							"POSITION":4
						},
						{
							"NORMAL":7,
							"POSITION":6
						},
						{
							"NORMAL":9,
							"POSITION":8
						},
						{
							"NORMAL":11,
							"POSITION":10
						}
					]
				}
			],
			"name":"material1",
			"extras":{
				"targetNames":["","","",""
				]
			}
		}
	],
	"materials":[
		{
			"name":"principledshader",
			"pbrMetallicRoughness":{
				"baseColorFactor":[0.200000003,0,0.0864360556,1
				],
				"metallicFactor":0.280000001,
				"roughnessFactor":0.300000012,
				"baseColorTexture":{
					"index":0
				}
			}
		}
	],
	"scenes":[
		{
			"nodes":[0
			]
		}
	],
	"textures":[
		{
			"source":0
		}
	],
	"images":[
		{
			"uri":"texture.jpg",
			"mimeType":"image/jpeg"
		}
	],
	"scene":0
}

Hi Josef,

Did you get any further with this? I’ve been going via Blender to get 3D stuff into Zap, but I wanted to try and sort out a workflow directly from Houdini instead. And I haven’t really played much with animation yet, more with static objects I animate afterwards. It’d be incredibly cool to be able to generate animations within Houdini and pull them into AR though. Matt Estela has a tiny animated AR thing on cgwiki that he created within Houdini then exported as USDZ, but that’s not readily usable with Zap.

Any pointers greatly appreciated, but otherwise I’ll have a play and report back here :slight_smile:

Hi everyone! :zap:

I wonder if this post is of use at all?

If you discover anything else that may also be helpful, feel free to add it to the above thread!

Have a great day!
Francesca :blush:

OK - I’ve managed to get animations from Houdini 19 into Zap. Still got some work to do, but observations so far:

  • .glb seems to work best
  • for SOP level animations, make sure they’re packed before animation. I’ve had some weirdness when trying to import multiple (different) packed and animated objects merged together - the animations have come through corrupted. Keeping to a single packed prim per object seems to work OK, even if you have multiple instances of it animating. So if you, say, pack a mesh, then use a Copy To Points SOP to instance it to some moving points, that seems to work fine
  • I got that Unexpected End of JSON any time I forgot to pack the mesh first - you can see by the size of the output file that it’s storing the whole mesh per frame rather than just a transform, which makes sense. But it could well be the size of the file that’s causing the error.
  • Haven’t yet tried OBJ level anims, but I’ll have a go when I get a chance.

One thing that’s become a bit clearer about Zap Studio’s import process: if you drag a file to the import bar, Zap tries to create a new subsymbol for it, which can be either useful or a pain, depending on what you’re trying to do. If you want the mesh to be imported into the current symbol (ie the project root, if that’s where you are right now) you have to click the “+” and choose the file, rather than dragging it in. Then it’s up to you to set up materials manually, and set up a timeline to animate the “Animation Frame” parameter if that’s how you want to control the anim. Personally I prefer to run the animation with a script - set up a Z.every handler or similar to increment the symbol.nodes.my_glb_mesh.animationFrame(frame) value.

1 Like

There are 2 things you can do:

1- Import in blender and re-export. This works sometimes.
2- Upload to sketchfab and import. This always work. Even if you can’t import the glb directly, Studio always succeeds at importing from sketchfab. So you can use sketchfab as an intermediary and delete the model later. Don’t ask me why this works, I don’t know. But it does :man_shrugging:.

1 Like