ok, a bit more work, i've come up with this

moves around the biggest angle and calculates the scale for the other angles

Code:
#include <acknex.h>
#include <default.c>


#define bone_pan skill1
#define bone_tilt skill2
#define bone_roll skill3


STRING* str_model = "dummy_man.mdl";
STRING* str_bone = "waist";

//rotate angle by
void bone_rotate(ENTITY* ent, ANGLE* ang_temp){
	
	ANGLE ang_target;
	
	vec_set(ang_target, ent.bone_pan); //current bone position
	vec_add(ang_target, ang_temp);
	
	int int_maxpivot = 0;
	
	//find which is moving the most
	if(abs(ang_temp.pan) > abs(ang_temp.tilt)){
		
		if(abs(ang_temp.pan) > abs(ang_temp.roll)){
			
			int_maxpivot = 1; //biggest is pan
		}else{
			
			int_maxpivot = 3; //biggest is roll
		}
	}else{
		
		if(abs(ang_temp.tilt) > abs(ang_temp.roll)){
			
			int_maxpivot = 2; //biggest is tilt
		}else{
			
			int_maxpivot = 3; //biggest is roll
		}
	}
	
	var var_pandiff = 1;
	var var_tiltdiff = 1;
	var var_rolldiff = 1;
	
	//calculate percentages based on biggest pivot
	switch(int_maxpivot){
		
		case 1: //pan
			var_tiltdiff = ang_temp.tilt / ang_temp.pan;
			var_rolldiff = ang_temp.roll / ang_temp.pan;
		break;
		
		case 2: //tilt
			var_pandiff = ang_temp.pan / ang_temp.tilt;
			var_rolldiff = ang_temp.roll / ang_temp.tilt;
		break;
		
		case 3: //roll
			var_pandiff = ang_temp.pan / ang_temp.roll;
			var_tiltdiff = ang_temp.tilt / ang_temp.roll;
		break;
	}
	
	
	while(ent.bone_pan != ang_target.pan){
		
		if(ent.bone_pan < ang_target.pan){
			
			ent.bone_pan = minv(ent.bone_pan + (1 * var_pandiff * time_step), ang_target.pan);
			
		}else{
			
			ent.bone_pan = maxv(ent.bone_pan - (1 * var_pandiff * time_step), ang_target.pan);
		}
		
		if(ent.bone_tilt < ang_target.tilt){
			
			ent.bone_tilt = minv(ent.bone_tilt + (1 * var_tiltdiff * time_step), ang_target.tilt);
			
		}else{
			
			ent.bone_tilt = maxv(ent.bone_tilt - (1 * var_tiltdiff * time_step), ang_target.tilt);
		}
		
		if(ent.bone_roll < ang_target.roll){
			
			ent.bone_roll = minv(ent.bone_roll + (1 * var_rolldiff * time_step), ang_target.roll);
			
		}else{
			
			ent.bone_roll = maxv(ent.bone_roll - (1 * var_rolldiff * time_step), ang_target.roll);
		}
		
		ent_bonereset(ent, str_bone);
		ent_bonerotate(ent, str_bone, ent.bone_pan);
		wait(1);
	}
}


//rotate angle to
void bone_rotate_to(ENTITY* ent, ANGLE* ang_temp){
	
	ANGLE ang_target;
	
//	vec_set(ang_target, ent.bone_pan); //current bone position
//	vec_add(ang_target, ang_temp);
	
	vec_set(ang_target, ang_temp);
	
	int int_maxpivot = 0;
	
	//find which is moving the most
	if(abs(ang_temp.pan) > abs(ang_temp.tilt)){
		
		if(abs(ang_temp.pan) > abs(ang_temp.roll)){
			
			int_maxpivot = 1; //biggest is pan
		}else{
			
			int_maxpivot = 3; //biggest is roll
		}
	}else{
		
		if(abs(ang_temp.tilt) > abs(ang_temp.roll)){
			
			int_maxpivot = 2; //biggest is tilt
		}else{
			
			int_maxpivot = 3; //biggest is roll
		}
	}
	
	var var_pandiff = 1;
	var var_tiltdiff = 1;
	var var_rolldiff = 1;
	
	//calculate percentages based on biggest pivot
	switch(int_maxpivot){
		
		case 1: //pan
			var_tiltdiff = ang_temp.tilt / ang_temp.pan;
			var_rolldiff = ang_temp.roll / ang_temp.pan;
		break;
		
		case 2: //tilt
			var_pandiff = ang_temp.pan / ang_temp.tilt;
			var_rolldiff = ang_temp.roll / ang_temp.tilt;
		break;
		
		case 3: //roll
			var_pandiff = ang_temp.pan / ang_temp.roll;
			var_tiltdiff = ang_temp.tilt / ang_temp.roll;
		break;
	}
	
	
	while(ent.bone_pan != ang_target.pan){
		
		if(ent.bone_pan < ang_target.pan){
			
			ent.bone_pan = minv(ent.bone_pan + (1 * var_pandiff * time_step), ang_target.pan);
			
		}else{
			
			ent.bone_pan = maxv(ent.bone_pan - (1 * var_pandiff * time_step), ang_target.pan);
		}
		
		if(ent.bone_tilt < ang_target.tilt){
			
			ent.bone_tilt = minv(ent.bone_tilt + (1 * var_tiltdiff * time_step), ang_target.tilt);
			
		}else{
			
			ent.bone_tilt = maxv(ent.bone_tilt - (1 * var_tiltdiff * time_step), ang_target.tilt);
		}
		
		if(ent.bone_roll < ang_target.roll){
			
			ent.bone_roll = minv(ent.bone_roll + (1 * var_rolldiff * time_step), ang_target.roll);
			
		}else{
			
			ent.bone_roll = maxv(ent.bone_roll - (1 * var_rolldiff * time_step), ang_target.roll);
		}
		
		ent_bonereset(ent, str_bone);
		ent_bonerotate(ent, str_bone, ent.bone_pan);
		wait(1);
	}
}


void main(){
	
	wait(1);
	
	level_load(NULL);
	
	me = ent_create(str_model, vector(150, 0, 0), NULL);
	
	vec_set(my.bone_pan, vector(45, 0, 0));
	ent_bonerotate(me, str_bone, my.bone_pan);
	
//	bone_rotate(me, vector(90, 0, 0));
	bone_rotate_to(me, vector(90, 0, 0));
}

change the strings at the top for the entity and bone you want to spawn and move,

ent_rotate() will rotate the bone that distance,
ent_rotate_to() will rotate the bone to that angle,

hopefully linear interpolation is enough, have a look at the cinematic swooping camera if you wanted polynomial interpolation

hope this helps


*No consideration for negative numbers or use of ang()*

Last edited by MrGuest; 02/15/10 01:03.