Bullet Collision Detection & Physics Library
btMiniSDF.cpp
Go to the documentation of this file.
1 #include "btMiniSDF.h"
2 
3 //
4 //Based on code from DiscreGrid, https://github.com/InteractiveComputerGraphics/Discregrid
5 //example:
6 //GenerateSDF.exe -r "32 32 32" -d "-1.6 -1.6 -.6 1.6 1.6 .6" concave_box.obj
7 //The MIT License (MIT)
8 //
9 //Copyright (c) 2017 Dan Koschier
10 //
11 
12 #include <limits.h>
13 #include <string.h> //memcpy
14 
16 {
17  const char* m_data;
18  int m_size;
19 
21 
22  btSdfDataStream(const char* data, int size)
23  :m_data(data),
24  m_size(size),
25  m_currentOffset(0)
26  {
27 
28  }
29 
30  template<class T> bool read(T& val)
31  {
32  int bytes = sizeof(T);
33  if (m_currentOffset+bytes<=m_size)
34  {
35  char* dest = (char*)&val;
36  memcpy(dest,&m_data[m_currentOffset],bytes);
37  m_currentOffset+=bytes;
38  return true;
39  }
40  btAssert(0);
41  return false;
42  }
43 };
44 
45 
46 bool btMiniSDF::load(const char* data, int size)
47 {
48  int fileSize = -1;
49 
50  btSdfDataStream ds(data,size);
51  {
52  double buf[6];
53  ds.read(buf);
54  m_domain.m_min[0] = buf[0];
55  m_domain.m_min[1] = buf[1];
56  m_domain.m_min[2] = buf[2];
57  m_domain.m_min[3] = 0;
58  m_domain.m_max[0] = buf[3];
59  m_domain.m_max[1] = buf[4];
60  m_domain.m_max[2] = buf[5];
61  m_domain.m_max[3] = 0;
62  }
63  {
64  unsigned int buf2[3];
65  ds.read(buf2);
66  m_resolution[0] = buf2[0];
67  m_resolution[1] = buf2[1];
68  m_resolution[2] = buf2[2];
69  }
70  {
71  double buf[3];
72  ds.read(buf);
73  m_cell_size[0] = buf[0];
74  m_cell_size[1] = buf[1];
75  m_cell_size[2] = buf[2];
76  }
77  {
78  double buf[3];
79  ds.read(buf);
80  m_inv_cell_size[0] = buf[0];
81  m_inv_cell_size[1] = buf[1];
82  m_inv_cell_size[2] = buf[2];
83  }
84  {
85  unsigned long long int cells;
86  ds.read(cells);
87  m_n_cells = cells;
88  }
89  {
90  unsigned long long int fields;
91  ds.read(fields);
92  m_n_fields = fields;
93  }
94 
95 
96  unsigned long long int nodes0;
97  std::size_t n_nodes0;
98  ds.read(nodes0);
99  n_nodes0 = nodes0;
100  if (n_nodes0 > 1024 * 1024 * 1024)
101  {
102  return m_isValid;
103  }
104  m_nodes.resize(n_nodes0);
105  for (unsigned int i=0;i<n_nodes0;i++)
106  {
107  unsigned long long int n_nodes1;
108  ds.read(n_nodes1);
109  btAlignedObjectArray<double>& nodes = m_nodes[i];
110  nodes.resize(n_nodes1);
111  for ( int j=0;j<nodes.size();j++)
112  {
113  double& node = nodes[j];
114  ds.read(node);
115  }
116  }
117 
118  unsigned long long int n_cells0;
119  ds.read(n_cells0);
120  m_cells.resize(n_cells0);
121  for (int i=0;i<n_cells0;i++)
122  {
123  unsigned long long int n_cells1;
124  btAlignedObjectArray<btCell32 >& cells = m_cells[i];
125  ds.read(n_cells1);
126  cells.resize(n_cells1);
127  for (int j=0;j<n_cells1;j++)
128  {
129  btCell32& cell = cells[j];
130  ds.read(cell);
131  }
132  }
133 
134  {
135  unsigned long long int n_cell_maps0;
136  ds.read(n_cell_maps0);
137 
138  m_cell_map.resize(n_cell_maps0);
139  for (int i=0;i<n_cell_maps0;i++)
140  {
141  unsigned long long int n_cell_maps1;
142  btAlignedObjectArray<unsigned int>& cell_maps = m_cell_map[i];
143  ds.read(n_cell_maps1);
144  cell_maps.resize(n_cell_maps1);
145  for (int j=0;j<n_cell_maps1;j++)
146  {
147  unsigned int& cell_map = cell_maps[j];
148  ds.read(cell_map);
149  }
150  }
151  }
152 
153  m_isValid = (ds.m_currentOffset == ds.m_size);
154  return m_isValid;
155 }
156 
157 
158 unsigned int btMiniSDF::multiToSingleIndex(btMultiIndex const & ijk) const
159 {
160  return m_resolution[1] * m_resolution[0] * ijk.ijk[2] + m_resolution[0] * ijk.ijk[1] + ijk.ijk[0];
161 }
162 
165 {
166  btAssert(m_isValid);
167  btVector3 tmp;
168  tmp.m_floats[0] = m_cell_size[0]*(double)ijk.ijk[0];
169  tmp.m_floats[1] = m_cell_size[1]*(double)ijk.ijk[1];
170  tmp.m_floats[2] = m_cell_size[2]*(double)ijk.ijk[2];
171 
172 
173  btVector3 origin = m_domain.min() + tmp;
174 
175  btAlignedBox3d box = btAlignedBox3d (origin, origin + m_cell_size);
176  return box;
177 }
178 
180 btMiniSDF::singleToMultiIndex(unsigned int l) const
181 {
182  btAssert(m_isValid);
183  unsigned int n01 = m_resolution[0] * m_resolution[1];
184  unsigned int k = l / n01;
185  unsigned int temp = l % n01;
186  unsigned int j = temp / m_resolution[0];
187  unsigned int i = temp % m_resolution[0];
188  btMultiIndex mi;
189  mi.ijk[0] = i;
190  mi.ijk[1] = j;
191  mi.ijk[2] = k;
192  return mi;
193 }
194 
196 btMiniSDF::subdomain(unsigned int l) const
197 {
198  btAssert(m_isValid);
199  return subdomain(singleToMultiIndex(l));
200 }
201 
202 
205 {
206  btAssert(m_isValid);
207  btShapeMatrix res;
208 
209  btScalar x = xi[0];
210  btScalar y = xi[1];
211  btScalar z = xi[2];
212 
213  btScalar x2 = x*x;
214  btScalar y2 = y*y;
215  btScalar z2 = z*z;
216 
217  btScalar _1mx = 1.0 - x;
218  btScalar _1my = 1.0 - y;
219  btScalar _1mz = 1.0 - z;
220 
221  btScalar _1px = 1.0 + x;
222  btScalar _1py = 1.0 + y;
223  btScalar _1pz = 1.0 + z;
224 
225  btScalar _1m3x = 1.0 - 3.0 * x;
226  btScalar _1m3y = 1.0 - 3.0 * y;
227  btScalar _1m3z = 1.0 - 3.0 * z;
228 
229  btScalar _1p3x = 1.0 + 3.0 * x;
230  btScalar _1p3y = 1.0 + 3.0 * y;
231  btScalar _1p3z = 1.0 + 3.0 * z;
232 
233  btScalar _1mxt1my = _1mx * _1my;
234  btScalar _1mxt1py = _1mx * _1py;
235  btScalar _1pxt1my = _1px * _1my;
236  btScalar _1pxt1py = _1px * _1py;
237 
238  btScalar _1mxt1mz = _1mx * _1mz;
239  btScalar _1mxt1pz = _1mx * _1pz;
240  btScalar _1pxt1mz = _1px * _1mz;
241  btScalar _1pxt1pz = _1px * _1pz;
242 
243  btScalar _1myt1mz = _1my * _1mz;
244  btScalar _1myt1pz = _1my * _1pz;
245  btScalar _1pyt1mz = _1py * _1mz;
246  btScalar _1pyt1pz = _1py * _1pz;
247 
248  btScalar _1mx2 = 1.0 - x2;
249  btScalar _1my2 = 1.0 - y2;
250  btScalar _1mz2 = 1.0 - z2;
251 
252 
253  // Corner nodes.
254  btScalar fac = 1.0 / 64.0 * (9.0 * (x2 + y2 + z2) - 19.0);
255  res[0] = fac * _1mxt1my * _1mz;
256  res[1] = fac * _1pxt1my * _1mz;
257  res[2] = fac * _1mxt1py * _1mz;
258  res[3] = fac * _1pxt1py * _1mz;
259  res[4] = fac * _1mxt1my * _1pz;
260  res[5] = fac * _1pxt1my * _1pz;
261  res[6] = fac * _1mxt1py * _1pz;
262  res[7] = fac * _1pxt1py * _1pz;
263 
264  // Edge nodes.
265 
266  fac = 9.0 / 64.0 * _1mx2;
267  btScalar fact1m3x = fac * _1m3x;
268  btScalar fact1p3x = fac * _1p3x;
269  res[ 8] = fact1m3x * _1myt1mz;
270  res[ 9] = fact1p3x * _1myt1mz;
271  res[10] = fact1m3x * _1myt1pz;
272  res[11] = fact1p3x * _1myt1pz;
273  res[12] = fact1m3x * _1pyt1mz;
274  res[13] = fact1p3x * _1pyt1mz;
275  res[14] = fact1m3x * _1pyt1pz;
276  res[15] = fact1p3x * _1pyt1pz;
277 
278  fac = 9.0 / 64.0 * _1my2;
279  btScalar fact1m3y = fac * _1m3y;
280  btScalar fact1p3y = fac * _1p3y;
281  res[16] = fact1m3y * _1mxt1mz;
282  res[17] = fact1p3y * _1mxt1mz;
283  res[18] = fact1m3y * _1pxt1mz;
284  res[19] = fact1p3y * _1pxt1mz;
285  res[20] = fact1m3y * _1mxt1pz;
286  res[21] = fact1p3y * _1mxt1pz;
287  res[22] = fact1m3y * _1pxt1pz;
288  res[23] = fact1p3y * _1pxt1pz;
289 
290  fac = 9.0 / 64.0 * _1mz2;
291  btScalar fact1m3z = fac * _1m3z;
292  btScalar fact1p3z = fac * _1p3z;
293  res[24] = fact1m3z * _1mxt1my;
294  res[25] = fact1p3z * _1mxt1my;
295  res[26] = fact1m3z * _1mxt1py;
296  res[27] = fact1p3z * _1mxt1py;
297  res[28] = fact1m3z * _1pxt1my;
298  res[29] = fact1p3z * _1pxt1my;
299  res[30] = fact1m3z * _1pxt1py;
300  res[31] = fact1p3z * _1pxt1py;
301 
302  if (gradient)
303  {
304  btShapeGradients& dN = *gradient;
305 
306  btScalar _9t3x2py2pz2m19 = 9.0 * (3.0 * x2 + y2 + z2) - 19.0;
307  btScalar _9tx2p3y2pz2m19 = 9.0 * (x2 + 3.0 * y2 + z2) - 19.0;
308  btScalar _9tx2py2p3z2m19 = 9.0 * (x2 + y2 + 3.0 * z2) - 19.0;
309  btScalar _18x = 18.0 * x;
310  btScalar _18y = 18.0 * y;
311  btScalar _18z = 18.0 * z;
312 
313  btScalar _3m9x2 = 3.0 - 9.0 * x2;
314  btScalar _3m9y2 = 3.0 - 9.0 * y2;
315  btScalar _3m9z2 = 3.0 - 9.0 * z2;
316 
317  btScalar _2x = 2.0 * x;
318  btScalar _2y = 2.0 * y;
319  btScalar _2z = 2.0 * z;
320 
321  btScalar _18xm9t3x2py2pz2m19 = _18x - _9t3x2py2pz2m19;
322  btScalar _18xp9t3x2py2pz2m19 = _18x + _9t3x2py2pz2m19;
323  btScalar _18ym9tx2p3y2pz2m19 = _18y - _9tx2p3y2pz2m19;
324  btScalar _18yp9tx2p3y2pz2m19 = _18y + _9tx2p3y2pz2m19;
325  btScalar _18zm9tx2py2p3z2m19 = _18z - _9tx2py2p3z2m19;
326  btScalar _18zp9tx2py2p3z2m19 = _18z + _9tx2py2p3z2m19;
327 
328  dN(0,0) =_18xm9t3x2py2pz2m19 * _1myt1mz;
329  dN(0,1) =_1mxt1mz * _18ym9tx2p3y2pz2m19;
330  dN(0,2) =_1mxt1my * _18zm9tx2py2p3z2m19;
331  dN(1,0) =_18xp9t3x2py2pz2m19 * _1myt1mz;
332  dN(1,1) =_1pxt1mz * _18ym9tx2p3y2pz2m19;
333  dN(1,2) =_1pxt1my * _18zm9tx2py2p3z2m19;
334  dN(2,0) =_18xm9t3x2py2pz2m19 * _1pyt1mz;
335  dN(2,1) =_1mxt1mz * _18yp9tx2p3y2pz2m19;
336  dN(2,2) =_1mxt1py * _18zm9tx2py2p3z2m19;
337  dN(3,0) =_18xp9t3x2py2pz2m19 * _1pyt1mz;
338  dN(3,1) =_1pxt1mz * _18yp9tx2p3y2pz2m19;
339  dN(3,2) =_1pxt1py * _18zm9tx2py2p3z2m19;
340  dN(4,0) =_18xm9t3x2py2pz2m19 * _1myt1pz;
341  dN(4,1) =_1mxt1pz * _18ym9tx2p3y2pz2m19;
342  dN(4,2) =_1mxt1my * _18zp9tx2py2p3z2m19;
343  dN(5,0) =_18xp9t3x2py2pz2m19 * _1myt1pz;
344  dN(5,1) =_1pxt1pz * _18ym9tx2p3y2pz2m19;
345  dN(5,2) =_1pxt1my * _18zp9tx2py2p3z2m19;
346  dN(6,0) =_18xm9t3x2py2pz2m19 * _1pyt1pz;
347  dN(6,1) =_1mxt1pz * _18yp9tx2p3y2pz2m19;
348  dN(6,2) =_1mxt1py * _18zp9tx2py2p3z2m19;
349  dN(7,0) =_18xp9t3x2py2pz2m19 * _1pyt1pz;
350  dN(7,1) =_1pxt1pz * _18yp9tx2p3y2pz2m19;
351  dN(7,2) =_1pxt1py * _18zp9tx2py2p3z2m19;
352 
353  dN.topRowsDivide(8, 64.0);
354 
355  btScalar _m3m9x2m2x = -_3m9x2 - _2x;
356  btScalar _p3m9x2m2x = _3m9x2 - _2x;
357  btScalar _1mx2t1m3x = _1mx2 * _1m3x;
358  btScalar _1mx2t1p3x = _1mx2 * _1p3x;
359  dN( 8,0) = _m3m9x2m2x * _1myt1mz,
360  dN( 8,1) = -_1mx2t1m3x * _1mz,
361  dN( 8,2) = -_1mx2t1m3x * _1my;
362  dN( 9,0) = _p3m9x2m2x * _1myt1mz,
363  dN( 9,1) = -_1mx2t1p3x * _1mz,
364  dN( 9,2) = -_1mx2t1p3x * _1my;
365  dN(10,0) = _m3m9x2m2x * _1myt1pz,
366  dN(10,1) = -_1mx2t1m3x * _1pz,
367  dN(10,2) = _1mx2t1m3x * _1my;
368  dN(11,0) = _p3m9x2m2x * _1myt1pz,
369  dN(11,1) = -_1mx2t1p3x * _1pz,
370  dN(11,2) = _1mx2t1p3x * _1my;
371  dN(12,0) = _m3m9x2m2x * _1pyt1mz,
372  dN(12,1) = _1mx2t1m3x * _1mz,
373  dN(12,2) = -_1mx2t1m3x * _1py;
374  dN(13,0) = _p3m9x2m2x * _1pyt1mz,
375  dN(13,1) = _1mx2t1p3x * _1mz,
376  dN(13,2) = -_1mx2t1p3x * _1py;
377  dN(14,0) = _m3m9x2m2x * _1pyt1pz,
378  dN(14,1) = _1mx2t1m3x * _1pz,
379  dN(14,2) = _1mx2t1m3x * _1py;
380  dN(15,0) = _p3m9x2m2x * _1pyt1pz,
381  dN(15,1) = _1mx2t1p3x * _1pz,
382  dN(15,2) = _1mx2t1p3x * _1py;
383 
384  btScalar _m3m9y2m2y = -_3m9y2 - _2y;
385  btScalar _p3m9y2m2y = _3m9y2 - _2y;
386  btScalar _1my2t1m3y = _1my2 * _1m3y;
387  btScalar _1my2t1p3y = _1my2 * _1p3y;
388  dN(16,0) = -_1my2t1m3y * _1mz,
389  dN(16,1) = _m3m9y2m2y * _1mxt1mz,
390  dN(16,2) = -_1my2t1m3y * _1mx;
391  dN(17,0) = -_1my2t1p3y * _1mz,
392  dN(17,1) = _p3m9y2m2y * _1mxt1mz,
393  dN(17,2) = -_1my2t1p3y * _1mx;
394  dN(18,0) = _1my2t1m3y * _1mz,
395  dN(18,1) = _m3m9y2m2y * _1pxt1mz,
396  dN(18,2) = -_1my2t1m3y * _1px;
397  dN(19,0) = _1my2t1p3y * _1mz,
398  dN(19,1) = _p3m9y2m2y * _1pxt1mz,
399  dN(19,2) = -_1my2t1p3y * _1px;
400  dN(20,0) = -_1my2t1m3y * _1pz,
401  dN(20,1) = _m3m9y2m2y * _1mxt1pz,
402  dN(20,2) = _1my2t1m3y * _1mx;
403  dN(21,0) = -_1my2t1p3y * _1pz,
404  dN(21,1) = _p3m9y2m2y * _1mxt1pz,
405  dN(21,2) = _1my2t1p3y * _1mx;
406  dN(22,0) = _1my2t1m3y * _1pz,
407  dN(22,1) = _m3m9y2m2y * _1pxt1pz,
408  dN(22,2) = _1my2t1m3y * _1px;
409  dN(23,0) = _1my2t1p3y * _1pz,
410  dN(23,1) = _p3m9y2m2y * _1pxt1pz,
411  dN(23,2) = _1my2t1p3y * _1px;
412 
413 
414  btScalar _m3m9z2m2z = -_3m9z2 - _2z;
415  btScalar _p3m9z2m2z = _3m9z2 - _2z;
416  btScalar _1mz2t1m3z = _1mz2 * _1m3z;
417  btScalar _1mz2t1p3z = _1mz2 * _1p3z;
418  dN(24,0) = -_1mz2t1m3z * _1my,
419  dN(24,1) = -_1mz2t1m3z * _1mx,
420  dN(24,2) = _m3m9z2m2z * _1mxt1my;
421  dN(25,0) = -_1mz2t1p3z * _1my,
422  dN(25,1) = -_1mz2t1p3z * _1mx,
423  dN(25,2) = _p3m9z2m2z * _1mxt1my;
424  dN(26,0) = -_1mz2t1m3z * _1py,
425  dN(26,1) = _1mz2t1m3z * _1mx,
426  dN(26,2) = _m3m9z2m2z * _1mxt1py;
427  dN(27,0) = -_1mz2t1p3z * _1py,
428  dN(27,1) = _1mz2t1p3z * _1mx,
429  dN(27,2) = _p3m9z2m2z * _1mxt1py;
430  dN(28,0) = _1mz2t1m3z * _1my,
431  dN(28,1) = -_1mz2t1m3z * _1px,
432  dN(28,2) = _m3m9z2m2z * _1pxt1my;
433  dN(29,0) = _1mz2t1p3z * _1my,
434  dN(29,1) = -_1mz2t1p3z * _1px,
435  dN(29,2) = _p3m9z2m2z * _1pxt1my;
436  dN(30,0) = _1mz2t1m3z * _1py,
437  dN(30,1) = _1mz2t1m3z * _1px,
438  dN(30,2) = _m3m9z2m2z * _1pxt1py;
439  dN(31,0) = _1mz2t1p3z * _1py,
440  dN(31,1) = _1mz2t1p3z * _1px,
441  dN(31,2) = _p3m9z2m2z * _1pxt1py;
442 
443  dN.bottomRowsMul(32u - 8u, 9.0 / 64.0);
444 
445  }
446 
447  return res;
448 }
449 
450 
451 
452 bool btMiniSDF::interpolate(unsigned int field_id, double& dist, btVector3 const& x,
453  btVector3* gradient) const
454 {
455  btAssert(m_isValid);
456  if (!m_isValid)
457  return false;
458 
459  if (!m_domain.contains(x))
460  return false;
461 
462  btVector3 tmpmi = ((x - m_domain.min())*(m_inv_cell_size));//.cast<unsigned int>().eval();
463  unsigned int mi[3] = {(unsigned int )tmpmi[0],(unsigned int )tmpmi[1],(unsigned int )tmpmi[2]};
464  if (mi[0] >= m_resolution[0])
465  mi[0] = m_resolution[0]-1;
466  if (mi[1] >= m_resolution[1])
467  mi[1] = m_resolution[1]-1;
468  if (mi[2] >= m_resolution[2])
469  mi[2] = m_resolution[2]-1;
470  btMultiIndex mui;
471  mui.ijk[0] = mi[0];
472  mui.ijk[1] = mi[1];
473  mui.ijk[2] = mi[2];
474  int i = multiToSingleIndex(mui);
475  unsigned int i_ = m_cell_map[field_id][i];
476  if (i_ == UINT_MAX)
477  return false;
478 
479  btAlignedBox3d sd = subdomain(i);
480  i = i_;
481  btVector3 d = sd.m_max-sd.m_min;//.diagonal().eval();
482 
483  btVector3 denom = (sd.max() - sd.min());
484  btVector3 c0 = btVector3(2.0,2.0,2.0)/denom;
485  btVector3 c1 = (sd.max() + sd.min())/denom;
486  btVector3 xi = (c0*x - c1);
487 
488  btCell32 const& cell = m_cells[field_id][i];
489  if (!gradient)
490  {
491  //auto phi = m_coefficients[field_id][i].dot(shape_function_(xi, 0));
492  double phi = 0.0;
493  btShapeMatrix N = shape_function_(xi, 0);
494  for (unsigned int j = 0u; j < 32u; ++j)
495  {
496  unsigned int v = cell.m_cells[j];
497  double c = m_nodes[field_id][v];
498  if (c == DBL_MAX)
499  {
500  return false;;
501  }
502  phi += c * N[j];
503  }
504 
505  dist = phi;
506  return true;
507  }
508 
509  btShapeGradients dN;
510  btShapeMatrix N = shape_function_(xi, &dN);
511 
512  double phi = 0.0;
513  gradient->setZero();
514  for (unsigned int j = 0u; j < 32u; ++j)
515  {
516  unsigned int v = cell.m_cells[j];
517  double c = m_nodes[field_id][v];
518  if (c == DBL_MAX)
519  {
520  gradient->setZero();
521  return false;
522  }
523  phi += c * N[j];
524  (*gradient)[0] += c * dN(j, 0);
525  (*gradient)[1] += c * dN(j, 1);
526  (*gradient)[2] += c * dN(j, 2);
527  }
528  (*gradient) *= c0;
529  dist = phi;
530  return true;
531 }
532 
void bottomRowsMul(int row, double val)
Definition: btMiniSDF.h:74
btAlignedBox3d subdomain(btMultiIndex const &ijk) const
Definition: btMiniSDF.cpp:164
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
btSdfDataStream(const char *data, int size)
Definition: btMiniSDF.cpp:22
btScalar m_floats[4]
Definition: btVector3.h:112
btVector3 m_min
Definition: btMiniSDF.h:16
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define btAssert(x)
Definition: btScalar.h:131
btVector3 m_max
Definition: btMiniSDF.h:17
const btVector3 & min() const
Definition: btMiniSDF.h:19
bool interpolate(unsigned int field_id, double &dist, btVector3 const &x, btVector3 *gradient) const
Definition: btMiniSDF.cpp:452
bool load(const char *data, int size)
Definition: btMiniSDF.cpp:46
unsigned int multiToSingleIndex(btMultiIndex const &ijk) const
Definition: btMiniSDF.cpp:158
const char * m_data
Definition: btMiniSDF.cpp:17
unsigned int ijk[3]
Definition: btMiniSDF.h:11
btShapeMatrix shape_function_(btVector3 const &xi, btShapeGradients *gradient=0) const
Definition: btMiniSDF.cpp:204
int size() const
return the number of elements in the array
unsigned int m_cells[32]
Definition: btMiniSDF.h:90
void setZero()
Definition: btVector3.h:683
const btVector3 & max() const
Definition: btMiniSDF.h:24
btMultiIndex singleToMultiIndex(unsigned int l) const
Definition: btMiniSDF.cpp:180
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
void topRowsDivide(int row, double denom)
Definition: btMiniSDF.h:66
void resize(int newsize, const T &fillData=T())
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
bool read(T &val)
Definition: btMiniSDF.cpp:30