134 lines
4.9 KiB
C++
134 lines
4.9 KiB
C++
//----------------------------------------------------------------------------------------------------
|
|
//
|
|
// WINDMILL
|
|
//
|
|
// version : 2.0
|
|
// Moteur de rendu 3D base sur la methode de rasterisation avec buffer de profondeur
|
|
//
|
|
// Cree par Olivier Lanneau, alias NineStars
|
|
// Planet-casio.fr
|
|
//
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
|
#include "windmill.hpp"
|
|
|
|
void debug_pop(char const *fmt, ...);
|
|
|
|
extern Texture tex_white;
|
|
extern Texture tex_light;
|
|
extern Texture tex_dark;
|
|
extern Texture tex_black;
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// TRANSFORMATION 3D
|
|
//----------------------------------------------------------------------------------------------------
|
|
void Windmill::transform_model_to_world(Object* object, Vertex vertex[], int vertex_length)
|
|
{
|
|
int cos = 0, sin = 0;
|
|
|
|
// precalcul de cos et sin
|
|
// /!\ CHANGEMENT D'ECHELLE : cos et sin << 10
|
|
/*if (object->axe == Z_BILLBOARD)
|
|
{
|
|
float angle_look_at_camera = atan2f(camera.y - object->y, camera.x - object->x);
|
|
float angle_rad = angle_look_at_camera + 3.1415 * object->angle / 180.0;
|
|
cosinus = 1024 * cosf(angle_rad);
|
|
sinus = 1024 * sinf(angle_rad);
|
|
}*/
|
|
//if (object->rotation.Null() == false)
|
|
if (object->axe == N)
|
|
{
|
|
float angle_rad = 3.1415 * object->angle / 180.0;
|
|
cos = 1024 * cosf(angle_rad);
|
|
sin = 1024 * sinf(angle_rad);
|
|
}
|
|
|
|
// transformation de chaque vertex
|
|
for (int k = 0; k<vertex_length; k++)
|
|
{
|
|
int vertex_x = vertex[k].x;
|
|
int vertex_y = vertex[k].y;
|
|
int vertex_z = vertex[k].z;
|
|
|
|
//if (cos == 0 and sin == 0)
|
|
if(object->axe == N)
|
|
{
|
|
vertex[k].x = vertex_x + object->position.x;
|
|
vertex[k].y = vertex_y + object->position.y;
|
|
vertex[k].z = vertex_z + object->position.z;
|
|
}
|
|
/*else
|
|
{
|
|
int a1 = object->rotation.x * object->rotation.x * (1024 - cos) + cos;
|
|
int a2 = object->rotation.x * object->rotation.y * (1024 - cos) - object->rotation.z * sin;
|
|
int a3 = object->rotation.x * object->rotation.y * (1024 - cos) + object->rotation.y * sin;
|
|
int a4 = object->rotation.x * object->rotation.y * (1024 - cos) + object->rotation.z * sin;
|
|
int a5 = object->rotation.y * object->rotation.y * (1024 - cos) + cos;
|
|
int a6 = object->rotation.y * object->rotation.z * (1024 - cos) - object->rotation.x * sin;
|
|
int a7 = object->rotation.x * object->rotation.z * (1024 - cos) - object->rotation.y * sin;
|
|
int a8 = object->rotation.y * object->rotation.z * (1024 - cos) + object->rotation.x * sin;
|
|
int a9 = object->rotation.z * object->rotation.z * (1024 - cos) + cos;
|
|
|
|
vertex[k].x = (a1 * vertex_x + a2 * vertex_y + a3 * vertex_z) / 1024 + object->position.x;
|
|
vertex[k].y = (a4 * vertex_x + a5 * vertex_y + a6 * vertex_z) / 1024 + object->position.y;
|
|
vertex[k].z = (a7 * vertex_x + a8 * vertex_y + a9 * vertex_z) / 1024 + object->position.z;
|
|
|
|
//vertex[k].x = ((vertex_x * cosinus - vertex_z * sinus) >> 10) + object->position.x;
|
|
//vertex[k].y = ((vertex_y * cosinus - vertex_z * sinus) >> 10) + object->position.y;
|
|
//vertex[k].z = ((vertex_y * sinus + vertex_z * cosinus) >> 10) + object->position.z;
|
|
}*/
|
|
if (object->axe == RX)
|
|
{
|
|
vertex[k].x = vertex_x + object->position.x;
|
|
vertex[k].y = ((vertex_y * cos - vertex_z * sin) / 1024) + object->position.y;
|
|
vertex[k].z = ((vertex_y * sin + vertex_z * cos) / 1024) + object->position.z;
|
|
}
|
|
if (object->axe == RY)
|
|
{
|
|
vertex[k].x = ((vertex_x * cos - vertex_z * sin) / 1024) + object->position.x;
|
|
vertex[k].y = vertex_y + object->position.y;
|
|
vertex[k].z = ((vertex_x * sin + vertex_z * cos) / 1024) + object->position.z;
|
|
}
|
|
if (object->axe == RZ)// or object->axe == Z_BILLBOARD)
|
|
{
|
|
vertex[k].x = ((vertex_x * cos - vertex_y * sin) / 1024) + object->position.x;
|
|
vertex[k].y = ((vertex_x * sin + vertex_y * cos) / 1024) + object->position.y;
|
|
vertex[k].z = vertex_z + object->position.z;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void Windmill::transform_world_to_camera(Vertex vertex[], int vertex_length)
|
|
{
|
|
for (int k = 0; k<vertex_length; k++)
|
|
{
|
|
// translation
|
|
int vertex_x = int(camera.x) - vertex[k].x;
|
|
int vertex_y = int(camera.y) - vertex[k].y;
|
|
int vertex_z = int(camera.z) - vertex[k].z;
|
|
// rotation
|
|
vertex[k].z = (-(camera.a1 * vertex_x + camera.a2 * vertex_y + camera.a3 * vertex_z) ) / SCALE_AI;
|
|
vertex[k].x = (camera.a4 * vertex_x + camera.a5 * vertex_y + camera.a6 * vertex_z ) / SCALE_AI;
|
|
vertex[k].y = (camera.a7 * vertex_x + camera.a8 * vertex_y + camera.a9 * vertex_z ) / SCALE_AI;
|
|
}
|
|
}
|
|
|
|
|
|
void Windmill::transform_camera_to_screen(Vertex vertex[], int vertex_length)
|
|
{
|
|
for (int k = 0; k<vertex_length; k++)
|
|
{
|
|
// perspective
|
|
vertex[k].x = (vertex[k].x * camera.scale_coef) / vertex[k].z + shift_x;
|
|
vertex[k].y = (vertex[k].y * camera.scale_coef) / vertex[k].z + shift_y;
|
|
|
|
// pre calcul
|
|
vertex[k].inv_z = (1<<13) / vertex[k].z;
|
|
vertex[k].z_normalized = (1<<15) * ( float(vertex[k].z - camera.near) / float(camera.far) );
|
|
}
|
|
}
|