BRL-CAD
sh_cloud.c
Go to the documentation of this file.
1 /* S H _ C L O U D . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1985-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file liboptical/sh_cloud.c
21  *
22  * An attempt at 2D Geoffrey Gardner style cloud texture map
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stddef.h>
29 #include <stdio.h>
30 #include <math.h>
31 
32 #include "vmath.h"
33 #include "raytrace.h"
34 #include "optical.h"
35 
39 };
40 #define CL_NULL ((struct cloud_specific *)0)
41 #define CL_O(m) bu_offsetof(struct cloud_specific, m)
42 
44  {"%f", 1, "thresh", CL_O(cl_thresh), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
45  {"%f", 1, "range", CL_O(cl_range), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
46  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
47 };
48 
49 
50 HIDDEN int cloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip);
51 HIDDEN int cloud_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp);
52 HIDDEN void cloud_print(register struct region *rp, void *dp);
53 HIDDEN void cloud_free(void *cp);
54 
55 struct mfuncs cloud_mfuncs[] = {
56  {MF_MAGIC, "cloud", 0, MFI_UV, 0,
57  cloud_setup, cloud_render, cloud_print, cloud_free },
58 
59  {0, (char *)0, 0, 0, 0,
60  0, 0, 0, 0 }
61 };
62 
63 
64 /*
65  * Returns the texture value for a plane point
66  */
67 double
68 cloud_texture(register fastf_t x, register fastf_t y, fastf_t Contrast, fastf_t initFx, fastf_t initFy)
69 {
70  register int i;
71  fastf_t Px, Py, Fx, Fy, C;
72  fastf_t t1, t2, k;
73 
74  /* NOTE: we intentionally multiply by a truncated 0.707
75  * (truncating to three decimal places) so we get consistent
76  * results across single and double-precision computation.
77  *
78  * Not truncating is an option, but the benchmark results would
79  * need to be recomputed (they have background clouds) and the
80  * single-precision sensitivity would need to be tested.
81  *
82  * Factor compounding with and without truncation (M_SQRT1_2):
83  * .707 .7071067811...
84  * .499 .4999999998...
85  * .352 .3535533904...
86  */
87  static const fastf_t seven0seven = (int)(M_SQRT1_2*1000.0)/1000.0;
88 
89  t1 = t2 = 0;
90 
91  /*
92  * Compute initial Phases and Frequencies
93  * Freq "1" goes through 2Pi as x or y go thru 0.0 -> 1.0
94  */
95  Fx = M_2PI * initFx;
96  Fy = M_2PI * initFy;
97  Px = M_PI_2 * bn_tab_sin(0.5 * Fy * y);
98  Py = M_PI_2 * bn_tab_sin(0.5 * Fx * x);
99 
100  /* unattenuated starting factor */
101  C = 1.0;
102 
103 /* we iterate in pi/2 steps to 2pi */
104 #define TWO_PI_OVER_PI_OVER_TWO 4
105 
106  for (i = 0; i < TWO_PI_OVER_PI_OVER_TWO; i++) {
107  /*
108  * Compute one term of each summation.
109  */
110  t1 += C * bn_tab_sin(Fx * x + Px) + Contrast;
111  t2 += C * bn_tab_sin(Fy * y + Py) + Contrast;
112 
113  /*
114  * Compute the new phases and frequencies.
115  * N.B. The phases shouldn't vary the same way!
116  */
117  Px = M_PI_2 * bn_tab_sin(Fy * y);
118  Py = M_PI_2 * bn_tab_sin(Fx * x);
119  Fx *= 2;
120  Fy *= 2;
121 
122  /* next iteration is multiplied by a diminishing sqrt(1/2)
123  * factor, see above note regarding precision.
124  */
125  C *= seven0seven;
126  }
127 
128  /* Choose a magic k! */
129  /* Compute max possible summation */
130  k = TWO_PI_OVER_PI_OVER_TWO * 2 * TWO_PI_OVER_PI_OVER_TWO;
131 
132  return t1 * t2 / k;
133 }
134 
135 
136 HIDDEN int
137 cloud_setup(register struct region *UNUSED(rp), struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *UNUSED(rtip))
138 {
139  register struct cloud_specific *cp;
140 
141  BU_CK_VLS(matparm);
142  BU_GET(cp, struct cloud_specific);
143  *dpp = cp;
144 
145  cp->cl_thresh = 0.35;
146  cp->cl_range = 0.3;
147  if (bu_struct_parse(matparm, cloud_parse, (char *)cp, NULL) < 0)
148  return -1;
149 
150  return 1;
151 }
152 
153 
154 HIDDEN void
155 cloud_print(register struct region *rp, void *dp)
156 {
157  bu_struct_print(rp->reg_name, cloud_parse, (char *)dp);
158 }
159 
160 
161 HIDDEN void
162 cloud_free(void *cp)
163 {
164  BU_PUT(cp, struct cloud_specific);
165 }
166 
167 
168 /*
169  * Return a sky color with translucency control.
170  * Threshold is the intensity below which it is completely translucent.
171  * Range in the range on intensities over which translucence varies
172  * from 0 to 1.
173  * thresh=0.35, range=0.3 for decent clouds.
174  */
175 int
176 cloud_render(struct application *UNUSED(ap), const struct partition *UNUSED(pp), struct shadework *swp, void *dp)
177 {
178  register struct cloud_specific *cp =
179  (struct cloud_specific *)dp;
180  double intensity;
181  fastf_t TR;
182 
183  intensity = cloud_texture(swp->sw_uv.uv_u, swp->sw_uv.uv_v,
184  1.0, 2.0, 1.0);
185 
186  /* Intensity is normalized - check bounds */
187  if (intensity > 1.0)
188  intensity = 1.0;
189  else if (intensity < 0.0)
190  intensity = 0.0;
191 
192  /* Compute Translucency Function */
193  TR = 1.0 - (intensity - cp->cl_thresh) / cp->cl_range;
194  if (TR < 0.0)
195  TR = 0.0;
196  else if (TR > 1.0)
197  TR = 1.0;
198 
199  swp->sw_color[0] = ((1-TR) * intensity + (TR * .31)); /* Red */
200  swp->sw_color[1] = ((1-TR) * intensity + (TR * .31)); /* Green */
201  swp->sw_color[2] = ((1-TR) * intensity + (TR * .78)); /* Blue */
202  return 1;
203 }
204 
205 
206 /*
207  * Local Variables:
208  * mode: C
209  * tab-width: 8
210  * indent-tabs-mode: t
211  * c-file-style: "stroustrup"
212  * End:
213  * ex: shiftwidth=4 tabstop=8
214  */
#define bn_tab_sin(_a)
Definition: rand.h:127
fastf_t C[2 *MAX_CNT+1][2 *MAX_CNT+1]
Definition: dsp_brep.cpp:38
double cloud_texture(register fastf_t x, register fastf_t y, fastf_t Contrast, fastf_t initFx, fastf_t initFy)
Definition: sh_cloud.c:68
#define MF_MAGIC
Definition: magic.h:205
HIDDEN int cloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
Definition: sh_cloud.c:137
Header file for the BRL-CAD common definitions.
fastf_t cl_thresh
Definition: sh_cloud.c:37
struct bu_structparse cloud_parse[]
Definition: sh_cloud.c:43
const char * reg_name
Identifying string.
Definition: raytrace.h:539
#define HIDDEN
Definition: common.h:86
void bu_struct_print(const char *title, const struct bu_structparse *parsetab, const char *base)
Definition: parse.c:1221
if(share_geom)
Definition: nmg_mod.c:3829
#define BU_CK_VLS(_vp)
Definition: vls.h:69
#define CL_O(m)
Definition: sh_cloud.c:41
HIDDEN void cloud_free(void *cp)
Definition: sh_cloud.c:162
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
#define TWO_PI_OVER_PI_OVER_TWO
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
HIDDEN void cloud_print(register struct region *rp, void *dp)
Definition: sh_cloud.c:155
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
int bu_struct_parse(const struct bu_vls *in_vls, const struct bu_structparse *desc, const char *base, void *data)
Definition: parse.c:878
struct mfuncs cloud_mfuncs[]
Definition: sh_cloud.c:55
HIDDEN int cloud_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_cloud.c:176
fastf_t cl_range
Definition: sh_cloud.c:38
Definition: vls.h:56
#define M_SQRT1_2
Definition: fft.h:38
double fastf_t
Definition: defines.h:300
Header file for the BRL-CAD Optical Library, LIBOPTICAL.