star-camera

Camera models
git clone git://git.meso-star.fr/star-camera.git
Log | Files | Refs | README | LICENSE

test_scam_orthographic.c (4435B)


      1 /* Copyright (C) 2021-2023 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "scam.h"
     17 #include "test_scam_utils.h"
     18 
     19 #include <rsys/double3.h>
     20 #include <rsys/double33.h>
     21 #include <rsys/logger.h>
     22 
     23 static void
     24 log_stream(const char* msg, void* ctx)
     25 {
     26   ASSERT(msg);
     27   (void)msg, (void)ctx;
     28   printf("%s", msg);
     29 }
     30 
     31 int
     32 main(int argc, char** argv)
     33 {
     34   struct logger logger;
     35   struct scam_orthographic_args args = SCAM_ORTHOGRAPHIC_ARGS_DEFAULT;
     36   struct scam* cam = NULL;
     37   const size_t nsamps = 10000;
     38   double screen2world[9];
     39   double world2screen[9];
     40   double axis_x[3];
     41   double axis_y[3];
     42   double axis_z[3];
     43   double solid_angle;
     44   size_t i;
     45   enum scam_type type = SCAM_NONE;
     46   (void)argc, (void)argv;
     47 
     48   CHK(scam_create_orthographic(NULL, NULL, 0, NULL, &cam) == RES_BAD_ARG);
     49   CHK(scam_create_orthographic(NULL, NULL, 0, &args, NULL) == RES_BAD_ARG);
     50   CHK(scam_create_orthographic(NULL, NULL, 0, &args, &cam) == RES_OK);
     51 
     52   CHK(scam_get_type(cam, &type) == RES_OK);
     53   CHK(type == SCAM_ORTHOGRAPHIC);
     54   CHK(scam_ref_put(cam) == RES_OK);
     55 
     56   CHK(logger_init(&mem_default_allocator, &logger) == RES_OK);
     57   logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
     58   logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
     59   logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
     60 
     61   CHK(scam_create_orthographic(&logger, NULL, 0, &args, &cam) == RES_OK);
     62   CHK(scam_ref_put(cam) == RES_OK);
     63 
     64   CHK(scam_create_orthographic(NULL, &mem_default_allocator, 0, &args, &cam) == RES_OK);
     65   CHK(scam_ref_put(cam) == RES_OK);
     66 
     67   d3_set(args.target, args.position);
     68   CHK(scam_create_orthographic(NULL, NULL, 1, &args, &cam) == RES_BAD_ARG);
     69 
     70   d3(args.position, 0, 0, 0);
     71   d3(args.target, 0, 1, 0);
     72   d3(args.up, 0, 1, 0);
     73   CHK(scam_create_orthographic(NULL, NULL, 1, &args, &cam) == RES_BAD_ARG);
     74 
     75   args = SCAM_ORTHOGRAPHIC_ARGS_DEFAULT;
     76   args.aspect_ratio = 0;
     77   CHK(scam_create_orthographic(NULL, NULL, 1, &args, &cam) == RES_BAD_ARG);
     78 
     79   args.aspect_ratio = 1;
     80   args.height = 0;
     81   CHK(scam_create_orthographic(NULL, NULL, 1, &args, &cam) == RES_BAD_ARG);
     82 
     83   args.position[0] = rand_canonical();
     84   args.position[1] = rand_canonical();
     85   args.position[2] = rand_canonical();
     86   args.target[0] = rand_canonical();
     87   args.target[1] = rand_canonical();
     88   args.target[2] = rand_canonical();
     89   args.up[0] = rand_canonical();
     90   args.up[1] = rand_canonical();
     91   args.up[2] = rand_canonical();
     92   args.height = 10;
     93   args.aspect_ratio = 16.0/9.0;
     94 
     95   CHK(scam_create_orthographic(NULL, NULL, 1, &args, &cam) == RES_OK);
     96   CHK(scam_perspective_get_solid_angle(cam, &solid_angle) == RES_BAD_ARG);
     97 
     98   /* Precompute camera parameters */
     99   d3_normalize(axis_z, d3_sub(axis_z, args.target, args.position));
    100   d3_normalize(axis_x, d3_cross(axis_x, axis_z, args.up));
    101   d3_normalize(axis_y, d3_cross(axis_y, axis_z, axis_x));
    102 
    103   d3_muld(screen2world+0, axis_x, 0.5*args.height*args.aspect_ratio);
    104   d3_muld(screen2world+3, axis_y, 0.5*args.height);
    105   d3_set (screen2world+6, axis_z);
    106   d33_inverse(world2screen, screen2world);
    107 
    108   FOR_EACH(i, 0, nsamps) {
    109     double pos[3];
    110     struct scam_sample sample = SCAM_SAMPLE_NULL;
    111     struct scam_ray ray = SCAM_RAY_NULL;
    112 
    113     sample.film[0] = rand_canonical();
    114     sample.film[1] = rand_canonical();
    115     CHK(scam_generate_ray(cam, &sample, &ray) == RES_OK);
    116 
    117     /* Check the ray direction */
    118     CHK(d3_eq_eps(ray.dir, axis_z, 1.e-6));
    119 
    120     /* Transform the ray origin in camera space */
    121     d3_sub(pos, ray.org, args.position);
    122     d33_muld3(pos, world2screen, pos);
    123 
    124     /* Check that the ray origin lies on the image plane */
    125     CHK(-1 <= pos[0] && pos[0] <= 1);
    126     CHK(-1 <= pos[1] && pos[1] <= 1);
    127     CHK(eq_eps(pos[2], 0, 1.e-6));
    128   }
    129 
    130   CHK(scam_ref_put(cam) == RES_OK);
    131 
    132   logger_release(&logger);
    133   CHK(mem_allocated_size() == 0);
    134   return 0;
    135 }