stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

sdis_camera.c (3745B)


      1 /* Copyright (C) 2016-2025 |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 "sdis.h"
     17 #include "sdis_camera.h"
     18 #include "sdis_device_c.h"
     19 
     20 #include <rsys/mem_allocator.h>
     21 
     22 /*******************************************************************************
     23  * Helper functions
     24  ******************************************************************************/
     25 static void
     26 camera_release(ref_T* ref)
     27 {
     28   struct sdis_camera* cam = CONTAINER_OF(ref, struct sdis_camera, ref);
     29   struct sdis_device* dev;
     30   ASSERT(ref);
     31   dev = cam->dev;
     32   MEM_RM(dev->allocator, cam);
     33   SDIS(device_ref_put(dev));
     34 }
     35 
     36 /*******************************************************************************
     37  * Exported functions
     38  ******************************************************************************/
     39 res_T
     40 sdis_camera_create(struct sdis_device* dev, struct sdis_camera** out_cam)
     41 {
     42   const double pos[3] = {0, 0, 0};
     43   const double tgt[3] = {0, 0,-1};
     44   const double up[3] = {0, 1, 0};
     45   struct sdis_camera* cam = NULL;
     46   res_T res = RES_OK;
     47 
     48   if(!dev || !out_cam) {
     49     res = RES_BAD_ARG;
     50     goto error;
     51   }
     52 
     53   cam = MEM_CALLOC(dev->allocator, 1, sizeof(struct sdis_camera));
     54   if(!cam) {
     55     res = RES_MEM_ERR;
     56     goto error;
     57   }
     58   SDIS(device_ref_get(dev));
     59   cam->dev = dev;
     60   ref_init(&cam->ref);
     61   cam->rcp_proj_ratio = 1.0;
     62   cam->fov_x = PI/2.0;
     63   SDIS(camera_look_at(cam, pos, tgt, up));
     64 
     65 exit:
     66   if(out_cam) *out_cam = cam;
     67   return res;
     68 error:
     69   if(cam) {
     70     SDIS(camera_ref_put(cam));
     71     cam = NULL;
     72   }
     73   goto exit;
     74 }
     75 
     76 res_T
     77 sdis_camera_ref_get(struct sdis_camera* cam)
     78 {
     79   if(!cam) return RES_BAD_ARG;
     80   ref_get(&cam->ref);
     81   return RES_OK;
     82 }
     83 
     84 res_T
     85 sdis_camera_ref_put(struct sdis_camera* cam)
     86 {
     87   if(!cam) return RES_BAD_ARG;
     88   ref_put(&cam->ref, camera_release);
     89   return RES_OK;
     90 }
     91 
     92 res_T
     93 sdis_camera_set_proj_ratio(struct sdis_camera* cam, const double ratio)
     94 {
     95   double y[3] = {0};
     96   if(!cam || ratio <= 0) return RES_BAD_ARG;
     97   if(d3_normalize(y, cam->axis_y) <= 0) return RES_BAD_ARG;
     98   cam->rcp_proj_ratio = 1.0 / ratio;
     99   d3_muld(cam->axis_y, y, cam->rcp_proj_ratio);
    100   return RES_OK;
    101 }
    102 
    103 res_T
    104 sdis_camera_set_fov(struct sdis_camera* cam, const double fov_x)
    105 {
    106   double z[3] = {0};
    107   double img_plane_depth;
    108   if(!cam || (float)fov_x <= 0) return RES_BAD_ARG;
    109   if(d3_normalize(z, cam->axis_z) <= 0) return RES_BAD_ARG;
    110   img_plane_depth = 1.0/tan(fov_x*0.5);
    111   d3_muld(cam->axis_z, z, img_plane_depth);
    112   cam->fov_x = fov_x;
    113   return RES_OK;
    114 }
    115 
    116 res_T
    117 sdis_camera_look_at
    118   (struct sdis_camera* cam,
    119    const double pos[3],
    120    const double tgt[3],
    121    const double up[3])
    122 {
    123   double x[3], y[3], z[3];
    124   double img_plane_depth;
    125   if(!cam || !pos || !tgt || !up) return RES_BAD_ARG;
    126 
    127   if(d3_normalize(z, d3_sub(z, tgt, pos)) <= 0) return RES_BAD_ARG;
    128   if(d3_normalize(x, d3_cross(x, z, up)) <= 0) return RES_BAD_ARG;
    129   if(d3_normalize(y, d3_cross(y, z, x)) <= 0) return RES_BAD_ARG;
    130   img_plane_depth = 1.0/tan(cam->fov_x*0.5);
    131 
    132   d3_set(cam->axis_x, x);
    133   d3_muld(cam->axis_y, y, cam->rcp_proj_ratio);
    134   d3_muld(cam->axis_z, z, img_plane_depth);
    135   d3_set(cam->position, pos);
    136   return RES_OK;
    137 }
    138