star-camera

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

scam_orthographic.c (4555B)


      1 /* Copyright (C) 2021-2023 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * Tyhis 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_c.h"
     17 #include "scam_log.h"
     18 
     19 #include <rsys/double3.h>
     20 #include <rsys/double33.h>
     21 #include <rsys/math.h>
     22 
     23 #include <math.h>
     24 
     25 /*******************************************************************************
     26  * Helper functions
     27  ******************************************************************************/
     28 static res_T
     29 setup_orthographic(struct scam* cam, const struct scam_orthographic_args* args)
     30 {
     31   double x[3], y[3], z[3];
     32   res_T res = RES_OK;
     33   ASSERT(cam && args && cam->type == SCAM_ORTHOGRAPHIC);
     34 
     35   cam->param.ortho = ORTHOGRAPHIC_DEFAULT;
     36 
     37   if(args->aspect_ratio <= 0) {
     38     log_err(cam,
     39       "orthographic camera: invalid aspect ratio: %g\n",
     40       args->aspect_ratio);
     41     res = RES_BAD_ARG;
     42     goto error;
     43   }
     44 
     45   if(args->height <= 0) {
     46     log_err(cam,
     47       "orthographic camera: invalid height: %g\n",
     48       args->height);
     49     res = RES_BAD_ARG;
     50     goto error;
     51   }
     52 
     53   if(d3_normalize(z, d3_sub(z, args->target, args->position)) <= 0
     54   || d3_normalize(x, d3_cross(x, z, args->up)) <= 0
     55   || d3_normalize(y, d3_cross(y, z, x)) <= 0) {
     56     log_err(cam,
     57       "orthographic camera: invalid point of view:\n"
     58       "  position = %g %g %g\n"
     59       "  target   = %g %g %g\n"
     60       "  up       = %g %g %g\n",
     61       SPLIT3(args->position), SPLIT3(args->target), SPLIT3(args->up));
     62     res = RES_BAD_ARG;
     63     goto error;
     64   }
     65 
     66   cam->param.ortho.height = args->height;
     67   cam->param.ortho.aspect_ratio = args->aspect_ratio;
     68 
     69   d3_set(cam->param.ortho.position, args->position);
     70   
     71   d3_muld(cam->param.ortho.screen2world+0, x, 0.5*args->height*args->aspect_ratio);
     72   d3_muld(cam->param.ortho.screen2world+3, y, 0.5*args->height);
     73   d3_set (cam->param.ortho.screen2world+6, z);
     74 
     75   d3_set(cam->param.ortho.camera2world+0, x);
     76   d3_set(cam->param.ortho.camera2world+3, y);
     77   d3_set(cam->param.ortho.camera2world+6, z);
     78 
     79 exit:
     80   return res;
     81 error:
     82   goto exit;
     83 }
     84 
     85 /*******************************************************************************
     86  * Exported function
     87  ******************************************************************************/
     88 SCAM_API res_T
     89 scam_create_orthographic
     90   (struct logger* logger, /* NULL <=> use builtin logger */
     91    struct mem_allocator* allocator, /* NULL <=> use default allocator */
     92    const int verbose, /* Verbosity level */
     93    struct scam_orthographic_args* args,
     94    struct scam** out_cam)
     95 {
     96   struct scam* cam = NULL;
     97   res_T res = RES_OK;
     98 
     99   if(!args || !out_cam) {
    100     res = RES_BAD_ARG;
    101     goto error;
    102   }
    103 
    104   res = camera_create(logger, allocator, verbose, SCAM_ORTHOGRAPHIC, &cam);
    105   if(res != RES_OK) goto error;
    106   res = setup_orthographic(cam, args);
    107   if(res != RES_OK) goto error;
    108 
    109 exit:
    110   if(out_cam) *out_cam = cam;
    111   return res;
    112 error:
    113   if(cam) {
    114     SCAM(ref_put(cam));
    115     cam = NULL;
    116   }
    117   goto exit;
    118 }
    119 
    120 /*******************************************************************************
    121  * Local function
    122  ******************************************************************************/
    123 void
    124 orthographic_generate_ray
    125   (const struct scam* cam,
    126    const struct scam_sample* sample,
    127    struct scam_ray* ray)
    128 {
    129   double x[3], y[3];
    130   double pos[3];
    131 
    132   ASSERT(cam && sample && ray);
    133   ASSERT(cam->type == SCAM_ORTHOGRAPHIC);
    134   ASSERT(0 <= sample->film[0] && sample->film[0] < 1);
    135   ASSERT(0 <= sample->film[1] && sample->film[1] < 1);
    136 
    137   /* Transform the sampled position in screen space */
    138   pos[0] = sample->film[0]*2-1;
    139   pos[1] = sample->film[1]*2-1;
    140   pos[2] = 0;
    141 
    142   /* Transform the sampled position in world space */
    143   d3_muld(x, cam->param.ortho.screen2world+0, pos[0]);
    144   d3_muld(y, cam->param.ortho.screen2world+3, pos[1]);
    145   d3_add(ray->org, x, y);
    146   d3_add(ray->org, ray->org, cam->param.ortho.position);
    147 
    148   /* Setup the ray direction to the image plane normal, i.e. the z axis of the
    149    * camera */
    150   d3_set(ray->dir, cam->param.ortho.camera2world+6);
    151 }