1 // -----------------------------------------------------------------------
3 // -----------------------------------------------------------------------
4 // Code to render a sphere
5 // From Pixelate #11, article written by Martijn 'amarillion' van Iersel
6 // -----------------------------------------------------------------------
7 // Modified by Kronoman to suit the needs of the game.
8 // -----------------------------------------------------------------------
15 get_planet_rotation_matrix() is a little helper function to calculate a
16 rotation matrix for a planet. An ordinary rotation matrix doesn't work well
19 MATRIX *m: pointer to the resulting MATRIX struct
20 fixed rotation: rotation of the planet around its axis of rotation
21 fixed axisx, axisz: rotation around the x and z axes.
23 void get_planet_rotation_matrix (MATRIX
*m
, fixed rotation
, fixed axisx
, fixed axisz
)
26 // apply rotation around y axis first
27 get_y_rotate_matrix (&m1
, rotation
);
29 // then apply rotation around x and z axes.
30 get_rotation_matrix (&m2
, axisx
, 0, axisz
);
32 matrix_mul (&m2
, &m1
, m
);
36 get_mapped_sphere_ex() is similar to get_mapped_sphere(), but also takes
37 a rotation matrix as argument to draw a rotated sphere.
39 BITMAP *target = bitmap to display onto
40 int cx, cy = center of the sphere
41 int r = radius of the sphere
42 BITMAP *map = bitmap to map onto the sphere
43 MATRIX *rotmat = rotation matrix
45 void mapped_sphere_ex (BITMAP
*target
, int cx
, int cy
, int r
, BITMAP
*map
, MATRIX
*rotmat
)
47 int x
, y
; // coordinates on the target bitmap
48 int p
, q
; // coordinates on the source bitmap
50 for (y
= -r
; y
< r
; y
++)
52 fixed q_cos
= fixcos (- fixasin (itofix (y
) / r
)) * r
;
53 for (x
= - fixtoi (q_cos
) + 1; x
< fixtoi(q_cos
) - 1; x
++)
55 fixed newq_cos
, temp_p
, temp_q
=0; // some temporary variables
56 #warning Dirty Hack: Using int32_t instead of fixed to avoid a dirty error
57 int32_t newx
, newy
, newz
; // x, y and z after rotation
58 fixed z
; // z before rotation. we don't have to calculate x and y
61 // using pythagoras and the formula for a sphere:
62 // x^2 + y^2 + z^2 = r^2
64 z
= fixsqrt (r
* itofix (r
) - x
* itofix (x
) - y
* itofix (y
));
66 // apply the rotation matrix to x, y, z.
67 // put the result in newx, newy, newz
68 apply_matrix (rotmat
, itofix(x
), itofix(y
), z
, &newx
, &newy
, &newz
);
70 //just as in sphere2.c, we need to check if q_cos is 0
71 //however, q_cos depends on y, and we just calculated a new y
72 //thus we have to calculate q_cos again.
73 newq_cos
= fixcos (temp_q
) * r
;
76 // it is possible to use temp_p
77 // temp_p = fixasin (fixdiv (itofix (x), q_cos));
78 // however, I found I get less rounding errors if I use
79 // fixatan2 instead. The principle remains the same.
80 temp_p
= fixatan2 (fixdiv (newx
, newq_cos
), fixdiv (newz
, newq_cos
));
87 p
= fixtoi (temp_p
) * (map
->w
-1) / 256;
90 temp_q
= fixasin (newy
/ r
);
91 q
= fixtoi (temp_q
+ itofix (64)) * (map
->h
-1) / 128;
93 putpixel (target
, x
+ cx
, y
+ cy
, getpixel(map
, p
, q
) );