# GM:S 1.4 (3D)Trying to make a limb. (lengthdir_# mess)

Discussion in 'Programming' started by marasovec, Jun 8, 2019.

1. ### marasovecMember

Joined:
Sep 15, 2016
Posts:
343
Here's a pic of that what I'm trying to do (the whole limb rotates around it's origin)

10 and 30 long parts are attached but I can't figure out a solution how to attach the 50 long part

Here's my code
Code:
```// 30 long part
d3d_model_draw(leg1, 0, 0, 0, tex1);
d3d_transform_set_identity();

// 50 long part (not working)
x+lengthdir_x(10,dir)+lengthdir_x(30,dir),
y+lengthdir_y(10,dir)+lengthdir_y(30,dir),
z+lengthdir_y(30,-pitch-90));
d3d_model_draw(leg2, 0, 0, 0, tex2);
d3d_transform_set_identity();
```

Joined:
Jun 26, 2016
Posts:
4,894

3. ### marasovecMember

Joined:
Sep 15, 2016
Posts:
343
@FrostyCat Ok that should work. But how can I get the position of the last point?

4. ### FrostyCatMember

Joined:
Jun 26, 2016
Posts:
4,894
The point of hierarchical transformations is to NOT explicitly calculate every joint position. You just draw where the transformation stack says you are (i.e. relative position (0, 0, 0) transformed by the matrix), then matrix-multiply and push the next transformation on top of that and repeat until every component is drawn.

5. ### MistyMember

Joined:
Jun 22, 2016
Posts:
1,073
From my feeble attempts, I could never figure out how to use the stack functions to animate more than one limb. There is an official tutorial, that animates merely a serpent figure thing, nothing more.

Marasovec, there is a vital function you may need. It is known as the vector function, the d3d vertex.

6. ### FrostyCatMember

Joined:
Jun 26, 2016
Posts:
4,894
That only happens when you either pop too many times before drawing subsequent joints, or reset the transformation matrix back to identity after every joint. The latter is an awful habit that I see in a lot GM amateurs and GML-based tutorials, but NEVER from anyone who has formal training in 3D graphics.

Let's say you have an octopus with 8 limbs connected to a central body. Let the current transformation matrix be M and start at the top of the stack, the first transformation to the body be A, and from that the transformation to each limb be B0 through B7. Then the process looks like this:
• (Current matrix: M)
• Push A (Current matrix: AM)
• Draw body
• Push B0 (Current matrix: (B0)(AM))
• Draw limb (Current matrix: (B0)(AM))
• Pop (Current matrix: AM)
• ...
• Push Bn (Current matrix: (Bn)(AM))
• Draw limb (Current matrix: (Bn)(AM))
• Pop (Current matrix: AM)
• ...
• Push B7 (Current matrix: (B7)(AM))
• Draw limb (Current matrix: (B7)(AM))
• Pop (Current Matrix: AM)
• Pop (Current Matrix: M)

7. ### marasovecMember

Joined:
Sep 15, 2016
Posts:
343
I tried a way with point_direction_3d and point_distance_3d and it actually worked. It feels unprofessional but if it works it ain't stupid
The middle part is a bit stretched but there is almost no visible difference

8. ### MistyMember

Joined:
Jun 22, 2016
Posts:
1,073
Yeah uhh...I dont think its going to work. The problem is that d3d rotations are only applied to the origin (0,0,0). So for each transformation you have to set it back to the identity matrix first.

9. ### YellowAfterlifeᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀForum StaffModerator

Joined:
Apr 21, 2016
Posts:
2,509
I have an ancient (2013!) example on this matter https://yal.cc/gamemaker-basic-3d-bone-animations/

It goes like this:
Code:
```var i, j;
d3d_set_projection(200, 100, 100, 0, 0, 30, 0, 0, 1)
// draw the bones:
for (i = 0; i < bones; i += 1) {
j = i
d3d_transform_stack_push() // save current transformation matrix
// form bone transformation matrix semi-recurisvely:
while (j >= 0) {
j = bone_parent[j]
}
draw_set_color(bone_color[i])
d3d_model_draw(bone_model[i], 0, 0, 0, bone_texture[i])
d3d_transform_stack_pop() // restore transformation matrix afterwards
}```

Last edited: Jun 9, 2019
marasovec and TheSnidr like this.
10. ### MistyMember

Joined:
Jun 22, 2016
Posts:
1,073
Yeah that is exactly the tutorial I was talking about earlier. I dont see how to use it as separate limbs, only one steady tentacle. I never really gave it much effort though. From what I can tell though it cant be done. Just my immediate observation, dont be mad if I'm wrong, im not 100% sure.

11. ### YellowAfterlifeᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀForum StaffModerator

Joined:
Apr 21, 2016
Posts:
2,509
Well, as you can see in this exact snippet, every bone has a parent bone that it'll get attached to.
Change it to something other than preceding bone, and

12. ### MistyMember

Joined:
Jun 22, 2016
Posts:
1,073
K let me try it and see.

EDIT: Ok so like...the code is actually working, but I'm not sure how effecient this is in terms of rotations.
Take for example a human with a body, upper leg, lower leg, and foot.
The body does 6 transform operations (pop and push, and 4 transforms.)
The upper leg does 10 transforms. (pop and push, 8 transforms.)
The lower leg does 14.
The foot does 18.
In total thats 40 transforms just for one leg. So for a whole human that would be 192 transforms.

Last edited: Jun 10, 2019