Open whatisor opened 7 years ago
This would actually be a great ideia, we could have JSON serialization all in one place for every object, objects could register in the loaders and this would avoid really big handwritten type check lists in the loaders.
Something like this would be cool
Object.prototype.toJSON = ...
Object.fromJSON = ...
XPTOLoader.register("type", Object);
It would be also nice to apply this to resources, that main problem here is the fact that is kinda of a big code change, but i think its worth.
I am using toJSON (for object, not for Geometry), ObjectLoader can load back. However, it lacks Animation.
However, it lacks Animation.
Can you explain a bit? ObjectLoader
is able to parse animations. Besides, AnimationClip
has a toJSON()
method.
@Mugen87 My flow is:
A bit of clarification — the mesh does not include animation because the mesh does not "have" animation, or own a reference to it. A single animation clip might be targeting many meshes, or non-mesh objects, or even objects in multiple scenes. Because animation is not a descendant of the scene, or attached to a descendant, you will have to export it separately. Similarly, when exporting to glTF you'd need to pass in a list of animations explicitly:
exporter.parse( scene, function ( gltf ) {
// ...
}, { animations: [clip1, clip2, ...] } );
That aside, the idea of distributing the ObjectLoader implementation into a fromJSON
method on each class sounds promising...
@donmccurdy I mean to export original Object loaded from ObjectLoader, not mesh inside. It is THREE.Group which include animations
I understand that seems like it should work, but technically a THREE.Group has no official way of "including animations", even though a JSON file does, and I don't think there's any way to implement that without an extra step to include the animations with the object(s). I still like the idea of having a fromJSON
method on objects.
Should it be interesting to inherit an "serializable interface" with type, toJson and fromJson ?
I think it would be better to let classes such as BufferGeometry(BoxBufferGeometry, SphereBufferGeometry ...etc), Material(MeshBasicMaterial, ...etc), Mesh to have their own "fromJSON" method. The ObjectLoader is just like a factory design pattern. If we use ObjectLoader to parse json, we must load a json file but actually loading json and parsing json are 2 different things. we might use parse method without loading a json file, maybe we already has a json object and want to parse it into instance object. So each class has fromJSON method to handle their json format, and ObjectLoader just use these classes' method to parse json.
For materials, material.fromJSON( json )
would work with inheritance quite well. MeshPhysicalMaterial can deserialize its own properties, and call super.fromJSON( ... )
to get the inherited properties. It would import Color and Texture classes but not much else.
But what about scene.fromJSON( json )
? The scene could have any kind of object as children ... Object3D, Mesh, InstancedMesh, PointLight, SpotLight, LightProbe, ... and ideally the Scene class should not import all of that, to ensure that tree-shaking works. It would be even better if it's possible for a custom object, like MyCustomMesh, to implement toJSON()
and fromJSON()
and "just work" when serializing/deserializing a scene that contains it.
I'm not sure how to structure that. We need to avoid import * as THREE
to maintain tree-shaking. Maybe it needs a factory argument, like fromJSON( json, loader )
and the user can provide the whole THREE namespace if they don't care about tree-shaking, a subset if they do, or custom objects in addition to the core library?
// Give me everything, forget tree-shaking.
import * as THREE from 'three';
var loader = new THREE.ObjectLoader().register( THREE );
var scene = new THREE.Scene().fromJSON( json, loader );
// Tree-shaking, please.
import {Scene, Mesh, Object3D, Group} from 'three';
var loader = new THREE.ObjectLoader().register( {
Scene, Mesh, Object3D, Group
} );
var scene = new THREE.Scene().fromJSON( json, loader );
// Tree-shaking++.
import {Scene, Mesh, Object3D, Group} from 'three';
import {MagicMesh} from 'three-magic-mesh';
var loader = new THREE.ObjectLoader().register( {
Scene, Mesh, Object3D, Group, MagicMesh
} );
var scene = new THREE.Scene().fromJSON( json, loader );
I only mention objects above, but it's similar for materials and geometries. :/
I'm running into this right now - it seems like all responsibility of (re)constructing objects is in the hands of ObjectLoader, e.g.
It would be easier to extend the loader if most classes were to implement a to/fromJSON method.
Also, because of this large switch
case on the object's type
parameter, it's difficult to add another custom type. It's seems tightly coupled with setting the objects other properties, like matrices, animations and such. I'd like to see that step separated out.
Description of the problem
We have toJSON api. As a consistency, I think we should have fromJSON. It will be powerful for data management.
Three.js version
Browser
OS
Hardware Requirements (graphics card, VR Device, ...)