Files
kichikuou_xsystem35-sdl2/modules/SACT/sprite_eupdate_perspect.c
T
kichikuou ebb249cd47 Remove 15bpp surface operations
These were used only with X11 backend.
2020-10-04 16:01:48 +09:00

177 lines
4.0 KiB
C

// 透視投影変換のうち、X軸とY軸周りの回転のみを考慮
/*
X軸回転行列 1 0 0 0
0 cos sin 0
0 -sin cos 0
0 0 0 1
Y軸回転行列 cos 0 sin 0
0 1 0 0
-sin 0 cos 0
0 0 0 1
視点座標変換行列 (G)
1 0 0 0
0 1 0 0
0 0 -1 0
0 0 t 1 , t = 1
透視変換行列 (H)
1 0 0 0
0 1 0 0
0 0 1/s 1/s
0 0 -1 0 , s = 1
X軸回転 (ys = height/2)
k[1] = -sin(rx* M_PI / 180) / (float)ys;
k[2] = cos(rx* M_PI / 180);
k[3] = cos(rx* M_PI / 180);
k[7] = 1;
Y軸回転 (xs = width/2)
k[0] = sin(ry * M_PI / 180) / (float)xs;
k[2] = cos(ry * M_PI / 180);
k[3] = 1;
k[7] = cos(ry * M_PI / 180);
*/
#include <math.h>
static void do_per(surface_t *in, surface_t *out, float *k) {
int i, j, m, n;
float x, y, w;
int xs = in->width /2;
int ys = in->height /2;
switch(in->depth) {
case 16: {
WORD *src, *dst;
for (i = -ys; i < ys; i++) {
for (j = -xs; j < xs; j++) {
w = k[0] * j + k[1]*i + k[2];
x = k[3] * j + k[4]*i + k[5];
y = k[6] * j + k[7]*i + k[8];
x = x / w;
y = y / w;
if (y > 0) m = (int)y;
else m = (int)(y -1);
if (x > 0) n = (int)x;
else n = (int)(x - 1);
src = (WORD *)GETOFFSET_PIXEL( in, n+xs, m+ys);
dst = (WORD *)GETOFFSET_PIXEL(out, j+xs, i+ys);
if (( m >= -ys) && (m < ys) && (n >= -xs) && (n < xs)) {
*dst = *src;
} else {
*dst = 0;
}
}
}
break;
}
case 24:
case 32: {
DWORD *src, *dst;
for (i = -ys; i < ys; i++) {
for (j = -xs; j < xs; j++) {
w = k[0] * j + k[1]*i + k[2];
x = k[3] * j + k[4]*i + k[5];
y = k[6] * j + k[7]*i + k[8];
x = x / w;
y = y / w;
if (y > 0) m = (int)y;
else m = (int)(y -1);
if (x > 0) n = (int)x;
else n = (int)(x - 1);
src = (DWORD *)GETOFFSET_PIXEL( in, n+xs, m+ys);
dst = (DWORD *)GETOFFSET_PIXEL(out, j+xs, i+ys);
if (( m >= -ys) && (m < ys) && (n >= -xs) && (n < xs)) {
*dst = *src;
} else {
*dst = 0;
}
}
}
break;
}}
}
static void perspect_rotatex(surface_t *in, surface_t *out, double rx) {
float k[9] = {0.0};
k[1] = -sin(rx) / (in->height / 2.0);
k[2] = cos(rx);
k[3] = cos(rx);
k[7] = 1.0;
do_per(in, out, k);
}
static void perspect_rotatey(surface_t *in, surface_t *out, double ry) {
float k[9] = {0.0};
k[0] = sin(ry) / (in->width / 2.0);
k[2] = cos(ry);
k[3] = 1.0;
k[7] = cos(ry);
do_per(in, out, k);
}
// ポリゴン回転(Y軸・半計回り)
static void ec25_cb(surface_t *src, surface_t *dst) {
int curstep, maxstep;
maxstep = 180;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
if (curstep < 90) {
perspect_rotatey(src, sf0, -curstep * M_PI / 180);
} else {
perspect_rotatey(dst, sf0, (180 - curstep) * M_PI / 180);
}
ags_updateFull();
}
// ポリゴン回転(Y軸・計回り)
static void ec26_cb(surface_t *src, surface_t *dst) {
int curstep, maxstep;
maxstep = 180;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
if (curstep < 90) {
perspect_rotatey(src, sf0, curstep * M_PI / 180);
} else {
perspect_rotatey(dst, sf0, (curstep - 180) * M_PI / 180);
}
ags_updateFull();
}
// ポリゴン回転(X軸・時計回り)
static void ec28_cb(surface_t *src, surface_t *dst) {
int curstep, maxstep;
maxstep = 180;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
if (curstep < 90) {
perspect_rotatex(src, sf0, -curstep * M_PI / 180);
} else {
perspect_rotatex(dst, sf0, (180 - curstep) * M_PI / 180);
}
ags_updateFull();
}
// ポリゴン回転(X軸)
static void ec29_cb(surface_t *src, surface_t *dst) {
int curstep, maxstep;
maxstep = 180;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
if (curstep < 90) {
perspect_rotatex(src, sf0, curstep * M_PI / 180);
} else {
perspect_rotatex(dst, sf0, (curstep - 180) * M_PI / 180);
}
ags_updateFull();
}