Jump to content
Eternal Lands Official Forums
Sign in to follow this  
Schmurk

Useful actors and bones functions...

Recommended Posts

Hi all!

 

For the missiles needs, I've developed some functions to handle bones and some actor properties. However, I'm quite sure that for some of these functions, equivalent ones already exists somewhere in the client code. Moreover, I've just corrected a bug in the eye candy module by using some of my functions which are for the moment nested in my module. So the point is that it should be good to place these functions in a place that would be more appropriate.

 

The function I'm referring to are the following ones (in my code):

  • * get_actor_z: gets the Z position of an actor according to the height map
    * get_actor_rotation_matrix: computes the rotation matrix of a char
    * get_actor_bone_local_position: get the local position of an actor bone (without actor rotation and translation)
    * get_actor_bone_absolute_position: get the absolute position of an actor bone (after actor rotation and translation)
    * transform_actor_local_position_to_absolute: convert a local position to an absolute position according to the actor rotation matrix and position

I know that Karen is using similar functions for bones positions so maybe we could decide a place where to put them in order to share them. We can maybe put them in actors.* files or in a new file?

 

If you have any ideas/suggestions about this, please submit them...

Share this post


Link to post
Share on other sites

cal_aux.c seems good to me because the actual cal.c file is more animation oriented.

So we can put for example actors related functions in actors.c (like get_actor_z and get_actor_rotation_matrix) and all other functions related to bones maniputation into cal_aux.c

Share this post


Link to post
Share on other sites

Could you also add a universal

rotate_bone(int point1, int point2, float degrees, float duration)

function which rotates the bone between skeleton point1 and skeleton point2 by x degrees in y seconds?

Share this post


Link to post
Share on other sites

Could you also add a universal

rotate_bone(int point1, int point2, float degrees, float duration)

function which rotates the bone between skeleton point1 and skeleton point2 by x degrees in y seconds?

Hum I can do such a thing but it requires a new actor command and maybe some other parameters that have to be stored in the actor struct. It will also need a system seperated from the missiles system in order to do it.

 

BTW, I don't really understand what you mean by rotate the bone between 2 points by x degree? can you explain it a little more or do a drawing please?

 

Anyway, the functions I've told about in my first post are now split in actors.* and cal.* files. And the weapon glowing bug in the eye candy is fixed.

Share this post


Link to post
Share on other sites

From an older version of missiles.c:

void rotate_actor_bones(actor *a)
{
struct CalSkeleton *skel;
struct CalBone *bone[2];
struct CalQuaternion *rot[2];
struct CalQuaternion *tmp;

if (a->cal_rotation_blend < 0.0)
	return;

skel = CalModel_GetSkeleton(a->calmodel);

bone[0] = CalSkeleton_GetBone(skel, 11);
bone[1] = CalSkeleton_GetBone(skel, 12);

rot[0] = CalBone_GetRotation(bone[0]);
rot[1] = CalBone_GetRotation(bone[1]);

tmp = CalQuaternion_New();

 

Maybe I don't understand that code, but to me it looks like you get the bone between the skeleton points 11 and 12.

http://www.superfloh.dyndns.org/el/bones.jpg

The bone in the lower torso.

 

I'd like to have a function to rotate bones to do some of the things discussed here http://www.eternal-lands.com/forum/index.php?showtopic=39727

 

No new animations and server side commands are needed if those bone rotations are only done when the actor is currently not in an animation. (flickering or jerky movements may occur when the actor with a raised arm enters some animation ...)

 

And the weapon glowing bug in the eye candy is fixed.

 

Great :blush:

I'll start working on all the other effects right away. Expect a patch in a few days :D

Edited by Florian

Share this post


Link to post
Share on other sites

No, in fact I was taking bones 11 and 12 to rotate both of them.

 

In reality, the bones are not the lines you're seeing on the skeleton between 2 points. The bones are the points.

The lines are just showing the parent/child links, that's all.

 

All bones have a position and an orientation. I said that I'll change the skeleton display to show the orientation of the bones but I didn't do it yet. However, I'll do it soon...

 

Anyway, if you want to change the position of a bone, you have two things to specify: its new postion and it's new orientation.

 

There are 2 ways to express the orientation change for a bone:

- a vector that will be used as an axis and an angle around this axis

- a starting vector and a ending vector from which we can compute the rotation axis and angle

 

Then to apply these rotations correctly, a system is needed to maintain the rotations (rotations are applied each time the char is drawn on the screen) and to progressivley change them in order to obtain an animation. This is what I'm doing for missiles but if you want to use that for emotes are something like this, we need to have a new system and the best is to specialize each emotes cause it'll be hard to have a general system that does that as most of the time, you'll have to rotate several bones at the same time and with different angles...

 

Take a look at the new code I've done to rotate char torso bones and cape bones and you'll understand what I mean... And the code is not finished yet as I'll also have to take in account the crossbow for which some rotations are different.

Share this post


Link to post
Share on other sites

I've just updated the display of the skeleton in debug mode and now it looks like that:

 

skeletonxv7.jpg

 

BTW, it could be nice if someone could add an option to enable or not the display of bones orientations... :D

Share this post


Link to post
Share on other sites

 

Then to apply these rotations correctly, a system is needed to maintain the rotations (rotations are applied each time the char is drawn on the screen) and to progressivley change them in order to obtain an animation. This is what I'm doing for missiles but if you want to use that for emotes are something like this, we need to have a new system and the best is to specialize each emotes cause it'll be hard to have a general system that does that as most of the time, you'll have to rotate several bones at the same time and with different angles...

 

 

I didnt go through the code in deep, and stop me if i'm saying nonsense, but what about a general system for moving bones based on some simple grammar? Something like a string "Bn[xn,yn,zn,wn,t1,t2]Bm[xm,ym,zm,wm,t1,t3]" that can be "compiled" in a simple animation that moves Bone n by quaternion (xn,yn,zn,wn) from time t1 to time t2, and Bone m by a different quaternion from time t1 to time t3...maybe the result of compilation can be a CalAnimation struct to feed to the CalMixer...This way every emotes can be encoded in a few bytes without dedicated code.

Share this post


Link to post
Share on other sites

Sure, we can make a system that would be configurable with little scripts. However, I don't think we can use CalAnimation for emotes but maybe I'm wrong (I'm not a cal export after all). I guess that a CalAnimation must define the rotations for all the bones of the actor. So we can't move or rotate just a part of the model like an arm for example.

 

So unless I'm wrong and Cal is already able to do that, I think we need a system that will be close to what I've already done in my code and that allows to fade from the current state of an actor part to a new state.

Share this post


Link to post
Share on other sites

However, I don't think we can use CalAnimation for emotes but maybe I'm wrong (I'm not a cal export after all). I guess that a CalAnimation must define the rotations for all the bones of the actor. So we can't move or rotate just a part of the model like an arm for example.

 

According to my poor knowledge of Cal3d gained here, a CalAnimation (loaded from .caf files) contains data for moving bones only, so various CalAnimations can be blended by the CalMixer. I dont know how to create a CalAnimation struct and fill it (apart by loading a .caf), in order to test cal3d functionalities. Any clues? Can you point me to relevant code? Tnx :fire:

Share this post


Link to post
Share on other sites

To build an animation from scratch, you have to use the functions defined in the cal3d_wrapper.h file and follow the Cal3d online documentation which is unfortunately very poor :fire:

But if the goal is to make animations, I think the best is to ask Roja to do them with blender. It'll be much better.

 

Anyway, when we look at the doc, we can see that the mixer has a function to start an action that will override only part of the bones of the current animation so this is the key to do emotes. However, the actual client code does not allow to override an action by another one so if we want to do that, we need first to modify the part of the code that is dealing with animations...

Share this post


Link to post
Share on other sites

So we can't move or rotate just a part of the model like an arm for example.

Stupid question: isn't that what you're doing to rotate the actor's torso to aim at things? All bones connected to the torso also move. So, if we rotate the arm bone or shoulder bone, the whole arm and hand and weapon should also move, right?

Share this post


Link to post
Share on other sites

Yes, this is what I'm doing and this is why I'm not using the standard animation system. The thing is that I don't need to just apply the rotations once in order it works, I have to apply the rotations each time the actor is displayed or else the rotations are lost.

Share this post


Link to post
Share on other sites

Yes, this is what I'm doing and this is why I'm not using the standard animation system. The thing is that I don't need to just apply the rotations once in order it works, I have to apply the rotations each time the actor is displayed or else the rotations are lost.

Hmm, I imagened the data structures to be "a little" different.

OK, now I see your point why it's not that easy.

Share this post


Link to post
Share on other sites

I've just noticed that the names Roja has defined for each bones are stored in the skeleton data structure and that we can access to them and even find a bone ID by its name. This can be very useful for all features which are interacting with cal3d models like actors banners, eye candy, missiles and maybe some others. With such a thing, we can get rid of all bones ID problems by using names instead.

 

However, searching a bone by its name in a skeleton can be time consuming so I think we should store the most important bones ID directly in the actor_types structure upon actor load.

For the moment, I'm thinking of the following bones that can be useful:

  • head
  • torso bones
  • cape bones
  • left/right hands
  • weapon
  • shield
  • arrow

If nobody is against this idea, I'll try to work on that. And if you think of other bones ID that should be stored, please tell me...

 

@Roja: I've spotted another problem by doing this. The bones names are not always the same in all models. The root bone is present everywhere, the head almost everywhere (but not for spiders) and for the torso, it's called differently in all models. Would it be possible to have something more consistent? Or at least speak about it to sort out all the useful bones names for every skeletons... thx in advance

 

EDIT: here is the list of skeletons that are loaded by the client with the correspondence between bones names and IDs.

Edited by Schmurk

Share this post


Link to post
Share on other sites

Thank you for the screenshots Roja, they helped me a lot! :cry:

 

So, I've put in place a new skeleton data structure that holds IDs of main used bones in the client for each skeleton (17 in total). These skeletons are setup upon load and each actor_types structure now points to one of these skeletons.

 

To use it, it's very easy, just have a look at the skeletons.h file. I've started to use it in the missiles code and also in the eye candy code for the weapon position. If someone knows some other places where bones are used, he can change them too and from now, it should be nice if all bones access pass by this structure. It'll avoid some problems with IDs which are rarely the same for all skeletons.

 

Anyway, please report me if you find any bug...

Share this post


Link to post
Share on other sites

Added.

But be careful, the position of the bone defines the wrist of the char so if you want to find a position that is inside the hand, you have to add a shift or use a weapon bone instead.

Share this post


Link to post
Share on other sites

Added.

But be careful, the position of the bone defines the wrist of the char so if you want to find a position that is inside the hand, you have to add a shift or use a weapon bone instead.

Thanks. I think the wrist is absolutely acceptable for spells.

 

Am I right that body and head are defined for every skeleton? That would be great to have a default fallback.

Share this post


Link to post
Share on other sites
Am I right that body and head are defined for every skeleton? That would be great to have a default fallback.

It's the goal :icon13:

The only bones that are not defined for all skeletons are human/monsters specific ones like hands, weapons, cape.

But you have at least head, mouth, body_top, body_bottom for all the others. For more detail, you can have a look at Roja's screenshots and at the code in the skeleton.c

Share this post


Link to post
Share on other sites

It would be nice to have a "maxz-bone", the highest bone in the skeleton. This way the cal_get_maxz function could be defined easily and the banners will always been shown in the right position. I used the head bone to solve the issue, but it is not working well for spiders.

Share this post


Link to post
Share on other sites

I've added a highest_bone in the skeleton but I didn't take in account the ears of animals. So most of the time, this bone corresponds to the head, the neck or the top body. If you can test it to see if it works, it would be great. If it doesn't work, you can also try to change bones in the skeleton.c file and see if there are better ones.

 

Anyway, I just had a quick look at the banner code and I think the problem is more complex (I hope to be wrong on this one). The code is using the bounding box max_z but this value seems to be computed with cal_get_maxz at another place of the code. So I think that we should try to better understand all what is done here...

At the same time, I don't know how the objects under mouse are found but I bet that it uses bounding boxes to help and for some actors like birds, this is not working anymore (we can't attack them). So it could be nice to also look at that too...

Share this post


Link to post
Share on other sites

Highest_bone works nicely. You are right about the bounding box problem. I modified draw_actor to display the boundibox of monsters and it seems that for birds the height from ground is not added (the bounding box moves on the ground under them).

 

I tried to figure out where the height is set and i saw a couple of lines like this:

 

 

z_pos=actor->tmp.z_pos;

.

.

.

if(z_pos==0.0f)//actor is walking, as opposed to flying, get the height underneath

z_pos=-2.2f+height_map[actor_id->tmp.y_tile_pos*tile_map_size_x*6+actor_id->tmp.x_tile_pos]*0.2f;

 

 

however a printf before and after shows that z_pos is always 0 for every monster, even for birds. Maybe the bbox is calculated in a space before the height translation (cal3d functions are undocumented)? Any ideas?

 

I noticed that my cal_get_maxz works on CalSkeleton and CalBone functions, while build_actor_bounding_box uses CalCoreSkeleton and CalCoreBone...what is the difference exactly?

 

Still investigating...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×