1 registered members (AndrewAMD),
945
guests, and 8
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Copy bone anim script: Euler trouble
#465218
04/12/17 19:12
04/12/17 19:12
|
Joined: Sep 2003
Posts: 6,861 Kiel (Germany)
Superku
OP
Senior Expert
|
OP
Senior Expert
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
|
Hello! Every now and then I need to copy the current bones animation of one entity to that of a "clone" entity. Therefore I've written a basic script which tries to do so, yet a few bones are rotating weirdly at some points in the animation. Either there's something wrong with my code/ concept or it's an Euler angle issue - hate those! The script:
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
MATERIAL* anim_copy_mat =
{
effect = "anim_copy_mat.fx";
flags = AUTORELOAD;
}
void ent_anim_copy(ENTITY* eTarget, ENTITY* eSource)
{
int i,numBones,hparent;
ANGLE angle,angle2,angle3,eSourceOldPan;
numBones = ent_bones(eSource);
ent_bonereset_all(eTarget);
vec_set(&eSourceOldPan,&(eSource->pan));
vec_set(&(eSource->pan),nullvector); // ang_for_bone returns global angles
for(i = 0; i < numBones; i++)
{
ang_for_bone(&angle,eSource,i+1); // use bone handles/ indices instead of names
hparent = ent_boneparent(eSource,NULL,i+1);
if(hparent > 0)
{
ang_for_bone(&angle2,eSource,hparent); // eTarget's bone is already rotated by parent bone's rotation => undo it!
ang_diff(&angle3,nullvector,&angle2); // best way to do this? I doubt it.
ang_add(&angle,&angle3);
}
ent_bonerotate(eTarget,i+1,&angle);
}
vec_set(&(eSource->pan),&eSourceOldPan);
}
void main()
{
fps_max = 60;
video_mode = 10;
d3d_antialias = 9;
level_load(NULL);
me = ent_create("robot.mdl",vector(450,120,0),NULL);
my.material = anim_copy_mat;
you = ent_create("robot.mdl",vector(450,-120,0),NULL);
your.material = anim_copy_mat;
while(1)
{
my.pan += time_step;
my.skill20 += 10*time_step;
my.skill20 %= 360;
my.skill21 = sinv(my.skill20)*50+50;
ent_animate(me,"bjump",my.skill20,0);
my.skill22 += 30*time_step;
my.skill22 %= 360;
my.skill23 = sinv(my.skill22)*50;
ent_bonerotate(my,"Bone6",vector(0,my.skill23,0));
ent_bonerotate(my,"Bone8",vector(0,-my.skill23,0));
ent_bonerotate(my,"Bone1",vector(my.skill20,0,0));
your.pan = my.pan;
ent_anim_copy(you,me);
time_factor = 1-0.9*key_ctrl;
wait(1);
}
}
If you don't have a lot of things better to do than to give this a try I'd like to hear your thoughts on this. Thanks!
"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual Check out my new game: Pogostuck: Rage With Your Friends
|
|
|
Re: Copy bone anim script: Euler trouble
[Re: alibaba]
#465288
04/15/17 12:59
04/15/17 12:59
|
Joined: Sep 2003
Posts: 6,861 Kiel (Germany)
Superku
OP
Senior Expert
|
OP
Senior Expert
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
|
Alright, thanks for your feedback and testing! However, I noticed a problem with that code, that is temporarily setting eSource's orientation to zero. Subsequent ang_for_bone instructions can fail then, seemingly at random (they take the wrong pan value in consideration). I'm 99% sure I've once read a post by jcl telling someone that he should not change pan multiple times per frame, as some stuff is based on matrices or whatever internally and information can get lost then. I could not find that post anymore though. As a workaround or fix I need a few ang_add() operations sadly (those which add eSourcePanInv):
void ent_anim_copy(ENTITY* eTarget, ENTITY* eSource)
{
int i,numBones,hparent;
ANGLE angle,angle2,angle3,eSourcePanInv;
numBones = ent_bones(eSource);
ent_bonereset_all(eTarget);
ang_diff(&eSourcePanInv,nullvector,&(eSource->pan));
for(i = 0; i < numBones; i++)
{
ang_for_bone(&angle,eSource,i+1); // use bone handles/ indices instead of names
ang_add(&angle,&eSourcePanInv);
hparent = ent_boneparent(eSource,NULL,i+1);
if(hparent > 0)
{
ang_for_bone(&angle2,eSource,hparent); // eTarget's bone is already rotated by parent bone's rotation => undo it!
ang_add(&angle2,&eSourcePanInv);
ang_diff(&angle3,nullvector,&angle2); // best way to do this? I doubt it.
ang_add(&angle,&angle3);
}
ent_bonerotate(eTarget,i+1,&angle);
}
}
"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual Check out my new game: Pogostuck: Rage With Your Friends
|
|
|
|