random unedited code splurge.
csqc defs/builtins:
http://triptohell.info/moodles/fteqcc/fteextensions.qc
csqc code. make some console command to invoke test2 or something.
Code: Select all
//keep the ragdoll object updated.
static void() rag_predraw =
{
#if 1
if (!self.animobject)
{
self.animobject = skel_create(self.modelindex);
skel_build(self.animobject, self, self.modelindex, 0, 0, 0, 1);
}
#else
skel_build(self.skeletonindex, self, self.modelindex, 0, 0, 0, 1);
#endif
skel_ragupdate(self, "", self.animobject);
};
//spawn a ragdoll
void() test2 =
{
local entity e;
e = spawn();
e.movetype = MOVETYPE_NONE;
e.solid = SOLID_NOT;
e.owner = world;
e.angles = [0, 0, 0];
e.angles_x *= -1;
e.mass = 10;
e.drawmask = MASK_NORMAL;
e.predraw = rag_predraw;
e.alpha = 0.9;
setmodel(e, "models/player/erebus.iqm");
setsize(self, VEC_HULL_MIN, VEC_HULL_MAX);
setorigin(e, vieworg);
e.skeletonindex = skel_create(e.modelindex);
skel_build(e.skeletonindex, e, e.modelindex, 0, 0, 0, 1);
skel_ragupdate(e, "doll test.doll", e.animobject);
skel_ragupdate(e, "animate 0", e.animobject);
};
models/player/erebus.iqm is from xonotic. extract it yourself.
models/player/erebus.doll
Code: Select all
//see skeletal.txt (http://fteqw.svn.sourceforge.net/viewvc/fteqw/trunk/specs/skeletal.txt) for info on this file format.
updatejoint default
type hinge
draw 0
offset 0 0 0
lostop -0.1
histop 0.1
axis 0
erp 0.2
cfm 0.001
lostop2 -0.5
histop2 0.5
axis2
erp2 0.2
cfm2 0.001
updatebody default
shape box
draw 0
animate 1
mass 1
//main body... ish.
body torso master
shape sphere
mass 2
//glue the torso in place.
//joint glue torso
// type hinge
body head "head"
shape sphere
joint head head torso
pivot "neck"
type universal
lostop -0.5
histop 0.5
lostop2 -2
histop2 2
//joint glue head
// type point
//let the legs bend backwards a little
updatejoint default
lostop -2
histop 0.1
//left leg
body uleg.l upperleg_L
// orient
body lleg.l lowerleg_L
// orient
body foot.l foot_L
// orient
size 2
//right leg
body uleg.r upperleg_R
// orient
body lleg.r lowerleg_R
// orient
body foot.r foot_R
// orient
size 2
joint hip.l torso uleg.l
type universal
lostop -1
histop 1
joint knee.l uleg.l lleg.l
joint ankle.l lleg.l foot.l
lostop -0.5
histop 0.5
joint hip.r torso uleg.r
type universal
lostop -1
histop 1
joint knee.r uleg.r lleg.r
joint ankle.r lleg.r foot.r
lostop -0.5
histop 0.5
//arms tend to bend forwards...
updatejoint default
type hinge
lostop -0.5
histop 2
//left arm
body uarm.l upperarm_L
animate 0
// orient
body larm.l forearm_L
animate 0
// orient
body hand.l hand_L
animate 0
// orient
//right arm
body uarm.r upperarm_R
animate 0
// orient torso.r
body larm.r forearm_R
animate 0
// orient urarm.r
body hand.r hand_R
animate 0
// orient larm.r
joint shoulder.l torso uarm.l
type point
lostop2 -1.6
histop2 0.1
joint elbow.l uarm.l larm.l
type point
lostop -1
histop 1
draw 1
joint wrist.l larm.l hand.l
type point
lostop -1
histop 1
// pivot BONE -32 0 0
joint shoulder.r torso uarm.r
type point
lostop2 -0.1
histop2 1.6
joint elbow.r uarm.r larm.r
type point
joint wrist.r larm.r hand.r
type point
// pivot BONE 32 0 0
body toe.r toe_R
body toe.l toe_L
updatejoint default
type hinge
lostop -0.2
histop 0.1
lostop2 -0.2
histop2 0.1
joint hackfix.l toe.l foot.l
joint hackfix.r toe.r foot.r
if done properly, your console command should make an entity spawn and ragdoll down to the floor.
basically, create a skeletal object, tells it to use a doll file. keep poking your skeletal object each frame to keep it updated (it will will do physics if not poked, but won't update the bone info).
note that the code actually uses two skeletal objects. one contains animation data, the other contains physics+final data. the data in the animation data can be used to tell the 'animated' bodies where to move to (so it can kick things etc), and for the bones without bodies to have some position that looks right. If you don't use a second skeletal object, it'll just use the base pose or something for bones-without-bodies.
it probably doesn't work too well with vid_restart. you should probably spam skel_ragupdate with the doll command rather than the empty command. this ensures the entity resets if the doll became invalid due to being flushed for whatever reason. on the plus side, it does make editing the doll file easier.
its still a Work In Progress extension. I documented it in that document for two reasons:
1) gives people something fun to aim for.
2) needs a bit more use+examples+feedback+etc before it can be more than wip.
its been a while since I touched it...
feel free to suggest lots of fixes/tweaks to make it more robust/versatile/easier.
Sidenote: you can get the same thing working via ssqc by providing a model.iqm.doll file and setting self.frame|=65535. the flag-in-frame thing sets all the dolls 'animate' settings to 0, causing it to go limp and collapse. set that half way through your death animation and it should inherit momentum from the animation. that's the theory anyway.
its still worth using csqc for this stuff, so you can do animation blending properly as per the previous chapter in csqc-for-idiots for when the entity is still alive.