Legacy GM (3D)Trying to make a limb. (lengthdir_# mess)

marasovec

Member
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_transform_add_rotation_y(pitch);
d3d_transform_add_rotation_z(dir);
d3d_transform_add_scaling(3, 3, 3);
d3d_transform_add_translation(x+lengthdir_x(10,dir), y+lengthdir_y(10,dir), z);
d3d_model_draw(leg1, 0, 0, 0, tex1);
d3d_transform_set_identity();

// 50 long part (not working)
d3d_transform_add_rotation_y(45);
d3d_transform_add_rotation_z(dir);
d3d_transform_add_scaling(3, 3, 3);
d3d_transform_add_translation(
    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();
 

FrostyCat

Redemption Seeker
@FrostyCat Ok that should work. But how can I get the position of the last point?
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.
 
M

Misty

Guest
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.
 

FrostyCat

Redemption Seeker
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.
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)
 

marasovec

Member
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
 
M

Misty

Guest
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)
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.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
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) {
        d3d_transform_add_translation(bone_pos_x[j], bone_pos_y[j], bone_pos_z[j])
        d3d_transform_add_rotation_x(bone_rot_x[j])
        d3d_transform_add_rotation_y(bone_rot_y[j])
        d3d_transform_add_rotation_z(bone_rot_z[j])
        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:
M

Misty

Guest
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.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
I dont see how to use it as separate limbs, only one steady tentacle.
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, andupload_2019-6-9_21-38-42.png
 
M

Misty

Guest
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:
Top