moguri / panda3d-gltf Goto Github PK
View Code? Open in Web Editor NEWglTF utilities for Panda3D
License: BSD 3-Clause "New" or "Revised" License
glTF utilities for Panda3D
License: BSD 3-Clause "New" or "Revised" License
Using Blender 2.8:
"+Y Up" option checked -> Model in Panda3D is upside down, -Z is up.
"+Y Up" option checked and model converted to bam with "--skip-axis-conversion" -> model in Panda3D is sideways, +Y is up.
"+Y Up" option unchecked -> model in Panda3D is sideways, +Y is up.
"+Y Up" option unchecked and model converted to bam with "--skip-axis-conversion" -> model in Panda3D axis is correct, +Z is up.
Hi
I exported makehuman character into blender scene, did simple animation (without changing scale or pos) and exported to gltf embedded or glb. Result is same.
I didn't include converted bam file since it's big
Exported model has broken anim since its animation wasn't added to NLA editor. Exporting bad models could be prevented by making anim added to NLA track (pushed down) before exporting (optional key) or show some warning about it. Also make scale of armature 1.0 or just show warning to let user manually fix it.
This causes this assertion when trying to flatten the model in Panda:
Assertion failed: orig_index >= 0 && orig_index < (int)blend_map.size() at line 1387 of panda/src/pgraph/geomTransformer.cxx
This model reproduces the issue:
http://rdb.name/flower.blend
I think the fix is: in combine_mesh_skin, if tdata.has_column()
returns False, just continue without assigning an empty TransformBlendTable. However, I don't have the time to test right now.
The glTF 2.0 specification states the indices property is optional for primitives and when not present the same semantics as WebGL drawArrays() should be used to construct the mesh.
The TriangleWithoutIndices.gltf model demonstrates this issue. Load the file into the viewer and observe that the model bounding box is empty.
I traced this back to the converter code. It looks like only the case of an indexed geometry has been considered. I am wondering if this is just an oversight or it's not a straight forward fix.
Support inner/outerConeAngle
property for KHR_lights_punctual
This is needed to support "shadeless" models. This can probably be implemented by calling set_light_off()
on affected NodePath objects.
I wish to load gltf-files without axis conversion, like I do when I provide --skip-axis-conversion
on the commandline.
Is this possible? It eludes me how this can be achieved.
Thanks in advance!
KHR_lights support should also be kept around for now. KHR_lights_punctual spec
When trying to load a model with two armatures using the Actor class, only one of them seem to get loaded. The other armature and also the model parented to it are not visible in the application.
If I try and load the model as a static model, both objects are displayed. There also is a difference in the shading. The Actor loaded model seems to be shadeless while the static models are shaded.
Loading the bam file with pview also only shows the static model and no animations get loaded.
A sample code with blend and bam file showing the problem:
TwoArmatures.tar.gz
After converting with blend2bam the mesh is not morphed by bones even if getCurrentAnim() returns the correct animation. Exporting gltf from blender shows very erroneous animation playing in gltf-viewer.
floop.zip - play("Action")
rebecca.zip - play("walk_forward")
glTF uses a 4-component tangent vector and does not supply a bi-tangent (this is assumed to be calculated in the shader). As such, models loaded by panda3d-gltf will follow this convention. There is also talk about following this in Panda as well. However, at the moment, this means that models loaded by this project will not work correctly with the normal mapping done by the auto-shader (simplepbr does support these tangents).
More often than not, the camera is not in front of the model, adding self.cam.look_at(self.model_root)
here :
Line 53 in fd8cf74
would help a lot.
Loading of external .bin files from .gltf files is extremely slow, the root cause is that
panda3d-gltf/gltf/converter.py
Line 377 in fd8cf74
Does not specify the size of the chunk to read from the stream, and the default value is 512 bytes, so for a 11MB file, it means more that 22000 chunk read followed by buffer concatenation, which takes several minutes. Adding size=1024*1024 makes the file load in a jiffy.
Testing with https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/MetalRoughSpheres loading the .gltf shows invalid or extra triangles:
The actual mesh is a pure array of spheres :
My code keeps giving me this error and I'm not sure why:
`Known pipe types:
CocoaGraphicsPipe
(all display modules loaded.)
2019-12-08 20:48:32.412 Python[13236:353176] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to (null)
:gobj(error): GeomTriangles references vertices up to 61, but GeomVertexData has only 50 rows!
Assertion failed: primitive->check_valid(cdata->_data.get_read_pointer(current_thread)) at line 364 of panda/src/gobj/geom.cxx
Traceback (most recent call last):
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/gltf/converter.py", line 1243, in load_model
convert(file_path, bamfilepath, gltf_settings)
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/gltf/converter.py", line 1228, in convert
converter.update(gltf_data, writing_bam=True)
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/gltf/converter.py", line 149, in update
self.load_mesh(meshid, gltf_mesh, gltf_data)
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/gltf/converter.py", line 976, in load_mesh
self.load_primitive(node, gltf_primitive, gltf_data)
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/gltf/converter.py", line 963, in load_primitive
geom.add_primitive(prim)
AssertionError: primitive->check_valid(cdata->_data.get_read_pointer(current_thread)) at line 364 of panda/src/gobj/geom.cxx
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/gltf/loader.py", line 21, in load_file
options=options
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/gltf/converter.py", line 1249, in load_model
raise RuntimeError("Failed to convert glTF file")
RuntimeError: Failed to convert glTF file
:loader(error): Loading scene.gltf failed with RuntimeError exception.
:loader(error): Couldn't load file /Developer/Panda3D/models/scene.gltf: invalid.
Traceback (most recent call last):
File "/Users/38167/PycharmProjects/viren/scene.py", line 163, in
app = MyApp()
File "/Users/38167/PycharmProjects/viren/scene.py", line 72, in init
self.plant = Actor("/Developer/Panda3D/models/scene.gltf")
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/direct/actor/Actor.py", line 290, in init
self.loadModel(models, copy = copy, okMissing = okMissing)
File "/Users/38167/PycharmProjects/viren/venv/lib/python3.7/site-packages/direct/actor/Actor.py", line 1900, in loadModel
raise IOError("Could not load Actor model %s" % (modelPath))
OSError: Could not load Actor model /Developer/Panda3D/models/scene.gltf
Process finished with exit code 1`
A function should be added to load glTF files. This can convert to BAM and then call Panda's normal model loading mechanisms.
Axis conversion in glsl-viewer is either upside down or on its side.
When exported from blender with Y+ unchecked and run regularly with showbase the view appears correct for a single frame before the camera seems to snap 90 degrees down the X axis (to the floor). Run main.py:
test.zip
This could be done by adding a joint for each animated object in the animation, but rather than hooking it up to a JointVertexTransform to transform vertices, we would use joint.add_local_transform()
or joint.add_net_transform()
(ie. the equivalent of actor.exposeJoint
) to have Panda copy the transformation to the object in question.
The animated object should probably be made a ModelNode to prevent Panda from flattening it.
Also see panda3d/panda3d#457, which discusses a way of implementing object animations without use of joints in Panda3D.
We will need to record morph targets into the GeomVertexData for the meshes via extra columns. These columns are named via InternalName::get_morph()
. glTF doesn't name morphs, so we will use the target index as a name.
I've uploaded a minimal test .gltf file (and the Blender 2.80 file that produced it) containing two bones (bone1
and bone2
) in an armature:
multiple_roots.zip
Only one bone is exported, however, and this error message is repeated once for each vertex affected by the second bone:
Could not find joint in jvtmap:
joint=1.0
jvtmap=OrderedDict([(0, bone1)])
bam-info -ls
shows that the second bone is imported as a regular node instead of as a joint:
ModelRoot Scene
PandaNode Armature
PandaNode Cube
Character Armature
GeomNode Cube (1 geoms: S:(MaterialAttrib TextureAttrib))
PandaNode bone2 T:m(pos 0 0 -4 hpr -180 90 -180)
This appears to be due to the last line of code here:
panda3d-gltf/gltf/converter.py
Lines 730 to 734 in fd8cf74
After having a confusing issue I found out that Panda3D will not update its model loading cache when using a GLTF file.
So if I load a GLTF file it will create the cache for it. After that if I update or delete the GLTF file Panda will still load the old file from cache.
For now I can work around this issue by using the "noCache = True" option when loading a model.
For reference on this issue:
https://discourse.panda3d.org/t/strange-issue-with-model-texture/25462/3
gltf-viewer should not be using cache models and should always try re-converting/loading. This can be done by passing noCache=True
to the loader.
Support range
property for KHR_lights_punctual
Shapekey animations break unless all of the shapekeys are at 0 on the first frame.
To fix this animation, add keyframes for all shapekeys at frame 0 with a value of 0.
Support intensity
property for KHR_lights_punctual
I created three bones connected with a mesh, made an animation and exported to gltf 2.0 from a blender 2.8. However, I received a KeyError: 'skeleton' error when using panda3d-gltf. Full text:
C:\Panda3D-1.10.3-x64\FPS>gltf2bam anim.gltf output.bam
Traceback (most recent call last):
File "c:\panda3d-1.10.3-x64\python\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "c:\panda3d-1.10.3-x64\python\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Panda3D-1.10.3-x64\python\Scripts\gltf2bam.exe\__main__.py", line 9, in <module>
File "c:\panda3d-1.10.3-x64\python\lib\site-packages\gltf\cli.py", line 44, in main
gltf.converter.convert(args.src, args.dst, settings)
File "c:\panda3d-1.10.3-x64\python\lib\site-packages\gltf\converter.py", line 1102, in convert
converter.update(gltf_data, writing_bam=True)
File "c:\panda3d-1.10.3-x64\python\lib\site-packages\gltf\converter.py", line 139, in update
self.load_skin(skinid, gltf_skin, gltf_data)
File "c:\panda3d-1.10.3-x64\python\lib\site-packages\gltf\converter.py", line 664, in load_skin
root = gltf_data['nodes'][gltf_skin['skeleton']]
KeyError: 'skeleton'
Some models without tangent data cause the converter to crash due to division by zero.
Traceback (most recent call last): File "/usr/local/lib/python3.5/dist-packages/panda3d_gltf-0.3-py3.5.egg/gltf/converter.py", line 1310, in load_model convert(file_path, bamfilepath, gltf_settings) File "/usr/local/lib/python3.5/dist-packages/panda3d_gltf-0.3-py3.5.egg/gltf/converter.py", line 1288, in convert converter.update(gltf_data, writing_bam=True) File "/usr/local/lib/python3.5/dist-packages/panda3d_gltf-0.3-py3.5.egg/gltf/converter.py", line 150, in update self.load_mesh(meshid, gltf_mesh, gltf_data) File "/usr/local/lib/python3.5/dist-packages/panda3d_gltf-0.3-py3.5.egg/gltf/converter.py", line 1043, in load_mesh self.load_primitive(node, gltf_primitive, gltf_data) File "/usr/local/lib/python3.5/dist-packages/panda3d_gltf-0.3-py3.5.egg/gltf/converter.py", line 978, in load_primitive self.calculate_tangents(geom) File "/usr/local/lib/python3.5/dist-packages/panda3d_gltf-0.3-py3.5.egg/gltf/converter.py", line 1005, in calculate_tangents fconst = 1.0 / (duv1.x * duv2.y - duv2.x * duv1.y) ZeroDivisionError: float division by zero
Tested with the latest panda3d-gltf and Panda3d-1.10.5-dev92
One model causing the crash is the Hubble model available here : https://exoplanets.nasa.gov/resources/2214/hubble-space-telescope-3d-model/ but other models cause the same problem.
I got this model where babylon.js viewer work, but panda3d animation is broken. Dunno what is happening exactly.
and Panda3D:
This supports Panda's Filename
object and VFS.
When testing the normals and normal maps using https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/NormalTangentMirrorTest one can see that the normals are not correctly oriented:
This is the output of the viewer :
This is the expected output :
As one can see, the orientation of the specular reflection and the shading is not the same across all column as it should have been.
One root cause could be that the axis conversion from Y-up to Z-up is not properly applied on both the normal and the tangent.
The BLENDER_physics extension exposes groups and masks, but these are not being converted to appropriate masks for either Bullet or Panda CollisionSolids.
Ideally this would work whether the model is using CollisionSolids or Bullet shapes.
Could not find a version that satisfies the requirement panda3d-simplepbr>=0.2.2 (from panda3d-gltf) (from versions: )
No matching distribution found for panda3d-simplepbr>=0.2.2 (from panda3d-gltf)
Very interesting project! It would be much easier to adopt it for an existing project if there would be a bam2gltf (or egg2gltf) utility to convert over existing models.
It doesn't work on Windows because an OS-specific filename is being passed to the Loader:
panda3d-gltf/gltf/converter.py
Line 1227 in d2e9aa8
Be advised that NamedTemporaryFile is buggy in older Python versions; it reports the filename in the wrong case. To work around this, you can do:
fn = Filename.from_os_specific(bamfile.name)
fn.make_true_case()
return loader.load_sync(fn, **loader_kwargs)
When a model has no normal map, the fallback normal texture should be applied on the model, however it seems it's not the case.
If I print the attire states applied to the nodes, I get this
MaterialAttrib:Material mat0 c(1 1 1 1) r1 m1 l0 t0
TextureAttrib:on 0: 1: 2:normal-fallback
The normal texture is correctly there, but if I print the texture stages applied, it's not present :
scene0/node0/node1
TextureStage 0
TextureStage 1
And visually the normals are garbage.
If I replace the current code :
texture.setup_2d_texture(1, 1, Texture.T_unsigned_byte, Texture.F_rgba)
texture.set_clear_color(LColor(0.5, 0.5, 1, 1))
with
image = PNMImage(1, 1, 3)
image.setXel(0, 0, LRGBColor(0.5, 0.5, 1))
texture.load(image)
The texture stage is properly added :
scene0/node0/node1
TextureStage 2
TextureStage 0
TextureStage 1
And visually the normals are correct:
@rdb, is it correct that a texture stage with an empty texture is not applied ? If so I will make a PR to switch to texture.load().
$ gltf2bam sliderbar.glb sliderbar.bam
Traceback (most recent call last):
File "/usr/bin/gltf2bam", line 11, in
load_entry_point('panda3d-gltf==0.1.0', 'console_scripts', 'gltf2bam')()
File "/usr/lib/python3.7/site-packages/gltf/cli.py", line 44, in main
gltf.converter.convert(args.src, args.dst, settings)
File "/usr/lib/python3.7/site-packages/gltf/converter.py", line 1092, in convert
gltf_data = json.load(gltf_file)
File "/usr/lib/python3.7/json/init.py", line 293, in load
return loads(fp.read(),
File "/usr/lib/python3.7/codecs.py", line 322, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf4 in position 12: invalid continuation byte
This really is only a box created in blender having a black principled bsdf shader. and a bit of bevel. Nothing special
On some composite models, some nodes have wrong transformation applied to them, resulting in a broken model.
For example, here is a model of the Hubble space telescope : https://exoplanets.nasa.gov/resources/2214/hubble-space-telescope-3d-model/
Which is rendered fine with BabylonJS, Blender, ...
But with panda3d-gltf, several parts are not positioned and oriented properly.
Here is a dump of the loaded scene :
ModelRoot Scene PandaNode Light T:m(pos 4.07625 5.90386 -1.00545 hpr -104.532 37.1947 -3.97275) PandaNode Camera T:m(pos 7.35889 4.95831 6.92579 hpr -46.692 63.5593 0) Camera Camera ( PerspectiveLens ) PerspectiveLens fov = 22.8952 22.8952 PandaNode alpha_tex01 T:m(pos 0.0952893 1.45378 -5.57658 hpr -90 -6.48857e-06 180 scale 0.345791) GeomNode Cylinder.008 (1 geoms: S:(MaterialAttrib TextureAttrib TransparencyAttrib)) PandaNode AO_1 T:m(hpr 0 0 -180 scale 2.25687 2.25687 2.68318) GeomNode Cylinder.003 (1 geoms: S:(MaterialAttrib TextureAttrib)) PandaNode AO_light T:m(hpr 0 0 -180 scale 2.25687 2.25687 2.68318) GeomNode Cylinder.007 (1 geoms: S:(MaterialAttrib TextureAttrib)) PandaNode foil_gold T:m(hpr 0 0 -180 scale 1.05556) GeomNode Cube.002 (1 geoms) PandaNode foil_silver T:m(hpr 0 0 -180 scale 1.05556) GeomNode Cube.000 (1 geoms: S:(MaterialAttrib TextureAttrib)) PandaNode shiny_panel T:m(hpr -90 -4.32571e-06 180 scale 0.345791) GeomNode Cylinder.009 (1 geoms: S:(MaterialAttrib TextureAttrib)) PandaNode shiny_panel_cylinder T:m(pos -1.94723e-05 0.72426 3.86028 hpr 0 0 -180 scale 2.25687 2.25687 2.68318) GeomNode Cylinder.000 (1 geoms: S:(MaterialAttrib TextureAttrib)) PandaNode tex_01 T:m(hpr -90 -4.32571e-06 180 scale 0.345791) GeomNode Cylinder.004 (1 geoms: S:(MaterialAttrib TextureAttrib)) PandaNode tex_02 T:m(hpr 0 0 -180 scale 1.05556) GeomNode Cube.001 (1 geoms: S:(MaterialAttrib TextureAttrib)) PandaNode tex_03 T:m(hpr 0 0 -180 scale 2.25687 2.25687 2.68318) GeomNode Cylinder.010 (1 geoms: S:(MaterialAttrib TextureAttrib))
What is strange is that the transformation are identical to the values seen in Blender, so maybe the parenting is wrong ?
Loading an animated model with double precision float version of Panda leads to a crash :
Known pipe types: glxGraphicsPipe (all display modules loaded.) Traceback (most recent call last): File "gltf/../gltf/converter.py", line 1631, in load_model convert(file_path, bamfilepath, gltf_settings) File "gltf/../gltf/converter.py", line 1609, in convert converter.update(gltf_data, writing_bam=True) File "gltf/../gltf/converter.py", line 356, in update add_node(scene_root, gltf_scene, nodeid, {}, {}) File "gltf/../gltf/converter.py", line 223, in add_node self.build_character(char, nodeid, {}, cvsmap2, gltf_data, recurse=False) File "gltf/../gltf/converter.py", line 1025, in build_character gltf_data, recurse=recurse) File "gltf/../gltf/converter.py", line 1399, in build_animation_morph create_channels(group, nodeid, target_names, weights) File "gltf/../gltf/converter.py", line 1376, in create_channels group.set_table(CPTAFloat(target_weights)) TypeError: AnimChannelScalarTable.set_table() argument 1 must be ConstPointerToArray, not panda3d.core.ConstPointerToArray_float
Replacing CPTAFloat() by CPTADouble() solve the problem but it's obviously not portable. Also, I'm not sure if this is a Panda issue or not.
glTF is Y-Up, but Panda3D defaults to Z-Up
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.