164 lines
3.2 KiB
C
164 lines
3.2 KiB
C
/*
|
|
* This software is licensed under the terms of the MIT-License
|
|
* See COPYING for further information.
|
|
* ---
|
|
* Copyright (c) 2011-2018, Lukas Weber <laochailan@web.de>.
|
|
* Copyright (c) 2012-2018, Andrei Alexeyev <akari@alienslab.net>.
|
|
*/
|
|
|
|
#include "taisei.h"
|
|
|
|
#include "stageutils.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "taiseigl.h"
|
|
#include "global.h"
|
|
|
|
Stage3D stage_3d_context;
|
|
|
|
void init_stage3d(Stage3D *s) {
|
|
memset(s, 0, sizeof(Stage3D));
|
|
s->projangle = 45;
|
|
}
|
|
|
|
void add_model(Stage3D *s, SegmentDrawRule draw, SegmentPositionRule pos) {
|
|
s->models = realloc(s->models, (++s->msize)*sizeof(StageSegment));
|
|
|
|
s->models[s->msize - 1].draw = draw;
|
|
s->models[s->msize - 1].pos = pos;
|
|
}
|
|
|
|
void set_perspective_viewport(Stage3D *s, float n, float f, int vx, int vy, int vw, int vh) {
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
float facw = SCREEN_W/(float)VIEWPORT_W;
|
|
float fach = SCREEN_H/(float)VIEWPORT_H;
|
|
glScalef(facw,fach,1);
|
|
gluPerspective(s->projangle, 1, n, f);
|
|
glTranslatef(vx+vw/2.0, vy+vh/2.0, 0);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
}
|
|
|
|
void set_perspective(Stage3D *s, float n, float f) {
|
|
set_perspective_viewport(s, n, f, VIEWPORT_X, VIEWPORT_Y, VIEWPORT_W, VIEWPORT_H);
|
|
}
|
|
|
|
void update_stage3d(Stage3D *s) {
|
|
for(int i = 0; i < 3; i++){
|
|
s->cx[i] += s->cv[i];
|
|
}
|
|
}
|
|
|
|
void draw_stage3d(Stage3D *s, float maxrange) {
|
|
glPushMatrix();
|
|
|
|
if(s->crot[0])
|
|
glRotatef(-s->crot[0], 1, 0, 0);
|
|
if(s->crot[1])
|
|
glRotatef(-s->crot[1], 0, 1, 0);
|
|
if(s->crot[2])
|
|
glRotatef(-s->crot[2], 0, 0, 1);
|
|
|
|
if(s->cx[0] || s->cx[1] || s->cx[2])
|
|
glTranslatef(-s->cx[0],-s->cx[1],-s->cx[2]);
|
|
|
|
for(int i = 0; i < s->msize; i++) {
|
|
Vector **list;
|
|
list = s->models[i].pos(s->cx, maxrange);
|
|
|
|
for(int j = 0; list && list[j] != NULL; j++) {
|
|
s->models[i].draw(*list[j]);
|
|
free(list[j]);
|
|
}
|
|
|
|
free(list);
|
|
}
|
|
|
|
glPopMatrix();
|
|
}
|
|
|
|
void free_stage3d(Stage3D *s) {
|
|
free(s->models);
|
|
}
|
|
|
|
Vector **linear3dpos(Vector q, float maxrange, Vector p, Vector r) {
|
|
int i;
|
|
float n = 0, z = 0;
|
|
for(i = 0; i < 3; i++) {
|
|
n += q[i]*r[i] - p[i]*r[i];
|
|
z += r[i]*r[i];
|
|
}
|
|
|
|
float t = n/z;
|
|
|
|
Vector **list = NULL;
|
|
int size = 0;
|
|
int mod = 1;
|
|
|
|
int num = t;
|
|
while(1) {
|
|
Vector dif;
|
|
|
|
for(i = 0; i < 3; i++)
|
|
dif[i] = q[i] - p[i] - r[i]*num;
|
|
|
|
if(length(dif) < maxrange) {
|
|
list = realloc(list, (++size)*sizeof(Vector*));
|
|
list[size-1] = malloc(sizeof(Vector));
|
|
for(i = 0; i < 3; i++)
|
|
(*list[size-1])[i] = p[i] + r[i]*num;
|
|
} else if(mod == 1) {
|
|
mod = -1;
|
|
num = t;
|
|
} else {
|
|
break;
|
|
}
|
|
|
|
num += mod;
|
|
}
|
|
|
|
list = realloc(list, (++size)*sizeof(Vector*));
|
|
list[size-1] = NULL;
|
|
|
|
return list;
|
|
}
|
|
|
|
Vector **single3dpos(Vector q, float maxrange, Vector p) {
|
|
Vector d;
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < 3; i++)
|
|
d[i] = p[i] - q[i];
|
|
|
|
if(length(d) > maxrange) {
|
|
return NULL;
|
|
} else {
|
|
Vector **list = calloc(2, sizeof(Vector*));
|
|
|
|
list[0] = malloc(sizeof(Vector));
|
|
for(i = 0; i < 3; i++)
|
|
(*list[0])[i] = p[i];
|
|
list[1] = NULL;
|
|
|
|
return list;
|
|
}
|
|
}
|
|
|
|
void skip_background_anim(Stage3D *s3d, void (*update_func)(void), int frames, int *timer, int *timer2) {
|
|
int targetframes = *timer + frames;
|
|
|
|
while(++(*timer) < targetframes) {
|
|
if(timer2) {
|
|
++(*timer2);
|
|
}
|
|
|
|
update_func();
|
|
}
|
|
|
|
if(timer2) {
|
|
++(*timer2);
|
|
}
|
|
}
|