those 'create your character' screens

How do you guys go about doing this?
Some time ago I was in Pirates of the Carribean Online, which is written in Panda.
So basically you have some eye models and some ears, noses, hair, some clothes which you add to your character.

How do you guys do this? I mean if my model consists of many unmerged pieces, there is that tiny ‘holes’ effect and wrong lightning because of doubles.

You could use shape keys for that.

Uh…

For what?
Those pieces are separate geometry, its too many to load as 1 file.

Pirates does indeed use shape keys to change the shape of your eyes, ears, nose, and so on. They’re not separate pieces.

But other parts are separate pieces: hair, hats, coats, and such. There are different approaches for switching these out. One approach is to expose joints at runtime and parent the pieces to those joints, like the “looking and gripping” tutorial. This is easiest when the pieces are rigid, but it’s also possible with animated pieces, as long as you play the same animation at the same time. Another approach is to add all of these pieces to your avatar at once, in your modeling package; and just hide the pieces you don’t want to see at runtime.

David

Well for my purpose I’m afraid shapekeys are not an option. The body parts must be separate geometry ina separate egg files. and players are free to add their own created eggs.
So they must be separate. Also a custom texture is allowed, so again shapekeys arent an option.
I’m not sure but another reason is the pieces can go over 50 each, so a single file might be a bit big to load at once.

OK, I made some sample models to show my problem:
youshare.com/Guest/df35fb5f549dc285.zip.html
the body:

heads:

Now if I simply load them the obvious render artifact will come up from doubles:

Now what do you guys do at this situation?

You know this might be a big problem, if I understood you correctly. What if I want to have hats which in outdoor scenes are ‘influenced by the wind’ but that animation doesnt play in indoor locations? Does it meen I need to play them both at the same time or none at all? Thats one example I can think of.
Does this also mean that the head models can’t have weights which are used by bones in the ‘body’ model? I have bones on the body model (the main model) which also has bones for the face. Ive seen this done in other games, is it possible with Panda?

hm… what you could do, is writing a python script which fixes your vertex-normals after the export is done. which would at least fix your rendering artifacts. only a 3rd class workaround,tho

That sounds like a difficult one. I thought panda would have something like recalculateNormals function, don’t know if thats something the game engine should handle, but I’m sure if seen it in some games…
So what am I supposed to do. How to calculate the normal??

PS. I just played Pirates again and I see the hair is animated when you walk. Its attached to a joint, right? So what did you meen?

I don’t know why your pieces have to be in separate files. We have a pirates model that has hundreds of pieces in it. No problem.

You can’t easily recalculate the normals after the model has been loaded, but you can precalculate them by processing the egg file. You’ll have to write the code to do this, though. Or you can set them correctly in your modeling package in the first place (for instance by smoothing the normals while the entire head is available, then deleting the part of the head that you don’t want to keep).

As I said, separate pieces, like hair, can still be animated. It’s got the same skeleton as the main model; it’s just loaded up and parented to the same node at runtime. You can also apply a secondary animation to the hat or whatever; it’s the same thing as applying a secondary animation to your main model.

David

Again the game is moddable and people are free to drag and drop their model to the ‘head’ folder, on next startup it will be added to the list.
If you say memory isnt a problem than this is pretty much the only reason.

I guess this is the only one I can manage.

I hope Blender can handle this. Anyone here using Blender who can help me on this?

Sorry this part got me abit confused:

‘same animation at the same time’?
If you meen I can deform a piece with a bone from the parent piece, then what to play ‘at the same time’?

No, I mean that when you construct, say, a “walk” animation for your person, you also construct a “walk” animation for the hat at the same time that matches the walk cycle exactly.

Then when you want your hat-wearing person to walk, you play the “walk” animation you made for the person at the same time you pay the “walk” animation you made for the hat. Since you made them at the same time, and they were in sync when you made them, they will still be in sync when you play them back.

David

So if I have a node “Player”, node “Hat” which is attached to a joint of “Player”, I type

Player = Actor("player",{"walk":"walk"})
Player.loop("walk")

?
or do I also have to do

Hat.loop("walk")

at the same time?

Yes, you have to loop both of them at the same time.

David

Okay.
But what if I want a bone from “Player” to animate any model loaded as “Hat” which have weights? Possible?
I thought it would because can’t you have an animation for the ‘joint’ bone as well?

I’m not completely sure what you’re asking, but there are lots of ways to solve these kinds of problems.

At the most general, you can completely replicate the entire skeleton of your Player for the Hat model. Even though the Hat doesn’t have arms or legs, it can still have the arms and legs joints from your Player model (or rather, identically-named and -structured joints). Then, when you animate the walk cycle for your Player, apply the same animation to your Hat. You can do this because it has the same skeleton. Since the complete skeleton is available to the Hat model, you can have whatever weighting you need. In this case, you would parent the Hat to the same node you parent your Player to, and not to an exposed joint of the Player, because the Hat already has all of the animation it needs.

I don’t know whether you actually need to replicate the skeleton for the Hat. It’s up to you and precisely what you want your Hat to do.

David

Is this why you said I need to ‘play them at the same time’? Well it is the easiest solution, thanks for the info, but I’m afraid thats impossible for my purpose. Again, the game is going to be moddable and telling people to include the whole skeleton for each hair, clothes, accessories they create will be very tedious and unclean sort of.

And I can’t have weights if I attach it to an animated joint instead?

Okay, maybe this is too much of questions. I’ll make a demo skeleton for the avatar, add hair to it, make an animation for the hair bones then separate the hair vertices. Then I’ll load them both in Panda3d and attach the hair piece to the avatar and rrun the hair bones animation and see if it works. Sorry I was probaby too lazy to try this…

Okay, I tried. Here are the bones:

The hair bones are part of the skeleton of the avatar. I dont want the ‘hair’ to have bones, just weights.
The animation I’m aiming for:

The one I get if I just expose the joint and reparent the hair piece to it:

The code:

import direct.directbase.DirectStart
from direct.actor.Actor import Actor
from pandac.PandaModules import *

# lights, not important
dlight = DirectionalLight('dlight')
dlight.setColor(VBase4(0.7, 0.7, 0.7, 1))
dlnp = render.attachNewNode(dlight)
render.setLight(dlnp)
alight = AmbientLight('alight')
alight.setColor(VBase4(0.7, 0.7, 0.7, 1))
alnp = render.attachNewNode(alight)
render.setLight(alnp)


# avatar model
avatar = Actor("avatar/avatar", {'idle' : "avatar/avatar-idle"})
avatar.reparentTo(render)
avatar.loop('idle')
	
#Now we will expose the joint the hair joint. ExposeJoint allows us to
#get the position of a joint while it is animating. This is different than
#controlJonit which stops that joint from animating but lets us move it.
#This is particularly usefull for putting an object (like a weapon) in an
#actor's hand, or for hair
head = avatar.exposeJoint(None, 'modelRoot', 'hair')

# now we load the hair model and reparent it to the head bone (joint)
hair = loader.loadModel('avatar/hair')
hair.reparentTo(head)


run()

The project archive:
youshare.com/Guest/ca2a47c4f5fd3ba8.zip.html

The inherited weird orientation left aside, with this method you are simply reparenting nodes in Panda, even though the hair piece has weights, it will of course be ignored this way.

I’ll try again: What I want is to have the hair bones on the skeleton of ‘avatar’ model, and have only weights on all ‘hair’ models. Is that even possible, techincally?

No. You need to have bones in your hair, too. The same bones. Then you have to load the hair as an Actor, a separate Actor from the model.

David

Okay…

Is this because of the way 3d formats store data?