the perspective transform finally looks right
This commit is contained in:
parent
78de86f4a8
commit
8b8097253c
39
camera.c
39
camera.c
@ -22,15 +22,14 @@ camera_new(
|
||||
v3_t eye,
|
||||
v3_t lookat,
|
||||
v3_t up,
|
||||
float fov,
|
||||
float scale
|
||||
float fov
|
||||
)
|
||||
{
|
||||
camera_t * c = calloc(1, sizeof(*c));
|
||||
if (!c)
|
||||
return NULL;
|
||||
|
||||
camera_setup(c, eye, lookat, up, fov, scale);
|
||||
camera_setup(c, eye, lookat, up, fov);
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -41,8 +40,7 @@ camera_setup(
|
||||
v3_t eye,
|
||||
v3_t lookat,
|
||||
v3_t up,
|
||||
float fov,
|
||||
float scale
|
||||
float fov
|
||||
)
|
||||
{
|
||||
// compute the basis for the camera
|
||||
@ -62,9 +60,9 @@ camera_setup(
|
||||
{ u.p[2], v.p[2], w.p[2], 0 },
|
||||
{ -v3_dot(u,eye), -v3_dot(v,eye), -v3_dot(w,eye), 1 },
|
||||
#else
|
||||
{ u.p[0], u.p[1], u.p[2], -v3_dot(u,lookat) },
|
||||
{ v.p[0], v.p[1], v.p[2], -v3_dot(v,lookat) },
|
||||
{ w.p[0], w.p[1], w.p[2], -v3_dot(w,lookat) },
|
||||
{ u.p[0], u.p[1], u.p[2], -v3_dot(u,eye) },
|
||||
{ v.p[0], v.p[1], v.p[2], -v3_dot(v,eye) },
|
||||
{ w.p[0], w.p[1], w.p[2], -v3_dot(w,eye) },
|
||||
{ 0, 0, 0, 1 },
|
||||
#endif
|
||||
};
|
||||
@ -80,7 +78,7 @@ camera_setup(
|
||||
|
||||
// now compute the perspective projection matrix
|
||||
float s = 1.0 / tan(fov * M_PI / 180 / 2);
|
||||
c->near = 1.0;
|
||||
c->near = 4.0;
|
||||
c->far = 20;
|
||||
float f1 = - c->far / (c->far - c->near);
|
||||
float f2 = - c->far * c->near / (c->far - c->near);
|
||||
@ -142,17 +140,28 @@ camera_project(
|
||||
for (int j = 0 ; j < 4 ; j++)
|
||||
p[i] += c->r[i][j] * v[j];
|
||||
|
||||
if(1) fprintf(stderr, "%.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",
|
||||
// what if p->p[4] == 0?
|
||||
// pz < 0 == The point is behind us; do not display?
|
||||
//if (p[2] < c->near || p[2] > c->far)
|
||||
if (p[2] < 0)
|
||||
return 0;
|
||||
|
||||
p[0] /= p[3];
|
||||
p[1] /= p[3];
|
||||
/*
|
||||
for (int i = 0 ; i < 3 ; i++)
|
||||
p[i] /= p[3];
|
||||
p[2] /= p[3];
|
||||
*/
|
||||
|
||||
if(0) fprintf(stderr, "%.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",
|
||||
v[0], v[1], v[2],
|
||||
p[0], p[1], p[2], p[3]
|
||||
);
|
||||
|
||||
/*
|
||||
for (int i = 0 ; i < 3 ; i++)
|
||||
p[i] /= p[3];
|
||||
p[0] *= -1;
|
||||
p[1] *= -1;
|
||||
p[2] /= p[3];
|
||||
*/
|
||||
|
||||
|
||||
@ -162,10 +171,6 @@ camera_project(
|
||||
v_out->p[1] = p[1];
|
||||
v_out->p[2] = p[2];
|
||||
|
||||
// what if p->p[4] == 0?
|
||||
// pz < 0 == The point is behind us; do not display?
|
||||
if (p[2] < c->near || p[2] > c->far)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
6
camera.h
6
camera.h
@ -9,8 +9,7 @@ camera_new(
|
||||
v3_t eye,
|
||||
v3_t lookat,
|
||||
v3_t up,
|
||||
float fov,
|
||||
float scale
|
||||
float fov
|
||||
);
|
||||
|
||||
extern void
|
||||
@ -19,8 +18,7 @@ camera_setup(
|
||||
v3_t eye,
|
||||
v3_t lookat,
|
||||
v3_t up,
|
||||
float fov,
|
||||
float scale
|
||||
float fov
|
||||
);
|
||||
|
||||
/** Transform a XYZ point into a screen point.
|
||||
|
32
hiddenwire.c
32
hiddenwire.c
@ -768,8 +768,10 @@ int onscreen(
|
||||
{
|
||||
if (p->p[0] < -width/2 || width/2 < p->p[0])
|
||||
return 0;
|
||||
/*
|
||||
if (p->p[1] < -height/2 || height/2 < p->p[1])
|
||||
return 0;
|
||||
*/
|
||||
/*
|
||||
if (p->p[0] < 0 || width < p->p[0])
|
||||
return 0;
|
||||
@ -868,7 +870,8 @@ int main(
|
||||
}
|
||||
|
||||
|
||||
const camera_t * const cam = camera_new(eye, lookat, up, fov, scale);
|
||||
(void) scale;
|
||||
const camera_t * const cam = camera_new(eye, lookat, up, fov);
|
||||
|
||||
printf("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"%.0fpx\" height=\"%.0fpx\" viewbox=\"0 0 %.0f %.0f\">\n", width, height, width, height);
|
||||
|
||||
@ -897,18 +900,27 @@ int main(
|
||||
|
||||
for(int j = 0 ; j < 3 ; j++)
|
||||
{
|
||||
camera_project(cam, &stl->p[j], &s[j]);
|
||||
// if any points are behind us, reject
|
||||
// this one
|
||||
if (!camera_project(cam, &stl->p[j], &s[j]))
|
||||
{
|
||||
behind++;
|
||||
goto reject_early;
|
||||
}
|
||||
}
|
||||
|
||||
if(debug >= 2)
|
||||
fprintf(stderr, "%.3f,%.3f,%.3f -> %.1f,%.1f,%.1f\n",
|
||||
stl->p[0].p[0],
|
||||
stl->p[0].p[1],
|
||||
stl->p[0].p[2],
|
||||
s[0].p[0],
|
||||
s[0].p[1],
|
||||
s[0].p[2]
|
||||
for(int j = 0 ; j < 3 ; j++)
|
||||
{
|
||||
fprintf(stderr, "%.3f %.3f %.3f -> %.3f %.3f %.3f\n",
|
||||
stl->p[j].p[0],
|
||||
stl->p[j].p[1],
|
||||
stl->p[j].p[2],
|
||||
s[j].p[0],
|
||||
s[j].p[1],
|
||||
s[j].p[2]
|
||||
);
|
||||
}
|
||||
|
||||
tri_t * const tri = tri_new(s, stl->p);
|
||||
|
||||
@ -962,6 +974,8 @@ tri_print(tri);
|
||||
|
||||
reject:
|
||||
tri_delete(tri);
|
||||
reject_early:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
|
25
test.c
Normal file
25
test.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
#include "camera.h"
|
||||
#include "v3.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
v3_t lookat = {{0,0,0}};
|
||||
v3_t eye = {{0,-20,0}};
|
||||
v3_t up = {{0,0,1}};
|
||||
float fov = 20;
|
||||
|
||||
camera_t * camera = camera_new(eye, lookat, up, fov);
|
||||
|
||||
for (float x = -5 ; x <= 5 ; x += 5)
|
||||
for (float y = -25 ; y < 55 ; y += 5 )
|
||||
{
|
||||
v3_t v_in = {{ x, y, 5 }};
|
||||
v3_t v_out;
|
||||
int onscreen = camera_project(camera, &v_in, &v_out);
|
||||
if (!onscreen && y > eye.p[1])
|
||||
fprintf(stderr, "false positive\n");
|
||||
if (onscreen && y < eye.p[1])
|
||||
fprintf(stderr, "false negative\n");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user