summaryrefslogtreecommitdiffstats
path: root/src/bones.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bones.cpp')
-rw-r--r--src/bones.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/bones.cpp b/src/bones.cpp
index 88aa429..a9c6887 100644
--- a/src/bones.cpp
+++ b/src/bones.cpp
@@ -182,6 +182,25 @@ static bool hitbox_world(const BoneEntry *e, const Hitbox &b, Vector &out) {
182 return true; 182 return true;
183} 183}
184 184
185// HL2 humanoids (combine, metrocop, citizen, zombie, ...) use the ValveBiped
186// skeleton. Draw only the core chain: pelvis/spine/neck/head, clavicle to
187// hand, thigh to foot. Fingers, toes and extra model bones (e.g. the headcrab
188// on a zombie) are skipped.
189static bool core_bone_name(const char *n) {
190 if (!n || strncasecmp(n, "ValveBiped.Bip01_", 17) != 0)
191 return false;
192 if (contains_ci(n, "Finger") || contains_ci(n, "Toe") ||
193 contains_ci(n, "Headcrab"))
194 return false;
195 static const char *tokens[] = {"Pelvis", "Spine", "Neck", "Head1",
196 "Clavicle", "UpperArm", "Forearm", "Hand",
197 "Thigh", "Calf", "Foot", nullptr};
198 for (int i = 0; tokens[i]; i++)
199 if (contains_ci(n, tokens[i]))
200 return true;
201 return false;
202}
203
185static void dump_hitboxes(const BoneEntry *e) { 204static void dump_hitboxes(const BoneEntry *e) {
186 const StudioHdr *h = e->hdr; 205 const StudioHdr *h = e->hdr;
187 logf("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets, 206 logf("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets,
@@ -312,6 +331,26 @@ int bone_parent(int idx, int bone) {
312 return bone_at(e->hdr, bone)->parent; 331 return bone_at(e->hdr, bone)->parent;
313} 332}
314 333
334bool bone_is_skeleton_core(int idx, int bone) {
335 BoneEntry *e = find_entry(idx);
336 if (!e || !e->valid || bone < 0 || bone >= e->count)
337 return false;
338 return core_bone_name(bone_name_raw(e->hdr, bone));
339}
340
341int bone_nearest_core_parent(int idx, int bone) {
342 BoneEntry *e = find_entry(idx);
343 if (!e || !e->valid || bone < 0 || bone >= e->count)
344 return -1;
345 int p = bone_at(e->hdr, bone)->parent;
346 for (int guard = 0; p >= 0 && p < e->count && guard < 64; guard++) {
347 if (core_bone_name(bone_name_raw(e->hdr, p)))
348 return p;
349 p = bone_at(e->hdr, p)->parent;
350 }
351 return -1;
352}
353
315bool bone_pos(int idx, int bone, Vector &out) { 354bool bone_pos(int idx, int bone, Vector &out) {
316 BoneEntry *e = find_entry(idx); 355 BoneEntry *e = find_entry(idx);
317 if (!e || !e->valid || bone < 0 || bone >= e->count) 356 if (!e || !e->valid || bone < 0 || bone >= e->count)