Q: Why wont my Skeleton's head turn?

Discuss CSQC related programming.
Post Reply
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Q: Why wont my Skeleton's head turn?

Post by OneManClan »

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");
	}

	
}
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

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

Post by toneddu2000 »

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
Meadow Fun!! - my first commercial game, made with FTEQW game engine
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

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

Post by OneManClan »

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: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

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

Post by OneManClan »

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);
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

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

Post by toneddu2000 »

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
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Post Reply