Page 1 of 1

[CS:GO] GetBoneTransform

Posted: Tue Mar 21, 2023 8:15 pm
by cobana
Hello, i tried to get the map position of a specific bone of a player in CS:GO but i could not get it to work successfully.
I already searched through the forums and found a couple of threads that suggested using the vfunc GetBoneTransform() for it.

I copied and modified the code of the following post on how to use the above mentioned vfunc.
https://forums.sourcepython.com/viewtopic.php?f=20&t=1638&p=10920&hilit=getbonetransform#p10883

I also checked other referring posts to GetBoneTransform, eg.:
https://sourcepython.com/viewtopic.php?f=38&t=870&p=16038&hilit=getbonetransform&sid=0a4442cabf897bf2381274beed8dd3ac#p16038
https://sourcepython.com/viewtopic.php?f=20&t=1725&p=11399&hilit=getbonetransform+offset&sid=0a4442cabf897bf2381274beed8dd3ac#p11399

The last post is pointing out that the correct offset for the vfunc needs to be found for CS:GO. So my first guess is, that my code does not work because i got the wrong offset. How would one find the correct offset? Or is the offset still correct and i am missing a bug/logic flaw in my code?

Syntax: Select all

OFFSET_GetBoneTransform = 199

@Event('bullet_impact')
def bullet_impact(game_event):
userid = game_event['userid']
player = Player(index_from_userid(userid))

header = player.model_header

for bone_index in range(header.bones_count):
bone_name = header.get_bone(bone_index).name.lower()
if "head" in bone_name:
print(bone_name + ": " + str(bone_index))
break


## Source: viewtopic.php?f=20&t=1638&p=10920&hilit=getbonetransform#p10883
GetBoneTransform = player.pointer.make_virtual_function(OFFSET_GetBoneTransform,Convention.THISCALL,[DataType.POINTER, DataType.INT, DataType.POINTER],DataType.VOID)
matrix = Matrix3x4()
GetBoneTransform(player, bone_index, matrix)
print("player.origin: " + str(player.origin))
print("matrix.position: " + str(matrix.position))


Prints the following on some random shot:

Code: Select all

head_0: 8
player.origin: Vector(-1296.7099609375, -1392.4300537109375, 11488.03125)
matrix.position: Vector(0.0, 4.321107888263927e+27, 0.0)


Those both vectors should be close to each other besides, matrix.position.z which should be around +64 to player.origin.z so those values cant be right.

Thanks for any help!

Re: [CS:GO] GetBoneTransform

Posted: Tue Mar 21, 2023 8:36 pm
by L'In20Cible
cobana wrote:So my first guess is, that my code does not work because i got the wrong offset. How would one find the correct offset?
Easiest way would probably be to test increment the offset until you get results that make sense.

Re: [CS:GO] GetBoneTransform

Posted: Tue Mar 21, 2023 9:03 pm
by cobana
L'In20Cible wrote:
cobana wrote:So my first guess is, that my code does not work because i got the wrong offset. How would one find the correct offset?
Easiest way would probably be to test increment the offset until you get results that make sense.

I tried that already because of a post that you wrote (if i remember correctly) but i cannot find that post anymore.
I tried with an offset of 199 to 207 (both inclusive) but they all did not yield fitting results. Above 207 the srcds crashes with a segmentation fault. (i tried 207 to 211 and then stopped). Is there any other way? And thanks for your super fast reply.

Re: [CS:GO] GetBoneTransform

Posted: Wed Mar 22, 2023 3:15 am
by L'In20Cible
cobana wrote:(i tried 207 to 211 and then stopped).
You stopped too early! I believe it's 214 on Windows and 215 on Linux.

EDIT: Yup, it looks right.

Syntax: Select all

from core import PLATFORM
from core.cache import cached_property
from entities.entity import Entity
from memory import Convention
from memory import DataType
from memory.helpers import MemberFunction
from memory.manager import manager
from mathlib import Matrix3x4
from mathlib import Vector

class MyEntity(Entity):
caching = True

@cached_property
def get_bone_transform(self):
return MemberFunction(
manager,
DataType.VOID,
self.make_virtual_function(
214 if PLATFORM == 'windows' else 215,
Convention.THISCALL,
(DataType.POINTER, DataType.INT, DataType.POINTER),
DataType.VOID
),
self
)

glock = MyEntity.create('weapon_glock')
glock.origin = Vector(1.000000, 2.000000, 3.000000)
glock.spawn()

hdr = glock.model_header
for index, bone in enumerate(map(hdr.get_bone, range(hdr.bones_count))):
matrix = Matrix3x4()
glock.get_bone_transform(index, matrix)
print(f'{index} - {bone.name} = {matrix.position}')
0 - weapon_hand_R = Vector(1.0, 2.0, 3.0)
1 - weapon_holster_center = Vector(4.062496185302734, 1.9999990463256836, 6.527450084686279)
2 - sticker_d = Vector(1.3625290393829346, 4.543296813964844, 3.7153611183166504)
3 - sticker_a = Vector(1.6164259910583496, 4.543295860290527, 6.312037944793701)
4 - sticker_c = Vector(6.285242080688477, 4.543294906616211, 6.39211368560791)
5 - sticker_b = Vector(3.7472729682922363, 4.543295860290527, 6.384725093841553)
6 - weapon_slide = Vector(1.0, 2.0, 3.0)
7 - weapon_trigger = Vector(1.0, 2.0, 3.0)
8 - weapon_mag = Vector(1.0, 2.0, 3.0)

Re: [CS:GO] GetBoneTransform

Posted: Wed Mar 22, 2023 11:36 am
by cobana
L'In20Cible wrote:
cobana wrote:(i tried 207 to 211 and then stopped).
You stopped too early! I believe it's 214 on Windows and 215 on Linux.

Thank you so much! Tested it with 215 on Linux and its working as intended.