• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Question - Code [QUESTION] Matrix stack! [ANSWERED]

Will stacked matrixes in the matrix stack get all applied when drawing?!

Code:
matrix_stack_push(ma1); //rotation
matrix_stack_push(ma2); //translation
matrix_stack_push(ma3); //scale

matrix_set(matrix_world, matrix_stack_top());
draw...()
will this make the draw function has rotation + translation + scale applied?!
This is not well specified in the documentation... and in the link:

http://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/matrices/matrix_stack_push.html

it sure suggests that!!
 

FrostyCat

Member
Pushing a matrix only saves it onto a stack for popping later, you still need to apply the transformations with matrix_multiply() and then set it.
 

Mike

nobody important
GMC Elder
A push will multiply as well, but you will have to "set" it afterwards - as shown in the manual.

The top of the stack is the combined (multiplied) matrix, not the one you pushed.
 
A push will multiply as well, but you will have to "set" it afterwards - as shown in the manual.

The top of the stack is the combined (multiplied) matrix, not the one you pushed.
So pushing a matrix into the stack will make it go to (second from top) and the TOP one is always the multiplication of everything inside the stack... is it true!? ;) nice!!

This would be nicer if objects (children) draw code was called by the parents'...

NOTES for the example:
- every instance has a variable (ds_list) named children.
- every instance has a matrix (for local position).
- instance B is contained inside instance A children list.

The sequence:
1) instance A draw event pushes its matrix into the stack
2) instance A draws itself
3) instance A calls each child draw event
3.1) instance B draw event would push its local matrix to the stack
3.2) instance B would draw itself (and call draw event of its children).
3.3) instance B end of draw would pop its local matrix from stack.
4) instance A end of draw would pop its local matrix from stack.

can you disable draw event and make it being called by other object?
(would this be better performance wise/ is GMS prepared for this?!)

this way one would know the order in which the instance are drawn, because it would be the parent doing that!!

and this could happen for the update as well... :D sadly if you disable the instance you can't call it's update or draw events :(
and there is no way to disable "auto draw" and "auto update" and use this manual alternative!
 
Last edited:

Mike

nobody important
GMC Elder
No not quite... if you push a matrix, only the combined one goes onto the stack, unless you "set" it. (We will add a matrix_load(), I just noticed that was missing).

UnitMatrix is always on the stack
Top ->Unit
Push A -> Top is Unit*A (=A)
Push B - > Top is A*B
Push C - > Top is A*B(C
Pop -> Top is A*B
Push D -> Top is A*B*D
etc...

This is how simple hierarchical models are done (tanks with turrets etc). Pretty simple really. :)
 
No not quite... if you push a matrix, only the combined one goes onto the stack, unless you "set" it. (We will add a matrix_load(), I just noticed that was missing).

UnitMatrix is always on the stack
Top ->Unit
Push A -> Top is Unit*A (=A)
Push B - > Top is A*B
Push C - > Top is A*B(C
Pop -> Top is A*B
Push D -> Top is A*B*D
etc...

This is how simple hierarchical models are done (tanks with turrets etc). Pretty simple really. :)
Nice, that's just what I thought (not technically what I said.... but the ideia I had of how it worked ;) ).
In relation to the other question I asked:

Is it possible to disable the draw event and make it being called by other object?
this would be important if there are "attached" objects... or even UI...
where windows contents should be drawn after window frame and should inherit its matrix.
 

Mike

nobody important
GMC Elder
Just write a script and pass in an object id and then draw it from where ever you like.
 
Just write a script and pass in an object id and then draw it from where ever you like.
Ahhhhhhh.... woow how slow am I today! xD didn't realize that was possible... well... but the object will run its default draw script... is it possible to disable that?!

for example a command:

event_default_draw(false);
event_default_update(false);
 

FrostyCat

Member
No not quite... if you push a matrix, only the combined one goes onto the stack, unless you "set" it. (We will add a matrix_load(), I just noticed that was missing).

UnitMatrix is always on the stack
Top ->Unit
Push A -> Top is Unit*A (=A)
Push B - > Top is A*B
Push C - > Top is A*B(C
Pop -> Top is A*B
Push D -> Top is A*B*D
etc...

This is how simple hierarchical models are done (tanks with turrets etc). Pretty simple really. :)
This is not the same behaviour that standard implementations of "matrix pushing" exhibit. The standard behaviour for pushing A literally means putting A onto the stack, not AM. Even the old d3d_transform_stack_push() had the standard behaviour. Implementing it your way and not documenting the quirk will only cause confusion, and even documenting it would still raise eyebrows.

Please stop implementing standard functionality in "alternative" non-standard ways just because you think we'll use the non-standard behaviour more often. We've had similar arguments in 8.1 with dot_product(), when you insisted on implementing it as a normalized dot product instead of a straight dot product. Virtually nobody was on your side, and eventually you had to backpedal and implement it the standard way.

If it's not too late to change the name, please change it to something like matrix_stack_push_transform() to describe the added behaviour. If it is too late, please add a straight matrix_stack_push_current() so that we don't need to build a new identity matrix for the standard behaviour.
 
Last edited:

Mike

nobody important
GMC Elder
Sorry....totally disagree. On a matrix stack, push should always multiply.

I have never...ever done a matrix stack that wasn't like this, or seen one. There's no point doing a simple stack then having to manually do multiples, that's pointless work. Every time you push a matrix, you want it to combine. In the rarer cases you don't, this is where you would use the (missing) matrix_stack_load(). I filed a bug for the missing "matrix_stack_load()" command yesterday.
 
Sorry....totally disagree. On a matrix stack, push should always multiply.

I have never...ever done a matrix stack that wasn't like this, or seen one. There's no point doing a simple stack then having to manually do multiples, that's pointless work. Every time you push a matrix, you want it to combine. In the rarer cases you don't, this is where you would use the (missing) matrix_stack_load(). I filed a bug for the missing "matrix_stack_load()" command yesterday.
It makes sense... because if it was just a ds_stack... then it would be just pointless... (it would not give any programming nor performance advantage).
 
Top