jupyter-widgets / pythreejs

A Jupyter - Three.js bridge
https://pythreejs.readthedocs.io
Other
936 stars 187 forks source link

Support for GLTFLoader #246

Open yasmin496 opened 5 years ago

yasmin496 commented 5 years ago

Is there any way to load gltf models in pythreejs using the THREE.GLTFLoader api?

vidartf commented 5 years ago

Not currently, unfortunately. If anybody would be willing to contribute some time to implement it, I'd be happy to help out that someone in understanding the code base + reviewing the code though!

reductor commented 4 years ago

@vidartf I'd love to add support for GLTF, what needs to be done? Looks like the GLTFLoader is unfortunately in the examples not what is in the normal package, additionally it needs async/callbacks.

I took half a shot but couldn't manage to get it going, what do you suggest for doing it?

vidartf commented 4 years ago

@ReDucTor For files in examples we have traditionally vendored them (i.e. copying them into our repo). Since then, there has been some changes to the threejs distribution, so it should now be possible to import them. See here:

You can find in the examples/jsm directory an ES6 module version for almost all example files. If you install three.js via npm, you can import them like so:

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

So, I would do it like this:

Once you've figured it out and added any missing points to the list above (I'm mostly writing this off the top of my head), we should probably add that list do the developer docs.

vidartf commented 4 years ago

Notes on implementation: In JS, the loader is a helper that generates objects for you. This does not translate very well to widgets due to the async nature of such a process. Instead I would create a GLTFObject/GLTFModel/...? object that inherits Object3D but only takes the loaders args as its constructor args. See e.g. textures/ImageTexture for a similar concept (a custom class that exposes a Texture object loaded with the TextureLoader).

reductor commented 4 years ago

I have half done this based on ImageTexture however I run into a few other issues, the returned result is a dict with a few properties (including the scene).

However I hit some issues with this, the first is that completing the promise does not fill the properties, I wrapped the promise in another continuation which calls set to update the properties as a mechanism to wait.

However when this result arrives back into python it does not deserialize properly due to widgets expecting object to be serialized as a string which references a model ID.

In order to get around this I changed it to use InstanceDict which lets it be created from the serialized dict that gets sent to Python instead of the string, however this does not appear to work when being used, that I suspect is because the model ids do not match what is expected in when sent back to python for rendering.

Also with GLTF it's sometimes more then a model, it can contain an entire scene, animations, cameras, etc.

reductor commented 4 years ago

On a slightly related note, I have been thinking about the possibility of async adding method support (it appears there is already have an implementation), then GLTFLoader could be wrapped directly and methods even generate automatically, however that doesn't solve the current issues, would just move them elsewhere

vidartf commented 4 years ago

Would you mind opening up what you have as a PR? It is much easier to reason over these things as code than as a description of code in English. :)

reductor commented 4 years ago

I've opened a PR ( #321 ) to checkout for the current WIP