# Changing Actor Geometry on the Fly

Is there a way to swap out geometry (model) used for an Actor for another Geometry (model) and keep the same animations?

You can always swap out a completely different Actor that happens to have the same animations loaded.

David

But how?

self.MyActor = Actor("actor model 1 path", {animations});

If you wanted to swap the Actor’s model; that is, change the “actor model 1 path” to “actor model 2 path” and still use self.MyActor with everything else in place… How would you do that?

self.MyActor = Actor("actor model 2 path", {animations});

Would I just over write it like that? If so, what happens to the first data that was loaded? Will it be stuck in memory?

No, just create two Actors, and change them out in the scene graph:

self.MyActor1.hide()
self.MyActor2.show()

Or, if you don’t like hide and show and you want to completely replace the node, do something like this:

self.MyActor1.detachNode()
self.MyActor2.reparentTo(render)
self.MyActor2.setTransform(self.MyActor1.getTransform())

Or, if this is going to be a permanent change, and you don’t need to keep around the original Actor, you can replace it in your class:

transform = self.MyActor.getTransform()
self.MyActor.delete()
self.MyActor = Actor(...)
self.MyActor.reparentTo(render)
self.MyActor.setTransform(transform)

In these code snippets, I’m preserving the “transform”, which is the position and rotation of the original node. Presumably you’ll also want to preserve the currently playing animation and its current frame. I leave that part of it to you.

David

The problem with that logic is the fact you most likely will have collision nodes attached to your Actor.

When I said change Geometry, I mean just that; changing the geometry and keeping all animations and collisions for an actor intact.

In other words, I don’t want to change the Actor, just the look of the geometry, by swapping it with another model, on the fly.

I’m guessing this wasn’t thought of in the original P3D creation.

If P3D ever gets a make over, how about using dot syntax for accessing sub level objects?

Actor.Pants.setMaterial("")
Actor.Hat.setScale(1,5,8)
Actor.Hair.setTexture("", 1)
Actor.setTextureStage(ts0, text0)
Actor.Guantlets.setTextureStage(ts, tex);

My God… If that ever happend to P3D, I wouldn’t know how to react.

I’m use to engines having dot syntax style when accessing sub ojects, so it’s going to be hard for me to adapt to P3D that doesn’t use it (or have it build in).

I think I know what you’re doing with the getTransform though. You’re using the second Actor as visible geometry, while the original is still animating, but hidden. That could work, but a bit rough around the edges.

I don’t think it’s necessarily a common thing to have collision nodes directly attached to an Actor. I’ve never done it this way, though you’re right it’s a possible way to do it.

If you mean you have an avatar, which is represented by an Actor visually, and which also has collision geometry, I think it makes more sense to have a single common node for the avatar, then attach both your collision geometry and the Actor to that common node. That way you can easily replace out the Actor (which is after all just geometry) with a different Actor, without affecting your collision geometry or anything else. (And this way you wouldn’t even have to mess around with the transform, because your Actor wouldn’t have a local transform at all–it would be on the root node.)

This is the whole point of a scene-graph based system: the scene graph is a tool to manage the state of your different objects. To take the most advantage of a scene graph, you have to structure it according to the way you wish to change things.

If you really want to replace out just the geometry within the Actor, while keeping the same Actor instance for some reason, that is also possible, but it’s much more complicated so I wouldn’t recommend it unless you really have a good reason to do that.

David

One question -

When using setTransform(), should the geometry getting the transform values be another Actor? I’m guessing yes, because I’m guessing the vertices have to match up, correct?

I imagine P3D would crash if an Actor’s Transform was set to a Model that was lets say, a block, instead of another Actor of equal geometry.

When using setTransform(), should the geometry getting the transform values be another Actor? I'm guessing yes, because I'm guessing the vertices have to match up, correct?

No, it doesn’t matter. It’s just a transform matrix, not the placement of vertices or whatnot.

So the best way to create an actor is to create a PandaNode, then attach every part of the Actor to the PandaNode as individual pieces; like the boots, hat, body, ect. Then I guess you could address each piece without changing the other ones, but the problem is, only objects exported with an Actor will transformed by the skeleton/animation data.

Panda3D just doesn’t open up a lot of doors for you on some things, so you’re left out in the cold.

I don’t know what you mean. Of course there are lots of different things you might want to do with an Actor, but in general the best way to create an Actor is to model everything in your animation package and load it up with the Actor class. Bam, you’re done.

If you’re designing an Actor with lots of interchangeable clothing, this is a bit different than a conventional Actor that you just load and forget. There are lots of approaches people have used for interchangeable clothing, and we can talk about some of those if that’s what you’re interested in.

If there’s some other problem you’re trying to solve, you should let us know what it is–there’s no way we can give you useful advice if we don’t know what you’re talking about.

You say this sort of thing a lot. It seems a bit huffy, but maybe that’s unintentional and you’re just not aware of the vibe you’re giving off. I’m trying to help you learn how to use Panda. If you feel that Panda is not the engine for you, let us not keep you from finding the engine out there that is.

David

Well said David. I was just about to state that myself, but you beat me to it