fix: now rotating just fine
This commit is contained in:
parent
f2bb638c0b
commit
a1cd49180b
1 changed files with 59 additions and 71 deletions
128
source/main.c
128
source/main.c
|
@ -67,13 +67,6 @@ flipBuffers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
putPx(uint16_t x, uint16_t y, uint8_t c)
|
|
||||||
{
|
|
||||||
uint16_t pos = (GBA_SCREEN_W * y + x);
|
|
||||||
buffer[pos] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -82,8 +75,6 @@ putPx(uint16_t x, uint16_t y, uint8_t c)
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
#define VWIDTH 25
|
|
||||||
#define VHEIGHT 25
|
|
||||||
#define CUBE_WIDTH 10
|
#define CUBE_WIDTH 10
|
||||||
#define CUBE_WIDTH_FP ((1 << FP) * CUBE_WIDTH)
|
#define CUBE_WIDTH_FP ((1 << FP) * CUBE_WIDTH)
|
||||||
|
|
||||||
|
@ -103,21 +94,16 @@ enum faces {
|
||||||
#define ACTION_STEP 0.1
|
#define ACTION_STEP 0.1
|
||||||
#define ACTION_STEP_FP ((1 << FP) * ACTION_STEP)
|
#define ACTION_STEP_FP ((1 << FP) * ACTION_STEP)
|
||||||
|
|
||||||
#define SCALE 3 // how much is our initial render scaled
|
#define SCALE 5 // how much is our initial render scaled
|
||||||
|
|
||||||
volatile FIXED_POINT K1 = 20;
|
#define K1 (20)
|
||||||
volatile FIXED_POINT K2 = (2 * CUBE_WIDTH) + 10;
|
#define K2 (2 * CUBE_WIDTH + 10)
|
||||||
|
|
||||||
#define MULT_FP(a, b) ((a * b) >> FP)
|
#define MULT_FP(a, b) ((a * b) >> FP)
|
||||||
|
|
||||||
#define SQ(n) (n * n)
|
#define SQ(n) (n * n)
|
||||||
#define SQ_FP(n) (MULT_FP(n, n))
|
#define SQ_FP(n) (MULT_FP(n, n))
|
||||||
|
|
||||||
#define PLOT_COORD(x, y, c) \
|
|
||||||
for (uint8_t i = 0 ; i < SCALE ; ++i) \
|
|
||||||
for (uint8_t j = 0 ; j < SCALE ; ++j) \
|
|
||||||
putPx(x * SCALE + i, j + (SCALE * y), chooseColor(c));
|
|
||||||
|
|
||||||
#define GET_ROTATE_X_Q(a) ({ float _a = (a) ; \
|
#define GET_ROTATE_X_Q(a) ({ float _a = (a) ; \
|
||||||
struct Quaternions q = {}; q.w = FLOAT2FIXED(cos(_a * .5)); \
|
struct Quaternions q = {}; q.w = FLOAT2FIXED(cos(_a * .5)); \
|
||||||
q.x = FLOAT2FIXED(sin(_a * .5)); q; })
|
q.x = FLOAT2FIXED(sin(_a * .5)); q; })
|
||||||
|
@ -149,6 +135,25 @@ init_colors()
|
||||||
PALETTE[lastPaletteIndex] = color_order[lastPaletteIndex];
|
PALETTE[lastPaletteIndex] = color_order[lastPaletteIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
chooseColor(uint8_t c)
|
||||||
|
{
|
||||||
|
if (c >= 0 && c < NUM_FACES)
|
||||||
|
return c + 1; // palette 0 is bg
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putPx(uint16_t x, uint16_t y, uint8_t c)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0 ; i < SCALE ; ++i)
|
||||||
|
for (uint8_t j = 0 ; j < SCALE ; ++j) {
|
||||||
|
uint16_t pos = GBA_SCREEN_W * (y * SCALE + j) + x * SCALE + i;
|
||||||
|
buffer[pos] = chooseColor(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
uint8_t y;
|
uint8_t y;
|
||||||
|
@ -177,7 +182,7 @@ normalize(struct Quaternions *q)
|
||||||
{
|
{
|
||||||
float n = sqrt(FIXED2FLOAT(SQ_FP(q->w) + SQ_FP(q->x) +
|
float n = sqrt(FIXED2FLOAT(SQ_FP(q->w) + SQ_FP(q->x) +
|
||||||
SQ_FP(q->y) + SQ_FP(q->z)));
|
SQ_FP(q->y) + SQ_FP(q->z)));
|
||||||
if (n == 0 || n == 1)
|
if (n == 0.|| n == 1.)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
q->w = FLOAT2FIXED(FIXED2FLOAT(q->w) / n);
|
q->w = FLOAT2FIXED(FIXED2FLOAT(q->w) / n);
|
||||||
|
@ -192,17 +197,18 @@ mult(struct Quaternions *q, FIXED_POINT x, FIXED_POINT y, FIXED_POINT z)
|
||||||
//p = q * p * qbar
|
//p = q * p * qbar
|
||||||
struct Quaternions res;
|
struct Quaternions res;
|
||||||
|
|
||||||
|
// << 1 <=> * 2
|
||||||
res.w = 0;
|
res.w = 0;
|
||||||
res.x = MULT_FP(x, (SQ_FP(q->w) + SQ_FP(q->x) - SQ_FP(q->y) - SQ_FP(q->z)))
|
res.x = MULT_FP(x, (SQ_FP(q->w) + SQ_FP(q->x) - SQ_FP(q->y) - SQ_FP(q->z)))
|
||||||
+ (MULT_FP(y, (MULT_FP(q->x, q->y) - MULT_FP(q->w, q->z))) * 2)
|
+ (MULT_FP(y, (MULT_FP(q->x, q->y) - MULT_FP(q->w, q->z))) << 1)
|
||||||
+ (MULT_FP(z, (MULT_FP(q->x, q->z) + MULT_FP(q->w, q->y))) * 2);
|
+ (MULT_FP(z, (MULT_FP(q->x, q->z) + MULT_FP(q->w, q->y))) << 1);
|
||||||
|
|
||||||
res.y = (MULT_FP(x, (MULT_FP(q->x, q->y) + MULT_FP(q->w,q->z))) * 2)
|
res.y = (MULT_FP(x, (MULT_FP(q->x, q->y) + MULT_FP(q->w,q->z))) << 1)
|
||||||
+ (MULT_FP(y, (SQ_FP(q->w) - SQ_FP(q->x) + SQ_FP(q->y) - SQ_FP(q->z))))
|
+ (MULT_FP(y, (SQ_FP(q->w) - SQ_FP(q->x) + SQ_FP(q->y) - SQ_FP(q->z))))
|
||||||
+ (MULT_FP(z, (MULT_FP(q->y, q->z) - MULT_FP(q->w, q->x))) << 2);
|
+ (MULT_FP(z, (MULT_FP(q->y, q->z) - MULT_FP(q->w, q->x))) << 1);
|
||||||
|
|
||||||
res.z = (MULT_FP(x, (MULT_FP(q->x, q->z) - MULT_FP(q->w, q->y)))* 2)
|
res.z = (MULT_FP(x, (MULT_FP(q->x, q->z) - MULT_FP(q->w, q->y))) << 1)
|
||||||
+ (MULT_FP(y, (MULT_FP(q->y, q->z) + MULT_FP(q->w, q->x))) * 2)
|
+ (MULT_FP(y, (MULT_FP(q->y, q->z) + MULT_FP(q->w, q->x))) << 1)
|
||||||
+ MULT_FP(z, (SQ_FP(q->w) - SQ_FP(q->x) - SQ_FP(q->y) + SQ_FP(q->z)));
|
+ MULT_FP(z, (SQ_FP(q->w) - SQ_FP(q->x) - SQ_FP(q->y) + SQ_FP(q->z)));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -239,52 +245,17 @@ multQ(struct Quaternions *p, struct Quaternions *q)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t
|
uint8_t
|
||||||
chooseColor(uint8_t c)
|
chooseMainFace()
|
||||||
{
|
{
|
||||||
if (c >= 0 && c < NUM_FACES)
|
// TODO
|
||||||
return c + 1; // palette 0 is bg
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
|
||||||
chooseMainFace()
|
|
||||||
{
|
|
||||||
int total = 0;
|
|
||||||
int faces[NUM_FACES] = {0};
|
|
||||||
|
|
||||||
for (int k = 0; k < VWIDTH * VHEIGHT; ++k)
|
|
||||||
if (vertices[k] >= 0 && vertices[k] < NUM_FACES) {
|
|
||||||
faces[vertices[k]]++;
|
|
||||||
++total;
|
|
||||||
}
|
|
||||||
|
|
||||||
int max = 0, idx = 0;
|
|
||||||
for (int k = 0; k < NUM_FACES; ++k)
|
|
||||||
if (faces[k] > max) {
|
|
||||||
max = faces[k];
|
|
||||||
idx = k;
|
|
||||||
}
|
|
||||||
|
|
||||||
frontFacingFace = max > total * 0.9 ? idx : -1;
|
|
||||||
return frontFacingFace;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ISSUE the 4 vertices rendered do not make a convex quad
|
|
||||||
// we have to switch 2 vertices for that
|
|
||||||
#pragma GCC
|
|
||||||
uint8_t
|
uint8_t
|
||||||
isInQuad(const uint16_t x, const uint16_t y, uint8_t current_face)
|
isInQuad(const uint16_t x, const uint16_t y, uint8_t current_face)
|
||||||
{
|
{
|
||||||
uint16_t *points = (uint16_t *)&vertices[current_face * 8];
|
uint16_t *points = (uint16_t *)&vertices[current_face * 8];
|
||||||
// little hack
|
|
||||||
|
|
||||||
uint16_t tmpX = points[6], tmpY = points[7];
|
|
||||||
points[6] = points[4];
|
|
||||||
points[7] = points[5];
|
|
||||||
points[4] = tmpX;
|
|
||||||
points[5] = tmpY;
|
|
||||||
|
|
||||||
uint8_t pos = 0, neg = 0;
|
uint8_t pos = 0, neg = 0;
|
||||||
int32_t d;
|
int32_t d;
|
||||||
|
@ -294,15 +265,14 @@ isInQuad(const uint16_t x, const uint16_t y, uint8_t current_face)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
//Form a segment between the i'th point
|
//Form a segment between the i'th point
|
||||||
int32_t x1 = points[2 * i];
|
uint16_t x1 = points[2 * i];
|
||||||
int32_t y1 = points[2 * i + 1];
|
uint16_t y1 = points[2 * i + 1];
|
||||||
|
|
||||||
//And the i+1'th, or if i is the last, with the first point
|
//And the i+1'th, or if i is the last, with the first point
|
||||||
uint8_t i2 = (i + 1) % 4;
|
uint8_t i2 = (i + 1) % 4;
|
||||||
|
|
||||||
int32_t x2 = points[2 * i2];
|
uint16_t x2 = points[2 * i2];
|
||||||
int32_t y2 = points[2 * i2 + 1];
|
uint16_t y2 = points[2 * i2 + 1];
|
||||||
|
|
||||||
|
|
||||||
//Compute the cross product
|
//Compute the cross product
|
||||||
d = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1);
|
d = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1);
|
||||||
|
@ -318,9 +288,27 @@ isInQuad(const uint16_t x, const uint16_t y, uint8_t current_face)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the 4 vertices rendered do not make a convex quad
|
||||||
|
// we have to switch 2 vertices for that
|
||||||
|
// only works because we render 4 points left to right
|
||||||
|
void
|
||||||
|
makeConvex(uint16_t *points)
|
||||||
|
{
|
||||||
|
// little hack
|
||||||
|
|
||||||
|
uint16_t tmpX = points[6], tmpY = points[7];
|
||||||
|
points[6] = points[4];
|
||||||
|
points[7] = points[5];
|
||||||
|
points[4] = tmpX;
|
||||||
|
points[5] = tmpY;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fillQuads(uint8_t current_face)
|
fillQuads(uint8_t current_face)
|
||||||
{
|
{
|
||||||
|
makeConvex((uint16_t *)&vertices[current_face * 8]);
|
||||||
|
|
||||||
uint16_t top = UINT16_MAX, bot = 0, left = UINT16_MAX, right = 0;
|
uint16_t top = UINT16_MAX, bot = 0, left = UINT16_MAX, right = 0;
|
||||||
for (uint8_t k = 0 ; k < 8 ; ++k) {
|
for (uint8_t k = 0 ; k < 8 ; ++k) {
|
||||||
const uint16_t item = vertices[current_face * 8 + k];
|
const uint16_t item = vertices[current_face * 8 + k];
|
||||||
|
@ -341,7 +329,7 @@ fillQuads(uint8_t current_face)
|
||||||
for (uint16_t y = top ; y <= bot; ++y) {
|
for (uint16_t y = top ; y <= bot; ++y) {
|
||||||
for (uint16_t x = left ; x <= right ; ++x) {
|
for (uint16_t x = left ; x <= right ; ++x) {
|
||||||
if (isInQuad(x, y, current_face))
|
if (isInQuad(x, y, current_face))
|
||||||
PLOT_COORD(x, y, current_face);
|
putPx(x, y, current_face);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,7 +505,7 @@ uint8_t
|
||||||
getInput()
|
getInput()
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
uint8_t c = 'd';
|
uint8_t c = 's';
|
||||||
handleAngle(c);
|
handleAngle(c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -533,7 +521,7 @@ main()
|
||||||
memset(MEM_VRAM_MODE4, 0, GBA_SCREEN_H * GBA_SCREEN_W);
|
memset(MEM_VRAM_MODE4, 0, GBA_SCREEN_H * GBA_SCREEN_W);
|
||||||
memset((uint16_t *)vertices, UINT16_MAX, sizeof(uint16_t) * NUM_FACES * 4 * 2);
|
memset((uint16_t *)vertices, UINT16_MAX, sizeof(uint16_t) * NUM_FACES * 4 * 2);
|
||||||
//zBuff is not correct data struct, need a map or smth
|
//zBuff is not correct data struct, need a map or smth
|
||||||
memset((uint16_t *)zBuffer, 0, NUM_FACES * 2 * sizeof(FIXED_POINT));
|
memset((FIXED_POINT *)zBuffer, 0, NUM_FACES * 2 * sizeof(FIXED_POINT));
|
||||||
|
|
||||||
for (FIXED_POINT cubeX = -CUBE_WIDTH_FP + 1 * (1 << FP);
|
for (FIXED_POINT cubeX = -CUBE_WIDTH_FP + 1 * (1 << FP);
|
||||||
cubeX <= CUBE_WIDTH_FP - 1 * (1 << FP); cubeX += STEP_FP - 2 * (1 << FP)) {
|
cubeX <= CUBE_WIDTH_FP - 1 * (1 << FP); cubeX += STEP_FP - 2 * (1 << FP)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue