Moguri / panda3d-gltf

glTF utilities for Panda3D
BSD 3-Clause "New" or "Revised" License
82 stars 19 forks source link

gltf sample testing (1 out of 7 working) #133

Closed BMaxV closed 4 months ago

BMaxV commented 4 months ago

Hello,

as discussed on discord

I looked at some GLTF sample/test files.

You suggested to open a new issue for each broken file, I don't think that's reasonable for now. It's probably a better idea to pick one of the broken ones and open a new issue when you're working on it. Otherwise it's just spam.

Of the 7 files I tested, only the "AnimatedMorphCube.glb" worked, everything either didn't load, or didn't animate.

Some of the test files also didn't load animate in blender, which I used as a comparison. No idea how the webviewer works, that may not be comparable.

The versions I used were:

panda3d 1.10.14 panda3d-gltf 1.2.0 panda3d-simplepbr 4.11.0


This loads but doesn't animate, does work in blender

source

this just worked.

source

.local/lib/python3.10/site-packages/simplepbr/envmap.py", line 58, in hash
    name = hash(self.cubemap.fullpath)
AttributeError: 'NoneType' object has no attribute 'fullpath'

source

This did not work, but it did work in blender.

source

I copied some of the gltf viewer code to get some printouts.

source

Doesn't load, same pbr problem as above.

source

Loads in the script but doesn't animate, does not load with gltf-viewer. Does work in blender, includes a rigg so that maybe a good idea to start with this one.

source

from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor
import panda3d.core as p3d
import math

class Wrapper:
    def __init__(self):
        self.b = ShowBase()

        filename = "AnimatedMorphCube.glb" # this works
        filename = "AnimatedCube.gltf" # loads but doesn't animate.
        filename = "AnimatedTriangle.gltf" # this does not work. # doesn't load crash log attached # does not work in blender
        filename = "AnimatedBox.glb" # loads in the viewer, but not in this script. Doesn't animate, even in the viewer.
        filename = "CesiumMan.glb" # loads and animates, but is messed up, consistently though.
        filename = "InterpolationTest.glb" # loads but doesn't animate, no character found
        filename = "NormalTangentMirrorTest.glb" # loads, but no reflection in gltf viewer or this script
        #filename = "SimpleSkin.gtlf" # embedded, does not load
        filename = "RiggedFigure.glb" # gltfviewer does not load, this stcript does not but the animation doesn't play
        #filename = "RiggedFigure_embedded.gltf" does not work and it does not work in blender

        #cube = self.b.loader.loadModel(filename)
        #cube.reparentTo(self.b.render)
        #my_actor = Actor(filename)
        #my_actor.reparentTo(self.b.render)
        #animnames = my_actor.getAnimNames()
        #print("my animations:", animnames)
        #pos=(-2, 25, -3)
        #cube.setPos(pos)
        #pos=(-2, 24, -3)
        #my_actor.setPos(pos)

        self.model_root = self.b.loader.load_model(filename, noCache=True)

        self.model_root.reparent_to(self.b.render)

        bounds = self.model_root.getBounds()
        center = bounds.get_center()
        if bounds.is_empty():
            radius = 1
        else:
            radius = bounds.get_radius()

        fov = self.b.camLens.get_fov()
        distance = radius / math.tan(math.radians(min(fov[0], fov[1]) / 2.0))
        self.b.camLens.set_near(min(self.b.camLens.get_default_near(), radius / 2))
        self.b.camLens.set_far(max(self.b.camLens.get_default_far(), distance + radius * 2))
        trackball = self.b.trackball.node()
        trackball.set_origin(center)
        trackball.set_pos(0, distance, 0)
        trackball.setForwardScale(distance * 0.006)

        # Create a light if the model does not have one
        if not self.model_root.find('**/+Light'):
            self.light = self.b.render.attach_new_node(p3d.PointLight('light'))
            self.light.set_pos(0, -distance, distance)
            self.b.render.set_light(self.light)

        # Move lights to render
        self.model_root.clear_light()
        for light in self.model_root.find_all_matches('**/+Light'):
            light.parent.wrt_reparent_to(self.b.render)
            self.render.set_light(light)

        # Add some ambient light
        self.ambient = self.b.render.attach_new_node(p3d.AmbientLight('ambient'))
        self.ambient.node().set_color((.1, .1, .1, 1))
        self.b.render.set_light(self.ambient)

        if self.model_root.find('**/+Character'):
            self.anims = p3d.AnimControlCollection()
            p3d.autoBind(self.model_root.node(), self.anims, ~0)
            if self.anims.get_num_anims() > 0:

                self.anims.get_anim(0).loop(True)
            print("anim number",self.anims.get_num_anims())
        else:
            print("no character found")

if __name__ == "__main__":
    W = Wrapper()
    while True:
        W.b.taskMgr.step()

if there is anything else I can do, let me know.

BMaxV commented 4 months ago

I misunderstood how the animation system works in panda.

I think it's working as intended right now. So the "bug" and the non compliance doesn't make much sense.

What happens internally is that there is a table that the e.g. position values x_i are taken from, for any point in time t_i. We can then adjust how fast this fully predetermined animation plays in the engine. If the original animation was defined for 2 seconds and 24 fps and we play for 4 seconds, at 60 fps, that's where interpolation happens. Personally, that kind of solution smells to me, but I don't have data to back up that it's bad and it's out of scope for this issue and possible for the import module. We need to discuss first if we even want to make a change to the animation system to have that functionality at all. After that comes worrying about imports.

Anyway, back on topic: the gltf files that do work are those where all the animation curves are interpolated.

That means gltf isn't "fully supported" because there are valid files that this module and panda can't load.

Thanks go to entikan in particular, he explained it to me yesterday.

rdb commented 4 months ago

It could be a feature request for panda3d-gltf to handle the sampling/interpolation.

I think it would also be a valid feature request for Panda3D to support this natively.