2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Nicholas Bishop
20 * ***** END GPL LICENSE BLOCK *****
25 #include "ModelReader.h"
31 #if defined(_WIN32) && !defined(__MINGW32__)
32 #define isnan(n) _isnan(n)
35 void veccopy(float dst[3], const float src[3])
42 #define GET_FACE(_mesh, _n) \
43 (*(DualConFaces)(((char *)(_mesh)->faces) + ((_n) * (_mesh)->face_stride)))
45 #define GET_CO(_mesh, _n) \
46 (*(DualConCo)(((char *)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
48 class DualConInputReader : public ModelReader
51 const DualConInput *input_mesh;
52 int tottri, curface, offset;
53 float min[3], max[3], maxsize;
56 DualConInputReader(const DualConInput *mesh, float _scale)
57 : input_mesh(mesh), scale(_scale)
69 /* initialize tottri */
70 for (int i = 0; i < input_mesh->totface; i++)
71 tottri += GET_FACE(input_mesh, i)[3] ? 2 : 1;
73 veccopy(min, input_mesh->min);
74 veccopy(max, input_mesh->max);
76 /* initialize maxsize */
77 for (int i = 0; i < 3; i++) {
78 float d = max[i] - min[i];
84 for (int i = 0; i < 3; i++)
86 min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
87 max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
90 for (int i = 0; i < 3; i++)
91 min[i] -= maxsize * (1 / scale - 1) / 2;
95 Triangle *getNextTriangle()
97 if (curface == input_mesh->totface)
100 Triangle *t = new Triangle();
102 unsigned int *f = GET_FACE(input_mesh, curface);
104 veccopy(t->vt[0], GET_CO(input_mesh, f[0]));
105 veccopy(t->vt[1], GET_CO(input_mesh, f[1]));
106 veccopy(t->vt[2], GET_CO(input_mesh, f[2]));
109 veccopy(t->vt[0], GET_CO(input_mesh, f[2]));
110 veccopy(t->vt[1], GET_CO(input_mesh, f[3]));
111 veccopy(t->vt[2], GET_CO(input_mesh, f[0]));
114 if (offset == 0 && f[3])
121 /* remove triangle if it contains invalid coords */
122 for (int i = 0; i < 3; i++) {
123 const float *co = t->vt[i];
124 if (isnan(co[0]) || isnan(co[1]) || isnan(co[2])) {
126 return getNextTriangle();
133 int getNextTriangle(int t[3])
135 if (curface == input_mesh->totface)
138 unsigned int *f = GET_FACE(input_mesh, curface);
150 if (offset == 0 && f[3])
160 int getNumTriangles()
167 return input_mesh->totco;
170 float getBoundingBox(float origin[3])
172 veccopy(origin, min);
177 void getNextVertex(float v[3])
186 return sizeof(DualConInputReader);
190 void *dualcon(const DualConInput *input_mesh,
191 /* callbacks for output */
192 DualConAllocOutput alloc_output,
193 DualConAddVert add_vert,
194 DualConAddQuad add_quad,
203 DualConInputReader r(input_mesh, scale);
204 Octree o(&r, alloc_output, add_vert, add_quad,
205 flags, mode, depth, threshold, hermite_num);
207 return o.getOutputMesh();