BRL-CAD
wray.c
Go to the documentation of this file.
1 /* W R A Y . 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/wray.c
21  *
22  * Write a VLD-standard ray on the given file pointer.
23  * VLD-standard rays are defined by /vld/include/ray.h,
24  * included here for portability. A variety of VLD programs
25  * exist to manipulate these files, including rayvect.
26  *
27  * To obtain a UNIX-plot of a ray file, the procedure is:
28  * rayvect -mMM < file.ray > file.vect
29  * vectplot -mMM < file.vect > file.plot3
30  * tplot -Tmeg file.plot3 # or equivalent
31  *
32  */
33 
34 #include "common.h"
35 
36 #include <stdio.h>
37 #include <math.h>
38 
39 #include "vmath.h"
40 #include "raytrace.h"
41 #include "optical.h"
42 
43 
44 /* binary ray segment data record; see ray(4V) (SCCS vers 1.4) */
45 struct vldray
46 {
47  float ox; /* origin coordinates */
48  float oy;
49  float oz;
50  float rx; /* ray vector */
51  float ry;
52  float rz;
53  float na; /* origin surface normal */
54  float ne;
55  float pa; /* principal direction */
56  float pe;
57  float pc; /* principal curvature */
58  float sc; /* secondary curvature */
59  long ob; /* object code */
60  long rt; /* ray tag */
61 };
62 
63 
64 /*
65  * Convert the normal vector into an azimuth angle (from +X axis)
66  * and an elevation angle (up from XY plane).
67  * The normal is expected to be pointing out from the object.
68  * The elevation is most readily computed as:
69  *
70  * _ray.ne = asin(_norm[Z]);
71  *
72  * but the asin() function can't deal with floating point noise that
73  * might make _norm[Z] slightly outside of the range -1.0 to +1.0.
74  * A completely stable formulation is:
75  *
76  * _ray.ne = bn_atan2(_norm[Z], hypot(_norm[X], _norm[Y]));
77  *
78  * Note that the hypot() return is always positive, restricting the
79  * range of return values for elevation to between -pi/2 and +pi/2,
80  * while the range of return values for azimuth is between -pi and +pi.
81  *
82  * Because the normal vector has unit length (in 3-space, not necessarily
83  * in the XY plane), the magnitude of the X and Y elements will be <= 1.0,
84  * so the hypot() function can safely be expanded inline
85  * using a sqrt() call. This will often be more efficient, especially
86  * on machines with hardware sqrt().
87  */
88 #define WRAY_NORMAL(_ray, _norm) \
89  _ray.na = bn_atan2(_norm[Y], _norm[X]); \
90  _ray.ne = bn_atan2(_norm[Z], \
91  sqrt(_norm[X] * _norm[X] + _norm[Y] * _norm[Y]));
92 
93 /*
94  * The 32-bit ray tag field (rt) is encoded as follows:
95  * 13 bits for screen X,
96  * 13 bits for screen Y,
97  * 6 bits for ray level.
98  *
99  * This admits of different ray tags for every ray in a raytrace
100  * up to 4096x4096 pixels, with up to 64 levels of recursion.
101  * It is not clear just why this had to be encoded; it would have
102  * been more useful for the file to have several fields for this.
103  *
104  * 0 1 2 3 3
105  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106  * | Screen Y | Screen X | Level |
107  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108  */
109 #define WRAY_TAG(_ray, _ap) { \
110  if ((_ray.rt = _ap->a_level) > 0x3F || _ray.rt < 0) \
111  _ray.rt = 0x3F; \
112  _ray.rt |= ((_ap->a_x & 0x1FFF) << 6) | \
113  ((_ap->a_y & 0x1FFF) << (6+13)); \
114  }
115 
116 void
117 wray(struct partition *pp, struct application *ap, FILE *fp, const vect_t inormal)
118 {
119  struct vldray vldray;
120  register struct hit *hitp= pp->pt_inhit;
121 
122  VMOVE(&(vldray.ox), hitp->hit_point);
123  VSUB2(&(vldray.rx), pp->pt_outhit->hit_point,
124  hitp->hit_point);
125 
126  WRAY_NORMAL(vldray, inormal);
127 
128  vldray.pa = vldray.pe = vldray.pc = vldray.sc = 0; /* no curv */
129 
130  /* Air is marked by zero or negative region ID codes.
131  * When air is encountered, the air code is taken from reg_aircode.
132  * The negative of the air code is used for the "ob" field, to
133  * distinguish air from other regions.
134  */
135  if ((vldray.ob = pp->pt_regionp->reg_regionid) <= 0)
136  vldray.ob = -(pp->pt_regionp->reg_aircode);
137 
138  WRAY_TAG(vldray, ap);
139 
140  if (fwrite(&vldray, sizeof(struct vldray), 1, fp) != 1)
141  bu_bomb("rway: write error");
142 }
143 
144 
145 /*
146  * Write a VLD-standard ray for a section of a ray specified
147  * by the "in" and "out" distances along the ray. This is usually
148  * used for logging passage through "air" (i.e., no solid).
149  * The "inorm" flag holds an inward pointing normal (typ. a r_dir value)
150  * that will be flipped on output, so that the "air solid"
151  * has a proper outward pointing normal.
152  */
153 void
154 wraypts(vect_t in, vect_t inorm, vect_t out, int id, struct application *ap, FILE *fp)
155 {
156  struct vldray vldray;
157  vect_t norm;
158  size_t ret;
159 
160  VMOVE(&(vldray.ox), in);
161  VSUB2(&(vldray.rx), out, in);
162 
163  VREVERSE(norm, inorm);
164  WRAY_NORMAL(vldray, norm);
165 
166  vldray.pa = vldray.pe = vldray.pc = vldray.sc = 0; /* no curv */
167 
168  vldray.ob = id;
169 
170  WRAY_TAG(vldray, ap);
171 
172  ret = fwrite(&vldray, sizeof(struct vldray), 1, fp);
173  if (ret != 1)
174  bu_log("Unable to write ray\n");
175 }
176 
177 
178 /*
179  * Write "paint" into a VLD standard rayfile.
180  */
181 void
182 wraypaint(vect_t start, vect_t norm, int paint, struct application *ap, FILE *fp)
183 {
184  struct vldray vldray;
185  size_t ret;
186 
187  VMOVE(&(vldray.ox), start);
188  VSETALL(&(vldray.rx), 0);
189 
190  WRAY_NORMAL(vldray, norm);
191 
192  vldray.pa = vldray.pe = vldray.pc = vldray.sc = 0; /* no curv */
193 
194  vldray.ob = paint;
195 
196  WRAY_TAG(vldray, ap);
197 
198  ret = fwrite(&vldray, sizeof(struct vldray), 1, fp);
199  if (ret != 1)
200  bu_log("Unable to write paint into ray file\n");
201 }
202 
203 
204 /*
205  * Local Variables:
206  * mode: C
207  * tab-width: 8
208  * indent-tabs-mode: t
209  * c-file-style: "stroustrup"
210  * End:
211  * ex: shiftwidth=4 tabstop=8
212  */
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
struct region * pt_regionp
ptr to containing region
Definition: raytrace.h:580
struct hit * pt_outhit
OUT hit ptr.
Definition: raytrace.h:579
float pe
Definition: wray.c:56
void wraypts(vect_t in, vect_t inorm, vect_t out, int id, struct application *ap, FILE *fp)
Definition: wray.c:154
#define VSETALL(a, s)
Definition: color.c:54
float pa
Definition: wray.c:55
Definition: raytrace.h:248
#define WRAY_NORMAL(_ray, _norm)
Definition: wray.c:88
float sc
Definition: wray.c:58
Header file for the BRL-CAD common definitions.
float rz
Definition: wray.c:52
float na
Definition: wray.c:53
struct hit * pt_inhit
IN hit pointer.
Definition: raytrace.h:577
#define WRAY_TAG(_ray, _ap)
Definition: wray.c:109
float rx
Definition: wray.c:50
long rt
Definition: wray.c:60
float oy
Definition: wray.c:48
int reg_regionid
Region ID code. If <=0, use reg_aircode.
Definition: raytrace.h:542
point_t hit_point
DEPRECATED: Intersection point, use VJOIN1 hit_dist.
Definition: raytrace.h:251
void wraypaint(vect_t start, vect_t norm, int paint, struct application *ap, FILE *fp)
Definition: wray.c:182
void wray(struct partition *pp, struct application *ap, FILE *fp, const vect_t inormal)
Definition: wray.c:117
float oz
Definition: wray.c:49
float ry
Definition: wray.c:51
goto out
Definition: nmg_mod.c:3846
float pc
Definition: wray.c:57
int reg_aircode
Region ID AIR code.
Definition: raytrace.h:543
long ob
Definition: wray.c:59
Definition: wray.c:45
float ox
Definition: wray.c:47
float ne
Definition: wray.c:54
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
Header file for the BRL-CAD Optical Library, LIBOPTICAL.