Forum

Q: Why wont my Skeleton's head turn?

Discuss CSQC related programming.

Moderator: InsideQC Admins

Q: Why wont my Skeleton's head turn?

Postby OneManClan » Tue Jan 03, 2017 10:38 am

Hey people!!

My first foray into the world of Skeletal Animation, and for my first project, I've decided to start with (what I thought would be) the simple task of making a (skeletal) model's head turn to match the players POV. Unfortunately, in spite of all the new code, I cant see any difference. Here's the story so far (this is all CSQC):

1. In CSQC_Init, we intercept the (SSQC) player model

Code: Select all
deltalisten("progs/player.mdl", UpdatePlayer, 0);




2. In UpdatePlayer:

Code: Select all
float(float isnew) UpdatePlayer =
{
       
     setmodel(self, IQM_TEST_BOD);
   
   if(isnew)
   {
      // make the skeleton
      self.skeletonobject = skel_create(self.modelindex);
   
           PrintSkelInfo(); // a diagnostic function which proves the bones are there (see below)
      self.predraw = PlayerPredraw;
         
   }
   
   // trying to make the head spin using a global number. Why? Because since the whole model moves when the player turns, I wasn't sure if the head was moving or not, so this is just a way to get *any* indication that the skel is being rendered
   if(global_float > 360)
      global_float = 0;
   else
      global_float+= 1;
      
   vector a_vec;
   a_vec_x = global_float; //  I tried a_vec_y as well, no diff
   
   
   makevectors(self.angles); // not sure this is even needed
   //makevectors([-self.v_angle_x*0.2, 0, 0]); // copied from toneddu200's (working?) code - no diff

   
   // I suspect this line might be the problem:
skel_set_bone_world (self, 24, self.origin); // 24 is the head bone, proved by PrintSkelInfo()
//skel_set_bone_world (self, 24, v_forward + v_up); no diff


    self.drawmask = 1; // draw self
   
    // is self the local player?
    if (self.entnum == player_localentnum)
            self.renderflags = RF_EXTERNALMODEL; // dont draw it
    else
            self.renderflags = 0;

    return TRUE;
}

And here's the predraw function:
Code: Select all
float () PlayerPredraw =
{
   
   
   skel_build(self.skeletonindex, self, self.modelindex, 0, 23, 25); // 24 is the head bone

    // also tried:
    // skel_build(self.skeletonindex, self, self.modelindex, 0, 24, 24, 1);
   
   
   //self.drawmask = MASK_ENGINE;
   //return TRUE; // cant see the player with this
   return PREDRAW_AUTOADD;
   
   
}


Q: Why cant I see the players head rotating?

Possibility 1. The skel head isn't being rotated. Either skel_set_bone_world is being called incorrectly .. or maybe there's some problem with the way the bones were set up in the (Captn Bubs Quake1 replacement) model, which I exported as an IQM ( download it from here if you want to check it out)

Possibility 2. The head IS being rotated, but something, somewhere else is overriding the info. Or maybe skel_build isn't passing on the info to the head bone.

Possibility 3. The skeleton's animations are not being rendered ie something wrong/missing in PlayerPredraw


Diagnostics do seem to indicate that the head bone is NOT moving (http://pastebin.com/UcDDxMRH)

any response appreciated

OneManClan
ps: the following function PrintSkelInfo() prints all the bones in an IQM, and their parents. Output shows that the bones *are* being read:

Code: Select all
void (entity e) PrintSkelInfo =
{
   string bone_name, parent_name;
   
   // how many bones?
   float num_of_bones = skel_get_numbones(e.skeletonobject);
   
   print(e.classname, " has ", ftos(num_of_bones),  "bones:\n");
   
      
   // print all the bone names
   for(float i = 0; i < num_of_bones; i++)
   {
      bone_name = skel_get_bonename(e.skeletonobject, i);
      parent_name = skel_get_bonename(e.skeletonobject, skel_get_boneparent(e.skeletonobject, i));
      
      
      print(ftos(i), ": ", bone_name, ". Parent: ", parent_name, "\n");
   }

   
}
OneManClan
 
Posts: 243
Joined: Sat Feb 28, 2009 2:38 pm

Re: Q: Why wont my Skeleton's head turn?

Postby toneddu2000 » Tue Jan 03, 2017 10:21 pm

ok, first things first.

1)I'd put RF_EXTERNALMODEL in Init function, no need to define it every time imo
2) my code makevectors([-self.v_angle_x*0.2, 0, 0]); from fteskel works only with skel_mul_bone(s) after it
Did you try my fteskel code? If you try it, you'll see that spine is bending with neck and head, proportionally of 20% respect v_angle (that's why that *0.2)
3) How did you export your iqm model? Blender - iqm exporter? Did you try my iqm blender add on modification? Because, without that modification, bone order is scattered during exporting and fte can't handle the correct hierarchy so, bending the for example bone#20 is not neck and #21 is not head.
4) I also used csqc-only models. Not deltalisten stuff, I don't trust in deltalisten.
5)Make sure if you export correctly v_angle (make a test print) in csqc
6)Take a look at my skeleton creation guide in Blender, just in case

Hope it helps,
cheers
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Q: Why wont my Skeleton's head turn?

Postby OneManClan » Wed Jan 04, 2017 5:25 am

toneddu2000 wrote:Did you try my fteskel code?


Thanks toneddu2000, yes, I've been looking at your code (and trying to understand how it works).

Meanwhile, the reason the head wasn't turning was because I should have been using '.skeletonindex', NOT '.skeletonobject'. Thanks to Spike for spotting the mistake.

I'd mark this as 'solved' but I need to test it further.
OneManClan
 
Posts: 243
Joined: Sat Feb 28, 2009 2:38 pm

Re: Q: Why wont my Skeleton's head turn?

Postby OneManClan » Tue Jan 10, 2017 3:34 am

UPDATE:
It's working!!

Ok, I assumed skel_build() was the 'final step' of the skeletal animation process.. (maybe the word 'build' implied that we had 'made the plans', 'incorporated the changes', and now we 'build').. Anyway, skel_build is in fact the FIRST step. From csqcsysdefs.qc:
Animation data (according to the entity's frame info) is pulled from the specified model and blended into the specified skeletal object.


So (IIUC) skel_build:
float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addfrac) skel_build = #264;


1. finds the relevant skeletal object ('float skel')
2. assigns 'entity ent' as 'the entity we are affecting'
3. accesses the 'float modelindex' (the iqms) current pose,
2. retrieves the info (from the IQM) as to what the next pose is
3. selects the area (the float firstbone <-> float lastbone bone range) which is about to be affected
4. moves the joints 'float addfrac' percent

THEN we do the extra stuff (like making the head spin) [disclaimer: IIUC!! :) ]

Still trying to figure out how to use 'float retainfrac' ( "if set to 0 on the first call and 1 on the others, you can blend multiple animations together according to the addfrac value."), but anyway, this code makes the players head spin!

Code: Select all
float global_float;
vector global_theneck;

// replace mdls with iqms
// 'self' is the entity which is using the model
float(float isnew) UpdatePlayer =
{
       
     setmodel(self, IQM_TEST_BOD);
   
   if(isnew)
   {
         
      // make the skeleton, runs once
      self.skeletonindex = skel_create(self.modelindex);

global_theneck = skel_get_bonerel(self.skeletonindex, 24);
      
         
   }
   
   // runs every frame - this is the FIRST thing to do
skel_build(self.skeletonindex, self, self.modelindex, 0, 0, 0, 1);
   
   
   
   if(global_float > 360)
      global_float = 0;
   else
      global_float+= 2;
      
         vector a_vec = global_theneck;
   a_vec_y += global_float * frametime;
      a_vec_x = global_float;
   a_vec_z = 0;

   makevectors( a_vec);
// credit eukara for the example upon which this is based
   skel_mul_bone(self.skeletonindex, skel_find_bone(self.skeletonindex, "Head"), '0 0 0', v_forward, v_right, v_up);
OneManClan
 
Posts: 243
Joined: Sat Feb 28, 2009 2:38 pm

Re: Q: Why wont my Skeleton's head turn?

Postby toneddu2000 » Wed Jan 11, 2017 5:43 pm

cool man! Keep it up! If you discover how to use addfrac/retainfrac let us know. In fteskel and projectUnknown only thing I couldn't add was smoothing transition between frame and frame2
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy


Return to CSQC Programming

Who is online

Users browsing this forum: No registered users and 1 guest