Push / Pop Matrix Coordinates

Previous topic - Next topic

Qube

Me stuck :(

Lets say I've drawn a 3D object which is rotated and then placed with X_DRAWOBJ 1, 10, 10, 10 - I then use X_PUSHMATRIX / X_POPMATRIX to draw an object just behind it with X_DRAWOBJ 1, 0, 0, -1

Is there a way to get the real coordinates of the object I drew using push / pop matrix? - Or do I have to do some whizzy math?




Slydog

If you have both co-ordinates in a vector type variable, then adding the two vectors should do it. Such as:
Code (glbasic) Select
LOCAL parent AS TVector
LOCAL child AS TVector
parent.x = 10;  parent.y = 10;  parent.z = 10
child.x = 0;   child.y = 0;    child.z = -1

X_DRAWOBJ 1, parent.x, parent.y, parent.z
X_PUSHMATRIX . . .
X_DRAWOBJ 1, child.x, child.y, child.z
....
// To find out where the actual child was drawn in world space, use:
LOCAL world_location AS TVector
world_location = Vector_Add(parent, child)


Here's the TYPE to make this work:
Code (glbasic) Select
TYPE TVector
   x
   y
   z
ENDTYPE

// Add v1 to v2
FUNCTION Vector_Add AS TVector: v1 AS TVector, v2 AS TVector
   LOCAL v AS TVector
   v.x = v1.x + v2.x
   v.y = v1.y + v2.y
   v.z = v1.z + v2.z
   RETURN v
ENDFUNCTION


[Edit] My bad!  My code doesn't take rotation into account, which is probably why you are asking!  Hmm . . . tricky!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Slydog

I bet there would be an OpenGL call you could do to return / convert the current local and world space.
You could create a wrapper for this call probably, but I've never touched OpenGL much, so out of my scope.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Qube

Quote
[Edit] My bad!  My code doesn't take rotation into account, which is probably why you are asking!  Hmm . . . tricky!
Yeah, not as easy as I was hoping either  :S

Quote
bet there would be an OpenGL call you could do to return / convert the current local and world space.
Any such call would have to work in iOS - Can't believe no one has ever wanted to get the coors of an object drawn in push/pop matrix  O_O

Anyone out there with a solution?  :giveup:

Moru

I don't know much about 3D but have any of you looked into the entity layer posted on the boards?

bigsofty

Quote from: Moru on 2011-Apr-26
I don't know much about 3D but have any of you looked into the entity layer posted on the boards?

Which works great BTW, I can contest to that!  ;)
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

Kitty Hello

I see. You want to push, push, push and transform the matrix and get the "final" position of the model then?

There's no command for that :( I'll implement X_GETMATRIX for you.

Qube

Quote
I'll implement X_GETMATRIX for you.
That'd be brilliant if you could. Woohoo, thanks  :good:

Quote
You want to push, push, push and transform the matrix and get the "final" position of the model then?
Yes, I want/need to be able to draw an object as normal then pushmatrix and then be able to get various real world coors from various movements, for example :

1.. rotate an object at various angles
2.. draw it on screen
3.. pushmatrix
4.. movement -1,0,0
5.. get real world coors if I were to draw an object here
6.. movememt 0,0,-1
7.. get real world coors if I were to draw an object here
8.. popmatrix

Hope that makes sense. You can then use such data in chasecam routines, special fx where you don't need to draw immediately during the push/popmatrix (cuts down on heavy cos/sin usage).

I'd find (and sure others) the ability to get the real world coors after x_movement in push/popmatrix a huge help in 3D land  :good: :good:

Slydog

Quote[From Qube] You can then use such data in chasecam routines . . . (cuts down on heavy cos/sin usage)

You are so right!  Here is my current 'chase cam' routine, with damping.
It could be reduced to a few lines of code, if I could move the camera relative to the player.
I could now I guess if I converted to the Entity System, instead of my libraries.  Too late now?
(there is probably better ways to do the following, this was just my first attempt working with cameras!)

Code (glbasic) Select
FUNCTION Camera_Player:
LOCAL SPEED_DISTANCE = 2.0 // Units per second
LOCAL SPEED_ANGLE = 180.0 // Degrees per second
LOCAL DISTANCE_Y = 0.5 // Camera height above player

LOCAL camera_cur AS TVector
LOCAL camera_cur_len
LOCAL camera_cur_ang

LOCAL camera_dst AS TVector
LOCAL camera_dst_len = 0.75 // Camera should be this distance behind player
LOCAL camera_dst_ang
LOCAL camera_lookat_len = 0.75
LOCAL camera_lookat AS TVector

LOCAL step_angle
LOCAL step_length
LOCAL step_y

LOCAL player_pos AS TVector

LOCAL delta_angle

player_pos = Entity_Position_Get(_player.entity_id) // Current position of camera

// Calculate desired camera destination - directly behind player, "camera_dst_len" units away
camera_dst_ang = Angle_Clamp(_player.angle + 90.0) // Camera angle is opposite the player angle
camera_dst.x = COS(camera_dst_ang) * camera_dst_len // Camera x position behind player
camera_dst.z = -SIN(camera_dst_ang) * camera_dst_len // Camera z position behind player
camera_dst.y = DISTANCE_Y // Camera y position above  player

camera_lookat.x = player_pos.x + -COS(camera_dst_ang) * camera_lookat_len
camera_lookat.z = player_pos.z + SIN(camera_dst_ang) * camera_lookat_len
camera_lookat.y = player_pos.y

// Calcualte current camera details
camera_cur = Entity_Position_Get(_camera.entity_id) // Current position of camera
camera_cur = camera_cur.Subtract(player_pos) // Adjust so it's relative to player
camera_cur_len = SQR((camera_cur.x * camera_cur.x) + (camera_cur.z * camera_cur.z)) // C² = A² + B²
camera_cur_ang = ATAN(-camera_cur.z, camera_cur.x) // Current camera angle to player
camera_cur_ang = FMOD((camera_cur_ang+360.0),360.0) // Set angle to range of 0 to 359.9

// Calculate step sizes for this frame
step_angle = SPEED_ANGLE * (GETTIMER() / 1000.0) // Per frame, how much to change 'ANGLE'
step_length = SPEED_DISTANCE * (GETTIMER() / 1000.0) // Per frame, how much to change 'LENGTH'
step_y = SPEED_DISTANCE * (GETTIMER() / 1000.0) // Per frame, how much to change 'Y'

delta_angle =  Angle_Diff(camera_dst_ang, camera_cur_ang) // If postive, rotate clockwise, else counter-clockwise

// If 'current' > 'destination' reverse step direction of: ANGLE, LENGTH, Y
IF delta_angle < 0 THEN step_angle = -step_angle
IF camera_cur_len > camera_dst_len THEN step_length = -step_length
IF camera_cur.y > camera_dst.y THEN step_y = -step_y

// Rotate camera towards destination
IF ABS(step_angle) > ABS(delta_angle)
camera_cur_ang = camera_dst_ang
ELSE
camera_cur_ang = Angle_Clamp(camera_cur_ang + step_angle)
ENDIF

// Zoom in / out camera towards destination
IF ABS(step_length) > ABS(camera_cur_len - camera_dst_len)
camera_cur_len = camera_dst_len
ELSE
INC camera_cur_len, step_length
ENDIF

// Set camera to new destination
camera_cur_len = camera_dst_len
camera_cur.x = COS(camera_cur_ang) * (camera_cur_len) // New camera x position
camera_cur.z = -SIN(camera_cur_ang) * (camera_cur_len) // New camera z position

// Raise / Lower camera towards detination
IF ABS(step_length) > ABS(camera_cur.y - camera_dst.y)
camera_cur.y = camera_dst.y
ELSE
INC camera_cur.y, step_y
ENDIF

camera_cur = camera_cur.Add(player_pos) // Re-add player's position
_camera.Move(camera_cur)
_camera.Look(camera_lookat)
//_camera.Look(player_pos)
RETURN
ENDFUNCTION
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]