Actor(warning) How does Panda know the difference between an actor and a static object?

Hello! I’ve been working with Panda3d for a few months now, but I’ve never been able to figure out why I keep getting these errors whenever I use models exported from blender.

Known pipe types:
glxGraphicsPipe
(all display modules loaded.)
:Actor(warning): data/objects/rectangular_prism is not a character!
:Actor(warning): data/objects/rectangular_prism is not a character!
:Actor(warning): data/objects/sphere is not a character!

I thought I’d take a look at panda-model.egg to see if it showed some special flag or tag some sort, but as far as I see there’s nothing that seems immediately obvious.

I even changed the top of the egg file to this, removing and changing information to see if that did anything:
Tex1 {
“maps/panda-model.jpg”
format { rgb }
wrapu { repeat }
wrapv { repeat }
minfilter { linear_mipmap_linear }
magfilter { linear }
}
panda_blah {

blah {
panda_mblah {
panda_mesh.verts

and it’s still recognized as a character, even without specifying the animation that goes along with it. What’s going on here?

Am I correct in guessing that you’re loading these models via the “Actor” interface? That is, something like this:

myModel = Actor("path/to/model")

If so, then I believe that the problem lies with doing it that way: a model loaded as an Actor is presumed by Panda to be an Actor, I believe.

Instead, what I suggest for non-animated objects is to load them using the “loader” interface–something like this:

myModel = loader.loadModel("path/to/model")

(Animated models would still presumably be loaded via the “Actor” interface.)

That said, if I miss my guess above, how are you loading your models?

Actually, I originally loaded it as loader.loadModel(actor_object_data[actor_position]), but I want to transition to using animated models, so all I really want to know is why in the tutorial if I do

self.pandaActor = Actor("models/panda-model")

instead of

self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"})

there’s no mention of it not being a character?

By the way, here’s the way I’m loading them:

actor_name = 0
image_path = 1
actor_position = 2

self.actor_nodes\
= [self.render.attachNewNode(actor_object_data[actor_name])
  for actor_object_data in self.actors_data]

self.models\
= [Actor(actor_object_data[image_path])
  for actor_object_data in self.actors_data]

for i in range(self.number_of_actors):
  self.actor_nodes[i].setPos(self.actors_data[i][actor_position])
  self.models[i].reparentTo(self.actor_nodes[i])

As I said: if you load it as an Actor, Panda assumes that it is an Actor, I believe–regardless of whether you include a list of animations. (Offhand, I imagine that this might be useful in cases in which you want to load an Actor, but provide the animations only later, perhaps being loaded dynamically.)

In short, one loads Actors and non-animated models differently in Panda.

To deal with this, what you might do is to include logic in your program that distinguishes between animated models and non-animated ones, and uses “Actor” and “loader.loadModel” respectively. For example, if you intend to only ever construct Actors with a list of animations, you could test whether such a list has been provided. If so, you load the model as an Actor. If not, you load it via “loader.loadModel”.

Hmm… I’m not sure. It’s not complaining in the second case because “panda-model” presumably is a character–that is, it has an armature and can be animated. But I would expect it to not complain even without the animation-list in this case, since it’s (presumably) the same model.

Hello, berylliumquestion

Panda is opensource. It’s good, because we can always look in the source code:

image

Actor.py, line 1908

I think this is pretty self-explanatory.

Okay, so I just added another model, but this time I added an armature. It seems that satisfied at least one of the conditions that Panda checks for in an actor, but now I’ve got a completely different problem of the animation not showing up. I think I didn’t export it right from blender. It’s just a cube that rotates about the z axis, but it’s not doing that when I run my application.

Well, how did you export it? (And what exporter are you using? YABEE?)

If you’re using YABEE, then, if I’m not much mistaken, there are two ways to export an animation:

  1. Store your animations as “actions” in Blender, and select “all actions as animations”. This can result in some superfluous animation files being exported under some circumstances, but it’s still my preferred method.
  2. Store your animations on a single timeline, and delineate them in YABEE’s animation list via their start- and end- keyframes.

One more thought that occurs to me: you’ve mentioned loading Actors without providing a list of animations–when you load this rotating cube, are you providing an animation-list that includes the animation that you expect to see?

I’m not quite sure what you mean by either of those two points. I mean, I followed this tutorial about actions and I still got the exact same egg file. https://www.youtube.com/watch?v=Gb152Qncn2s I also don’t know how to delineate keyframes in YABEE, mostly because I’m not even sure what that means. Sorry, I’m not used animating, let alone animating 3d objects! I did dabble in flash animation a number of years ago, but that’s been almost a decade.

Also, how do I list animations, if they’re already a part of the egg file?

Okay, based on that video, it looks like you’re using actions (i.e. point (1) above)–which is probably easier than the keyframe-delineation method.

So, when you export your file, you should see a YABEE-specific screen, asking for things like the name of the egg file that you want to create. On the left of this are a number of options. Since you’re using actions, I recommend selecting the option labelled “All actions as animations”.

As to listing the animations, just to check, do I take it then that in YABEE’s options you have “Separate animation files” deselected?

In that case, according to the manual (see here for reference), it seems that you do in fact construct the Actor without giving it a set of animations. Sorry about that–I’m not used to keeping the animations in the model-file! ^^;

(I usually have “Separate animation files” selected, and so end up with a set of animation-files alongside the main model-file, which I then include when constructing my Actors.)

Good lord… I just realized I hadn’t noticed an entire options bar on the export screen. Wow, I’m sorry. :sweat_smile: I have the option you’re talking about selected now and separate animation files selected. So now I have an animation file, but it’s still not working. To see whether it’s a problem in my code I put the cube in the panda tutorial, and it actually works! However, it only does it when it reaches the end. Like it moves to one end of the arena, rotates, then moves to the other side, rotates, and repeat. It won’t rotate at all without the lerping code.

    # Load and transform the panda actor.
    self.pandaActor = Actor("rotating_cube", {"walk":"rotating_cube-rotate"})
    self.pandaActor.setPos((0, 10, 0))
    #self.pandaActor.setScale(0.005, 0.005, 0.005)
    self.pandaActor.reparentTo(self.render)
    
    # Loop its animation.
    self.pandaActor.loop("walk")
    
    # Create the four lerp intervals needed for the panda to
    # walk back and forth.
    pandaPosInterval1 = self.pandaActor.posInterval(13,
                                                    Point3(0, -10, 0),
                                                    startPos=Point3(0, 10, 0))
    pandaPosInterval2 = self.pandaActor.posInterval(13,
                                                    Point3(0, 10, 0),
                                                    startPos=Point3(0, -10, 0))
    pandaHprInterval1 = self.pandaActor.hprInterval(3,
                                                    Point3(180, 0, 0),
                                                    startHpr=Point3(0, 0, 0))
    pandaHprInterval2 = self.pandaActor.hprInterval(3,
                                                    Point3(0, 0, 0),
                                                    startHpr=Point3(180, 0, 0))
    
    print(pandaPosInterval1,
          pandaHprInterval1,
          pandaPosInterval2,
          pandaHprInterval2)
    # Create and play the sequence that coordinates the intervals.
    self.pandaPace = Sequence(pandaPosInterval1,
                              pandaHprInterval1,
                              pandaPosInterval2,
                              pandaHprInterval2,
                              name="pandaPace")
    self.pandaPace.loop()

That is odd! Hmm… Just to check: when you remove the lerp code and run the program, you say that it doesn’t animate–have you tried waiting about as long as it usually takes for the lerp code to take the object to one end of the arena? I’m wondering whether your animation hasn’t ended up with a long period of motionlessness.

If you try this and find that your model does seem to start animating after a time, perhaps go back to Blender and check the “action” associated with the animation. Specifically, check that you don’t have a gap at the start of the action–between “frame 0” and your first keyframe.

I commented out the lerp code and ran the app, then waited about 15 seconds, the time it took to get from one end to the other, and it just stayed still, I waited about another 10 to 20 seconds on top of that, and it still did nothing.

Also, I checked the keyframes, and the first keyframe is 1 away from 0, assuming the 0 with the numbers at the bottom of the timeline is what you’re talking about.

That’s very strange. Does it also happen with the panda-model that the tutorial by default uses?

Right now, I don’t know what to suggest, offhand. Thus, for the moment I’ll step aside; hopefully someone else will spot the issue! :/

The panda model works as expected, even without the lerp code. Hm…

Well, thank you for taking time out of your day to help me! I appreciate it. :slight_smile:

It’s my pleasure–I’m sorry that I wasn’t of more help! Good luck with figuring out the problem!

I just tried something else. The cube rotating is not due to the animation, but rather the lerping code. I just found out by unspecifying the animation. It still behaves in the same manner.

Ah, right, of course–I managed to completely miss last night that two of those intervals are hpr intervals–that is, intervals that rotate objects. Since your animation is also a rotation, it presumably appeared as though the animation was playing.

In that case, things are rather clearer: your animation isn’t working, I fear.

So, to start with, have you tried viewing your model in PView? If you use PView to open both your model and your animation file at the same time, you should see the animation playing, if it’s working. (If it doesn’t animate immediately, try pressing “a”.)

(If you’re not familiar with PView, an easy way to do this is to just re-export your model and animation from Blender, but this time select “Pview” on the left. This should cause YABEE to automatically show your model and animations in PView once the export has been completed.)

I used the pview command and pressed A and it said no animation. I tried it on two, one I exported as separate files and one that has the animation within the model file. Both of those said no animation.

Interestingly enough, when I export it and have pview selected, then it shows a player bar when I press A, but the cube doesn’t move. On the other hand, if I use pview from the console then and press A, then it tells me no animation.

I’m not sure about the version that has the animations within the model-file, but in the case of separate animation-files note that the animations will only show up if you include them when you view the model. Something like this:

pview myModel.egg myModel-myAnimation.egg

However, if you’re seeing a seek-bar when PView is run by YABEE after an export, that suggests to me that there may be an animation, but that it doesn’t actually have any movement in it.

Hum… at this point, if your Blender file isn’t too big, perhaps you could upload it somewhere for me to examine quickly. That might be quicker than wandering in the dark, guessing at where the problem might lie…

Sure, here. https://ufile.io/d2jfk