/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N S   D E   L ' E F F E T   D E   B R U M E  :                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xrv/champs_5.16$I' :                                                                                           */
/*                                                                                                                                   */
/*                    Jean-Francois Colonna (LACTAMME, 1992??????????).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E S T I O N   D E   L A   B R U M E   E V E N T U E L L E  :                                                             */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   GENERER_UN_EFFET_DE_BRUME                                                                                                     \
                    FAUX
DEFV(Local,DEFV(Logical,INIT(generer_un_effet_de_brume,GENERER_UN_EFFET_DE_BRUME)));
                                        /* Indique s'il faut ('VRAI') ou pas ('FAUX') entourer les points dans un effet de brume.    */
#define   EDITER_LE_MESSAGE_CHAMP_DE_BRUME_OU_Z_BUFFER                                                                                  \
                    VRAI
DEFV(Local,DEFV(Logical,INIT(editer_le_message_champ_de_brume_ou_z_buffer,EDITER_LE_MESSAGE_CHAMP_DE_BRUME_OU_Z_BUFFER)));
                                        /* Introduit le 20160806091642 pour controler 'v $xrv/champs_5.1A$I 20160806082438'...       */

#define   champ_de_brume                                                                                                                \
                    ImageA6                                                                                                             \
                                        /* Ou ranger le champ de brume...                                                            */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        P R E P A R A T I O N   D E   L ' I N I T I A L I S A T I O N   D U   ' Z - B U F F E R '  :                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   INITIALISER_LE_Z_BUFFER_EN_FONCTION_DES_SPHERES_VISUALISEES                                                                   \
                    FAUX
DEFV(Local,DEFV(Logical,INIT(initialiser_le_Z_Buffer_en_fonction_des_spheres_visualisees
                            ,INITIALISER_LE_Z_BUFFER_EN_FONCTION_DES_SPHERES_VISUALISEES
                             )
                )
     );
                                        /* Indique s'il faut initialiser le 'Z-Buffer' en fonction de la sphere la plus eloignee de  */
                                        /* l'observateur ('VRAI') ou bien a l'infini ('FAUX')...                                     */
                                        /*                                                                                           */
                                        /* L'examen des sequences :                                                                  */
                                        /*                                                                                           */
                                        /*                  xivPdf 10 2 / 002561_003072                                              */
                                        /*                                                                                           */
                                        /* et :                                                                                      */
                                        /*                                                                                           */
                                        /*                  xivPdf 10 2 / 004609_005120                                              */
                                        /*                                                                                           */
                                        /* a montre le 20000623120000 un phenomene explique le 20000627164827. On voit sur la        */
                                        /* premiere sequence (le "piston") des particules qui semblent plus grosses que celles       */
                                        /* de la seconde (les "aggregats"). Or les rayons des petites boules de la premiere valent   */
                                        /* 0.028*1.2=0.0336 alors que ceux de la seconde valent 0.034 ; or 0.034 > 0.0336...         */
                                        /* Le phenomene est purement visuel et provient de traitement de l'anti-aliasing dans        */
                                        /* 'v $xrv/champs_5.1C$I correction_d_anti_aliasing_aux_intersections' ou cette derniere     */
                                        /* variable depend de 'valeur_d_initialisation_du_Z_Buffer' dans le cas de spheres qui       */
                                        /* n'ont aucune sphere derriere. Or sur la sequence du "piston", il y a des grosses boules   */
                                        /* de rayon 0.028*1.8=0.0504 ; c'est donc cette valeur qui sert a calculer par la suite      */
                                        /* 'valeur_d_initialisation_du_Z_Buffer' via 'rayon_reel_de_visualisation'. Cela a ete       */
                                        /* compris en observant la dependance du phenomene vis a vis du rayon des grosses boules     */
                                        /* du piston.                                                                                */
                                        /*                                                                                           */
                                        /* Le 20000627164827, je rend conditionnel ce dispositif (et l'inhibe par defaut) qui figure */
                                        /* dans 'v $xrv/champs_5.16$I 20000627164827' et 'v $xrv/champs_5.26$I 20000627164827'.      */
DEFV(Local,DEFV(genere_Float,INIT(valeur_d_initialisation_du_Z_Buffer,F_MOINS_L_INFINI)));
                                        /* Valeur destinee a initialiser le 'Z-Buffer'. Celle-ci est calculee dynamiquement en       */
                                        /* fonction de l'ensemble des coordonnees 'Z' sur l'image. ATTENTION : il est imperatif      */
                                        /* de l'initialiser avec 'F_MOINS_L_INFINI', au cas ou l'effet de brume serait inactif...    */
DEFV(Local,DEFV(genere_Float,INIT(valeur_de_la_valeur_d_initialisation_du_Z_Buffer,F_MOINS_L_INFINI)));
                                        /* Valeur destinee a initialiser le 'Z-Buffer'. Celle-ci a ete ajoutee le 20051220114226     */
                                        /* afin de pouvoir etre introduite via un 'v $xrv/champs_5.1A$I Z0='. Il peut sembler lourd  */
                                        /* d'introduire 'valeur_de_la_valeur_d_initialisation_du_Z_Buffer' pour intialiser           */
                                        /* dynamiquement 'valeur_d_initialisation_du_Z_Buffer', mais c'est en fait destine a eviter  */
                                        /* des problemes au cas ou l'initialisation serait plusieurs fois (cas ou plusieurs images   */
                                        /* sont generees...).                                                                        */

#define   PREPARATION_DE_L_INITIALISATION_DU_Z_BUFFER                                                                                   \
                    Bblock                                                                                                              \
                    Test(IL_FAUT(initialiser_le_Z_Buffer_en_fonction_des_spheres_visualisees))                                          \
                         Bblock                                                                                                         \
                         EGAL(valeur_d_initialisation_du_Z_Buffer,F_INFINI);                                                            \
                                        /* Afin de calculer dynamiquement la future valeur d'initialisation du 'Z-Buffer' en         */ \
                                        /* fonction de la sphere la plus eloignee (et de sa coordonnee 'Z' et de son rayon).         */ \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         EGAL(valeur_d_initialisation_du_Z_Buffer,valeur_de_la_valeur_d_initialisation_du_Z_Buffer);                    \
                                        /* Initialisation de la future valeur d'initialisation du 'Z-Buffer'...                      */ \
                                        /*                                                                                           */ \
                                        /* Le 20051220114226, 'valeur_de_la_valeur_d_initialisation_du_Z_Buffer' a remplace le       */ \
                                        /* valeur explicite 'F_MOINS_L_INFINI'...                                                    */ \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Preparation de l'initialisation du 'Z-Buffer'...                                          */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        P A R A M E T R E S   D E   C O N V O L U T I O N   D U   ' Z - B U F F E R '  :                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   FACTEUR_MULTIPLICATIF_DE_CONVOLUTION_DU_Z_BUFFER                                                                              \
                    FU                                                                                                                  \
                                        /* Facteur multiplicatif du produit de convolution en chaque point {X,Y}.                    */
#define   NOMBRE_DE_POINTS_DU_NOYAU                                                                                                     \
                    EXP2(DOUP(UN))
DEFV(Local,DEFV(Int,INIT(nombre_de_points,NOMBRE_DE_POINTS_DU_NOYAU)));
                                        /* Nombre de points du noyau. ATTENTION, cette operation genere de legers artefacts, qui     */
                                        /* augmentent d'importance lorsque ce parametre augmente. On verra a ce propos l'image       */
                                        /* 'v $xiirs/ESCA.12' ou apparait une discontinuite lorsque l'on passe a des zones qui ont   */
                                        /* comme arriere-plan l'"infini"...                                                          */
#define   IL_FAUT_RENORMALISER                                                                                                          \
                    VRAI                                                                                                                \
                                        /* Faut-il renormaliser l'image ?                                                            */

#define   NOYAU(numero,valeur)                                                                                                          \
                    Bblock                                                                                                              \
                    EGAL(ITb1(noyau,INDX(numero,PREMIER_POINT)),valeur);                                                                \
                    EGAL(ITb1(inhibition_du_noyau,INDX(numero,PREMIER_POINT)),ACTIF);                                                   \
                    Eblock                                                                                                              \
                                        /* Initialisation du noyau de convolution...                                                 */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M E M O R I S A T I O N   D U   C H A M P   D E   B R U M E   ( O U   ' Z - B U F F E R ' )  :                             */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   MEMORISER_LE_CHAMP_DE_BRUME                                                                                                   \
                    FAUX
DEFV(Local,DEFV(Logical,INIT(memoriser_le_champ_de_brume,MEMORISER_LE_CHAMP_DE_BRUME)));
                                        /* Si 'IL_FAUT(generer_un_effet_de_brume)', indique si le 'champ_de_brume' doit etre fourni  */
                                        /* comme resultat ('VRAI'), ou bien oublie apres le calcul ('FAUX') ; rppelons que le champ  */
                                        /* de brume est "a une transformation lineaire pres" le 'Z-Buffer'. Dans le cas contraire    */
                                        /* ou 'IL_NE_FAUT_PAS(generer_un_effet_de_brume)', indique si le 'Z-Buffer' doit etre fourni */
                                        /* comme resultat ('VRAI'), ou bien oublie apres le calcul ('FAUX').                         */

#define   EDITER_LES_EXTREMA_DU_Z_BUFFER                                                                                                \
                    FAUX
DEFV(Local,DEFV(Logical,INIT(editer_les_extrema_du_Z_Buffer,EDITER_LES_EXTREMA_DU_Z_BUFFER)));
                                        /* Introduit le 20190801213747...                                                            */

#define   FILTRER_LE_Z_BUFFER                                                                                                           \
                    FAUX
#define   FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MINIMUM                                                                                  \
                    FU
#define   FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MAXIMUM                                                                                  \
                    FZERO
#define   FILTRAGE_DU_Z_BUFFER__TRANSLATION___________                                                                                  \
                    FZERO
DEFV(Local,DEFV(Logical,INIT(filtrer_le_Z_Buffer,FILTRER_LE_Z_BUFFER)));
DEFV(Local,DEFV(Float,INIT(filtrage_du_Z_Buffer__ponderation_du_minimum,FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MINIMUM)));
DEFV(Local,DEFV(Float,INIT(filtrage_du_Z_Buffer__ponderation_du_maximum,FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MAXIMUM)));
DEFV(Local,DEFV(Float,INIT(filtrage_du_Z_Buffer__translation___________,FILTRAGE_DU_Z_BUFFER__TRANSLATION___________)));
                                        /* Introduit le 20190801215802 et completes le 20190802090349 par les ponderations           */
                                        /* et translation...                                                                         */

DEFV(Local,DEFV(CHAR,INIT(POINTERc(nom_imageZ),NOM_PIPE_Local)));
                                        /* Nom de la sequence a generer...                                                           */

#define   GENERATION_D_UN_CHAMP_DE_BRUME(numero_de_l_image)                                                                             \
                    Bblock                                                                                                              \
                    Test(IL_FAUT(memoriser_le_champ_de_brume))                                                                          \
                         Bblock                                                                                                         \
                         DEFV(CHAR,INIT(POINTERc(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer)                                       \
                                       ,chain_Aconcaten2_sauf_nom_pipe(nom_imageZ,NUMERO_IMAGE(numero_de_l_image))                      \
                                        )                                                                                               \
                              );                                                                                                        \
                                                                                                                                        \
                         Test(IL_FAUT(generer_un_effet_de_brume))                                                                       \
                                        /* ATTENTION, on ne peut ecrire :                                                            */ \
                                        /*                                                                                           */ \
                                        /*        GENERATION_D_UNE_COMPOSANTE(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer        */ \
                                        /*                                   ,COND(IL_FAUT(generer_un_effet_de_brume)                */ \
                                        /*                                        ,champ_de_brume                                    */ \
                                        /*                                        ,Z_Buffer                                          */ \
                                        /*                                         )                                                 */ \
                                        /*                                   ,memoriser_le_champ_de_brume                            */ \
                                        /*                                    );                                                     */ \
                                        /*                                                                                           */ \
                                        /* a cause de la definition de 'v $xrv/champs_5.14$I GENERATION_D_UNE_COMPOSANTE'.           */ \
                              Bblock                                                                                                    \
                              GENERATION_D_UNE_COMPOSANTE(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer                               \
                                                         ,champ_de_brume                                                                \
                                                         ,memoriser_le_champ_de_brume                                                   \
                                                          );                                                                            \
                                        /* Memorisation du 'champ_de_brume'.                                                         */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              Test(IL_FAUT(editer_les_extrema_du_Z_Buffer))                                                             \
                                        /* Test introduit le 20190801213747...                                                       */ \
                                   Bblock                                                                                               \
                                   CAL2(Prin2("extrema du 'Z_Buffer'=(%+.^^^,%+.^^^)\n",Z_Buffer_____minimum,Z_Buffer_____maximum));    \
                                   Eblock                                                                                               \
                              ATes                                                                                                      \
                                   Bblock                                                                                               \
                                   Eblock                                                                                               \
                              ETes                                                                                                      \
                                                                                                                                        \
                              Test(IL_FAUT(filtrer_le_Z_Buffer))                                                                        \
                                        /* Test introduit le 20190801215802...                                                       */ \
                                   Bblock                                                                                               \
                                   BDEFV(imageF,Z_Buffer_filtre);                                                                       \
                                        /* Valeur du 'Z-Buffer' apres filtrage "passe-bande".                                        */ \
                                                                                                                                        \
                                   CALS(IFmove_avec_remplacement_d_un_niveau(Z_Buffer_filtre                                            \
                                                                            ,Z_Buffer                                                   \
                                                                            ,valeur_de_la_valeur_d_initialisation_du_Z_Buffer           \
                                                                            ,LIN2(filtrage_du_Z_Buffer__ponderation_du_minimum          \
                                                                                 ,Z_Buffer_____minimum                                  \
                                                                                 ,filtrage_du_Z_Buffer__ponderation_du_maximum          \
                                                                                 ,Z_Buffer_____maximum                                  \
                                                                                 ,filtrage_du_Z_Buffer__translation___________          \
                                                                                  )                                                     \
                                                                             )                                                          \
                                        );                                                                                              \
                                        /* Filtrage "passe-bande" du 'Z-Buffer' ; on notera que l'on ne peut utiliser la fonction    */ \
                                        /* 'IFnivo_extrema(...)' dans le cas du 'Z-Buffer' car, en effet, en ce qui concerne le      */ \
                                        /* 'niveau_minimal', on recupererait la valeur d'initialisation...                           */ \
                                        /*                                                                                           */ \
                                        /* On notera le 20190802093659 qu'evidemment si la valeur de remplacement de la valeur       */ \
                                        /* d'initialisation du 'Z-Buffer' est SUPERIEURE a 'Z_Buffer_____minimum', cela ne change    */ \
                                        /* pas ce minimum !                                                                          */ \
                                   CALS(IFmove(Z_Buffer,Z_Buffer_filtre));                                                              \
                                                                                                                                        \
                                   EDEFV(imageF,Z_Buffer_filtre);                                                                       \
                                        /* Valeur du 'Z-Buffer' apres filtrage "passe-bande".                                        */ \
                                   Eblock                                                                                               \
                              ATes                                                                                                      \
                                   Bblock                                                                                               \
                                   Eblock                                                                                               \
                              ETes                                                                                                      \
                                                                                                                                        \
                              GENERATION_D_UNE_COMPOSANTE(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer                               \
                                                         ,Z_Buffer                                                                      \
                                                         ,memoriser_le_champ_de_brume                                                   \
                                                          );                                                                            \
                                        /* Memorisation du 'Z-Buffer'.                                                               */ \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                                                                                                                                        \
                         CALZ_FreCC(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer);                                                   \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Generation d'un champ de brume de numero donne...                                         */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E N E R A T I O N   D E   L ' E F F E T   D E   B R U M E  :                                                             */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   GENERATION_DE_L_EVENTUEL_EFFET_DE_BRUME                                                                                       \
                    Bblock                                                                                                              \
                    Test(IL_FAUT(generer_un_effet_de_brume))                                                                            \
                         Bblock                                                                                                         \
                         DEFV(Logical,DTb1(niveaux_a_traiter,COULEURS));                                                                \
                                        /* Definit les niveaux sur lesquels on doit faire la convolution par 'Pconvolution()'.       */ \
                         DEFV(Logical,DTb1(niveaux_cumulables,COULEURS));                                                               \
                                        /* Definit les niveaux cumulables lors du calcul de 'Pconvolution_____cumul_courant'.        */ \
                         DEFV(Float,DTb1(noyau,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION));                                             \
                                        /* Noyau de la convolution,                                                                  */ \
                         DEFV(Logical,DTb1(inhibition_du_noyau,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION));                             \
                                        /* Et sa liste d'activite.                                                                   */ \
                         DEFV(Int,INIT(index,UNDEF));                                                                                   \
                                        /* Index d'initialisation du noyau.                                                          */ \
                         BDEFV(image,champ_de_brume_non_convolue);                                                                      \
                                        /* Champ de brume avant sa convolution ; il est donc equivalent au 'Z_buffer' apres          */ \
                                        /* complementation...                                                                        */ \
                                                                                                                                        \
                         BoIn(niveau,NOIR,BLANC,PAS_COULEURS)                                                                           \
                              Bblock                                                                                                    \
                              EGAL(ITb1(niveaux_a_traiter,INDX(niveau,NOIR)),VRAI);                                                     \
                              EGAL(ITb1(niveaux_cumulables,INDX(niveau,NOIR)),VRAI);                                                    \
                                        /* Initialisation telle que tous les niveaux soient a la fois "traitables" et "cumulables".  */ \
                              Eblock                                                                                                    \
                         EBoI                                                                                                           \
                                                                                                                                        \
                         Test(IFLE(nombre_de_points,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION))                                         \
                              Bblock                                                                                                    \
                              DoIn(index,PREMIER_POINT,LSTX(PREMIER_POINT,nombre_de_points),I)                                          \
                                   Bblock                                                                                               \
                                   NOYAU(index,FU);                                                                                     \
                                        /* Initialisation du noyau de convolution.                                                   */ \
                                   Eblock                                                                                               \
                              EDoI                                                                                                      \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              PRINT_ERREUR("la taille demandee pour le noyau de convolution est incompatible avec les definitions");    \
                                                                                                                                        \
                              EGAL(nombre_de_points,NOMBRE_DE_POINTS_DU_NOYAU);                                                         \
                              CAL1(Prer1("(la valeur %d par defaut est forcee)\n",nombre_de_points));                                   \
                                        /* Introduit le 20111031141950 car, en effet, manquait cruellement...                        */ \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                                                                                                                                        \
                         CALi(Ifloat_std_avec_renormalisation(champ_de_brume_non_convolue,Z_Buffer));                                   \
                                        /* Lorsqu'un effet de brume est demande, on renormalise le 'Z-Buffer'...                     */ \
                         CALi(Icomplementation(champ_de_brume_non_convolue,champ_de_brume_non_convolue));                               \
                                        /* Et on le complemente...                                                                   */ \
                                                                                                                                        \
                         CALi(Iconvolution_avec_renormalisation(champ_de_brume                                                          \
                                                               ,FACTEUR_MULTIPLICATIF_DE_CONVOLUTION_DU_Z_BUFFER                        \
                                                               ,champ_de_brume_non_convolue                                             \
                                                               ,niveaux_a_traiter,niveaux_cumulables                                    \
                                                               ,nombre_de_points,noyau,inhibition_du_noyau                              \
                                                               ,IL_FAUT_RENORMALISER                                                    \
                                                                )                                                                       \
                              );                                                                                                        \
                                        /* Cette convolution du champ de brume est effectuee avant l'effet de transparence car en    */ \
                                        /* effet il s'agit la d'un post-processing qui donc peut rentrer en conflit avec le          */ \
                                        /* traitement anti-aliasing qui est fait lui sans savoir qu'il y aura de la brume...         */ \
                                                                                                                                        \
                         CALi(Itransparence_05(Image_ROUGE,champ_de_brume,Image_ROUGE));                                                \
                         CALi(Itransparence_05(Image_VERTE,champ_de_brume,Image_VERTE));                                                \
                         CALi(Itransparence_05(Image_BLEUE,champ_de_brume,Image_BLEUE));                                                \
                                        /* Et on genere un effet de brume du type 'v $xci/vitre.51$K'...                             */ \
                                                                                                                                        \
                         EDEFV(image,champ_de_brume_non_convolue);                                                                      \
                                        /* Champ de brume avant sa convolution ; il est donc equivalent au 'Z_buffer' apres          */ \
                                        /* complementation...                                                                        */ \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Generation de l'eventuel effet de brume...                                                */



Copyright © Jean-François Colonna, 2019-2021.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / Ecole Polytechnique, 2019-2021.