libwindmill/src/dynamic.c

70 lines
2.6 KiB
C

/* *****************************************************************************
* dynamic.c -- dynamic thingies.
* Copyright (C) 2017 Olivier "Ninestars" Lanneau
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libwindmill.
* libwindmill is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libwindmill is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libwindmill; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************** */
#include <libwindmill/internals.h>
void wml_dynamic(wml_vertex_t *vertex, int axe, int x, int y, int z,
float cosinus, float sinus)
{
int vertex_x = vertex->x,
vertex_y = vertex->y,
vertex_z = vertex->z;
if (axe == N) {
vertex->x = vertex_x + x;
vertex->y = vertex_y + y;
vertex->z = vertex_z + z;
} else if (axe == X) {
vertex->x = vertex_x + x;
vertex->y = vertex_y * cosinus - vertex_z * sinus + y;
vertex->z = vertex_z * sinus + vertex_z * cosinus + z;
} else if (axe == Y) {
vertex->x = vertex_x * cosinus - vertex_z * sinus + x;
vertex->y = vertex_y + y;
vertex->z = vertex_x * sinus + vertex_z * cosinus + z;
} else if (axe == Z) {
vertex->x = vertex_x * cosinus - vertex_y * sinus + x;
vertex->y = vertex_x * sinus + vertex_y * cosinus + y;
vertex->z = vertex_z + z;
}
}
void wml_transform(wml_scene_t *scene, wml_vertex_t *vertex)
{
int vertex_x = vertex->x - (int)scene->camera_x,
vertex_y = vertex->y - (int)scene->camera_y,
vertex_z = vertex->z - (int)scene->camera_z;
/* produit matriciel */
int x = scene->a1 * vertex_x + scene->a2 * vertex_y;
int y = scene->a4 * vertex_x + scene->a5 * vertex_y + scene->a6 * vertex_z;
int z = scene->a7 * vertex_x + scene->a8 * vertex_y + scene->a9 * vertex_z;
/* perspective */
if (z < 0) { /* z < near * 128 * 128 */
vertex->x = -(x * scene->scale_coef + 8192) / z + shift_x;
vertex->y = -(y * scene->scale_coef + 8192) / z + shift_y;
vertex->z = 8192 / z;
/* calcul de z normalise entre les deux plans de clipping */
vertex->z_normalized = -(0xFFFF *
(scene->near_coef * z + scene->far_coef) + 32767) / z;
} else
vertex->z = 1;
}