Home / Forums / How to get Bone Matrix Positions in CS2 (Source 2 C_BaseEntity)?

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Question

How to get Bone Matrix Positions in CS2 (Source 2 C_BaseEntity)?

BoneMatrix_
CS2 & Skeleton Math
MEMBER
Rep: 190
Join Date: Aug 2024
Posts: 21
Thanks: 47
2y ago · Oct 4, 2023 2:20 PM
#1
Hey everyone,
In CS:GO we used to read
CPP
m_dwBoneMatrix
directly from the entity base. In Counter-Strike 2 (Source 2 engine), the structure changed significantly with the pawn/controller separation.

What is the proper pointer chain to read the bone positions array from
CPP
C_CSPlayerPawn
in CS2?
BoneMatrix_ · Source 2 Skeleton ESP & Hitboxes
The following users thanked BoneMatrix_ for this post:
VectorByte
Graphics & DirectX Dev
VIP
Rep: 420
Join Date: Aug 2022
Posts: 39
Thanks: 115
2y ago · Oct 4, 2023 3:45 PM
#2
In Source 2, bone data is stored inside the
CPP
CGameSceneNode
component attached to the player pawn.

Here is the chain:
1. Read
CPP
pGameSceneNode = *(uintptr_t*)(playerPawn + m_pGameSceneNode)

2. Read
CPP
pBoneArray = *(uintptr_t*)(pGameSceneNode + m_modelState + 0x80)
(or your current bone matrix offset)
3. Each bone is structured as a
CPP
struct BoneData { Vector3 pos; char pad[0x14]; };
(0x20 stride per bone).

CPP
struct BoneJointData {
    Vector3 position;
    float scale;
    Vector4 rotationQuaternion;
};

Vector3 GetBonePosition(uintptr_t pSceneNode, int boneIndex) {
    uintptr_t boneArray = *(uintptr_t*)(pSceneNode + 0x160 + 0x80); // adjust for current build offsets
    if (!boneArray) return { 0, 0, 0 };
    
    BoneJointData bone = *(BoneJointData*)(boneArray + (boneIndex * 32));
    return bone.position;
}
VectorByte | DirectX 11/12 Hooking & ImGui Overlays
Quote
Math is the language of game engines.
HexRays99
Senior Reverse Engineer
VIP
Rep: 380
Join Date: Apr 2022
Posts: 36
Thanks: 94
2y ago · Oct 4, 2023 5:10 PM
#3
To add to @VectorByte, common bone indices in Source 2:
- Head:
CPP
6

- Neck:
CPP
5

- Spine/Chest:
CPP
4
, Pelvis:
CPP
0

- Left Shoulder/Arm/Hand:
CPP
8, 9, 10

- Right Shoulder/Arm/Hand:
CPP
13, 14, 15

- Left Hip/Knee/Foot:
CPP
22, 23, 24

- Right Hip/Knee/Foot:
CPP
25, 26, 27


Once you read these vectors and WorldToScreen each point, you can draw a full skeletal wireframe with ImGui lines!
HexRays99 · Reverse Engineering & Static Analysis
CPP
// Always check your pointers!
if (!pLocalPlayer) return;
BoneMatrix_
CS2 & Skeleton Math
MEMBER
Rep: 190
Join Date: Aug 2024
Posts: 21
Thanks: 47
2y ago · Oct 5, 2023 8:30 AM
#4
Thank you so much @VectorByte and @HexRays99! Got the skeleton ESP drawing perfectly with zero flickering.
BoneMatrix_ · Source 2 Skeleton ESP & Hitboxes