BRL-CAD
btg.c
Go to the documentation of this file.
1 /* B T G . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2010-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 primitives/bot/btg.c
21  *
22  * the bot/tie glue.
23  *
24  */
25 
26 #define TIE_PRECISION 1
27 
28 #include "common.h"
29 
30 #include "raytrace.h"
31 #include "rtgeom.h"
32 #include "bot.h"
33 #include "tie.h"
34 
35 #include "btg.h"
36 
37 #include "tie.c"
38 #include "tie_kdtree.c"
39 
42 
43 int rt_bot_makesegs(struct hit *hits, size_t nhits, struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead, struct rt_piecestate *psp);
44 
45 void *
46 bottie_allocn_double(unsigned long long ntri)
47 {
48  struct tie_s *tie;
49  BU_ALLOC(tie, struct tie_s);
50  tie_init1(tie, ntri, TIE_KDTREE_FAST);
51  return tie;
52 }
53 
54 void
55 bottie_push_double(void *vtie, TIE_3 **tri, unsigned int ntri, void *u, unsigned int pstride)
56 {
57  struct tie_s *tie = (struct tie_s *)vtie;
58 
59  tie_push1(tie, tri, ntri, u, pstride);
60 }
61 
62 int
63 bottie_prep_double(struct soltab *stp, struct rt_bot_internal *bot_ip, struct rt_i *UNUSED(rtip))
64 {
65  struct tie_s *tie;
66  struct bot_specific *bot;
67  size_t tri_index, i;
68  TIE_3 *tribuf = NULL, **tribufp = NULL;
69 
70  RT_BOT_CK_MAGIC(bot_ip);
71 
72  BU_GET(bot, struct bot_specific);
73  stp->st_specific = (void *)bot;
74  bot->bot_mode = bot_ip->mode;
75  bot->bot_orientation = bot_ip->orientation;
76  bot->bot_flags = bot_ip->bot_flags;
77  if (bot_ip->thickness) {
78  bot->bot_thickness = (fastf_t *)bu_calloc(bot_ip->num_faces, sizeof(fastf_t), "bot_thickness");
79  for (tri_index = 0; tri_index < bot_ip->num_faces; tri_index++)
80  bot->bot_thickness[tri_index] = bot_ip->thickness[tri_index];
81  } else {
82  bot->bot_thickness = NULL;
83  }
84 
85  if (bot_ip->face_mode) {
86  bot->bot_facemode = bu_bitv_dup(bot_ip->face_mode);
87  } else {
88  bot->bot_facemode = BU_BITV_NULL;
89  }
90  bot->bot_facelist = NULL;
91 
92  tie = (struct tie_s *)bottie_allocn_double(bot_ip->num_faces);
93  if (tie != NULL) {
94  bot_ip->tie = bot->tie = tie;
95  } else {
96  return -1;
97  }
98 
99  if ((tribuf = (TIE_3 *)bu_malloc(sizeof(TIE_3) * 3 * bot_ip->num_faces, "triangle tribuffer")) == NULL) {
100  tie_free(tie);
101  return -1;
102  }
103  if ((tribufp = (TIE_3 **)bu_malloc(sizeof(TIE_3*) * 3 * bot_ip->num_faces, "triangle tribuffer pointer")) == NULL) {
104  tie_free(tie);
105  bu_free(tribuf, "tribuf");
106  return -1;
107  }
108 
109  for (i = 0; i < bot_ip->num_faces*3; i++) {
110  tribufp[i] = &tribuf[i];
111  VMOVE(tribuf[i].v, (bot_ip->vertices+3*bot_ip->faces[i]));
112  }
113 
114  /* tie_pushX sig: (struct tie_s *,
115  * TIE_3 **,
116  * unsigned int,
117  * void *,
118  * unsigned int);
119  */
120  tie_push1((struct tie_s *)bot_ip->tie, tribufp, bot_ip->num_faces, bot, 0);
121 
122  bu_free(tribuf, "tribuffer");
123  bu_free(tribufp, "tribufp");
124 
125  tie_prep1((struct tie_s *)bot->tie);
126 
127  VMOVE(stp->st_min, tie->amin);
128  VMOVE(stp->st_max, tie->amax);
129  VMOVE(stp->st_center, tie->mid);
130  stp->st_aradius = tie->radius;
131  stp->st_bradius = tie->radius;
132 
133  return 0;
134 }
135 
136 #define MAXHITS 128
137 
138 struct hitdata_s {
139  int nhits;
140  struct hit hits[MAXHITS];
142  struct xray *rp;
143 };
144 
145 static void *
146 hitfunc(struct tie_ray_s *ray, struct tie_id_s *id, struct tie_tri_s *UNUSED(tri), void *ptr)
147 {
148  struct hitdata_s *h = (struct hitdata_s *)ptr;
149  struct tri_specific *tsp;
150  struct hit *hp;
151  fastf_t dn; /* Direction dot Normal */
152  fastf_t abs_dn;
153  fastf_t alpha, beta;
154  vect_t wxb; /* vertex - ray_start */
155  vect_t xp; /* wxb cross ray_dir */
156 
157  if (h->nhits > (MAXHITS-1)) {
158  bu_log("Too many hits!\n");
159  return (void *)1;
160  }
161 
162  hp = &h->hits[h->nhits];
163  hp->hit_private = &h->ts[h->nhits];
164  tsp = (struct tri_specific *)hp->hit_private;
165  h->nhits++;
166 
167 
168  hp->hit_magic = RT_HIT_MAGIC;
169  hp->hit_dist = id->dist;
170  VMOVE(tsp->tri_N, id->norm);
171 
172  /* replicate hit_vpriv[] settings from original BOT code, used later to
173  * clean up odd hits, exit before entrance, or dangling entrance in
174  * make_bot_segment(). BOT hits were disappearing from the segment
175  * depending on hit_vpriv[X] uninitialized value.
176  */
177  dn = VDOT(tsp->tri_N, ray->dir);
178  abs_dn = dn >= 0.0 ? dn : (-dn);
179  VSUB2(wxb, tsp->tri_A, ray->pos);
180  VCROSS(xp, wxb, ray->dir);
181  alpha = VDOT(tsp->tri_CA, xp);
182  if (dn < 0.0) alpha = -alpha;
183  beta = VDOT(tsp->tri_BA, xp);
184  hp->hit_vpriv[X] = VDOT(tsp->tri_N, ray->dir);
185  hp->hit_vpriv[Y] = alpha / abs_dn;
186  hp->hit_vpriv[Z] = beta / abs_dn;
187  hp->hit_surfno = tsp->tri_surfno;
188 
189 
190  /* add hitdist into array and add one to nhits */
191  return NULL; /* continue firing */
192 }
193 
194 int
195 bottie_shot_double(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
196 {
197  struct bot_specific *bot;
198  struct tie_s *tie;
199  struct hitdata_s hitdata;
200  struct tie_id_s id;
201  struct tie_ray_s ray;
202  int i;
203  fastf_t dirlen;
204 
205  bot = (struct bot_specific *)stp->st_specific;
206  tie = (struct tie_s *)bot->tie;
207 
208  hitdata.nhits = 0;
209  hitdata.rp = &ap->a_ray;
210  /* do not need to init 'hits' and 'ts', tracked by 'nhits' */
211 
212  /* small backout applied to ray origin */
213  dirlen = MAGSQ(rp->r_dir);
214  VSUB2(ray.pos, rp->r_pt, rp->r_dir); /* step back one dirlen */
215  VMOVE(ray.dir, rp->r_dir);
216  ray.depth = ray.kdtree_depth = 0;
217 
218  tie_work1(tie, &ray, &id, hitfunc, &hitdata);
219 
220  /* use hitfunc to build the hit list */
221  if (hitdata.nhits == 0)
222  return 0;
223 
224  /* adjust hit distances to initial ray origin */
225  for (i = 0; i < hitdata.nhits; i++)
226  hitdata.hits[i].hit_dist = hitdata.hits[i].hit_dist - dirlen;
227 
228  /* FIXME: we don't have the hit_surfno but at least initialize it */
229  for (i = 0; i < hitdata.nhits; i++)
230  hitdata.hits[i].hit_surfno = 0;
231 
232  return rt_bot_makesegs(hitdata.hits, hitdata.nhits, stp, rp, ap, seghead, NULL);
233 }
234 
235 void
237 {
238  tie_free((struct tie_s *)vtie);
239 }
240 
241 /*
242  * Local Variables:
243  * tab-width: 8
244  * mode: C
245  * indent-tabs-mode: t
246  * c-file-style: "stroustrup"
247  * End:
248  * ex: shiftwidth=4 tabstop=8
249  */
struct xray a_ray
Actual ray to be shot.
Definition: raytrace.h:1583
uint32_t hit_magic
Definition: raytrace.h:249
int nhits
Definition: btg.c:139
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
void * hit_private
PRIVATE handle for xxx_shot()
Definition: raytrace.h:254
int bottie_shot_double(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
Definition: btg.c:195
Definition: raytrace.h:215
int tie_check_degenerate
Definition: btg.c:40
Definition: raytrace.h:368
int rt_bot_makesegs(struct hit *hits, size_t nhits, struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead, struct rt_piecestate *psp)
Definition: bot.c:320
vect_t tri_CA
Definition: plane_struct.h:64
Definition: raytrace.h:248
fastf_t st_aradius
Radius of APPROXIMATING sphere.
Definition: raytrace.h:433
Header file for the BRL-CAD common definitions.
int bottie_prep_double(struct soltab *stp, struct rt_bot_internal *bot_ip, struct rt_i *rtip)
Definition: btg.c:63
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
void bottie_free_double(void *vtie)
Definition: btg.c:236
#define BU_BITV_NULL
Definition: bitv.h:111
Definition: color.c:49
struct hit hits[MAXHITS]
Definition: btg.c:140
vect_t hit_vpriv
PRIVATE vector for xxx_*()
Definition: raytrace.h:253
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
void * bottie_allocn_double(unsigned long long ntri)
Definition: btg.c:46
fastf_t st_bradius
Radius of BOUNDING sphere.
Definition: raytrace.h:434
#define MAXHITS
Definition: btg.c:136
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
point_t st_max
max X, Y, Z of bounding RPP
Definition: raytrace.h:438
#define UNUSED(parameter)
Definition: common.h:239
struct bu_bitv * bu_bitv_dup(const struct bu_bitv *bv)
ustring alpha
vect_t r_dir
Direction of ray (UNIT Length)
Definition: raytrace.h:219
vect_t tri_N
Definition: plane_struct.h:66
point_t r_pt
Point at which ray starts.
Definition: raytrace.h:218
point_t st_min
min X, Y, Z of bounding RPP
Definition: raytrace.h:437
void * st_specific
-> ID-specific (private) struct
Definition: raytrace.h:435
struct xray * rp
Definition: btg.c:142
struct tri_specific ts[MAXHITS]
Definition: btg.c:141
void bottie_push_double(void *vtie, TIE_3 **tri, unsigned int ntri, void *u, unsigned int pstride)
Definition: btg.c:55
void TIE_VAL() tie_free(struct tie_s *tie)
Definition: tie.c:160
Definition: color.c:51
point_t tri_A
Definition: plane_struct.h:62
int hit_surfno
solid-specific surface indicator
Definition: raytrace.h:255
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
fastf_t hit_dist
dist from r_pt to hit_point
Definition: raytrace.h:250
double fastf_t
Definition: defines.h:300
Definition: btg.c:138
fastf_t TIE_PREC
Definition: btg.c:41
Definition: color.c:50
vect_t tri_BA
Definition: plane_struct.h:63
point_t st_center
Centroid of solid.
Definition: raytrace.h:432
#define RT_HIT_MAGIC
Definition: magic.h:161