windmill-gint/src/windmill_transform.cpp

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) );
}
}