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 eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up,
|
v3_t up,
|
||||||
float fov,
|
float fov
|
||||||
float scale
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
camera_t * c = calloc(1, sizeof(*c));
|
camera_t * c = calloc(1, sizeof(*c));
|
||||||
if (!c)
|
if (!c)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
camera_setup(c, eye, lookat, up, fov, scale);
|
camera_setup(c, eye, lookat, up, fov);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,8 +40,7 @@ camera_setup(
|
|||||||
v3_t eye,
|
v3_t eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up,
|
v3_t up,
|
||||||
float fov,
|
float fov
|
||||||
float scale
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// compute the basis for the camera
|
// compute the basis for the camera
|
||||||
@ -62,9 +60,9 @@ camera_setup(
|
|||||||
{ u.p[2], v.p[2], w.p[2], 0 },
|
{ u.p[2], v.p[2], w.p[2], 0 },
|
||||||
{ -v3_dot(u,eye), -v3_dot(v,eye), -v3_dot(w,eye), 1 },
|
{ -v3_dot(u,eye), -v3_dot(v,eye), -v3_dot(w,eye), 1 },
|
||||||
#else
|
#else
|
||||||
{ u.p[0], u.p[1], u.p[2], -v3_dot(u,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,lookat) },
|
{ 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,lookat) },
|
{ w.p[0], w.p[1], w.p[2], -v3_dot(w,eye) },
|
||||||
{ 0, 0, 0, 1 },
|
{ 0, 0, 0, 1 },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -80,7 +78,7 @@ camera_setup(
|
|||||||
|
|
||||||
// now compute the perspective projection matrix
|
// now compute the perspective projection matrix
|
||||||
float s = 1.0 / tan(fov * M_PI / 180 / 2);
|
float s = 1.0 / tan(fov * M_PI / 180 / 2);
|
||||||
c->near = 1.0;
|
c->near = 4.0;
|
||||||
c->far = 20;
|
c->far = 20;
|
||||||
float f1 = - c->far / (c->far - c->near);
|
float f1 = - c->far / (c->far - c->near);
|
||||||
float f2 = - c->far * c->near / (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++)
|
for (int j = 0 ; j < 4 ; j++)
|
||||||
p[i] += c->r[i][j] * v[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],
|
v[0], v[1], v[2],
|
||||||
p[0], p[1], p[2], p[3]
|
p[0], p[1], p[2], p[3]
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for (int i = 0 ; i < 3 ; i++)
|
|
||||||
p[i] /= p[3];
|
|
||||||
p[0] *= -1;
|
p[0] *= -1;
|
||||||
p[1] *= -1;
|
p[1] *= -1;
|
||||||
p[2] /= p[3];
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -162,10 +171,6 @@ camera_project(
|
|||||||
v_out->p[1] = p[1];
|
v_out->p[1] = p[1];
|
||||||
v_out->p[2] = p[2];
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
6
camera.h
6
camera.h
@ -9,8 +9,7 @@ camera_new(
|
|||||||
v3_t eye,
|
v3_t eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up,
|
v3_t up,
|
||||||
float fov,
|
float fov
|
||||||
float scale
|
|
||||||
);
|
);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
@ -19,8 +18,7 @@ camera_setup(
|
|||||||
v3_t eye,
|
v3_t eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up,
|
v3_t up,
|
||||||
float fov,
|
float fov
|
||||||
float scale
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Transform a XYZ point into a screen point.
|
/** 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])
|
if (p->p[0] < -width/2 || width/2 < p->p[0])
|
||||||
return 0;
|
return 0;
|
||||||
|
/*
|
||||||
if (p->p[1] < -height/2 || height/2 < p->p[1])
|
if (p->p[1] < -height/2 || height/2 < p->p[1])
|
||||||
return 0;
|
return 0;
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
if (p->p[0] < 0 || width < p->p[0])
|
if (p->p[0] < 0 || width < p->p[0])
|
||||||
return 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);
|
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++)
|
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)
|
if(debug >= 2)
|
||||||
fprintf(stderr, "%.3f,%.3f,%.3f -> %.1f,%.1f,%.1f\n",
|
for(int j = 0 ; j < 3 ; j++)
|
||||||
stl->p[0].p[0],
|
{
|
||||||
stl->p[0].p[1],
|
fprintf(stderr, "%.3f %.3f %.3f -> %.3f %.3f %.3f\n",
|
||||||
stl->p[0].p[2],
|
stl->p[j].p[0],
|
||||||
s[0].p[0],
|
stl->p[j].p[1],
|
||||||
s[0].p[1],
|
stl->p[j].p[2],
|
||||||
s[0].p[2]
|
s[j].p[0],
|
||||||
|
s[j].p[1],
|
||||||
|
s[j].p[2]
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
tri_t * const tri = tri_new(s, stl->p);
|
tri_t * const tri = tri_new(s, stl->p);
|
||||||
|
|
||||||
@ -962,6 +974,8 @@ tri_print(tri);
|
|||||||
|
|
||||||
reject:
|
reject:
|
||||||
tri_delete(tri);
|
tri_delete(tri);
|
||||||
|
reject_early:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
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