Absolute beginners guide to setattachment (draft)

DISCLAIMER:

Spoike  setattachment just sets tag_entity and tag_index fields, right?
OneManClan — 03/26/2021 no, i didnt know that
Spoike — 03/26/2021 and that stuff like this:
float robot_torso_bone_number = gettagindex(self, “torso”);
vector robot_torso_origin = gettaginfo(self, robot_torso_bone_number);
is just wrong
gettaginfo(self,0) would be more accurate there.
OneManClan — 03/26/2021 0?
Spoike — 03/26/2021 or gettaginfo(self.tag_entity, self.tag_index); would be what you were aiming for
getting the position of the PARENT’s tag on the CHILD entity is just wrong.
OneManClan — 03/26/2021 to be clear… by ‘is just wrong’ do you mean ‘wont get the results you expect’?
Spoike — 03/26/2021 inside RobotTorsothink, self is the torso.
trying to find the torso tag on the torso entity is a wtf
trying to find the torso entity on the entity that the torso is attached to makes much more sense.
but its also redundant when you can just call gettaginfo(self,0)
OneManClan — 03/26/2021 I think this was ‘if you make a dalekbody (parent), and are rotating the gunhand (child), how do you spin the gunhand around its own origin?’
Spoike — 03/26/2021 remember that tag 0 is the parent of the root bone
OneManClan — 03/26/2021 ah
Spoike — 03/26/2021 ie the entity’s actual origin.
that the root bone’s orientation is relative to
OneManClan — 03/26/2021 Fact or Fiction?: When a child becomes ‘setattached’, it’s origin becomes ‘0 0 0’
Spoike — 03/26/2021 false
OneManClan — 03/26/2021 !
damn
hm
Spoike — 03/26/2021 setattachment does not change the entity’s origin.
at all
OneManClan — 03/26/2021 so the ‘guide’ is fundamentally flawed
Spoike — 03/26/2021 if it started as 0 0 0 then it’ll remain as 0 0 0
just the entity will be positioned with 0 0 0 on the parent ent’s bone, with the child’s origin+angles serving as a translation relative to that point

OneManClan — 03/26/2021
man… see this is where a practical example of how to actually achieve a desired result would help slower ppl like me ‘GET IT’
Spoike — 03/26/2021
such entities must not be solid, because they won’t get relinked
slower people will never entirely ‘get it’ tbh, because ‘it’ is needlessly complicated.
additional offsets from the tag origin? wtf is that even about!

 

Absolute beginners guide to setattachment

NOTE: Afaik, setattachment is only compatible with FTE and DP

PREFACE
There’s already a very helpful page on the Quake Wiki, which pretty much covers all you need to know about setattachment, but for those who need more, here’s my unapologetically handholding guide, for absolute beginners, and of course, for a future me who doesn’t remember exactly how I got this working.

INTRODUCTION
Setattachment is a (ssqc) way to connect multiple models together so that they can appear as ‘one model’ but each body part can be controlled seperately. For this ‘step by step’ walkthrough we will make a model consisting of 3 parts: ‘RobotLegs’, ‘RobotTorso’, and ‘Robothead’. Each body part will have its own thinks, but ‘RobotTorso’ and ‘Robothead’ will be ‘child’ entities, permanently connected to ‘RobotLegs’, the ‘parent’ entity.

PREPARING THE MODEL
1. In Blender, make a (crappy boxy test) model with 3 bodyparts, RobotLegs, RobotTorso, and Robothead. Keep the three as seperate objects (ie don’t join them).

2. Make an armature, 3 bones “legs”, “torso”, and “head”, and connect each bone to its respective mesh. [TIP: If it’s a robot, check the weights (weight paint) to make sure that rotating one part has 0 influece on the adjoining part.]

3. Save the Blender file.

4. Export each body part with it’s bone as a seperate iqm (using Salzmans iqm exporter). Note: This example doesn’t need animations (leave the ‘animations’ field blank) TIP: Remember to scale the model up on Export (I’ve been using 8 with great results), otherwise you might have trouble seeing it in-game.

THE QUAKE C

[code]// declare the body parts
#define ROBOT_LEGS "progs/robot_legs.iqm"
#define ROBOT_TORSO "progs/robot_torso.iqm"
#define ROBOT_HEAD "progs/robot_head.iqm"[/code]

[code]
// precache them
precache_model(ROBOT_LEGS);
precache_model(ROBOT_TORSO);
precache_model(ROBOT_HEAD );
[/code]

[i]Note: I’m not sure if we should attach each part to ‘the part it directly connects to’ (ie other children), or to the parent?[/i]

[code]
// spawn the parent entity (the one the others will attach to)
entity Robotlegs = spawn();
setmodel (Robotlegs, ROBOT_LEGS);
setorigin(Robotlegs, where_you_want_it_to_spawn);
Robotlegs.think = Robotlegsthink;
Robotlegs.nextthink = time + 1;

// spawn the child entity 1: RobotTorso
entity RobotTorso= spawn();
setmodel (RobotTorso, ROBOT_TORSO);
// attach entity ‘RobotTorso’ to entity ‘Robotlegs’, using the RobotTorsobone/tag called ‘torso’
setattachment (RobotTorso, Robotlegs, "torso");
RobotTorso.think = RobotTorsothink;
RobotTorso.nextthink = time + 1;

// spawn the child entity 2: RobotTorso
entity RobotHead = spawn();
setmodel (RobotHead, ROBOT_HEAD);
// attach entity ‘RobotHead’ to entity ‘RobotTorso’, using the bone/tag called ‘head’
setattachment (RobotHead, RobotTorso, "head"); // Q: should it attach to Robotlegs/the parent??
RobotHead.think = RobotHeadthink;
RobotHead.nextthink = time + 1;

[/code]

6. Each bodypart now has its’ own ai (Robotlegsthink, RobotTorsothink, and RobotHeadthink).

7. When a child becomes ‘setattached’, it’s origin becomes ‘0 0 0’, and the parent becomes the childs .tag_entity. To get the parents origin, you can go:

[code]vector parent_origin = child.tag_entity.origin;[/code]

However we need the *childs* origin, and the way to do that is to use gettaginfo, as described below:

[code]
// the parent
void() Robotlegsthink =
{
// code for the Robotlegs
// origin is self.origin

}

// child
void() RobotTorsothink =
{
// code for the RobotTorso
// Note: self.origin is ‘0 0 0’

// To get RobotTorso’s origin:
float robot_torso_bone_number = gettagindex(self, "torso");
vector robot_torso_origin = gettaginfo(self, robot_torso_bone_number);

}
[/code]

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>