getoptified and made fov parameter

This commit is contained in:
Trammell hudson 2018-02-27 13:13:58 -05:00
parent 060a4d472d
commit c7504c0541
Failed to extract signature
3 changed files with 144 additions and 37 deletions

View File

@ -21,14 +21,16 @@ camera_t *
camera_new( camera_new(
v3_t eye, v3_t eye,
v3_t lookat, v3_t lookat,
v3_t up v3_t up,
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); camera_setup(c, eye, lookat, up, fov, scale);
return c; return c;
} }
@ -38,7 +40,9 @@ camera_setup(
camera_t * const c, camera_t * const c,
v3_t eye, v3_t eye,
v3_t lookat, v3_t lookat,
v3_t up v3_t up,
float fov,
float scale
) )
{ {
// compute the basis for the camera // compute the basis for the camera
@ -82,7 +86,6 @@ camera_setup(
} }
// now compute the perspective projection matrix // now compute the perspective projection matrix
float fov = 60;
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 = 1.0;
c->far = 200; c->far = 200;
@ -149,9 +152,9 @@ camera_project(
// Transform to screen coordinate frame, // Transform to screen coordinate frame,
// and return it to the caller // and return it to the caller
v_out->p[0] = p[0] * 100; v_out->p[0] = p[0];
v_out->p[1] = p[1] * 100; v_out->p[1] = p[1];
v_out->p[2] = p[2] * 100; v_out->p[2] = p[2];
// what if p->p[4] == 0? // what if p->p[4] == 0?
// pz < 0 == The point is behind us; do not display? // pz < 0 == The point is behind us; do not display?

View File

@ -8,7 +8,9 @@ extern camera_t *
camera_new( camera_new(
v3_t eye, v3_t eye,
v3_t lookat, v3_t lookat,
v3_t up v3_t up,
float fov,
float scale
); );
extern void extern void
@ -16,7 +18,9 @@ camera_setup(
camera_t * const c, camera_t * const c,
v3_t eye, v3_t eye,
v3_t lookat, v3_t lookat,
v3_t up v3_t up,
float fov,
float scale
); );
/** Transform a XYZ point into a screen point. /** Transform a XYZ point into a screen point.

View File

@ -10,14 +10,50 @@
#include <math.h> #include <math.h>
#include <err.h> #include <err.h>
#include <assert.h> #include <assert.h>
#include <getopt.h>
#include "v3.h" #include "v3.h"
#include "camera.h" #include "camera.h"
static const char usage[] =
"Usage: hiddenwire [options] file.stl > file.svg\n"
"\n"
"Options:\n"
" -h | -? | --help Help\n"
" -v | --verbose Enable debugging output\n"
" -c | --camera x,y,z Camera position\n"
" -l | --lookat x,y,z Target\n"
" -u | --up x,y,z Up vector\n"
" -F | --fov deg Field-of-view angle\n"
" -s | --scale s Scale factor\n"
" -p | --prune s Prune lines shorter than s\n"
" --no-backface Disable backface culling\n"
" --no-coplanar Disable coplanar merging\n"
" --no-hiddenwire Disable hidden wire frame removal\n"
"\n";
static const struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "verbose", 0, NULL, 'v' },
{ "no-backface", 0, NULL, 'B' },
{ "no-coplanar", 0, NULL, 'C' },
{ "no-hiddenwire", 0, NULL, 'H' },
{ "camera", 1, NULL, 'c' },
{ "lookat", 1, NULL, 'l' },
{ "up", 1, NULL, 'u' },
{ "scale", 1, NULL, 's' },
{ "prune", 1, NULL, 'p' },
{ "fov", 1, NULL, 'F' },
{ NULL, 0, NULL, 0 },
};
#ifndef M_PI #ifndef M_PI
#define M_PI 3.1415926535897932384 #define M_PI 3.1415926535897932384
#endif #endif
static int debug = 1; static int debug = 0;
typedef struct typedef struct
{ {
@ -637,28 +673,96 @@ return;
} }
int v3_parse(v3_t * out, const char * str)
{
int rc = sscanf(str, "%f,%f,%f",
&out->p[0],
&out->p[1],
&out->p[2]
);
if (rc != 3)
return -1;
return 0;
}
int main( int main(
int argc, int argc,
char ** argv char ** argv
) )
{ {
if (argc <= 1)
{
fprintf(stderr, "%s", usage);
return EXIT_FAILURE;
}
int opt;
int do_backface = 1;
int do_coplanar = 1;
int do_hidden = 1;
v3_t eye = { { 100, 0, 0 } };
v3_t lookat = { { 0, 0, 0 } };
v3_t up = { { 0, 0, 1 } };
float scale = 1;
float fov = 45;
float prune = 0.1;
while((opt = getopt_long(argc, argv ,"h?vBCHc:l:s:u:p:F:", long_options, NULL)) != -1)
{
switch(opt)
{
case 'h' : case '?':
printf("%s", usage);
return EXIT_SUCCESS;
default:
fprintf(stderr, "%s", usage);
return EXIT_FAILURE;
case 'v': debug++; break;
case 'B': do_backface = 0; break;
case 'C': do_coplanar = 0; break;
case 'H': do_hidden = 0; break;
case 'p': prune = atof(optarg); break;
case 's': scale = atof(optarg); break;
case 'F': fov = atof(optarg); break;
case 'c':
if (v3_parse(&eye, optarg) < 0)
return EXIT_FAILURE;
break;
case 'l':
if (v3_parse(&lookat, optarg) < 0)
return EXIT_FAILURE;
break;
case 'u':
if (v3_parse(&up, optarg) < 0)
return EXIT_FAILURE;
break;
}
}
// todo: sanity check fov, scale, etc
const size_t max_len = 32 << 20; const size_t max_len = 32 << 20;
uint8_t * const buf = calloc(max_len, 1); uint8_t * const buf = calloc(max_len, 1);
size_t offset = 0;
int filter_level = argc > 4 ? atoi(argv[4]) : 1; while(1)
{
ssize_t rc = read(0, buf, max_len); ssize_t rc = read(0, buf+offset, max_len - offset);
if (rc == -1) if (rc == -1)
return EXIT_FAILURE; return EXIT_FAILURE;
if (rc == 0)
break;
offset += rc;
}
const stl_header_t * const hdr = (const void*) buf; const stl_header_t * const hdr = (const void*) buf;
const stl_face_t * const stl_faces = (const void*)(hdr+1); const stl_face_t * const stl_faces = (const void*)(hdr+1);
const int num_triangles = hdr->num_triangles; const int num_triangles = hdr->num_triangles;
int backface = filter_level & 1;
int hidden = filter_level & 2;
int coplanar = filter_level & 4;
float coplanar_eps = 0.001; float coplanar_eps = 0.001;
if(debug) if(debug)
@ -668,16 +772,12 @@ int main(
} }
// looking at (0,0,0) const camera_t * const cam = camera_new(eye, lookat, up, fov, scale);
v3_t eye = { { -100, 40, 50 } };
v3_t lookat = { { 0, 0, 0 } };
v3_t up = { { 0, -1, 0 } };
const camera_t * const cam = camera_new(eye, lookat, up);
printf("<svg xmlns=\"http://www.w3.org/2000/svg\">\n"); printf("<svg xmlns=\"http://www.w3.org/2000/svg\">\n");
float off_x = 500; float off_x = 0;
float off_y = 500; float off_y = 0;
printf("<g transform=\"translate(%f %f)\">\n", off_x, off_y); printf("<g transform=\"translate(%f %f)\">\n", off_x, off_y);
int rejected = 0; int rejected = 0;
@ -696,17 +796,17 @@ int main(
v3_t s[3]; v3_t s[3];
for(int j = 0 ; j < 3 ; j++) for(int j = 0 ; j < 3 ; j++)
{
camera_project(cam, &stl->p[j], &s[j]); camera_project(cam, &stl->p[j], &s[j]);
}
if(0)fprintf(stderr, "%.3f,%.3f,%.3f -> %.0f,%.0f\n", if(debug >= 2)
fprintf(stderr, "%.3f,%.3f,%.3f -> %.1f,%.1f,%.1f\n",
stl->p[0].p[0], stl->p[0].p[0],
stl->p[0].p[1], stl->p[0].p[1],
stl->p[0].p[2], stl->p[0].p[2],
s[0].p[0], s[0].p[0],
s[0].p[1] s[0].p[1],
); s[0].p[2]
);
tri_t * const tri = tri_new(s, stl->p); tri_t * const tri = tri_new(s, stl->p);
@ -717,7 +817,7 @@ if(0)fprintf(stderr, "%.3f,%.3f,%.3f -> %.0f,%.0f\n",
// do a back-face cull to determine if this triangle // do a back-face cull to determine if this triangle
// is not facing us. we have to determine the orientation // is not facing us. we have to determine the orientation
// from the winding of the new projection // from the winding of the new projection
if (backface && tri->normal.p[2] <= 0) if (do_backface && tri->normal.p[2] <= 0)
goto reject; goto reject;
retained++; retained++;
@ -742,7 +842,7 @@ reject:
{ {
unsigned matches = 0; unsigned matches = 0;
if(coplanar) if(do_coplanar)
for(tri_t * t2 = zlist ; t2 ; t2 = t2->next) for(tri_t * t2 = zlist ; t2 ; t2 = t2->next)
{ {
if (t == t2) if (t == t2)
@ -776,7 +876,7 @@ reject:
// we now have a z-sorted list of triangles // we now have a z-sorted list of triangles
rejected = 0; rejected = 0;
if(hidden) if(do_hidden)
{ {
// work on each segment, intersecting it with all of the triangles // work on each segment, intersecting it with all of the triangles
int processed = 0; int processed = 0;