FreeWRL / FreeX3D 4.3.0
Component_Geometry3D.c
1/*
2
3
4X3D Geometry 3D Component
5
6*/
7
8
9/****************************************************************************
10 This file is part of the FreeWRL/FreeX3D Distribution.
11
12 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13
14 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26****************************************************************************/
27
28
29
30#include <config.h>
31#include <system.h>
32#include <display.h>
33#include <internal.h>
34
35#include <libFreeWRL.h>
36
37#include "../vrml_parser/Structs.h"
38#include "../main/headers.h"
39#include "../opengl/Frustum.h"
40#include "../opengl/OpenGL_Utils.h"
41#include "../opengl/Textures.h"
42#include "../scenegraph/Component_Shape.h"
43#include "../scenegraph/RenderFuncs.h"
44
45
46#include "Collision.h"
47#include "Polyrep.h"
48#include "LinearAlgebra.h"
49#include "Component_Geometry3D.h"
50#include "../x3d_parser/Bindable.h"
51
52
53/* used for vertices for VBOs. Note the tc coordinate... */
55 {
56 struct SFVec3f vert; //Vertex
57 struct SFVec3f norm; //Normal
58 struct SFVec2f tc; //Texcoord0
59 struct SFVec3f flat_norm;
60 };
61
62 typedef int cquad[4];
63typedef int ctri[3];
65{
66 struct point_XYZ *pts;
67 struct point_XYZ *tpts;
68 ctri *tris;
69 int ntris;
70 cquad *quads;
71 int nquads;
72 int npts;
73 double smin[3],smax[3];
74};
75
76
77
78typedef struct pComponent_Geometry3D{
79 int junk; //filler, no variables unless/untill vbos done
80 //SphereGeomVBO ShpereIndxVBO - are these per-instance or sharable?
81 struct sCollisionGeometry collisionSphere;
82 struct sCollisionGeometry collisionCylinder;
83 struct sCollisionGeometry collisionCone;
84 //struct point_XYZ *collisionSphere_tpts;
85 //struct point_XYZ *collisionCylinder_tpts;
86 //struct point_XYZ *collisionCone_tpts;
87}* ppComponent_Geometry3D;
88void *Component_Geometry3D_constructor(){
89 void *v = MALLOCV(sizeof(struct pComponent_Geometry3D));
90 memset(v,0,sizeof(struct pComponent_Geometry3D));
91 return v;
92}
93void Component_Geometry3D_init(struct tComponent_Geometry3D *t){
94 //public
95 //private
96 t->prv = Component_Geometry3D_constructor();
97 {
98 ppComponent_Geometry3D p = (ppComponent_Geometry3D)t->prv;
99 //generic geometry could in theory be static -its read only- but because we calculate it we malloc it,
100 // and because we malloc it we need to free it, and because of that we make it 1:1 with gglobal / browser
101 // so it can be freed on clear_.
102 bzero(&p->collisionSphere,sizeof(struct sCollisionGeometry)); //= {NULL,NULL,NULL,0,NULL,0,0, {0.0,0.0,0.0},{0.0,0.0,0.0}};
103 bzero(&p->collisionCylinder,sizeof(struct sCollisionGeometry)); // = {NULL,NULL,NULL,0,NULL,0,0, {0.0,0.0,0.0},{0.0,0.0,0.0}};
104 bzero(&p->collisionCone,sizeof(struct sCollisionGeometry)); //= {NULL,NULL,NULL,0,NULL,0,0, {0.0,0.0,0.0},{0.0,0.0,0.0}};
105 //transformed points are not read only -computed once on each frame- and _must_ be per gglobal
106 //p->collisionSphere_tpts;
107 //p->collisionCylinder_tpts;
108 //p->collisionCone_tpts;
109 }
110}
111void Component_Geometry3D_clear(struct tComponent_Geometry3D *t){
112 //public
113 //private
114 {
115 ppComponent_Geometry3D p = (ppComponent_Geometry3D)t->prv;
116 FREE_IF_NZ(p->collisionCone.tpts);
117 FREE_IF_NZ(p->collisionCylinder.tpts);
118 FREE_IF_NZ(p->collisionSphere.tpts);
119
120 FREE_IF_NZ(p->collisionCone.tris);
121 FREE_IF_NZ(p->collisionCylinder.quads);
122 FREE_IF_NZ(p->collisionCylinder.tris);
123 FREE_IF_NZ(p->collisionSphere.tris);
124
125 FREE_IF_NZ(p->collisionCone.pts);
126 FREE_IF_NZ(p->collisionCylinder.pts);
127 FREE_IF_NZ(p->collisionSphere.pts);
128 }
129}
130//ppComponent_Geometry3D p = (ppComponent_Geometry3D)gglobal()->Component_Geometry3D.prv;
131
132
133static GLfloat VBO_coneSideTexParams[]={
134 0.55f, 0.525f, 0.50f,
135 0.60f, 0.575f, 0.55f,
136 0.65f, 0.625f, 0.60f,
137 0.70f, 0.675f, 0.65f,
138 0.75f, 0.725f, 0.70f,
139 0.80f, 0.775f, 0.75f,
140 0.85f, 0.825f, 0.80f,
141 0.90f, 0.875f, 0.85f,
142 0.95f, 0.925f, 0.90f,
143 1.00f, 0.975f, 0.95f,
144 0.05f, 0.025f, 0.00f,
145 0.10f, 0.075f, 0.05f,
146 0.15f, 0.125f, 0.10f,
147 0.20f, 0.175f, 0.15f,
148 0.25f, 0.225f, 0.20f,
149 0.30f, 0.275f, 0.25f,
150 0.35f, 0.325f, 0.30f,
151 0.40f, 0.375f, 0.35f,
152 0.45f, 0.425f, 0.40f,
153 0.50f, 0.475f, 0.45f,
154 0.55f, 0.525f, 0.50f
155};
156
157/*******************************************************************************/
158
159/* have to regen the shape*/
160void compile_Box (struct X3D_Box *node) {
161 struct SFVec3f *pt;
162 struct SFVec3f *ptr;
163 float x = ((node->size).c[0])/2;
164 float y = ((node->size).c[1])/2;
165 float z = ((node->size).c[2])/2;
166
167 MARK_NODE_COMPILED
168
169 /* MALLOC memory (if possible)*/
170 if (!node->__points.p) ptr = MALLOC (struct SFVec3f *,sizeof(struct SFVec3f)*(36));
171 else ptr = node->__points.p;
172
173 /* now, create points; 6 points per face.*/
174 pt = ptr;
175
176
177#define PTF0 (*pt).c[0] = x; (*pt).c[1] = y; (*pt).c[2] = z; pt++;
178#define PTF1 (*pt).c[0] = -x; (*pt).c[1] = y; (*pt).c[2] = z; pt++;
179#define PTF2 (*pt).c[0] = -x; (*pt).c[1] = -y; (*pt).c[2] = z; pt++;
180#define PTF3 (*pt).c[0] = x; (*pt).c[1] = -y; (*pt).c[2] = z; pt++;
181#define PTR0 (*pt).c[0] = x; (*pt).c[1] = y; (*pt).c[2] = -z; pt++;
182#define PTR1 (*pt).c[0] = -x; (*pt).c[1] = y; (*pt).c[2] = -z; pt++;
183#define PTR2 (*pt).c[0] = -x; (*pt).c[1] = -y; (*pt).c[2] = -z; pt++;
184#define PTR3 (*pt).c[0] = x; (*pt).c[1] = -y; (*pt).c[2] = -z; pt++;
185
186
187 PTF0 PTF1 PTF2 PTF0 PTF2 PTF3 /* front */
188 PTR2 PTR1 PTR0 PTR3 PTR2 PTR0 /* back */
189 PTF0 PTR0 PTR1 PTF0 PTR1 PTF1 /* top */
190 PTF3 PTF2 PTR2 PTF3 PTR2 PTR3 /* bottom */
191 PTF0 PTF3 PTR3 PTF0 PTR3 PTR0 /* right */
192 PTF1 PTR1 PTR2 PTF1 PTR2 PTF2 /* left */
193
194 /* finished, and have good data */
195 node->__points.p = ptr;
196}
197#undef PTF0
198#undef PTF1
199#undef PTF2
200#undef PTR0
201#undef PTR1
202#undef PTR2
203#define DESIRE(whichOne,zzz) ((whichOne & zzz)==zzz)
204void render_Box (struct X3D_Box *node) {
205 extern GLfloat boxtex[]; /* in CFuncs/statics.c*/
206 extern GLfloat boxnorms[]; /* in CFuncs/statics.c*/
207 extern int boxwireindices[];
208 struct textureVertexInfo mtf = {boxtex,2,GL_FLOAT,0,NULL,NULL};
209
210 float x = ((node->size).c[0])/2;
211 float y = ((node->size).c[1])/2;
212 float z = ((node->size).c[2])/2;
213
214 /* test for <0 of sides */
215 if ((x < 0) || (y < 0) || (z < 0)) return;
216
217 COMPILE_IF_REQUIRED
218 if (!node->__points.p) return; /* still compiling */
219
220 /* for BoundingBox calculations */
221 setExtent(x,-x,y,-y,z,-z,X3D_NODE(node));
222
223 CULL_FACE(node->solid)
224
225 /* Draw it; assume VERTEX and NORMALS already defined.*/
226 textureCoord_send(&mtf);
227 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,(GLfloat *)node->__points.p);
228 FW_GL_NORMAL_POINTER (GL_FLOAT,0,boxnorms);
229
230 /* do the array drawing; sides are simple 0-1-2-3, 4-5-6-7, etc quads */
231 //if(fwl_getShadingStyle() == 3){
232 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
233 //wireframe triangles
234 sendElementsToGPU(GL_LINES,72,boxwireindices);
235 }else{
236 sendArraysToGPU (GL_TRIANGLES, 0, 36);
237 }
238
239 gglobal()->Mainloop.trisThisLoop += 24;
240}
241
242
243/*******************************************************************************/
244
245void compile_Cylinder (struct X3D_Cylinder * node) {
246 #define CYLDIV 20
247 float h = (node->height)/2;
248 float r = node->radius;
249 int i = 0;
250 struct MyVertex cylVert[CYLDIV * 4 * 3];
251 int indx = 0;
252
253 /* have to regen the shape*/
254 MARK_NODE_COMPILED
255
256
257 /* use VBOS for Cylinders? */
258
259 if (node->__cylinderVBO == 0) {
260 glGenBuffers(1,(GLuint*) &node->__cylinderVBO);
261 }
262
263 /* we create two triangle fans - the cone, and the bottom. */
264 /* first, the flat bit on the bottom */
265 indx=0;
266
267 if (node->bottom) {
268 for (i=0; i<CYLDIV; i++) {
269 double angle = PI*2*i/(double)CYLDIV;
270 double next_angle = PI*2*(i+1)/(double)CYLDIV;
271 /* vertex #1 */
272 cylVert[indx].vert.c[0] = r* (float) sin(angle);
273 cylVert[indx].vert.c[1] = (float) -h;
274 cylVert[indx].vert.c[2] = r* (float) cos(angle);
275 cylVert[indx].norm.c[0] = 0.0f;
276 cylVert[indx].norm.c[1] = -1.0f;
277 cylVert[indx].norm.c[2] = 0.0f;
278 cylVert[indx].tc.c[0] = 0.5f+0.5f* (float) sin(angle);
279 cylVert[indx].tc.c[1] = 0.5f+0.5f* (float) cos(angle);
280 indx++;
281
282 /* vertex #2 - in the centre */
283 cylVert[indx].vert.c[0] = 0.0f;
284 cylVert[indx].vert.c[1] = (float) -h;
285 cylVert[indx].vert.c[2] = 0.0f;
286 cylVert[indx].norm.c[0] = 0.0f;
287 cylVert[indx].norm.c[1] = -1.0f;
288 cylVert[indx].norm.c[2] = 0.0f;
289 cylVert[indx].tc.c[0] = 0.5f;
290 cylVert[indx].tc.c[1] = 0.5f;
291 indx++;
292
293 /* vertex #3 */
294 cylVert[indx].vert.c[0] = r* (float) sin(next_angle);
295 cylVert[indx].vert.c[1] = (float) -h;
296 cylVert[indx].vert.c[2] = r* (float) cos(next_angle);
297 cylVert[indx].norm.c[0] = 0.0f;
298 cylVert[indx].norm.c[1] = -1.0f;
299 cylVert[indx].norm.c[2] = 0.0f;
300 cylVert[indx].tc.c[0] = 0.5f+0.5f* (float) sin(next_angle);
301 cylVert[indx].tc.c[1] = 0.5f+0.5f* (float) cos(next_angle);
302 indx++;
303 }
304 }
305 if (node->top) {
306 /* same as bottom, but wind'em the other way */
307 for (i=0; i<CYLDIV; i++) {
308 double angle = PI*2*i/(double)CYLDIV;
309 double next_angle = PI*2*(i+1)/(double)CYLDIV;
310 /* vertex #1 */
311 cylVert[indx].vert.c[0] = r* (float) sin(next_angle);
312 cylVert[indx].vert.c[1] = (float) h;
313 cylVert[indx].vert.c[2] = r* (float) cos(next_angle);
314 cylVert[indx].norm.c[0] = 0.0f;
315 cylVert[indx].norm.c[1] = 1.0f;
316 cylVert[indx].norm.c[2] = 0.0f;
317 cylVert[indx].tc.c[0] = 0.5f+0.5f* (float) sin(next_angle);
318 cylVert[indx].tc.c[1] = 0.5f+0.5f* (float) cos(next_angle);
319 indx++;
320
321 /* vertex #2 - in the centre */
322 cylVert[indx].vert.c[0] = 0.0f;
323 cylVert[indx].vert.c[1] = (float) h;
324 cylVert[indx].vert.c[2] = 0.0f;
325 cylVert[indx].norm.c[0] = 0.0f;
326 cylVert[indx].norm.c[1] = 1.0f;
327 cylVert[indx].norm.c[2] = 0.0f;
328 cylVert[indx].tc.c[0] = 0.5f;
329 cylVert[indx].tc.c[1] = 0.5f;
330 indx++;
331
332 /* vertex #3 */
333 cylVert[indx].vert.c[0] = r* (float) sin(angle);
334 cylVert[indx].vert.c[1] = (float) h;
335 cylVert[indx].vert.c[2] = r* (float) cos(angle);
336 cylVert[indx].norm.c[0] = 0.0f;
337 cylVert[indx].norm.c[1] = 1.0f;
338 cylVert[indx].norm.c[2] = 0.0f;
339 cylVert[indx].tc.c[0] = 0.5f+0.5f* (float) sin(angle);
340 cylVert[indx].tc.c[1] = 0.5f+0.5f* (float) cos(angle);
341 indx++;
342 }
343 }
344
345
346
347 /* now, the sides */
348 if (node->side) {
349 for (i=0; i<CYLDIV; i++) {
350 double angle;
351
352 /* Triangle #1 for this segment of the side */
353 /* vertex #1 - bottom right */
354 angle = (double) (PI * 2 * (i+1.0f)) / (double) (CYLDIV);
355 cylVert[indx].vert.c[0] = r* (float) sin(angle);
356 cylVert[indx].vert.c[1] = (float) -h;
357 cylVert[indx].vert.c[2] = r* (float) cos(angle);
358
359 /* note the angle for normals is half way between faces */
360 angle = (double) (PI * 2 * (i+0.5f)) / (double) (CYLDIV);
361 cylVert[indx].norm.c[0] = (float) sin(angle);
362 cylVert[indx].norm.c[1] = 0.0f;
363 cylVert[indx].norm.c[2] = (float) cos(angle);
364
365 /* note that we use the Cone TC array; assume same division */
366 cylVert[indx].tc.c[0] = VBO_coneSideTexParams[i*3+0];
367 cylVert[indx].tc.c[1] = 0.0f;
368 indx++;
369
370 /* vertex #2 - top left */
371 angle = (double) (PI * 2 * (i+0.0f)) / (double) (CYLDIV);
372 cylVert[indx].vert.c[0] = r* (float) sin(angle);
373 cylVert[indx].vert.c[1] = (float) h;
374 cylVert[indx].vert.c[2] = r* (float) cos(angle);
375 angle = (double) (PI * 2 * (i-0.5f)) / (double) (CYLDIV);
376 cylVert[indx].norm.c[0] = (float) sin(angle);
377 cylVert[indx].norm.c[1] = 0.0f;
378 cylVert[indx].norm.c[2] = (float) cos(angle);
379 cylVert[indx].tc.c[0] = VBO_coneSideTexParams[i*3+2];
380 cylVert[indx].tc.c[1] = 1.0f;
381 indx++;
382
383 /* vertex #3 - bottom left */
384 angle = (double) (PI * 2 * (i+0.0f)) / (double) (CYLDIV);
385 cylVert[indx].vert.c[0] = r* (float) sin(angle);
386 cylVert[indx].vert.c[1] = (float) -h;
387 cylVert[indx].vert.c[2] = r* (float) cos(angle);
388 angle = (double) (PI * 2 * (i-0.5f)) / (double) (CYLDIV);
389 cylVert[indx].norm.c[0] = (float) sin(angle);
390 cylVert[indx].norm.c[1] = 0.0f;
391 cylVert[indx].norm.c[2] = (float) cos(angle);
392 cylVert[indx].tc.c[0] = VBO_coneSideTexParams[i*3+2];
393 cylVert[indx].tc.c[1] = 0.0f;
394 indx++;
395
396 /* Triangle #2 for this segment of the side */
397 /* vertex #1 - bottom right */
398 angle = (double) (PI * 2 * (i+1.0f)) / (double) (CYLDIV);
399 cylVert[indx].vert.c[0] = r* (float) sin(angle);
400 cylVert[indx].vert.c[1] = (float) -h;
401 cylVert[indx].vert.c[2] = r* (float) cos(angle);
402 angle = (double) (PI * 2 * (i+0.5f)) / (double) (CYLDIV);
403 cylVert[indx].norm.c[0] = (float) sin(angle);
404 cylVert[indx].norm.c[1] = 0.0f;
405 cylVert[indx].norm.c[2] = (float) cos(angle);
406 cylVert[indx].tc.c[0] = VBO_coneSideTexParams[i*3+0];
407 cylVert[indx].tc.c[1] = 0.0f;
408 indx++;
409
410 /* vertex #2 - top right */
411 angle = (double) (PI * 2 * (i+1.0f)) / (double) (CYLDIV);
412 cylVert[indx].vert.c[0] = r* (float) sin(angle);
413 cylVert[indx].vert.c[1] = (float) h;
414 cylVert[indx].vert.c[2] = r* (float) cos(angle);
415 angle = (double) (PI * 2 * (i+0.5f)) / (double) (CYLDIV);
416 cylVert[indx].norm.c[0] = (float) sin(angle);
417 cylVert[indx].norm.c[1] = 0.0f;
418 cylVert[indx].norm.c[2] = (float) cos(angle);
419 cylVert[indx].tc.c[0] = VBO_coneSideTexParams[i*3+0];
420 cylVert[indx].tc.c[1] = 1.0f;
421 indx++;
422
423 /* vertex #3 - top left */
424 angle = (float) (PI * 2 * (i+0.0f)) / (double) (CYLDIV);
425 cylVert[indx].vert.c[0] = r* (float) sin(angle);
426 cylVert[indx].vert.c[1] = (float) h;
427 cylVert[indx].vert.c[2] = r* (float) cos(angle);
428 angle = (double) (PI * 2 * (i-0.5f)) / (double) (CYLDIV);
429 cylVert[indx].norm.c[0] = (float) sin(angle);
430 cylVert[indx].norm.c[1] = 0.0f;
431 cylVert[indx].norm.c[2] = (float) cos(angle);
432 cylVert[indx].tc.c[0] = VBO_coneSideTexParams[i*3+2];
433 cylVert[indx].tc.c[1] = 1.0f;
434 indx++;
435 }
436
437 }
438
439 node->__cylinderTriangles = indx; //more precisely, number of vertices, (3 vertices per triangle)
440 {
441 //prepare flat normals for flat shading style
442 int i3;
443 for(i=0;i<indx/3;i++){
444 float a[3],b[3],c[3],d[3], e[3], f[3], g[3];
445 i3 = i*3;
446 memcpy(a,cylVert[i3 +0].vert.c,sizeof(struct SFColor));
447 memcpy(b,cylVert[i3 +1].vert.c,sizeof(struct SFColor));
448 memcpy(c,cylVert[i3 +2].vert.c,sizeof(struct SFColor));
449 vecdif3f(d,b,a);
450 vecdif3f(e,c,a);
451 veccross3f(f,d,e);
452 vecnormalize3f(g,f);
453 memcpy(cylVert[i3 +0].flat_norm.c,g,sizeof(struct SFColor));
454 memcpy(cylVert[i3 +1].flat_norm.c,g,sizeof(struct SFColor));
455 memcpy(cylVert[i3 +2].flat_norm.c,g,sizeof(struct SFColor));
456 }
457 }
458 {
459 //prepare wireframe indices
460 int i3, i6;
461 int *lindex = MALLOC(int *,indx * 2 * sizeof(int));
462 for(i=0;i<indx/3;i++){
463 i3 = i*3;
464 i6 = i*6;
465 lindex[i6+0] = i3 + 0;
466 lindex[i6+1] = i3 + 1;
467 lindex[i6+2] = i3 + 1;
468 lindex[i6+3] = i3 + 2;
469 lindex[i6+4] = i3 + 2;
470 lindex[i6+5] = i3 + 0;
471 }
472 node->__wireindices = lindex;
473 }
474
475 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->__cylinderVBO);
476 glBufferData(GL_ARRAY_BUFFER, sizeof(struct MyVertex)*indx, cylVert, GL_STATIC_DRAW);
477
478 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
479
480}
481void clear_Cylinder (struct X3D_Node *node) {
482 struct X3D_Cylinder *tnode = (struct X3D_Cylinder *)node;
483 if(tnode->__cylinderVBO)
484 glDeleteBuffers(1, (const GLuint *) &tnode->__cylinderVBO);
485 if(tnode->__wireindices)
486 FREE_IF_NZ(tnode->__wireindices);
487}
488
489void render_Cylinder (struct X3D_Cylinder * node) {
490 extern GLfloat cylsidetex[]; /* in CFuncs/statics.c*/
491 struct textureVertexInfo mtf = {cylsidetex,2,GL_FLOAT,0,NULL,NULL};
492
493 float h = (node->height)/2;
494 float r = node->radius;
495
496
497 if ((h < 0) || (r < 0)) {return;}
498
499 /* for BoundingBox calculations */
500 setExtent(r,-r,h,-h,r,-r,X3D_NODE(node));
501
502 COMPILE_IF_REQUIRED
503
504 CULL_FACE(node->solid)
505
506 // taken from the OpenGL.org website:
507 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
508
509 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->__cylinderVBO);
510
511 FW_GL_VERTEX_POINTER(3, GL_FLOAT, (GLsizei)sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(0));
512 //The starting point of the VBO, for the vertices
513 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_FLAT)){
514 //The starting point of normals, (3+3+2)*4 = 32 + bytes away
515 FW_GL_NORMAL_POINTER(GL_FLOAT, (GLsizei) sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(32));
516 }else{
517 //The starting point of normals, 3*4 = 12 + bytes away
518 FW_GL_NORMAL_POINTER(GL_FLOAT, (GLsizei) sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(12));
519 }
520 /* set up texture drawing for this guy */
521 mtf.pre_canned_textureCoords = NULL;
522 mtf.TC_size = 2;
523 mtf.TC_type = GL_FLOAT;
524 mtf.TC_stride = sizeof(struct MyVertex);
525 mtf.TC_pointer = BUFFER_OFFSET(24);
526 textureCoord_send(&mtf);
527 /* FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, ConeIndxVBO); */
528
529 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
530 //wireframe triangles
531 sendElementsToGPU(GL_LINES,node->__cylinderTriangles *2,node->__wireindices);
532 }else{
533 sendArraysToGPU(GL_TRIANGLES,0,node->__cylinderTriangles);
534 }
535 /* turn off */
536 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
537}
538
539
540
541/*******************************************************************************/
542
543void compile_Cone (struct X3D_Cone *node) {
544 /* DO NOT change this define, unless you want to recalculate statics below....*/
545 #define CONEDIV 20
546
547 float h = (node->height)/2;
548 float r = node->bottomRadius;
549 int i;
550 struct MyVertex coneVert[CONEDIV * 2 * 3];
551 int indx = 0;
552
553 /* have to regen the shape*/
554 MARK_NODE_COMPILED
555
556
557 if (node->__coneVBO == 0) {
558 glGenBuffers(1,(GLuint *) &node->__coneVBO);
559 }
560
561 /* we create two triangle fans - the cone, and the bottom. */
562 /* first, the flat bit on the bottom */
563 indx=0;
564
565 if (node->bottom) {
566 for (i=0; i<CONEDIV; i++) {
567 double angle = PI*2*i/(double)CONEDIV;
568 double next_angle = PI*2*(i+1)/(double)CONEDIV;
569 /* vertex #1 */
570 coneVert[indx].vert.c[0] = r* (float) sin(angle);
571 coneVert[indx].vert.c[1] = (float) -h;
572 coneVert[indx].vert.c[2] = r* (float) cos(angle);
573 coneVert[indx].norm.c[0] = 0.0f;
574 coneVert[indx].norm.c[1] = -1.0f;
575 coneVert[indx].norm.c[2] = 0.0f;
576 coneVert[indx].tc.c[0] = 0.5f+0.5f* (float) sin(angle);
577 coneVert[indx].tc.c[1] = 0.5f+0.5f* (float) cos(angle);
578 indx++;
579
580 /* vertex #2 - in the centre */
581 coneVert[indx].vert.c[0] = 0.0f;
582 coneVert[indx].vert.c[1] = (float) -h;
583 coneVert[indx].vert.c[2] = 0.0f;
584 coneVert[indx].norm.c[0] = 0.0f;
585 coneVert[indx].norm.c[1] = -1.0f;
586 coneVert[indx].norm.c[2] = 0.0f;
587 coneVert[indx].tc.c[0] = 0.5f;
588 coneVert[indx].tc.c[1] = 0.5f;
589 indx++;
590
591 /* vertex #3 */
592 coneVert[indx].vert.c[0] = r* (float) sin(next_angle);
593 coneVert[indx].vert.c[1] = (float) -h;
594 coneVert[indx].vert.c[2] = r* (float) cos(next_angle);
595 coneVert[indx].norm.c[0] = 0.0f;
596 coneVert[indx].norm.c[1] = -1.0f;
597 coneVert[indx].norm.c[2] = 0.0f;
598 coneVert[indx].tc.c[0] = 0.5f+0.5f* (float) sin(next_angle);
599 coneVert[indx].tc.c[1] = 0.5f+0.5f* (float) cos(next_angle);
600 indx++;
601 }
602 }
603
604
605 /* now, the sides */
606 if (node->side) {
607 GLfloat *tcp = VBO_coneSideTexParams;
608
609 for (i=0; i<CONEDIV; i++) {
610 double angle;
611
612 /* vertex #1 */
613 angle = (double) (PI * 2 * (i+1.0f)) / (double) (CONEDIV);
614 coneVert[indx].vert.c[0] = r* (float) sin(angle);
615 coneVert[indx].vert.c[1] = (float) -h;
616 coneVert[indx].vert.c[2] = r* (float) cos(angle);
617 coneVert[indx].norm.c[0] = (float) sin(angle);
618 coneVert[indx].norm.c[1] = (float)h/(r*2);
619 coneVert[indx].norm.c[2] = (float) cos(angle);
620
621 angle = (double) (PI * 2 * (i+0.0f)) / (double) (CONEDIV);
622 coneVert[indx].tc.c[0] = *tcp; tcp++;
623 coneVert[indx].tc.c[1] = 0.0f;
624 indx++;
625
626 /* vertex #2 - in the centre */
627 angle = (float) (PI * 2 * (i+0.5f)) / (double)(CONEDIV);
628 coneVert[indx].vert.c[0] = 0.0f;
629 coneVert[indx].vert.c[1] = (float) h;
630 coneVert[indx].vert.c[2] = 0.0f;
631 coneVert[indx].norm.c[0] = (float) sin(angle);
632 coneVert[indx].norm.c[1] = (float)h/(r*2);
633 coneVert[indx].norm.c[2] = (float) cos(angle);
634
635 coneVert[indx].tc.c[0] = *tcp; tcp++;
636 coneVert[indx].tc.c[1] = 1.0f;
637 indx++;
638
639 /* vertex #3 */
640 angle = (float) (PI * 2 * (i+0.0f)) / (double) (CONEDIV);
641 coneVert[indx].vert.c[0] = r* (float) sin(angle);
642 coneVert[indx].vert.c[1] = (float) -h;
643 coneVert[indx].vert.c[2] = r* (float) cos(angle);
644 coneVert[indx].norm.c[0] = (float) sin(angle);
645 coneVert[indx].norm.c[1] = (float)h/(r*2);
646 coneVert[indx].norm.c[2] = (float) cos(angle);
647
648 angle = (float) (PI * 2 * (i+1.0f)) / (double) (CONEDIV);
649 coneVert[indx].tc.c[0] = *tcp; tcp++;
650 coneVert[indx].tc.c[1] = 0.0f;
651 indx++;
652 }
653
654 }
655
656 node->__coneTriangles = indx;
657 {
658 //prepare flat normals for flat shading style
659 int i3;
660 for(i=0;i<indx/3;i++){
661 float a[3],b[3],c[3],d[3], e[3], f[3], g[3];
662 i3 = i*3;
663 memcpy(a,coneVert[i3 +0].vert.c,sizeof(struct SFColor));
664 memcpy(b,coneVert[i3 +1].vert.c,sizeof(struct SFColor));
665 memcpy(c,coneVert[i3 +2].vert.c,sizeof(struct SFColor));
666 vecdif3f(d,b,a);
667 vecdif3f(e,c,a);
668 veccross3f(f,d,e);
669 vecnormalize3f(g,f);
670 memcpy(coneVert[i3 +0].flat_norm.c,g,sizeof(struct SFColor));
671 memcpy(coneVert[i3 +1].flat_norm.c,g,sizeof(struct SFColor));
672 memcpy(coneVert[i3 +2].flat_norm.c,g,sizeof(struct SFColor));
673 }
674 }
675 {
676 //prepare wireframe indices
677 int i3, i6;
678 int *lindex = MALLOC(int *,indx * 2 * sizeof(int));
679 for(i=0;i<indx/3;i++){
680 i3 = i*3;
681 i6 = i*6;
682 lindex[i6+0] = i3 + 0;
683 lindex[i6+1] = i3 + 1;
684 lindex[i6+2] = i3 + 1;
685 lindex[i6+3] = i3 + 2;
686 lindex[i6+4] = i3 + 2;
687 lindex[i6+5] = i3 + 0;
688 }
689 node->__wireindices = lindex;
690 }
691
692 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, (GLuint) node->__coneVBO);
693 glBufferData(GL_ARRAY_BUFFER, sizeof(struct MyVertex)*indx, coneVert, GL_STATIC_DRAW);
694
695 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
696
697 /* no longer needed */
698 FREE_IF_NZ(node->__botpoints.p);
699 FREE_IF_NZ(node->__sidepoints.p);
700 FREE_IF_NZ(node->__normals.p);
701}
702void clear_Cone (struct X3D_Node *node) {
703 struct X3D_Cone *tnode = (struct X3D_Cone *)node;
704 if(tnode->__coneVBO)
705 glDeleteBuffers(1, (const GLuint *) &tnode->__coneVBO);
706}
707
708void render_Cone (struct X3D_Cone *node) {
709 extern float tribottex[]; /* in CFuncs/statics.c*/
710 struct textureVertexInfo mtf = {tribottex,2,GL_FLOAT,0,NULL,NULL};
711
712 float h = (node->height)/2;
713 float r = node->bottomRadius;
714
715 if ((h < 0) || (r < 0)) {return;}
716 COMPILE_IF_REQUIRED
717
718 /* for BoundingBox calculations */
719 setExtent(r,-r,h,-h,r,-r,X3D_NODE(node));
720
721
722 CULL_FACE(node->solid)
723 /* OK - we have vertex data, so lets just render it.*/
724 /* Always assume GL_VERTEX_ARRAY and GL_NORMAL_ARRAY are enabled.*/
725 // taken from the OpenGL.org website:
726 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
727
728 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->__coneVBO);
729
730 FW_GL_VERTEX_POINTER(3, GL_FLOAT, (GLsizei) sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices
731 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_FLAT)){
732 //The starting point of normals, (3+3+2)*4 = 32 + bytes away
733 FW_GL_NORMAL_POINTER(GL_FLOAT, (GLsizei) sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(32));
734 }else{
735 //The starting point of normals, 3*4 = 12 + bytes away
736 FW_GL_NORMAL_POINTER(GL_FLOAT, (GLsizei) sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(12));
737 }
738
739 /* set up texture drawing for this guy */
740 mtf.pre_canned_textureCoords = NULL;
741 mtf.TC_size = 2;
742 mtf.TC_type = GL_FLOAT;
743 mtf.TC_stride = sizeof(struct MyVertex);
744 mtf.TC_pointer = BUFFER_OFFSET(24);
745 textureCoord_send(&mtf);
746PRINT_GL_ERROR_IF_ANY("END1 render_geom");
747 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
748 //wireframe triangles
749 sendElementsToGPU(GL_LINES,node->__coneTriangles *2,node->__wireindices);
750 }else{
751 sendArraysToGPU(GL_TRIANGLES,0,node->__coneTriangles);
752 }
753
754PRINT_GL_ERROR_IF_ANY("END2 render_geom");
755 /* turn off */
756 //FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
757 //FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
758}
759
760
761
762/*******************************************************************************/
763/* how many triangles in this sphere? SPHDIV strips, each strip
764 has 2 triangles, and each triangles has 3 vertices and there are
765 SPHDIV rows */
766#define SPHDIV 20
767#define TRISINSPHERE (SPHDIV*3* SPHDIV)
768
769
770void compile_Sphere (struct X3D_Sphere *node) {
771 #define INIT_TRIG1(div) t_aa = (float) sin(PI/(div)); t_aa *= 2*t_aa; t_ab =(float) -sin(2*PI/(div));
772 #define START_TRIG1 t_sa = 0; t_ca = -1;
773 #define UP_TRIG1 t_sa1 = t_sa; t_sa -= t_sa*t_aa - t_ca * t_ab; t_ca -= t_ca * t_aa + t_sa1 * t_ab;
774 #define SIN1 t_sa
775 #define COS1 t_ca
776 #define INIT_TRIG2(div) t2_aa = (float) sin(PI/(div)); t2_aa *= 2*t2_aa; t2_ab = (float) -sin(2*PI/(div));
777 #define START_TRIG2 t2_sa = -1; t2_ca = 0;
778 #define UP_TRIG2 t2_sa1 = t2_sa; t2_sa -= t2_sa*t2_aa - t2_ca * t2_ab; t2_ca -= t2_ca * t2_aa + t2_sa1 * t2_ab;
779 #define SIN2 t2_sa
780 #define COS2 t2_ca
781
782 /* make the divisions 20; dont change this, because statics.c values*/
783 /* will then need recaculating.*/
784 extern GLfloat spherenorms[]; /* side normals*/
785 extern float spheretex[]; /* in CFuncs/statics.c*/
786
787 int count;
788 float rad = node->radius;
789 struct SFVec3f *ptr;
790
791 int v; int h;
792 float t_aa, t_ab, t_sa, t_ca, t_sa1;
793 float t2_aa, t2_ab, t2_sa, t2_ca, t2_sa1;
794 struct SFVec3f *pts;
795 //int *pindices;
796
797 /* have to regen the shape*/
798 MARK_NODE_COMPILED
799
800 /* MALLOC memory (if possible)*/
801 /* 2 vertexes per points. (+1, to loop around and close structure)*/
802 if (!node->__points.p) {
803 // malloc points. We seem to never need the ".n" size param, but initialize it
804 // anyway to keep things clean and even.
805 ptr = MALLOC (struct SFVec3f *,sizeof(struct SFVec3f) * (SPHDIV+1) * (SPHDIV+1) * 2);
806 node->__points.n = SPHDIV * (SPHDIV+1) * 2;
807 } else ptr = node->__points.p;
808
809 pts = ptr;
810 count = 0;
811
812 INIT_TRIG1(SPHDIV)
813 INIT_TRIG2(SPHDIV)
814
815 START_TRIG1
816 {
817 extern GLfloat spherenorms[]; /* side normals*/
818 extern float spheretex[]; /* in CFuncs/statics.c*/
819
820 //int myVertexVBOSize = (int) (sizeof(struct SFVec3f) +
821 // sizeof(struct SFVec3f) +
822 // sizeof(struct SFVec2f)) * SPHDIV * (SPHDIV+1) * 2;
823 int myVertexVBOSize = (int) sizeof(struct MyVertex) * SPHDIV * (SPHDIV+1) * 2;
824 struct MyVertex *SphVBO = MALLOC(struct MyVertex *, myVertexVBOSize);
825 struct SFVec3f *myNorms = (struct SFVec3f*)spherenorms;
826 struct SFVec2f *myTex = (struct SFVec2f*)spheretex;
827
828 if (node->_sideVBO == 0) {
829 glGenBuffers(1,(GLuint *) &node->_sideVBO);
830 }
831 for(v=0; v<SPHDIV; v++) {
832 float vsin1 = SIN1;
833 float vcos1 = COS1, vsin2,vcos2;
834 UP_TRIG1
835 vsin2 = SIN1;
836 vcos2 = COS1;
837 START_TRIG2
838 for(h=0; h<=SPHDIV; h++) {
839 float hsin1 = SIN2;
840 float hcos1 = COS2;
841 UP_TRIG2
842 pts[count].c[0] = rad * vsin2 * hcos1;
843 pts[count].c[1] = rad * vcos2;
844 pts[count].c[2] = rad * vsin2 * hsin1;
845
846 /* copy these points into the MyVertex Sphere VBO */
847 memcpy (SphVBO[count].vert.c, pts[count].c, sizeof (struct SFVec3f));
848 memcpy (SphVBO[count].norm.c, myNorms[count].c, sizeof (struct SFVec3f));
849 memcpy (SphVBO[count].tc.c, myTex[count].c, sizeof (struct SFVec2f));
850 count++;
851 pts[count].c[0] = rad * vsin1 * hcos1;
852 pts[count].c[1] = rad * vcos1;
853 pts[count].c[2] = rad * vsin1 * hsin1;
854 /* copy these points into the MyVertex Sphere VBO */
855 memcpy (SphVBO[count].vert.c, pts[count].c, sizeof (struct SFVec3f));
856 memcpy (SphVBO[count].norm.c, myNorms[count].c, sizeof (struct SFVec3f));
857 memcpy (SphVBO[count].tc.c, myTex[count].c, sizeof (struct SFVec2f));
858 count++;
859 }
860 }
861
862
863 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, (GLuint) node->_sideVBO);
864 glBufferData(GL_ARRAY_BUFFER, myVertexVBOSize, SphVBO, GL_STATIC_DRAW);
865
866 if (node->__SphereIndxVBO == 0) {
867 int pindices[TRISINSPHERE*2];
868 int *pind; // = pindices;
869 int row;
870 int indx;
871 pind = pindices;
872
873 glGenBuffers(1,(GLuint *)&node->__SphereIndxVBO);
874 //for (count=0; count<TRISINSPHERE*2; count++) pindices[count]=0;
875 for (row=0; row<SPHDIV; row++) {
876 indx=42*row;
877 for (count = 0; count < SPHDIV*2; count+=2) {
878 *pind = indx; pind++;
879 *pind = indx+1; pind++;
880 *pind = indx+2; pind++;
881 //printf ("wrote %u %u %u\n",indx, indx+1, indx+2);
882 *pind = indx+2; pind++;
883 *pind = indx+1; pind++;
884 *pind = indx+3; pind++;
885 //printf ("wrote %u %u %u\n",indx+2, indx+1, indx+3);
886 indx+=2;
887 }
888 }
889 node->__pindices = pindices;
890 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, node->__SphereIndxVBO);
891 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*TRISINSPHERE*2, pindices, GL_STATIC_DRAW);
892
893 {
894 //prepare wireframe indices - we'll use the pindices from above, still on the stack
895 int i, i3, i6, ntris;
896 int lindex[SPHDIV*SPHDIV*2*3*2];
897 ntris = SPHDIV * SPHDIV * 2;
898 glGenBuffers(1,(GLuint *) &node->__wireindicesVBO);
899 for(i=0;i<ntris;i++){
900 i3 = i*3;
901 i6 = i*6;
902 lindex[i6+0] = pindices[i3 + 0];
903 lindex[i6+1] = pindices[i3 + 1];
904 lindex[i6+2] = pindices[i3 + 1];
905 lindex[i6+3] = pindices[i3 + 2];
906 lindex[i6+4] = pindices[i3 + 2];
907 lindex[i6+5] = pindices[i3 + 0];
908 }
909 //node->__wireindices = lindex;
910 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, node->__wireindicesVBO);
911 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*SPHDIV*SPHDIV*2*3, lindex, GL_STATIC_DRAW);
912 }
913 }
914
915
916 FREE_IF_NZ(SphVBO);
917 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
918 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
919
920 }
921 /* finished - for threading */
922 node->__points.p = ptr;
923}
924
925void clear_Sphere (struct X3D_Node *node) {
926 struct X3D_Sphere *tnode = (struct X3D_Sphere *)node;
927 if(tnode->_sideVBO)
928 glDeleteBuffers(1, (const GLuint *) &tnode->_sideVBO);
929 if(tnode->__SphereIndxVBO)
930 glDeleteBuffers(1, (const GLuint *) &tnode->__SphereIndxVBO);
931}
932
933
934void render_Sphere (struct X3D_Sphere *node) {
935 /* make the divisions 20; dont change this, because statics.c values*/
936 /* will then need recaculating.*/
937
938 extern GLfloat spherenorms[]; /* side normals*/
939 extern float spheretex[]; /* in CFuncs/statics.c*/
940
941 struct textureVertexInfo mtf = {spheretex,2,GL_FLOAT,0,NULL,NULL};
942
943
944 float rad = node->radius;
945
946 if (rad<=0.0) { return;}
947
948 /* for BoundingBox calculations */
949 setExtent(rad,-rad,rad,-rad,rad,-rad,X3D_NODE(node));
950
951 COMPILE_IF_REQUIRED
952
953 CULL_FACE(node->solid)
954
955 /* Display the shape*/
956
957 // taken from the OpenGL.org website:
958 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
959
960 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, (GLuint) node->_sideVBO);
961
962 FW_GL_VERTEX_POINTER(3, GL_FLOAT, sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices
963 FW_GL_NORMAL_POINTER(GL_FLOAT, sizeof(struct MyVertex), (GLfloat *)BUFFER_OFFSET(12)); //The starting point of normals, 12 bytes away
964 mtf.pre_canned_textureCoords = NULL;
965 mtf.TC_size = 2;
966 mtf.TC_type = GL_FLOAT;
967 mtf.TC_stride = sizeof(struct MyVertex);
968 mtf.TC_pointer = BUFFER_OFFSET(24);
969 textureCoord_send(&mtf);
970
971 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
972 //wireframe triangles
973 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, node->__wireindicesVBO);
974 sendElementsToGPU(GL_LINES,TRISINSPHERE *3, (int *)BUFFER_OFFSET(0)); //node->__wireindices);
975 }else{
976 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, node->__SphereIndxVBO);
977 sendElementsToGPU (GL_TRIANGLES, TRISINSPHERE, (int *)BUFFER_OFFSET(0)); //The starting point of the IBO
978 }
979
980 /* turn off */
981 //FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
982 //FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
983}
984const char *getNodeName(struct X3D_Node *node){
985 //return DEF name if there is one, else NULL
986 const char *name = NULL;
987 if(node){
988 //broto warning - DEF name list should be per-executionContext
989 struct X3D_Proto *context;
990 context = (struct X3D_Proto *)node->_executionContext;
991 if(context){
992 //broto_search_DEFname(ec, fwpars[0]._string);
993 int i;
994 struct brotoDefpair def;
995 if(context->__DEFnames){
996 int ndefs = vectorSize(context->__DEFnames);
997 for(i=0;i<ndefs;i++){
998 def = vector_get(struct brotoDefpair, context->__DEFnames,i);
999 //printf("%x %x %s\n",node,def.node,def.name);
1000 if(def.node == node){
1001 name = def.name;
1002 break;
1003 }
1004 }
1005 }
1006 }
1007 }
1008 return name;
1009}
1010void render_IndexedFaceSet (struct X3D_IndexedFaceSet *node) {
1011 //static int count = 0;
1012 //int print_names = 0;
1013 //if(print_names){
1014 // unsigned char* nn = getNodeName(X3D_NODE(node));
1015 // if(nn) printf("[%s ",nn);
1016 // else printf("[.%d",count);
1017 // count++;
1018 //}
1019 //COMPILE_POLY_IF_REQUIRED (node->coord, node->fogCoord, node->color, node->normal, node->texCoord)
1020 if (!compile_poly_if_required(node, node->coord, node->fogCoord, node->color, node->normal, node->texCoord))return;
1021 //if (!node->_intern) return;
1022 CULL_FACE(node->solid)
1023 render_polyrep(node);
1024 //if(print_names) printf("]");
1025}
1026
1027void render_ElevationGrid (struct X3D_ElevationGrid *node) {
1028 //COMPILE_POLY_IF_REQUIRED (NULL, node->fogCoord, node->color, node->normal, node->texCoord)
1029 if (!compile_poly_if_required(node, NULL, node->fogCoord, node->color, node->normal, node->texCoord))return;
1030 CULL_FACE(node->solid)
1031 render_polyrep(node);
1032}
1033
1034void render_Extrusion (struct X3D_Extrusion *node) {
1035 //COMPILE_POLY_IF_REQUIRED (NULL,NULL,NULL,NULL,NULL)
1036 if (!compile_poly_if_required(node, NULL, NULL, NULL, NULL, NULL))return;
1037
1038 CULL_FACE(node->solid)
1039 render_polyrep(node);
1040}
1041
1042/* Fast culling possibilities:
1043 a) sphere-sphere
1044 b) MBB (axes-aligned Minimum Bounding Box or 'extent') (pr->maxVals[i], pr->minVals[i] i=0,1,2 or equivalent)
1045 two optional spaces in which to do the comparison: shape space or avatar(collision) space
1046 1. shape sphere/MBB > [Shape2Collision] > collision space coordinates. Or -
1047 2. avatar collision volume > [Collision2Shape] > into shape coords
1048 which ever way, we expect false positives, but don't want any false negatives which could make you fall through
1049 terrain or slide through walls. To be safe, error on the side of bigger collision volumes for shape and avatar.
1050*/
1051
1052/* note as of Jan 16, 2010 - not all collide_<shape> scenarios come through the following avatarCollisionVolumeIntersectMBB.
1053 All walking scnearios do.
1054 collide_generic, collide_box, collide_extrusion, collide_Text, collide_Rectangle2D: all walk/fly/examine do.
1055 collide_sphere,collide_cylinder,collide_cone - only walk comes through here. fly/examine done with the original analytical shape/analytical avatar code.
1056*/
1057
1058int avatarCollisionVolumeIntersectMBB(double *modelMatrix, double *prminvals, double* prmaxvals)
1059{
1060 /* returns 1 if your shape MBB overlaps the avatar collision volume
1061 modelMatrix[16] == shape2collision transform. collision space is like avatar space, except vertical aligned to gravity - current bound viewpoint(walk), or avatar(fly/examine) or global gravity
1062 prminvals[3],prmaxvals[3] - MBB minimum bounding box or extent of shape, in shape space
1063 the fastTestMethod can be set in mainloop.c render_collisions()
1064 */
1065 struct sNaviInfo *naviinfo;
1066 ttglobal tg = gglobal();
1067 struct sFallInfo* fi = FallInfo();
1068 naviinfo = (struct sNaviInfo*)tg->Bindable.naviinfo;
1069 if(fi->walking)
1070 {
1071 /* cylindrical / popcycle shaped avatar collision volume */
1072 GLDOUBLE awidth = naviinfo->width; /*avatar width*/
1073 GLDOUBLE atop = naviinfo->width; /*top of avatar (relative to eyepoint)*/
1074 GLDOUBLE abottom = -naviinfo->height; /*bottom of avatar (relative to eyepoint)*/
1075 GLDOUBLE astep = -naviinfo->height+naviinfo->step;
1076
1077 /* the following 2 flags are checked a few levels down, in the triangle/quad intersect avatar code get_poly_disp_2(p, 3, nused) */
1078 fi->checkCylinder = 1; /* 1= shape MBB overlaps avatar collision MBB, else 0 */
1079 fi->checkFall = 1; /* 1= shape MBB overlaps avatar fall/climb line segment else 0 */
1080 fi->checkPenetration = 1;
1081
1082 {
1083 /* minimum bounding box MBB test in avatar/collision space */
1084 double foot = abottom;
1085 if(fi->allowClimbing) foot = astep; /* < popcycle shaped avatar collision volume */
1086 /* do fall/climb bounds test (popcycle stick) */
1087 fi->checkFall = fi->canFall; /* only do the falling/climbing if we aren't already colliding - colliding over-rules falling/climbing */
1088 if(fi->checkFall) fi->checkFall = fast_ycylinder_MBB_intersect_collisionSpace(-fi->fallHeight,atop,0.0, modelMatrix, prminvals, prmaxvals);
1089 /* do collision volume bounds test (popcycle succulent part)*/
1090 fi->checkCylinder = fast_ycylinder_MBB_intersect_collisionSpace(foot,atop,awidth, modelMatrix, prminvals, prmaxvals);
1091 fi->checkPenetration = 0;
1092 if( fi->canPenetrate )
1093 fi->checkPenetration = overlapMBBs(fi->penMin,fi->penMax,prminvals,prmaxvals);
1094 if(!fi->checkCylinder && !fi->checkFall && !fi->checkPenetration){/*printf("$");*/ return 0;}
1095 }
1096 }
1097 else
1098 {
1099 /* examine/fly spherical avatar collision volume */
1100 GLDOUBLE awidth = naviinfo->width; /*avatar width - used as avatar sphere radius*/
1101 if( !fast_sphere_MBB_intersect_collisionSpace(awidth, modelMatrix, prminvals, prmaxvals )) return 0;
1102 }
1103 return 1;
1104}
1105
1106int avatarCollisionVolumeIntersectMBBf(double *modelMatrix, float *minVals, float *maxVals)
1107{
1108 /* converts pr.floats to doubles and re-delegates */
1109 int i;
1110 GLDOUBLE prminvals[3],prmaxvals[3];
1111 for(i=0;i<3;i++)
1112 {
1113 prminvals[i] = minVals[i];
1114 prmaxvals[i] = maxVals[i];
1115 }
1116 return avatarCollisionVolumeIntersectMBB(modelMatrix, prminvals,prmaxvals);
1117}
1118
1119
1120
1121void collide_genericfaceset (struct X3D_IndexedFaceSet *node ){
1122 GLDOUBLE modelMatrix[16];
1123 struct point_XYZ delta = { .x = 0,.y = 0,.z = 0 };
1124 #ifdef RENDERVERBOSE
1125 struct point_XYZ t_orig = { .x = 0,.y = 0,.z = 0 };
1126 #endif
1127 struct X3D_PolyRep* pr;
1128 prflags flags = 0;
1129 int change = 0;
1130
1131 /* JAS - first pass, intern is probably zero */
1132 if (!node->_intern || node->_intern->itype != 2) return;
1133 pr = (struct X3D_PolyRep*) node->_intern;
1134
1135 /* JAS - no triangles in this text structure */
1136 if (pr->ntri == 0) return;
1137
1138 /*save changed state.*/
1139 change = pr->irep_change;
1140 //COMPILE_POLY_IF_REQUIRED (NULL, NULL, NULL, NULL, NULL)
1141 if (!compile_poly_if_required(node, NULL, NULL, NULL, NULL, NULL))return;
1142
1143 pr->irep_change = change;
1144 /*restore changes state, invalidates mk_polyrep work done, so it can be done
1145 correclty in the RENDER pass */
1146
1147 if(!node->solid) {
1148 flags = flags | PR_DOUBLESIDED;
1149 }
1150
1151 /* IndexedFaceSets are "different", in that the user specifies points, among
1152 other things. The rendering pass takes these external points, and streams
1153 them to make rendering much faster on hardware accel. We have to check to
1154 see whether we have got here before the first rendering of a possibly new
1155 IndexedFaceSet */
1156 if (!pr->actualCoord) return;
1157 //{
1158 // struct Multi_Vec3f* tmp;
1159 // tmp = getCoordinate(node->coord,"Collision");
1160 // pr->actualCoord = (float *) tmp->p;
1161 //}
1162
1163 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1164 /*
1165 For examine and fly navigation modes, there's no gravity direction.
1166 Avatar collision volume is aligned to avatar and is spherical and
1167 symmetrically directional. This is the simple case. Specifications say for
1168 walk navigation mode gravity vector is down {0,-1,0} with respect to (wrt) the
1169 currently bound viewpoint, not including the viewpoint's orientation
1170 field and not including avatar navigation/tilt away from its parent
1171 bound-viewpoint pose. When you collide in walk mode, the avatar collision
1172 volume is aligned to bound-viewpoint. This is a slightly more complex case.
1173 To generalize the 2 cases, some Definitions:
1174 Spaces:
1175 Avatar space
1176 - gravity is avatar-down
1177 - Avatar is at {0,0,0} and +Y up is as you see up in your current view,
1178 +Z aft and +X to the right
1179 BoundViewpoint space - currently bound viewpoint (transform parent to avatar)
1180 BVVA space - Bound-Viewpoint-Vertically-aligned Avatar-centric
1181 - same as Avatar space with avatar at {0,0,0} except tilted so that gravity
1182 is in the direction of down {0,-1,0} for the currently bound viewpoint
1183 (instead for avatar), as per specs
1184 - gravity is bound-viewpoint down
1185 Collision space - Fly/Examine mode: Avatar space. Walk mode: BVVA space
1186 - the avatar collision volume - height, stepsize, width - are defined for
1187 collision space and axes aligned with it
1188 Shape space - raw shape <Coordinate> space
1189 Transforms:
1190 Bound2Avatar - transforms from BoundViewpoint space to Avatar space
1191 - computed from viewer.quat,viewer.pos
1192 Avatar2BVVA,BVVA2Avatar
1193 - computed from downvector in BoundViewpoint space transformed
1194 via Bound2Avatar into Avatar space
1195 - constant for a frame, computable once navigation mode and
1196 avatar pose is know for the frame
1197 Avatar2Collision - Fly/Examine: Identity, Walk: Avatar2BVVA
1198 Collision2Avatar - Fly/Examine: Identity, Walk: BVVA2Avatar
1199 Shape2Collision - Fly/Examine: modelMatrix, Walk: Avatar2BVVA*modelMatrix
1200
1201 goal: transform shape geometry into Collision space. (The avatar collision
1202 volume is by definition in collision space.)
1203 Do some collisions between shape and avatar.
1204 Transform collision correction deltas from collision space to avatar space,
1205 apply deltas to avatar position.
1206 implementation:
1207 transform shape into collision space - Fly/Examine:modelMatrix
1208 or Walk:(Avatar2BVVA * modelMatrix)
1209 transform collision correction deltas from collision space to avatar space:
1210 - done in Mainloop.c get_collisionoffset() with FallInfo.collision2avatar
1211 */
1212
1213 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1214 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
1215
1216
1217 #ifdef RENDERVERBOSE
1218 t_orig.x = modelMatrix[12];
1219 t_orig.y = modelMatrix[13];
1220 t_orig.z = modelMatrix[14];
1221 #endif
1222
1223 /* at this point, whichever method - modelMatrix is Shape2Collision
1224 and upvecmat is Collision2Avatar
1225 - pr.actualCoord - these are Shape space coordinates
1226 They will be transformed into CollisionSpace coordinates by the modelMatrix transform.
1227 */
1228 if(!avatarCollisionVolumeIntersectMBBf(modelMatrix, pr->minVals, pr->maxVals))return;
1229 /* passed fast test. Now for gruelling test */
1230
1231 delta = polyrep_disp2(pr,modelMatrix,flags); //polyrep_disp(abottom,atop,astep,awidth,pr,modelMatrix,flags);
1232
1233 /* delta is in collision space */
1234 /* lets say you are floating above ground by 3 units + avatar.height 1.75 = 4.75.
1235 Then delta = (0,3,0)*/
1236 vecscale(&delta,&delta,-1);
1237 accumulate_disp(CollisionInfo(),delta); /* we are accumulating in collision space (fly/examine: avatar space, walk: BVVA space) */
1238
1239#ifdef RENDERVERBOSE
1240 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.)) {
1241 /* printmatrix(modelMatrix);*/
1242 fprintf(stderr,"COLLISION_IFS: (%f %f %f) (%f %f %f)\n",
1243 t_orig.x, t_orig.y, t_orig.z,
1244 delta.x, delta.y, delta.z
1245 );
1246 }
1247#endif
1248
1249}
1250
1251
1252static void collisionSphere_init(struct X3D_Sphere *node)
1253{
1254 int i,j,count;
1255 /* for debug int k, biggestNum; */
1256 double radinverse;
1257 struct SFVec3f *pts = node->__points.p;
1258 ppComponent_Geometry3D p = (ppComponent_Geometry3D)gglobal()->Component_Geometry3D.prv;
1259
1260 /* re-using the compile_sphere node->__points data which is organized into GL_QUAD_STRIPS
1261 my understanding: there are SPHDIV/2 quad strips. Each quadstrip has SPHDIV quads, and enough points to do that many quads
1262 without sharing points with other quadstrips. So to make SPHDIV quads, you need 2 rows of SPHDIV+1 points.
1263 because there's 2 triangles per quad, there should be 2x as many triangles as quads.
1264 num quads = SPHDIV/2 x SPHDIV
1265 num points = SPHDIV/2 X [(SPHDIV+1) X 2] = SPHDIV*(SPHDIV+1)
1266 num tris = quads x 2 = SPHDIV X SPHDIV
1267 */
1268
1269 p->collisionSphere.npts = SPHDIV*(SPHDIV+1);
1270 p->collisionSphere.pts = MALLOC(void *, p->collisionSphere.npts * sizeof(struct point_XYZ));
1271 p->collisionSphere.tpts = MALLOC(void *, p->collisionSphere.npts * sizeof(struct point_XYZ));
1272 /* undo radius field on node so radius == 1 (generic, for all spheres, scale back later) */
1273 radinverse = 1.0;
1274 if( !APPROX(node->radius,0.0) ) radinverse = 1.0/node->radius;
1275 for(i=0;i<p->collisionSphere.npts;i++)
1276 {
1277 p->collisionSphere.pts[i].x = pts[i].c[0] * radinverse;
1278 p->collisionSphere.pts[i].y = pts[i].c[1] * radinverse;
1279 p->collisionSphere.pts[i].z = pts[i].c[2] * radinverse;
1280 }
1281
1282
1283 p->collisionSphere.ntris = SPHDIV * SPHDIV;
1284 p->collisionSphere.tris = MALLOC(void *, p->collisionSphere.ntris * sizeof(ctri));
1285 p->collisionSphere.nquads = 0;
1286 count = 0;
1287 for(i = 0; i < SPHDIV/2; i ++)
1288 {
1289 /* one quad strip of SPHDIV quads or SPHDIV*2 triangles */
1290 for(j=0;j<(2*SPHDIV);j+=2) //=+)
1291 {
1292 /* first triangle */
1293 p->collisionSphere.tris[count][0] = i*(SPHDIV+1)*2 + j;
1294 p->collisionSphere.tris[count][1] = i*(SPHDIV+1)*2 + j+1;
1295 p->collisionSphere.tris[count][2] = i*(SPHDIV+1)*2 + j+2;
1296 count ++;
1297 /* second triangle */
1298 p->collisionSphere.tris[count][0] = i*(SPHDIV+1)*2 + j+3;
1299 p->collisionSphere.tris[count][1] = i*(SPHDIV+1)*2 + j+2;
1300 p->collisionSphere.tris[count][2] = i*(SPHDIV+1)*2 + j+1;
1301 count ++;
1302 }
1303 }
1304 /* count should == num triangles
1305 debug check on indexing - biggestNum should == npts -1
1306 biggestNum = 0;
1307 for(i=0;i<collisionSphere.ntris;i++)
1308 for(j=0;j<3;j++)
1309 biggestNum = max(biggestNum,collisionSphere.tris[i][j]);
1310 */
1311 /* MBB */
1312 for(i=0;i<3;i++)
1313 {
1314 p->collisionSphere.smin[i] = -1.0; //rad;
1315 p->collisionSphere.smax[i] = 1.0; //rad;
1316 }
1317
1318}
1319#ifdef DEBUGGING_CODE
1320DEBUGGING_CODEint collisionSphere_render(double radius)
1321DEBUGGING_CODE{
1322DEBUGGING_CODE /* I needed to verify the collision mesh sphere was good, and it uses triangles, so I drew it the triangle way and it looked good
1323DEBUGGING_CODE to see it draw, you need to turn on collision and get close to a sphere - then it will initialize and start drawing it.
1324DEBUGGING_CODE */
1325DEBUGGING_CODE int i,j,count,highest;
1326DEBUGGING_CODE count = 0;
1327DEBUGGING_CODE highest = 0;
1328DEBUGGING_CODE for(i =0; i < collisionSphere.ntris; i++)
1329DEBUGGING_CODE {
1330DEBUGGING_CODE struct point_XYZ pts[3]; //,a,b,n;
1331DEBUGGING_CODE pts[0] = collisionSphere.pts[collisionSphere.tris[i][0]];
1332DEBUGGING_CODE pts[1] = collisionSphere.pts[collisionSphere.tris[i][1]];
1333DEBUGGING_CODE pts[2] = collisionSphere.pts[collisionSphere.tris[i][2]];
1334DEBUGGING_CODE FW_GL_BEGIN(GL_TRIANGLES);
1335DEBUGGING_CODE for(j=0;j<3;j++)
1336DEBUGGING_CODE FW_GL_VERTEX3D(pts[j].x*radius,pts[j].y*radius,pts[j].z*radius);
1337DEBUGGING_CODE#define FW_GL_END() glEnd()
1338DEBUGGING_CODE FW_GL_END();
1339DEBUGGING_CODE }
1340DEBUGGING_CODE return 0;
1341DEBUGGING_CODE}
1342#endif
1343
1344struct point_XYZ get_poly_disp_2(struct point_XYZ* p, int num, struct point_XYZ n);
1345#define FLOAT_TOLERANCE 0.00000001
1346void collide_Sphere (struct X3D_Sphere *node) {
1347 struct point_XYZ t_orig = { .x = 0,.y = 0,.z = 0 }; /*transformed origin*/
1348 struct point_XYZ p_orig= { .x = 0,.y = 0,.z = 0 }; /*projected transformed origin */
1349 struct point_XYZ n_orig = { .x = 0,.y = 0,.z = 0 }; /*normal(unit length) transformed origin */
1350 GLDOUBLE modelMatrix[16];
1351 GLDOUBLE awidth,atop,abottom,dist2;
1352 struct point_XYZ delta = { .x = 0,.y = 0,.z = 0 };
1353 GLDOUBLE radius;
1354 struct sNaviInfo *naviinfo;
1355 ttglobal tg = gglobal();
1356 ppComponent_Geometry3D p = (ppComponent_Geometry3D)gglobal()->Component_Geometry3D.prv;
1357 naviinfo = (struct sNaviInfo*)tg->Bindable.naviinfo;
1358
1359 /*easy access, naviinfo.step unused for sphere collisions */
1360 awidth = naviinfo->width; /*avatar width*/
1361 atop = naviinfo->width; /*top of avatar (relative to eyepoint)*/
1362 abottom = -naviinfo->height; /*bottom of avatar (relative to eyepoint)*/
1363
1364 /* this sucker initialized yet? */
1365 if (node->__points.p == NULL) return;
1366
1367
1368 /* get the transformed position of the Sphere, and the scale-corrected radius. */
1369 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1370
1371 /* apply radius to generic r=1 sphere */
1372 //radscale.x = radscale.y = radscale.z = node->radius;
1373 //scale_to_matrix (modelMatrix, &radscale);
1374 //matmultiply(modelMatrix,FallInfo.avatar2collision,modelMatrix);
1375
1376 if(FallInfo()->walking)
1377 {
1378 /* mesh method */
1379
1380 int i;
1381 double disp;
1382 struct point_XYZ n;
1383 struct point_XYZ a,b, dispv, maxdispv = { .x = 0,.y = 0,.z = 0 };
1384 struct point_XYZ radscale;
1385 double maxdisp = 0;
1386 radscale.x = radscale.y = radscale.z = node->radius;
1387 scale_to_matrix (modelMatrix, &radscale);
1388 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1389 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
1390
1391 if(!p->collisionSphere.npts) collisionSphere_init(node);
1392 if( !avatarCollisionVolumeIntersectMBB(modelMatrix, p->collisionSphere.smin,p->collisionSphere.smax)) return;
1393
1394 for(i=0;i<p->collisionSphere.npts;i++)
1395 transform(&p->collisionSphere.tpts[i],&p->collisionSphere.pts[i],modelMatrix);
1396
1397 for(i = 0; i < p->collisionSphere.ntris; i++)
1398 {
1399 /*only clip faces "facing" origin */
1400 //if(vecdot(&n[ci],&middle) < 0.)
1401 {
1402 struct point_XYZ pts[3];
1403 pts[0] = p->collisionSphere.tpts[p->collisionSphere.tris[i][0]];
1404 pts[1] = p->collisionSphere.tpts[p->collisionSphere.tris[i][1]];
1405 pts[2] = p->collisionSphere.tpts[p->collisionSphere.tris[i][2]];
1406 /* compute normal - could compute once in shapespace then transform */
1407 VECDIFF(pts[1],pts[0],a);
1408 VECDIFF(pts[2],pts[1],b); /* or [2] [0] direction not sensitive for some functions */
1409 veccross(&n,a,b); /* 6 multiplies */
1410 vecnormal(&n,&n);
1411 dispv = get_poly_disp_2(pts,3,n);
1412 disp = vecdot(&dispv,&dispv);
1413 if( (disp > FLOAT_TOLERANCE) && (disp > maxdisp) ){
1414 maxdisp = disp;
1415 maxdispv = dispv;
1416 }
1417 }
1418 }
1419 delta = maxdispv;
1420 vecscale(&delta,&delta,-1);
1421 }else{
1422 /* easy analytical sphere-sphere stuff */
1423 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1424 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
1425
1426 t_orig.x = modelMatrix[12];
1427 t_orig.y = modelMatrix[13];
1428 t_orig.z = modelMatrix[14];
1429 radius = pow(det3x3(modelMatrix),1./3.) * node->radius;
1430
1431 /* squared distance to center of sphere (on the y plane)*/
1432 dist2 = t_orig.x * t_orig.x + t_orig.z * t_orig.z;
1433
1434 /* easy tests. clip as if sphere was a box */
1435 /*clip with cylinder */
1436
1437 if(dist2 - (radius + awidth) * (radius +awidth) > 0) {
1438 return;
1439 }
1440 /*clip with bottom plane */
1441 if(t_orig.y + radius < abottom) {
1442 return;
1443 }
1444 /*clip with top plane */
1445 if(t_orig.y-radius > atop) {
1446 return;
1447 }
1448
1449 /* project onto (y x t_orig) plane */
1450 p_orig.x = sqrt(dist2);
1451 p_orig.y = t_orig.y;
1452 p_orig.z = 0;
1453 /* we need this to unproject rapidly */
1454 /* n_orig is t_orig.y projected on the y plane, then normalized. */
1455 n_orig.x = t_orig.x;
1456 n_orig.y = 0.0;
1457 n_orig.z = t_orig.z;
1458 VECSCALE(n_orig,1.0/p_orig.x); /*equivalent to vecnormal(n_orig);, but faster */
1459 #ifdef RENDERVERBOSE
1460 printf ("sphere, p_orig %lf %lf %lf, n_orig %lf %lf %lf\n",p_orig.x, p_orig.y, p_orig.z, n_orig.x, n_orig.y, n_orig.z);
1461 #endif
1462
1463 /* 5 cases : sphere is over, over side, side, under and side, under (relative to y axis) */
1464 /* these 5 cases correspond to the 5 vornoi regions of the cylinder */
1465 if(p_orig.y > atop) {
1466 if(p_orig.x < awidth) {
1467 #ifdef RENDERVERBOSE
1468 printf(" /* over, we push down. */ \n");
1469 #endif
1470 delta.y = (p_orig.y - radius) - (atop);
1471 } else {
1472 struct point_XYZ d2s;
1473 GLDOUBLE ratio;
1474 #ifdef RENDERVERBOSE
1475 printf(" /* over side */ \n");
1476 #endif
1477 /* distance vector from corner to center of sphere*/
1478 d2s.x = p_orig.x - awidth;
1479 d2s.y = p_orig.y - (atop);
1480 d2s.z = 0;
1481 ratio = 1- radius/sqrt(d2s.x * d2s.x + d2s.y * d2s.y);
1482 if(ratio >= 0) {
1483 /* no collision */
1484 return;
1485 }
1486 /* distance vector from corner to surface of sphere, (do the math) */
1487 VECSCALE(d2s, ratio );
1488 /* unproject, this is the fastest way */
1489 delta.y = d2s.y;
1490 delta.x = d2s.x* n_orig.x;
1491 delta.z = d2s.x* n_orig.z;
1492 }
1493 } else if(p_orig.y < abottom) {
1494 if(p_orig.x < awidth) {
1495 #ifdef RENDERVERBOSE
1496 printf(" /* under, we push up. */ \n");
1497 #endif
1498 delta.y = (p_orig.y + radius) -abottom;
1499 } else {
1500 struct point_XYZ d2s;
1501 GLDOUBLE ratio;
1502 #ifdef RENDERVERBOSE
1503 printf(" /* under side */ \n");
1504 #endif
1505 /* distance vector from corner to center of sphere*/
1506 d2s.x = p_orig.x - awidth;
1507 d2s.y = p_orig.y - abottom;
1508 d2s.z = 0;
1509 ratio = 1- radius/sqrt(d2s.x * d2s.x + d2s.y * d2s.y);
1510 if(ratio >= 0) {
1511 /* no collision */
1512 return;
1513 }
1514
1515 /* distance vector from corner to surface of sphere, (do the math) */
1516 VECSCALE(d2s, ratio );
1517
1518 /* unproject, this is the fastest way */
1519 delta.y = d2s.y;
1520 delta.x = d2s.x* n_orig.x;
1521 delta.z = d2s.x* n_orig.z;
1522 }
1523 } else {
1524 #ifdef RENDERVERBOSE
1525 printf(" /* side */ \n");
1526 #endif
1527 /* push to side */
1528 delta.x = ((p_orig.x - radius)- awidth) * n_orig.x;
1529 delta.z = ((p_orig.x - radius)- awidth) * n_orig.z;
1530 }
1531 }
1532 accumulate_disp(CollisionInfo(),delta);
1533
1534 #ifdef RENDERVERBOSE
1535 if((delta.x != 0. || delta.y != 0. || delta.z != 0.))
1536 printf("COLLISION_SPH: (%f %f %f) (%f %f %f) (px=%f nx=%f nz=%f)\n",
1537 t_orig.x, t_orig.y, t_orig.z,
1538 delta.x, delta.y, delta.z,
1539 p_orig.x, n_orig.x, n_orig.z
1540 );
1541 #endif
1542}
1543
1544
1545void collide_Box (struct X3D_Box *node) {
1546 /*easy access, naviinfo.step unused for sphere collisions */
1547 struct sNaviInfo *naviinfo;
1548 struct point_XYZ iv = { .x = 0,.y = 0,.z = 0 };
1549 struct point_XYZ jv = { .x = 0,.y = 0,.z = 0 };
1550 struct point_XYZ kv = { .x = 0,.y = 0,.z = 0 };
1551 struct point_XYZ ov = { .x = 0,.y = 0,.z = 0 };
1552 struct point_XYZ delta;
1553 GLDOUBLE awidth, atop, abottom, astep, modelMatrix[16];
1554 ttglobal tg = gglobal();
1555
1556 naviinfo = (struct sNaviInfo*)tg->Bindable.naviinfo;
1557 awidth = naviinfo->width; /*avatar width*/
1558 atop = naviinfo->width; /*top of avatar (relative to eyepoint)*/
1559 abottom = -naviinfo->height; /*bottom of avatar (relative to eyepoint)*/
1560 astep = -naviinfo->height+naviinfo->step;
1561
1562 iv.x = ((node->size).c[0]);
1563 jv.y = ((node->size).c[1]);
1564 kv.z = ((node->size).c[2]);
1565 ov.x = -((node->size).c[0])/2; ov.y = -((node->size).c[1])/2; ov.z = -((node->size).c[2])/2;
1566
1567 /* get the transformed position of the Box, and the scale-corrected radius. */
1568 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1569 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1570 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
1571 {
1572 int i;
1573 double shapeMBBmin[3],shapeMBBmax[3];
1574 for(i=0;i<3;i++)
1575 {
1576 shapeMBBmin[i] = DOUBLE_MIN(-(node->size).c[i]*.5,(node->size).c[i]*.5);
1577 shapeMBBmax[i] = DOUBLE_MAX(-(node->size).c[i]*.5,(node->size).c[i]*.5);
1578 }
1579 if( !avatarCollisionVolumeIntersectMBB(modelMatrix, shapeMBBmin,shapeMBBmax)) return;
1580 }
1581 /* get transformed box edges and position */
1582 transform(&ov,&ov,modelMatrix);
1583 transform3x3(&iv,&iv,modelMatrix);
1584 transform3x3(&jv,&jv,modelMatrix);
1585 transform3x3(&kv,&kv,modelMatrix);
1586
1587 delta = box_disp(abottom,atop,astep,awidth,ov,iv,jv,kv);
1588 vecscale(&delta,&delta,-1);
1589 accumulate_disp(CollisionInfo(),delta);
1590
1591 #ifdef RENDERVERBOSE
1592 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.))
1593 printf("COLLISION_BOX: (%f %f %f) (%f %f %f)\n",
1594 ov.x, ov.y, ov.z,
1595 delta.x, delta.y, delta.z
1596 );
1597 if((fabs(delta.x != 0.) || fabs(delta.y != 0.) || fabs(delta.z) != 0.))
1598 printf("iv=(%f %f %f) jv=(%f %f %f) kv=(%f %f %f)\n",
1599 iv.x, iv.y, iv.z,
1600 jv.x, jv.y, jv.z,
1601 kv.x, kv.y, kv.z
1602 );
1603 #endif
1604}
1605
1606
1607#define CONEDIV 20
1608
1609static void collisionCone_init(struct X3D_Cone *node)
1610{
1611 //we pass in a node instance, so we don't have to split up the compile_ code that generates
1612 // geometry - we can just copy some
1613 /* for debug ctri ct; */
1614 /* for debug struct point_XYZ a,b,n; */
1615 int i,count;
1616 /* for debug int j,k,biggestNum; */
1617 double h,r,inverseh,inverser;
1618 struct SFVec3f *pts;// = node->__botpoints;
1619 struct SFVec3f *pt;
1620 struct Multi_Vec3f botpoints;
1621 ppComponent_Geometry3D p = (ppComponent_Geometry3D)gglobal()->Component_Geometry3D.prv;
1622
1623 /* re-using the compile_cone node->__points data which is organized into GL_TRAIANGLE_FAN (bottom) and GL_TRIANGLES (side)
1624
1625 my understanding:
1626 bottom: there are CONEDIV triangles arranged in a fan around a center point, with CONEDIV perimeter points
1627 side: there are CONEDIV side triangles formed with the top point and perimeter points
1628 num triangles: CONEDIV x 2
1629 num points: CONEDIV perimeter + center bottom + centre top = CONEDIV+2
1630 __botpoints:
1631 pt[0] - top point of cone
1632 pt[1-CONEDIV] - perimeter points
1633 pt[CONEDIV+1] - centre of bottom
1634 (there are sidepoints too, but duplicate the points in botpoints)
1635 */
1636 p->collisionCone.npts = CONEDIV+2;
1637 p->collisionCone.pts = MALLOC(void *, p->collisionCone.npts * sizeof(struct point_XYZ));
1638 p->collisionCone.tpts = MALLOC(void *, p->collisionCone.npts * sizeof(struct point_XYZ));
1639
1640 p->collisionCone.ntris = CONEDIV *2;
1641 p->collisionCone.tris = MALLOC(void *, p->collisionCone.ntris * sizeof(ctri));
1642 count = 0;
1643 h = (node->height);
1644 r = node->bottomRadius;
1645 inverseh = 1.0;
1646 inverser = 1.0;
1647 if( !APPROX(h,0.0) ) inverseh = 1.0/h;
1648 if( !APPROX(r,0.0) ) inverser = 1.0/r;
1649
1650
1651 /* ok - we copy the non-VBO code here so that Doug Sandens Cylinder Collision code
1652 uses the same algorithm whether running in VBO mode or not */
1653
1654 /* MALLOC memory (if possible)*/
1655 botpoints.p = MALLOC (struct SFVec3f *, sizeof(struct SFVec3f)*(CONEDIV+3));
1656
1657 /* generate the vertexes for the triangles; top point first. (note: top point no longer used)*/
1658 pt = botpoints.p;
1659 pt[0].c[0] = 0.0f; pt[0].c[1] = (float) h; pt[0].c[2] = 0.0f;
1660 for (i=1; i<=CONEDIV; i++) {
1661 pt[i].c[0] = (float) (r* sin(PI*2*i/(float)CONEDIV));
1662 pt[i].c[1] = (float) -h;
1663 pt[i].c[2] = (float) (r* cos(PI*2*i/(float)CONEDIV));
1664 }
1665 /* and throw another point that is centre of bottom*/
1666 pt[CONEDIV+1].c[0] = 0.0f; pt[CONEDIV+1].c[1] = (float) -h; pt[CONEDIV+1].c[2] = 0.0f;
1667
1668 /* and, for the bottom, [CONEDIV] = [CONEDIV+2]; but different texture coords, so...*/
1669 memcpy (&pt[CONEDIV+2].c[0],&pt[CONEDIV].c[0],sizeof (struct SFVec3f));
1670
1671#ifdef fwIGNORE
1672 /* side triangles. Make 3 seperate points per triangle... makes sendArraysToGPU with normals*/
1673 /* easier to handle.*/
1674 /* rearrange bottom points into this array; top, bottom, left.*/
1675 spt = sidepoints.p;
1676 for (i=0; i<CONEDIV; i++) {
1677 /* top point*/
1678 spt[i*3].c[0] = 0.0f; spt[i*3].c[1] = (float) h; spt[i*3].c[2] = 0.0f;
1679 /* left point*/
1680 memcpy (&spt[i*3+1].c[0],&pt[i+1].c[0],sizeof (struct SFVec3f));
1681 /* right point*/
1682 memcpy (&spt[i*3+2].c[0],&pt[i+2].c[0],sizeof (struct SFVec3f));
1683 }
1684
1685 /* wrap bottom point around once again... ie, final right point = initial left point*/
1686 memcpy (&spt[(CONEDIV-1)*3+2].c[0],&pt[1].c[0],sizeof (struct SFVec3f));
1687#endif
1688
1689
1690
1691 pts = botpoints.p;
1692 for(i=0;i<(CONEDIV+2);i++)
1693 {
1694 /* points */
1695 p->collisionCone.pts[i].x = pts[i].c[0]*inverser;
1696 p->collisionCone.pts[i].y = pts[i].c[1]*inverseh;
1697 p->collisionCone.pts[i].z = pts[i].c[2]*inverser;
1698 }
1699 for(i=0;i<CONEDIV;i++)
1700 {
1701 /* side triangles */
1702 p->collisionCone.tris[count][0] = 0; /* top point */
1703 p->collisionCone.tris[count][1] = i +1;
1704 p->collisionCone.tris[count][2] = i > (CONEDIV-2)? 1 : i+2; /*wrap-around, normally i+2 */
1705 count ++;
1706 }
1707 for(i=0;i<CONEDIV;i++)
1708 {
1709 /* bottom triangles */
1710 p->collisionCone.tris[count][0] = CONEDIV+1; /* bottom center point */
1711 p->collisionCone.tris[count][1] = i +1;
1712 p->collisionCone.tris[count][2] = i > (CONEDIV-2)? 1 : i+2;
1713 count ++;
1714 }
1715
1716
1717 /* count should == num triangles
1718 debug check on indexing - biggestNum should == npts -1
1719 biggestNum = 0;
1720 for(i=0;i<collisionCone.ntris;i++)
1721 for(j=0;j<3;j++)
1722 biggestNum = max(biggestNum,collisionCone.tris[i][j]);
1723 */
1724 /* MBB */
1725 for(i=0;i<3;i+=2)
1726 {
1727 p->collisionCone.smin[i] = -1.0; //r;
1728 p->collisionCone.smax[i] = 1.0; //r;
1729 }
1730 p->collisionCone.smin[1] = -1.0; //-h;
1731 p->collisionCone.smax[1] = 1.0; //h;
1732
1733 /* ok - we copy the non-VBO code here so that Doug Sandens Cylinder Collision code
1734 uses the same algorithm whether running in VBO mode or not */
1735 FREE_IF_NZ(botpoints.p);
1736}
1737#ifdef DEBUG_COLLISIONCONE
1738int collisionCone_render(double r, double h)
1739{
1740 /* I needed to verify the collision mesh was good, and it uses triangles, so I drew it the triangle way and it looked good
1741 to see it draw, you need to turn on collision and get close to the mesh object - then it will initialize and start drawing it.
1742 */
1743 int i,j;
1744 for(i =0; i < collisionCone.ntris; i++)
1745 {
1746 struct point_XYZ pts[3]; //,a,b,n;
1747 pts[0] = collisionCone.pts[collisionCone.tris[i][0]];
1748 pts[1] = collisionCone.pts[collisionCone.tris[i][1]];
1749 pts[2] = collisionCone.pts[collisionCone.tris[i][2]];
1750 glBegin(GL_TRIANGLES);
1751 for(j=0;j<3;j++)
1752 FW_GL_VERTEX3D(pts[j].x*r,pts[j].y*h,pts[j].z*r);
1753 glEnd();
1754 }
1755 return 0;
1756}
1757#endif
1758void collide_Cone (struct X3D_Cone *node) {
1759 /*easy access, naviinfo.step unused for sphere collisions */
1760 struct sNaviInfo *naviinfo;
1761 GLDOUBLE awidth, atop, abottom, astep, scale, modelMatrix[16];
1762 float h,r;
1763 struct point_XYZ iv = { .x = 0,.y = 0,.z = 0 };
1764 struct point_XYZ jv = { .x = 0,.y = 0,.z = 0 };
1765 struct point_XYZ t_orig = { .x = 0,.y = 0,.z = 0 };
1766 struct point_XYZ delta;
1767 ttglobal tg = gglobal();
1768 ppComponent_Geometry3D p = (ppComponent_Geometry3D)tg->Component_Geometry3D.prv;
1769 naviinfo = (struct sNaviInfo*)tg->Bindable.naviinfo;
1770
1771 awidth = naviinfo->width; /*avatar width*/
1772 atop = naviinfo->width; /*top of avatar (relative to eyepoint)*/
1773 abottom = -naviinfo->height; /*bottom of avatar (relative to eyepoint)*/
1774 astep = -naviinfo->height+naviinfo->step;
1775
1776 h = (node->height) /2;
1777 r = (node->bottomRadius) ;
1778
1779 scale = 0.0; /* FIXME: won''t work for non-uniform scales. */
1780
1781 /* is this node initialized? if not, get outta here and do this later */
1782 if (node->__coneVBO == 0) return;
1783
1784 iv.y = h; jv.y = -h;
1785
1786 /* get the transformed position of the Sphere, and the scale-corrected radius. */
1787 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1788
1789 //matmultiply(modelMatrix,FallInfo.avatar2collision,modelMatrix);
1790 if(FallInfo()->walking)
1791 {
1792 /* mesh method */
1793 int i;
1794 double disp;
1795 struct point_XYZ n;
1796 struct point_XYZ a,b, dispv, maxdispv = { .x = 0,.y = 0,.z = 0 };
1797 double maxdisp = 0;
1798 struct point_XYZ radscale;
1799
1800 if(!p->collisionCone.npts) collisionCone_init(node);
1801#ifdef DEBUG_COLLISIONCONE
1802 collisionCone_render(5.0,5.0);
1803#endif
1804 radscale.x = radscale.z = node->bottomRadius;
1805 radscale.y = node->height;
1806 scale_to_matrix (modelMatrix, &radscale);
1807 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1808 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
1809 if( !avatarCollisionVolumeIntersectMBB(modelMatrix, p->collisionCone.smin,p->collisionCone.smax)) return;
1810
1811
1812 for(i=0;i<p->collisionCone.npts;i++)
1813 transform(&p->collisionCone.tpts[i],&p->collisionCone.pts[i],modelMatrix);
1814 for(i = 0; i < p->collisionCone.ntris; i++)
1815 {
1816 /*only clip faces "facing" origin */
1817 //if(vecdot(&n[ci],&middle) < 0.) {
1818 {
1819 struct point_XYZ pts[3];
1820 pts[0] = p->collisionCone.tpts[p->collisionCone.tris[i][0]];
1821 pts[1] = p->collisionCone.tpts[p->collisionCone.tris[i][1]];
1822 pts[2] = p->collisionCone.tpts[p->collisionCone.tris[i][2]];
1823 /* compute normal - could compute once in shapespace then transform */
1824 VECDIFF(pts[1],pts[0],a);
1825 VECDIFF(pts[2],pts[1],b); /* or [2] [0] direction not sensitive for some functions */
1826 veccross(&n,a,b); /* 6 multiplies */
1827 vecnormal(&n,&n);
1828 dispv = get_poly_disp_2(pts,3,n);
1829 disp = vecdot(&dispv,&dispv);
1830 if( (disp > FLOAT_TOLERANCE) && (disp > maxdisp) ){
1831 maxdisp = disp;
1832 maxdispv = dispv;
1833 }
1834 }
1835 }
1836 delta = maxdispv;
1837 }else{
1838 /* values for rapid test */
1839 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1840 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
1841
1842 t_orig.x = modelMatrix[12];
1843 t_orig.y = modelMatrix[13];
1844 t_orig.z = modelMatrix[14];
1845 scale = pow(det3x3(modelMatrix),1./3.);
1846
1847 if(!fast_ycylinder_cone_intersect(abottom,atop,awidth,t_orig,scale*h,scale*r)) return;
1848
1849 /* get transformed box edges and position */
1850 transform(&iv,&iv,modelMatrix);
1851 transform(&jv,&jv,modelMatrix);
1852
1853 delta = cone_disp(abottom,atop,astep,awidth,jv,iv,scale*r);
1854 }
1855 vecscale(&delta,&delta,-1);
1856
1857 accumulate_disp(CollisionInfo(),delta);
1858
1859 #ifdef RENDERVERBOSE
1860 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.))
1861 printf("COLLISION_CON: (%f %f %f) (%f %f %f)\n",
1862 iv.x, iv.y, iv.z,
1863 delta.x, delta.y, delta.z
1864 );
1865 if((fabs(delta.x != 0.) || fabs(delta.y != 0.) || fabs(delta.z) != 0.))
1866 printf("iv=(%f %f %f) jv=(%f %f %f) bR=%f\n",
1867 iv.x, iv.y, iv.z,
1868 jv.x, jv.y, jv.z,
1869 scale*r
1870 );
1871 #endif
1872}
1873
1874static void collisionCylinder_init(struct X3D_Cylinder *node)
1875{
1876 /* for debug ctri ct; */
1877 /* for debug struct point_XYZ a,b,n; */
1878 int i, tcount, qcount;
1879 /* for debug - int j,k,biggestNum; */
1880 double h,r,inverseh,inverser;
1881 struct SFVec3f *pts;// = node->__botpoints;
1882 ppComponent_Geometry3D p = (ppComponent_Geometry3D)gglobal()->Component_Geometry3D.prv;
1883
1884 /* re-using the compile_cylinder node->__points data which is organized into GL_TRAIANGLE_FAN (bottom and top)
1885 and GL_QUADS (side)
1886
1887 my understanding:
1888 bottom and top: there are CYLDIV triangles arranged in a fan around a center point, with CYLDIV perimeter points
1889 side: there are CYLDIV side quads formed with the top and bottom perimeter points
1890 num triangles: CYLDIV x 2
1891 num quads: CYLDIV
1892 num points: CYLDIV * 2 + center bottom + centre top = CYLDIV*2 +2
1893 __points:
1894 pt[0- CYLDIV*2-1 + 2] - perimeter points including wrap-around points ordered as follows:
1895 +h,-h,+h,-h .. vertical pair order, with 2 extra for easy wrap-around indexing
1896 pt[CYLDIV*2+2] - top center point of cylinder
1897 pt[CYLDIV*2+3] - centre of bottom
1898 */
1899 p->collisionCylinder.npts = CYLDIV*2+2+2;
1900 p->collisionCylinder.pts = MALLOC(void *, p->collisionCylinder.npts * sizeof(struct point_XYZ));
1901 p->collisionCylinder.tpts = MALLOC(void *, p->collisionCylinder.npts * sizeof(struct point_XYZ));
1902
1903 p->collisionCylinder.ntris = CYLDIV *2;
1904 p->collisionCylinder.tris = MALLOC(void *, p->collisionCylinder.ntris * sizeof(ctri));
1905 p->collisionCylinder.nquads = CYLDIV;
1906 p->collisionCylinder.quads = MALLOC(void *, p->collisionCylinder.nquads * sizeof(cquad));
1907
1908 tcount = 0;
1909 qcount = 0;
1910 h = node->height;
1911 r = node->radius;
1912 inverseh = inverser = 1.0;
1913 if(!APPROX(h,0.0)) inverseh = 1.0/h;
1914 if(!APPROX(r,0.0)) inverser = 1.0/r;
1915 {
1916 float a1;
1917 /* ok - we copy the non-VBO code here so that Doug Sandens Cylinder Collision code
1918 uses the same algorithm whether running in VBO mode or not */
1919 pts = MALLOC(struct SFVec3f *,sizeof(struct SFVec3f)*2*(CYLDIV+4));
1920
1921 /* now, create the vertices; this is a quad, so each face = 4 points*/
1922 for (i=0; i<CYLDIV; i++) {
1923 a1 = (float) (PI*2*i)/(float)CYLDIV;
1924 pts[i*2+0].c[0] = (float) (r* sin(a1));
1925 pts[i*2+0].c[1] = (float) h;
1926 pts[i*2+0].c[2] = (float) (r* cos(a1));
1927 pts[i*2+1].c[0] = (float) (r* sin(a1));
1928 pts[i*2+1].c[1] = (float) -h;
1929 pts[i*2+1].c[2] = (float) (r* cos(a1));
1930 }
1931
1932 /* wrap the points around*/
1933 memcpy (&pts[CYLDIV*2].c[0],&pts[0].c[0],sizeof(struct SFVec3f)*2);
1934
1935 /* center points of top and bottom*/
1936 pts[CYLDIV*2+2].c[0] = 0.0f; pts[CYLDIV*2+2].c[1] = (float) h; pts[CYLDIV*2+2].c[2] = 0.0f;
1937 pts[CYLDIV*2+3].c[0] = 0.0f; pts[CYLDIV*2+3].c[1] = (float)-h; pts[CYLDIV*2+3].c[2] = 0.0f;
1938 }
1939 for(i=0;i<p->collisionCylinder.npts;i++)
1940 {
1941 /* points */
1942 p->collisionCylinder.pts[i].x = pts[i].c[0]*inverser;
1943 p->collisionCylinder.pts[i].y = pts[i].c[1]*inverseh;
1944 p->collisionCylinder.pts[i].z = pts[i].c[2]*inverser;
1945 }
1946 for(i=0;i<CYLDIV;i++)
1947 {
1948 /* side quads */
1949 p->collisionCylinder.quads[qcount][0] = i*2; /* top point */
1950 p->collisionCylinder.quads[qcount][1] = i*2 +1;
1951 p->collisionCylinder.quads[qcount][2] = i*2 +3; /*wrap-around, normally i+2 */
1952 p->collisionCylinder.quads[qcount][3] = i*2 +2;
1953 qcount ++;
1954 }
1955 //pt[CYLDIV*2+2].c[0] = 0.0; pt[CYLDIV*2+2].c[1] = (float) h; pt[CYLDIV*2+2].c[2] = 0.0;
1956 //pt[CYLDIV*2+3].c[0] = 0.0; pt[CYLDIV*2+3].c[1] = (float)-h; pt[CYLDIV*2+3].c[2] = 0.0;
1957
1958 for(i=0;i<CYLDIV;i++)
1959 {
1960 /* bottom triangles */
1961 p->collisionCylinder.tris[tcount][0] = CYLDIV*2+3; /* bottom center point */
1962 p->collisionCylinder.tris[tcount][1] = i*2 +1;
1963 p->collisionCylinder.tris[tcount][2] = (i+1)*2 +1;
1964 tcount ++;
1965 }
1966 for(i=0;i<CYLDIV;i++)
1967 {
1968 /* top triangles */
1969 p->collisionCylinder.tris[tcount][0] = CYLDIV*2+2; /* top center point */
1970 p->collisionCylinder.tris[tcount][1] = i*2;
1971 p->collisionCylinder.tris[tcount][2] = (i+1)*2;
1972 tcount ++;
1973 }
1974
1975 /* count should == num triangles
1976 debug check on indexing - biggestNum should == npts -1
1977 biggestNum = 0;
1978 for(i=0;i<collisionCylinder.ntris;i++)
1979 for(j=0;j<3;j++)
1980 biggestNum = max(biggestNum,collisionCylinder.tris[i][j]);
1981 */
1982 /* MBB */
1983 for(i=0;i<3;i+=2)
1984 {
1985 p->collisionCylinder.smin[i] = -1.0; //r;
1986 p->collisionCylinder.smax[i] = 1.0; //r;
1987 }
1988 p->collisionCylinder.smin[1] = -1.0; //-h/2;
1989 p->collisionCylinder.smax[1] = 1.0; //h/2;
1990
1991 FREE_IF_NZ(pts);
1992}
1993
1994#ifdef DEBUGGING_CODE
1995DEBUGGING_CODEint collisionCylinder_render(double r, double h)
1996DEBUGGING_CODE{
1997DEBUGGING_CODE /* I needed to verify the collision mesh was good, and it uses triangles, so I drew it the triangle way and it looked good
1998DEBUGGING_CODE to see it draw, you need to turn on collision and get close to the mesh object - then it will initialize and start drawing it.
1999DEBUGGING_CODE */
2000DEBUGGING_CODE int i,j;
2001DEBUGGING_CODE for(i =0; i < collisionCylinder.ntris; i++)
2002DEBUGGING_CODE {
2003DEBUGGING_CODE struct point_XYZ pts[3]; //,a,b,n;
2004DEBUGGING_CODE pts[0] = collisionCylinder.pts[collisionCylinder.tris[i][0]];
2005DEBUGGING_CODE pts[1] = collisionCylinder.pts[collisionCylinder.tris[i][1]];
2006DEBUGGING_CODE pts[2] = collisionCylinder.pts[collisionCylinder.tris[i][2]];
2007DEBUGGING_CODE FW_GL_BEGIN(GL_TRIANGLES);
2008DEBUGGING_CODE for(j=0;j<3;j++)
2009DEBUGGING_CODE FW_GL_VERTEX3D(pts[j].x*r,pts[j].y*h,pts[j].z*r);
2010DEBUGGING_CODE FW_GL_END();
2011DEBUGGING_CODE }
2012DEBUGGING_CODE for(i =0; i < collisionCylinder.nquads; i++)
2013DEBUGGING_CODE {
2014DEBUGGING_CODE struct point_XYZ pts[4]; //,a,b,n;
2015DEBUGGING_CODE pts[0] = collisionCylinder.pts[collisionCylinder.quads[i][0]];
2016DEBUGGING_CODE pts[1] = collisionCylinder.pts[collisionCylinder.quads[i][1]];
2017DEBUGGING_CODE pts[2] = collisionCylinder.pts[collisionCylinder.quads[i][2]];
2018DEBUGGING_CODE pts[3] = collisionCylinder.pts[collisionCylinder.quads[i][3]];
2019DEBUGGING_CODE FW_GL_BEGIN(GL_QUADS);
2020DEBUGGING_CODE for(j=0;j<4;j++)
2021DEBUGGING_CODE FW_GL_VERTEX3D(pts[j].x*r,pts[j].y*h,pts[j].z*r);
2022DEBUGGING_CODE FW_GL_END();
2023DEBUGGING_CODE }
2024DEBUGGING_CODE return 0;
2025DEBUGGING_CODE}
2026#endif
2027
2028
2029void collide_Cylinder (struct X3D_Cylinder *node) {
2030 /*easy access, naviinfo.step unused for sphere collisions */
2031 struct sNaviInfo *naviinfo;
2032 GLDOUBLE awidth,atop,abottom,astep,scale,modelMatrix[16];
2033 float h,r;
2034 struct point_XYZ iv = { .x = 0,.y = 0,.z = 0 };
2035 struct point_XYZ jv = { .x = 0,.y = 0,.z = 0 };
2036 struct point_XYZ t_orig = { .x = 0,.y = 0,.z = 0 };
2037 struct point_XYZ delta;
2038 ttglobal tg = gglobal();
2039 ppComponent_Geometry3D p = (ppComponent_Geometry3D)tg->Component_Geometry3D.prv;
2040 naviinfo = (struct sNaviInfo*)tg->Bindable.naviinfo;
2041
2042 awidth = naviinfo->width; /*avatar width*/
2043 atop = naviinfo->width; /*top of avatar (relative to eyepoint)*/
2044 abottom = -naviinfo->height; /*bottom of avatar (relative to eyepoint)*/
2045 astep = -naviinfo->height+naviinfo->step;
2046
2047 h = (node->height)/2;
2048 r = (node->radius);
2049
2050
2051 scale=0.0; /* FIXME: won''t work for non-uniform scales. */
2052
2053 iv.y = h;
2054 jv.y = -h;
2055
2056 /* get the transformed position of the Sphere, and the scale-corrected radius. */
2057 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
2058
2059 //matmultiply(modelMatrix,FallInfo.avatar2collision,modelMatrix);
2060 if(FallInfo()->walking)
2061 {
2062 /* mesh method */
2063 int i;
2064 double disp;
2065 struct point_XYZ n;
2066 struct point_XYZ a,b, dispv, radscale, maxdispv = { .x = 0,.y = 0,.z = 0 };
2067 double maxdisp = 0;
2068
2069 if(!p->collisionCylinder.npts)
2070 collisionCylinder_init(node);
2071 radscale.x = radscale.z = node->radius;
2072 radscale.y = node->height;
2073 scale_to_matrix (modelMatrix, &radscale);
2074 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
2075 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
2076 if( !avatarCollisionVolumeIntersectMBB(modelMatrix, p->collisionCylinder.smin,p->collisionCylinder.smax)) return;
2077
2078 for(i=0;i<p->collisionCylinder.npts;i++)
2079 transform(&p->collisionCylinder.tpts[i],&p->collisionCylinder.pts[i],modelMatrix);
2080
2081 for(i = 0; i < p->collisionCylinder.ntris; i++)
2082 {
2083 struct point_XYZ pts[3];
2084 pts[0] = p->collisionCylinder.tpts[p->collisionCylinder.tris[i][0]];
2085 pts[1] = p->collisionCylinder.tpts[p->collisionCylinder.tris[i][1]];
2086 pts[2] = p->collisionCylinder.tpts[p->collisionCylinder.tris[i][2]];
2087 /* compute normal - could compute once in shapespace then transform */
2088 VECDIFF(pts[1],pts[0],a);
2089 VECDIFF(pts[2],pts[1],b); /* or [2] [0] direction not sensitive for some functions */
2090 veccross(&n,a,b); /* 6 multiplies */
2091 vecnormal(&n,&n);
2092 dispv = get_poly_disp_2(pts,3,n);
2093 disp = vecdot(&dispv,&dispv);
2094 if( (disp > FLOAT_TOLERANCE) && (disp > maxdisp) ){
2095 maxdisp = disp;
2096 maxdispv = dispv;
2097 }
2098 }
2099 for(i = 0; i < p->collisionCylinder.nquads; i++)
2100 {
2101 struct point_XYZ pts[4];
2102 pts[0] = p->collisionCylinder.tpts[p->collisionCylinder.quads[i][0]];
2103 pts[1] = p->collisionCylinder.tpts[p->collisionCylinder.quads[i][1]];
2104 pts[2] = p->collisionCylinder.tpts[p->collisionCylinder.quads[i][2]];
2105 pts[3] = p->collisionCylinder.tpts[p->collisionCylinder.quads[i][3]];
2106 /* compute normal - could compute once in shapespace then transform */
2107 VECDIFF(pts[1],pts[0],a);
2108 VECDIFF(pts[2],pts[1],b); /* or [2] [0] direction not sensitive for some functions */
2109 veccross(&n,a,b); /* 6 multiplies */
2110 vecnormal(&n,&n);
2111 dispv = get_poly_disp_2(pts,4,n);
2112 disp = vecdot(&dispv,&dispv);
2113 if( (disp > FLOAT_TOLERANCE) && (disp > maxdisp) ){
2114 maxdisp = disp;
2115 maxdispv = dispv;
2116 }
2117 }
2118 delta = maxdispv;
2119 }else{
2120 /* values for rapid test */
2121 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
2122 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
2123 t_orig.x = modelMatrix[12];
2124 t_orig.y = modelMatrix[13];
2125 t_orig.z = modelMatrix[14];
2126 scale = pow(det3x3(modelMatrix),1./3.);
2127 if(!fast_ycylinder_cone_intersect(abottom,atop,awidth,t_orig,scale*h,scale*r)) return;
2128 /* get transformed box edges and position */
2129 transform(&iv,&iv,modelMatrix);
2130 transform(&jv,&jv,modelMatrix);
2131 delta = cylinder_disp(abottom,atop,astep,awidth,jv,iv,scale*r);
2132 }
2133 vecscale(&delta,&delta,-1);
2134 accumulate_disp(CollisionInfo(),delta);
2135 #ifdef RENDERVERBOSE
2136 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.))
2137 printf("COLLISION_CYL: (%f %f %f) (%f %f %f)\n",
2138 iv.x, iv.y, iv.z,
2139 delta.x, delta.y, delta.z
2140 );
2141 if((fabs(delta.x != 0.) || fabs(delta.y != 0.) || fabs(delta.z) != 0.))
2142 printf("iv=(%f %f %f) jv=(%f %f %f) bR=%f\n",
2143 iv.x, iv.y, iv.z,
2144 jv.x, jv.y, jv.z,
2145 scale*r
2146 );
2147 #endif
2148}
2149
2150void collide_Extrusion (struct X3D_Extrusion *node) {
2151 GLDOUBLE modelMatrix[16];
2152 struct point_XYZ delta = { .x = 0,.y = 0,.z = 0 };
2153 #ifdef RENDERVERBOSE
2154 struct point_XYZ t_orig = { .x = 0,.y = 0,.z = 0 };
2155 #endif
2156 struct X3D_PolyRep *pr;
2157 prflags flags = 0;
2158 int change = 0;
2159
2160 /* JAS - first pass, intern is probably zero */
2161 if (node->_intern == NULL || node->_intern->itype != 2) return;
2162 pr = (struct X3D_PolyRep*) node->_intern;
2163 /* JAS - no triangles in this text structure */
2164 if (pr->ntri == 0) return;
2165
2166 /*save changed state.*/
2167 change = pr->irep_change;
2168 //COMPILE_POLY_IF_REQUIRED(NULL, NULL, NULL, NULL, NULL)
2169 if (!compile_poly_if_required(node, NULL, NULL, NULL, NULL, NULL))return;
2170 if (pr->actualCoord == NULL) return; //not compiled yet
2171
2172 pr->irep_change = change;
2173 /*restore changes state, invalidates compile_polyrep work done, so it can be done
2174 correclty in the RENDER pass */
2175
2176 if(!node->solid) {
2177 flags = flags | PR_DOUBLESIDED;
2178 }
2179 /* printf("_PolyRep = %d\n",node->_intern);*/
2180 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
2181
2182 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
2183 //dug9july2011 matmultiply(modelMatrix,FallInfo()->avatar2collision,modelMatrix);
2184
2185 #ifdef RENDERVERBOSE
2186 t_orig.x = modelMatrix[12];
2187 t_orig.y = modelMatrix[13];
2188 t_orig.z = modelMatrix[14];
2189 #endif
2190
2191 if(!avatarCollisionVolumeIntersectMBBf(modelMatrix, pr->minVals, pr->maxVals))return;
2192 delta = polyrep_disp2(pr,modelMatrix,flags);
2193 vecscale(&delta,&delta,-1);
2194 accumulate_disp(CollisionInfo(),delta);
2195
2196#ifdef RENDERVERBOSE
2197 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.)) {
2198/* printmatrix(modelMatrix);*/
2199 fprintf(stderr,"COLLISION_EXT: (%f %f %f) (%f %f %f)\n",
2200 t_orig.x, t_orig.y, t_orig.z,
2201 delta.x, delta.y, delta.z
2202 );
2203 }
2204#endif
2205}
2206
2207int elevationgrid_disp2(struct X3D_ElevationGrid *node, double *mat2collision){
2208 // general polyrep collision does a few ugly things:
2209 // 1. transforms all the points into collision/avatar space
2210 // 2. iterates over all the triangles (a few times)
2211 // this elevationGrid optimization will take a few shortcuts:
2212 // a) only do gravity, if enabled
2213 // b) transform avatar gravity vector into grid space
2214 // c) use elevationGrid rows, columns, xspace,zspace, to look up heights by avatar position xz in grid space
2215 // d) see if its a collision
2216 // e) update the climing / falling parameters (and skip wall penetration detection and bump collision testing)
2217 // if for some reason it can't handle it, it returns -1, and then the generic collision can be called
2218 struct sFallInfo *fi;
2219 int hit,i;
2220
2221 hit = -1; //0 handled, and no colliision, 1=handled and collision, -1=not handled (not woaking, or gravity vector not perpendicular to grid)
2222 fi = FallInfo();
2223
2224 if(fi->walking)
2225 {
2226 struct point_XYZ result;
2227 float centerf[3],bottomf[3];
2228 double centerd[3], bottomd[3], spined[3], vertvecd[3];
2229 double cosine;
2230 double tmin[3],tmax[3]; /* MBB for facet */
2231 struct sNaviInfo *naviinfo;
2232 GLDOUBLE awidth, atop, abottom, astep;
2233 ttglobal tg = gglobal();
2234
2235 double mat2shape[16];
2236 matinverseAFFINE(mat2shape,mat2collision);
2237
2238 naviinfo = (struct sNaviInfo *)tg->Bindable.naviinfo;
2239 //awidth = naviinfo->width; /*avatar width*/
2240 //atop = naviinfo->width; /*top of avatar (relative to eyepoint)*/
2241 abottom = -naviinfo->height; /*bottom of avatar (relative to eyepoint)*/
2242 //astep = -naviinfo->height+naviinfo->step;
2243
2244 //set up 2 points to represent avatar walk vector, in avatar space
2245 vecsetd(centerd,0.0,0.0,0.0);
2246 vecsetd(bottomd,0.0,abottom,0.0);
2247 //transform those points to shape space
2248 transformAFFINEd(bottomd,bottomd,mat2shape);
2249 transformAFFINEd(centerd,centerd,mat2shape);
2250 //see if avatar's spine vector is 'vertical' in elevationGrid space
2251 vecsetd(vertvecd,0.0,-1.0,0.0);
2252 vecdifd(spined,centerd,bottomd);
2253 cosine = vecdotd(spined,vertvecd);
2254 double2float(bottomf,bottomd,3);
2255 //printf("a");
2256 if(fabs(cosine) > .65){
2257 int inside;
2258 //yes, primarily vertical vector, can use 2D math on 'bottom'
2259 inside = bottomf[0] <= node->_extent[0] && bottomf[0] >= node->_extent[1];
2260 inside &= bottomf[2] <= node->_extent[4] && bottomf[2] >= node->_extent[5];
2261 //printf("b");
2262 if(inside){
2263 double spinelength, vcenterd[3];
2264 float x,z,cx,cz, deltah, gridpointf[3];
2265 //printf("c");
2266 hit = 0;
2267 spinelength = veclengthd(spined);
2268 //make avatar center in vertical space
2269 vecscaled(vcenterd,vertvecd,spinelength);
2270 vecaddd(centerd,bottomd,vcenterd);
2271 double2float(centerf,centerd,3);
2272 //see if grid height is below, between or above avatar spine
2273 x = bottomf[0];
2274 z = bottomf[2];
2275 //node->xDimension
2276 // z h2 h3
2277 // ^ h0 h1
2278 // |-->x
2279 //(ix,iz)
2280 float hh[4],gridheight;
2281 int i0,i1,i2,i3, ix, iz;
2282 ix = (int)(x/node->xSpacing);
2283 iz = (int)(z/node->zSpacing);
2284 i0 = iz * node->xDimension + ix;
2285 i1 = i0 + 1;
2286 i2 = i0 + node->xDimension;
2287 i3 = i2 + 1;
2288 hh[0] = node->height.p[i0];
2289 hh[1] = node->height.p[i1];
2290 hh[2] = node->height.p[i2];
2291 hh[3] = node->height.p[i3];
2292 //normalize cell x and z
2293 cx = (x - ix*node->xSpacing)/node->xSpacing;
2294 cz = (z - iz*node->zSpacing)/node->zSpacing;
2295 //height interpolation by finite elements > bilinear interpolotion of height
2296 // (could do cubic using 3x3 chunks)
2297 gridheight = hh[0]*(1.0f - cz)*(1.0f - cx)
2298 + hh[1]*(1.0f - cz)*cx
2299 + hh[2]*cz*(1.0f - cx)
2300 + hh[3]*cz*cx;
2301 vecset3f(gridpointf,x,gridheight,z);
2302
2303 double gridpoint[3];
2304 float2double(gridpoint,gridpointf,3);
2305 transformAFFINEd(gridpoint,gridpoint,mat2collision);
2306 //printf("_");
2307 hit = 0;
2308
2309 // scraped from:
2310 // accumulateFallingClimbing(abottom,atop,astep,p,num,n,tmin,tmax); //y1, y2, p, num, n);
2311
2312 double hhh = gridpoint[1];
2313 double hhbelowfoot = hhh - abottom;
2314 if( hhh < 0.0 )
2315 {
2316 /* falling */
2317 if( hhh < abottom && hhh > -fi->fallHeight)
2318 {
2319 //printf("v");
2320 /* FALLING */
2321 if(fi->hits ==0)
2322 fi->hfall = hhbelowfoot; //hh - y1;
2323 else
2324 if(hhbelowfoot > fi->hfall) fi->hfall = hhbelowfoot; //hh - y1;
2325 fi->hits++;
2326 fi->isFall = 1;
2327 }else{
2328 //printf("~");
2329 /* regular below / nadir collision - below avatar center but above avatar's feet which are at 0.0 - avatar.height*/
2330 if( hhh >= abottom ) /* && hh <= (y1-ystep) ) //no step height implementation */
2331 {
2332 /* CLIMBING. handled elsewhere for displacements, except annihilates any fall*/
2333 fi->canFall = 0;
2334
2335 if( fi->isClimb == 0 )
2336 fi->hclimb = hhbelowfoot; //hh - y1;
2337 else
2338 fi->hclimb = DOUBLE_MAX(fi->hclimb,hhbelowfoot);
2339 fi->isClimb = 1;
2340 }
2341 }
2342 }
2343 double head = 0.0;
2344 double hhabovehead = hhh - head;
2345 if( hhabovehead > 0.0 )
2346 {
2347 /* climbing from undergound */
2348 if( hhabovehead < fi->climbHeight)
2349 {
2350 //printf("^");
2351 /* CLIMBING */
2352 fi->canFall = 0;
2353
2354 if( fi->isClimb == 0 )
2355 fi->hclimb = hhabovehead + abottom; //hh - y1;
2356 else
2357 fi->hclimb = DOUBLE_MAX(fi->hclimb,hhabovehead + abottom);
2358 fi->isClimb = 1;
2359 }
2360 }
2361 }
2362 }
2363 }
2364
2365 return hit;
2366}
2367
2368void collide_ElevationGrid(struct X3D_ElevationGrid *node){
2369 double modelMatrix[16];
2370 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
2371 /*
2372 For examine and fly navigation modes, there's no gravity direction.
2373 Avatar collision volume is aligned to avatar and is spherical and
2374 symmetrically directional. This is the simple case. Specifications say for
2375 walk navigation mode gravity vector is down {0,-1,0} with respect to (wrt) the
2376 currently bound viewpoint, not including the viewpoint's orientation
2377 field and not including avatar navigation/tilt away from its parent
2378 bound-viewpoint pose. When you collide in walk mode, the avatar collision
2379 volume is aligned to bound-viewpoint. This is a slightly more complex case.
2380 To generalize the 2 cases, some Definitions:
2381 Spaces:
2382 Avatar space
2383 - gravity is avatar-down
2384 - Avatar is at {0,0,0} and +Y up is as you see up in your current view,
2385 +Z aft and +X to the right
2386 BoundViewpoint space - currently bound viewpoint (transform parent to avatar)
2387 BVVA space - Bound-Viewpoint-Vertically-aligned Avatar-centric
2388 - same as Avatar space with avatar at {0,0,0} except tilted so that gravity
2389 is in the direction of down {0,-1,0} for the currently bound viewpoint
2390 (instead for avatar), as per specs
2391 - gravity is bound-viewpoint down
2392 Collision space - Fly/Examine mode: Avatar space. Walk mode: BVVA space
2393 - the avatar collision volume - height, stepsize, width - are defined for
2394 collision space and axes aligned with it
2395 Shape space - raw shape <Coordinate> space
2396 Transforms:
2397 Bound2Avatar - transforms from BoundViewpoint space to Avatar space
2398 - computed from viewer.quat,viewer.pos
2399 Avatar2BVVA,BVVA2Avatar
2400 - computed from downvector in BoundViewpoint space transformed
2401 via Bound2Avatar into Avatar space
2402 - constant for a frame, computable once navigation mode and
2403 avatar pose is know for the frame
2404 Avatar2Collision - Fly/Examine: Identity, Walk: Avatar2BVVA
2405 Collision2Avatar - Fly/Examine: Identity, Walk: BVVA2Avatar
2406 Shape2Collision - Fly/Examine: modelMatrix, Walk: Avatar2BVVA*modelMatrix
2407
2408 goal: transform shape geometry into Collision space. (The avatar collision
2409 volume is by definition in collision space.)
2410 Do some collisions between shape and avatar.
2411 Transform collision correction deltas from collision space to avatar space,
2412 apply deltas to avatar position.
2413 implementation:
2414 transform shape into collision space - Fly/Examine:modelMatrix
2415 or Walk:(Avatar2BVVA * modelMatrix)
2416 transform collision correction deltas from collision space to avatar space:
2417 - done in Mainloop.c get_collisionoffset() with FallInfo.collision2avatar
2418 */
2419
2420 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
2421
2422 int ihit = -1;
2423 if(node->_nodeType == NODE_ElevationGrid){
2424 float delta3f[3];
2425 ihit = elevationgrid_disp2((struct X3D_ElevationGrid*)node,modelMatrix);
2426 //if(ihit==0) printf("0");
2427 //if(ihit==1) printf("1");
2428 //if(ihit==-1) printf(".");
2429 }
2430 if(0) if(ihit == -1){
2431 //above couldn't handle it, thunking to generic
2432 //problem: if its a really dense grid, the framerate plummets
2433 collide_genericfaceset ((struct X3D_IndexedFaceSet *)node );
2434 }
2435
2436}
2437
2438void rendray_Sphere (struct X3D_Sphere *node) {
2439 struct point_XYZ t_r1,t_r2;
2440 float r = node->radius;
2441 /* Center is at zero. t_r1 to t_r2 and t_r1 to zero are the vecs */
2442
2443 float tr1sq;// = (float) VECSQ(t_r1);
2444 struct point_XYZ dr2r1;
2445 float dlen;
2446 float a,b,c,disc;
2447 //VECCOPY(t_r1,tg->RenderFuncs.t_r1);
2448 //VECCOPY(t_r2,tg->RenderFuncs.t_r2);
2449 get_current_ray(&t_r1, &t_r2);
2450
2451 tr1sq = (float) VECSQ(t_r1);
2452
2453 VECDIFF(t_r2,t_r1,dr2r1);
2454 dlen = (float) VECSQ(dr2r1);
2455
2456 a = dlen; /* tr1sq - 2*tr1tr2 + tr2sq; */
2457 b = 2.0f*((float)VECPT(dr2r1, t_r1));
2458 c = tr1sq - r*r;
2459
2460 disc = b*b - 4*a*c; /* The discriminant */
2461
2462 if(disc > 0) { /* HITS */
2463 float q ;
2464 float sol1 ;
2465 float sol2 ;
2466 float cx,cy,cz;
2467 q = (float) sqrt(disc);
2468 /* q = (-b+(b>0)?q:-q)/2; */
2469 sol1 = (-b+q)/(2*a);
2470 sol2 = (-b-q)/(2*a);
2471 /*
2472 printf("SPHSOL0: (%f %f %f) (%f %f %f)\n",
2473 t_r1.x, t_r1.y, t_r1.z, t_r2.x, t_r2.y, t_r2.z);
2474 printf("SPHSOL: (%f %f %f) (%f) (%f %f) (%f) (%f %f)\n",
2475 tr1sq, tr2sq, tr1tr2, a, b, c, und, sol1, sol2);
2476 */
2477 cx = (float) MRATX(sol1);
2478 cy = (float) MRATY(sol1);
2479 cz = (float) MRATZ(sol1);
2480 rayhit(sol1, cx,cy,cz, cx/r,cy/r,cz/r, -1,-1, "sphere 0");
2481 cx = (float) MRATX(sol2);
2482 cy = (float) MRATY(sol2);
2483 cz = (float) MRATZ(sol2);
2484 rayhit(sol2, cx,cy,cz, cx/r,cy/r,cz/r, -1,-1, "sphere 1");
2485 }
2486
2487}
2488
2489
2490void rendray_Box (struct X3D_Box *node) {
2491 float x,y,z;
2492 struct point_XYZ t_r1,t_r2;
2493
2494 //VECCOPY(t_r1,tg->RenderFuncs.t_r1);
2495 //VECCOPY(t_r2,tg->RenderFuncs.t_r2);
2496
2497 get_current_ray(&t_r1, &t_r2);
2498
2499 x = ((node->size).c[0])/2;
2500 y = ((node->size).c[1])/2;
2501 z = ((node->size).c[2])/2;
2502 /* 1. x=const-plane faces? */
2503 if(!XEQ) {
2504 float xrat0 = (float) XRAT(x);
2505 float xrat1 = (float) XRAT(-x);
2506 #ifdef RENDERVERBOSE
2507 printf("!XEQ: %f %f\n",xrat0,xrat1);
2508 #endif
2509
2510 if(TRAT(xrat0)) {
2511 float cy = (float) MRATY(xrat0);
2512 #ifdef RENDERVERBOSE
2513 printf("TRok: %f\n",cy);
2514 #endif
2515
2516 if(cy >= -y && cy < y) {
2517 float cz = (float) MRATZ(xrat0);
2518 #ifdef RENDERVERBOSE
2519 printf("cyok: %f\n",cz);
2520 #endif
2521
2522 if(cz >= -z && cz < z) {
2523 #ifdef RENDERVERBOSE
2524 printf("czok:\n");
2525 #endif
2526
2527 rayhit(xrat0, x,cy,cz, 1,0,0, -1,-1, "cube x0");
2528 }
2529 }
2530 }
2531 if(TRAT(xrat1)) {
2532 float cy = (float) MRATY(xrat1);
2533 if(cy >= -y && cy < y) {
2534 float cz = (float) MRATZ(xrat1);
2535 if(cz >= -z && cz < z) {
2536 rayhit(xrat1, -x,cy,cz, -1,0,0, -1,-1, "cube x1");
2537 }
2538 }
2539 }
2540 }
2541 if(!YEQ) {
2542 float yrat0 = (float) YRAT(y);
2543 float yrat1 = (float) YRAT(-y);
2544 if(TRAT(yrat0)) {
2545 float cx = (float) MRATX(yrat0);
2546 if(cx >= -x && cx < x) {
2547 float cz = (float) MRATZ(yrat0);
2548 if(cz >= -z && cz < z) {
2549 rayhit(yrat0, cx,y,cz, 0,1,0, -1,-1, "cube y0");
2550 }
2551 }
2552 }
2553 if(TRAT(yrat1)) {
2554 float cx = (float) MRATX(yrat1);
2555 if(cx >= -x && cx < x) {
2556 float cz = (float) MRATZ(yrat1);
2557 if(cz >= -z && cz < z) {
2558 rayhit(yrat1, cx,-y,cz, 0,-1,0, -1,-1, "cube y1");
2559 }
2560 }
2561 }
2562 }
2563 if(!ZEQ) {
2564 float zrat0 = (float) ZRAT(z);
2565 float zrat1 = (float) ZRAT(-z);
2566 if(TRAT(zrat0)) {
2567 float cx = (float) MRATX(zrat0);
2568 if(cx >= -x && cx < x) {
2569 float cy = (float) MRATY(zrat0);
2570 if(cy >= -y && cy < y) {
2571 rayhit(zrat0, cx,cy,z, 0,0,1, -1,-1,"cube z0");
2572 }
2573 }
2574 }
2575 if(TRAT(zrat1)) {
2576 float cx = (float) MRATX(zrat1);
2577 if(cx >= -x && cx < x) {
2578 float cy = (float) MRATY(zrat1);
2579 if(cy >= -y && cy < y) {
2580 rayhit(zrat1, cx,cy,-z, 0,0,-1, -1,-1,"cube z1");
2581 }
2582 }
2583 }
2584 }
2585}
2586
2587
2588void rendray_Cylinder (struct X3D_Cylinder *node) {
2589
2590 float h,r,y;
2591 struct point_XYZ t_r1,t_r2;
2592 //VECCOPY(t_r1,tg->RenderFuncs.t_r1);
2593 //VECCOPY(t_r2,tg->RenderFuncs.t_r2);
2594 get_current_ray(&t_r1, &t_r2);
2595
2596 h = (node->height) /*cget*//2; /* pos and neg dir. */
2597 r = (node->radius) /*cget*/;
2598 y = h;
2599 /* Caps */
2600 if(!YEQ) {
2601 float yrat0 = (float) YRAT(y);
2602 float yrat1 = (float) YRAT(-y);
2603 if(TRAT(yrat0)) {
2604 float cx = (float) MRATX(yrat0);
2605 float cz = (float) MRATZ(yrat0);
2606 if(r*r > cx*cx+cz*cz) {
2607 rayhit(yrat0, cx,y,cz, 0,1,0, -1,-1, "cylcap 0");
2608 }
2609 }
2610 if(TRAT(yrat1)) {
2611 float cx = (float) MRATX(yrat1);
2612 float cz = (float) MRATZ(yrat1);
2613 if(r*r > cx*cx+cz*cz) {
2614 rayhit(yrat1, cx,-y,cz, 0,-1,0, -1,-1, "cylcap 1");
2615 }
2616 }
2617 }
2618 /* Body -- do same as for sphere, except no y axis in distance */
2619 //if((!XEQ) && (!ZEQ)) //can't pick with ortho on initial load
2620 //can pick with ortho on initial load: if(!(XEQ && ZEQ))
2621 if(!(XEQ && ZEQ)){
2622 float dx = (float)(t_r2.x-t_r1.x);
2623 float dz = (float)(t_r2.z-t_r1.z);
2624 float a = (float)(dx*dx + dz*dz);
2625 float b = (float) (2*(dx * t_r1.x + dz * t_r1.z));
2626 float c = (float) (t_r1.x * t_r1.x + t_r1.z * t_r1.z - r*r);
2627 float und;
2628 b /= a; c /= a;
2629 und = b*b - 4*c;
2630 if(und > 0) { /* HITS the infinite cylinder */
2631 float sol1 = (-b+(float) sqrt(und))/2;
2632 float sol2 = (-b-(float) sqrt(und))/2;
2633 float cy,cx,cz;
2634 cy = (float) MRATY(sol1);
2635 if(cy > -h && cy < h) {
2636 cx = (float) MRATX(sol1);
2637 cz = (float) MRATZ(sol1);
2638 rayhit(sol1, cx,cy,cz, cx/r,0,cz/r, -1,-1, "cylside 1");
2639 }
2640 cy = (float) MRATY(sol2);
2641 if(cy > -h && cy < h) {
2642 cx = (float) MRATX(sol2);
2643 cz = (float) MRATZ(sol2);
2644 rayhit(sol2, cx,cy,cz, cx/r,0,cz/r, -1,-1, "cylside 2");
2645 }
2646 }
2647 }
2648}
2649
2650void rendray_Cone (struct X3D_Cone *node) {
2651 float h,y,r,dx,dy,dz,a,b,c,tmp,und;
2652 struct point_XYZ t_r1,t_r2;
2653
2654 // VECCOPY(t_r1,tg->RenderFuncs.t_r1);
2655 // VECCOPY(t_r2,tg->RenderFuncs.t_r2);
2656
2657 get_current_ray(&t_r1, &t_r2);
2658
2659 h = (node->height) /*cget*//2; /* pos and neg dir. */
2660 y = h;
2661 r = (node->bottomRadius) /*cget*/;
2662 dx = (float) (t_r2.x-t_r1.x);
2663 dz = (float) (t_r2.z-t_r1.z);
2664 dy = (float) (t_r2.y-t_r1.y);
2665 a = dx*dx + dz*dz - (r*r*dy*dy/(2*h*2*h));
2666 b = (float) (2*(dx*t_r1.x + dz*t_r1.z) +
2667 2*r*r*dy/(2*h)*(0.5-t_r1.y/(2*h)));
2668 tmp = (float)((0.5-t_r1.y/(2*h)));
2669 c = (float)(t_r1.x * t_r1.x + t_r1.z * t_r1.z)
2670 - r*r*tmp*tmp;
2671
2672 b /= a; c /= a;
2673 und = b*b - 4*c;
2674 /*
2675 printf("CONSOL0: (%f %f %f) (%f %f %f)\n",
2676 t_r1.x, t_r1.y, t_r1.z, t_r2.x, t_r2.y, t_r2.z);
2677 printf("CONSOL: (%f %f %f) (%f) (%f %f) (%f)\n",
2678 dx, dy, dz, a, b, c, und);
2679 */
2680 if(und > 0) { /* HITS the infinite cylinder */
2681 float sol1 = (-b+(float)sqrt(und))/2;
2682 float sol2 = (-b-(float)sqrt(und))/2;
2683 float cy,cx,cz;
2684 cy = (float)MRATY(sol1);
2685 if(cy > -h && cy < h) {
2686 cx = (float)MRATX(sol1);
2687 cz = (float)MRATZ(sol1);
2688 /* XXX Normal */
2689 rayhit(sol1, cx,cy,cz, cx/r,0,cz/r, -1,-1, "conside 1");
2690 }
2691 cy = (float) MRATY(sol2);
2692 if(cy > -h && cy < h) {
2693 cx = (float) MRATX(sol2);
2694 cz = (float) MRATZ(sol2);
2695 rayhit(sol2, cx,cy,cz, cx/r,0,cz/r, -1,-1, "conside 2");
2696 }
2697 /*
2698 printf("CONSOLV: (%f %f) (%f %f)\n", sol1, sol2,cy0,cy);
2699 */
2700 }
2701 if(!YEQ) {
2702 float yrat0 = (float) YRAT(-y);
2703 if(TRAT(yrat0)) {
2704 float cx = (float) MRATX(yrat0);
2705 float cz = (float) MRATZ(yrat0);
2706 if(r*r > cx*cx + cz*cz) {
2707 rayhit(yrat0, cx, -y, cz, 0, -1, 0, -1, -1, "conbot");
2708 }
2709 }
2710 }
2711}
2712
2713// TEAPOT sept 2016
2714// http://www.web3d.org/x3d/content/examples/Basic/ExperimentalBinaryCompression/Teapot.html
2715// https://www.sjbaker.org/wiki/index.php?title=The_History_of_The_Teapot#Images_of_the_Complete_Dataset
2716// tests teapot-no_shaders.wrl
2717
2718static struct X3D_IndexedFaceSet *teapotifs = NULL;
2719static struct X3D_Coordinate *teapot_coord;
2720static int teapot_coordindex_p [] = {1,2,3,4,-1,5,1,4,6,-1,7,5,6,8,-1,9,7,8,10,-1,11,9,10,12,-1,4,3,13,14,-1,6,4,14,15,-1,8,6,15,16,-1,10,8,16,17,-1,12,10,17,18,-1,14,13,19,20,-1,15,14,20,21,-1,16,15,21,22,-1,17,16,22,23,-1,18,17,23,24,-1,20,19,25,26,-1,21,20,26,27,-1,22,21,27,28,-1,23,22,28,29,-1,24,23,29,30,-1,26,25,31,32,-1,27,26,32,33,-1,28,27,33,34,-1,29,28,34,35,-1,30,29,35,36,-1,32,31,37,38,-1,33,32,38,39,-1,34,33,39,40,-1,35,34,40,41,-1,36,35,41,42,-1,38,37,43,44,-1,39,38,44,45,-1,40,39,45,46,-1,41,40,46,47,-1,42,41,47,48,-1,44,43,49,50,-1,45,44,50,51,-1,46,45,51,52,-1,47,46,52,53,-1,48,47,53,54,-1,50,49,55,56,-1,51,50,56,57,-1,52,51,57,58,-1,53,52,58,59,-1,54,53,59,60,-1,56,55,61,62,-1,57,56,62,63,-1,58,57,63,64,-1,59,58,64,65,-1,60,59,65,66,-1,62,61,67,68,-1,63,62,68,69,-1,64,63,69,70,-1,65,64,70,71,-1,66,65,71,72,-1,68,67,2,1,-1,69,68,1,5,-1,70,69,5,7,-1,71,70,7,9,-1,72,71,9,11,-1,73,11,12,74,-1,75,73,74,76,-1,77,75,76,78,-1,79,77,78,80,-1,81,79,80,82,-1,83,81,82,84,-1,74,12,18,85,-1,76,74,85,86,-1,78,76,86,87,-1,80,78,87,88,-1,82,80,88,89,-1,84,82,89,90,-1,85,18,24,91,-1,86,85,91,92,-1,87,86,92,93,-1,88,87,93,94,-1,89,88,94,95,-1,90,89,95,96,-1,91,24,30,97,-1,92,91,97,98,-1,93,92,98,99,-1,94,93,99,100,-1,95,94,100,101,-1,96,95,101,102,-1,97,30,36,103,-1,98,97,103,104,-1,99,98,104,105,-1,100,99,105,106,-1,101,100,106,107,-1,102,101,107,108,-1,103,36,42,109,-1,104,103,109,110,-1,105,104,110,111,-1,106,105,111,112,-1,107,106,112,113,-1,108,107,113,114,-1,109,42,48,115,-1,110,109,115,116,-1,111,110,116,117,-1,112,111,117,118,-1,113,112,118,119,-1,114,113,119,120,-1,115,48,54,121,-1,116,115,121,122,-1,117,116,122,123,-1,118,117,123,124,-1,119,118,124,125,-1,120,119,125,126,-1,121,54,60,127,-1,122,121,127,128,-1,123,122,128,129,-1,124,123,129,130,-1,125,124,130,131,-1,126,125,131,132,-1,127,60,66,133,-1,128,127,133,134,-1,129,128,134,135,-1,130,129,135,136,-1,131,130,136,137,-1,132,131,137,138,-1,133,66,72,139,-1,134,133,139,140,-1,135,134,140,141,-1,136,135,141,142,-1,137,136,142,143,-1,138,137,143,144,-1,139,72,11,73,-1,140,139,73,75,-1,141,140,75,77,-1,142,141,77,79,-1,143,142,79,81,-1,144,143,81,83,-1,120,126,132,-1,120,132,138,-1,120,138,144,-1,120,144,83,-1,120,83,84,-1,120,84,90,-1,120,90,96,-1,120,96,102,-1,120,102,108,-1,120,108,114,-1,2,154,145,3,-1,3,145,146,13,-1,13,147,148,19,-1,19,149,877,25,-1,25,877,150,31,-1,31,150,151,37,-1,37,151,43,-1,43,1180,155,49,-1,49,155,1181,55,-1,55,152,153,61,-1,61,156,67,-1,67,154,2,-1,147,13,146,-1,149,19,148,-1,1180,43,151,-1,55,1181,152,-1,61,153,156,-1,67,156,154,-1,157,158,159,160,-1,161,157,160,162,-1,163,161,162,164,-1,165,163,164,166,-1,167,165,166,168,-1,160,159,169,170,-1,162,160,170,171,-1,164,162,171,172,-1,166,164,172,173,-1,168,166,173,174,-1,170,169,175,176,-1,171,170,176,177,-1,172,171,177,178,-1,173,172,178,179,-1,174,173,179,180,-1,176,175,181,182,-1,177,176,182,183,-1,178,177,183,184,-1,179,178,184,185,-1,180,179,185,186,-1,182,181,187,188,-1,183,182,188,189,-1,184,183,189,190,-1,185,184,190,191,-1,186,185,191,192,-1,188,187,193,194,-1,189,188,194,195,-1,190,189,195,196,-1,191,190,196,197,-1,192,191,197,198,-1,194,193,199,200,-1,195,194,200,201,-1,196,195,201,202,-1,197,196,202,203,-1,198,197,203,204,-1,200,199,205,206,-1,201,200,206,207,-1,202,201,207,208,-1,203,202,208,209,-1,204,203,209,210,-1,206,205,211,212,-1,207,206,212,213,-1,208,207,213,214,-1,209,208,214,215,-1,210,209,215,216,-1,212,211,217,218,-1,213,212,218,219,-1,214,213,219,220,-1,215,214,220,221,-1,216,215,221,222,-1,218,217,223,224,-1,219,218,224,225,-1,220,219,225,226,-1,221,220,226,227,-1,222,221,227,228,-1,224,223,158,157,-1,225,224,157,161,-1,226,225,161,163,-1,227,226,163,165,-1,228,227,165,167,-1,229,167,168,230,-1,231,229,230,232,-1,233,231,232,234,-1,235,233,234,236,-1,237,235,236,238,-1,230,168,174,239,-1,232,230,239,240,-1,234,232,240,241,-1,236,234,241,242,-1,238,236,242,243,-1,239,174,180,244,-1,240,239,244,245,-1,241,240,245,246,-1,242,241,246,247,-1,243,242,247,248,-1,244,180,186,249,-1,245,244,249,250,-1,246,245,250,251,-1,247,246,251,252,-1,248,247,252,253,-1,249,186,192,254,-1,250,249,254,255,-1,251,250,255,256,-1,252,251,256,257,-1,253,252,257,258,-1,254,192,198,259,-1,255,254,259,260,-1,256,255,260,261,-1,257,256,261,262,-1,258,257,262,263,-1,259,198,204,264,-1,260,259,264,265,-1,261,260,265,266,-1,262,261,266,267,-1,263,262,267,268,-1,264,204,210,269,-1,265,264,269,270,-1,266,265,270,271,-1,267,266,271,272,-1,268,267,272,273,-1,269,210,216,274,-1,270,269,274,275,-1,271,270,275,276,-1,272,271,276,277,-1,273,272,277,278,-1,274,216,222,279,-1,275,274,279,280,-1,276,275,280,281,-1,277,276,281,282,-1,278,277,282,283,-1,279,222,228,284,-1,280,279,284,285,-1,281,280,285,286,-1,282,281,286,287,-1,283,282,287,288,-1,284,228,167,229,-1,285,284,229,231,-1,286,285,231,233,-1,287,286,233,235,-1,288,287,235,237,-1,158,289,290,159,-1,159,290,291,169,-1,169,292,175,-1,175,292,293,181,-1,181,293,294,187,-1,187,294,295,193,-1,193,295,199,-1,199,296,297,205,-1,205,297,298,211,-1,211,298,217,-1,217,299,300,223,-1,223,301,289,158,-1,1189,238,243,1182,-1,1182,243,248,1183,-1,1183,248,253,1184,-1,1184,253,258,-1,302,258,263,1185,-1,1185,263,268,-1,1188,268,273,-1,1188,273,278,1186,-1,1186,278,283,303,-1,1187,283,288,-1,305,288,237,304,-1,169,291,292,-1,296,199,295,-1,299,217,298,-1,223,300,301,-1,258,302,1184,-1,268,876,1185,-1,876,268,1188,-1,303,283,1187,-1,1187,288,305,-1,306,307,308,309,-1,310,306,309,311,-1,312,310,311,313,-1,314,312,313,315,-1,316,314,315,317,-1,318,316,317,319,-1,309,308,320,321,-1,311,309,321,322,-1,313,311,322,323,-1,315,313,323,324,-1,317,315,324,325,-1,319,317,325,326,-1,321,320,327,328,-1,322,321,328,329,-1,323,322,329,330,-1,324,323,330,331,-1,325,324,331,332,-1,326,325,332,333,-1,328,327,334,335,-1,329,328,335,336,-1,330,329,336,337,-1,331,330,337,338,-1,332,331,338,339,-1,333,332,339,340,-1,335,334,341,342,-1,336,335,342,343,-1,337,336,343,344,-1,338,337,344,345,-1,339,338,345,346,-1,340,339,346,347,-1,342,341,348,349,-1,343,342,349,350,-1,344,343,350,351,-1,345,344,351,352,-1,346,345,352,353,-1,347,346,353,354,-1,349,348,355,356,-1,350,349,356,357,-1,351,350,357,358,-1,352,351,358,359,-1,353,352,359,360,-1,354,353,360,361,-1,356,355,362,363,-1,357,356,363,364,-1,358,357,364,365,-1,359,358,365,366,-1,360,359,366,367,-1,361,360,367,368,-1,363,362,369,370,-1,364,363,370,371,-1,365,364,371,372,-1,366,365,372,373,-1,367,366,373,374,-1,368,367,374,375,-1,370,369,376,377,-1,371,370,377,378,-1,372,371,378,379,-1,373,372,379,380,-1,374,373,380,381,-1,375,374,381,382,-1,377,376,383,384,-1,378,377,384,385,-1,379,378,385,386,-1,380,379,386,387,-1,381,380,387,388,-1,382,381,388,389,-1,384,383,390,391,-1,385,384,391,392,-1,386,385,392,393,-1,387,386,393,394,-1,388,387,394,395,-1,389,388,395,396,-1,391,390,397,398,-1,392,391,398,399,-1,393,392,399,400,-1,394,393,400,401,-1,395,394,401,402,-1,396,395,402,403,-1,398,397,404,405,-1,399,398,405,406,-1,400,399,406,407,-1,401,400,407,408,-1,402,401,408,409,-1,403,402,409,410,-1,405,404,411,412,-1,406,405,412,413,-1,407,406,413,414,-1,408,407,414,415,-1,409,408,415,416,-1,410,409,416,417,-1,412,411,418,419,-1,413,412,419,420,-1,414,413,420,421,-1,415,414,421,422,-1,416,415,422,423,-1,417,416,423,424,-1,419,418,425,426,-1,420,419,426,427,-1,421,420,427,428,-1,422,421,428,429,-1,423,422,429,430,-1,424,423,430,431,-1,426,425,432,433,-1,427,426,433,434,-1,428,427,434,435,-1,429,428,435,436,-1,430,429,436,437,-1,431,430,437,438,-1,433,432,439,440,-1,434,433,440,441,-1,435,434,441,442,-1,436,435,442,443,-1,437,436,443,444,-1,438,437,444,445,-1,440,439,446,447,-1,441,440,447,448,-1,442,441,448,449,-1,443,442,449,450,-1,444,443,450,451,-1,445,444,451,452,-1,447,446,453,454,-1,448,447,454,455,-1,449,448,455,456,-1,450,449,456,457,-1,451,450,457,458,-1,452,451,458,459,-1,454,453,460,461,-1,455,454,461,462,-1,456,455,462,463,-1,457,456,463,464,-1,458,457,464,465,-1,459,458,465,466,-1,461,460,467,468,-1,462,461,468,469,-1,463,462,469,470,-1,464,463,470,471,-1,465,464,471,472,-1,466,465,472,473,-1,468,467,307,306,-1,469,468,306,310,-1,470,469,310,312,-1,471,470,312,314,-1,472,471,314,316,-1,473,472,316,318,-1,474,318,319,475,-1,476,474,475,477,-1,478,476,477,479,-1,475,319,326,480,-1,477,475,480,481,-1,479,477,481,482,-1,483,479,482,484,-1,485,483,484,486,-1,487,485,486,488,-1,480,326,333,489,-1,481,480,489,490,-1,482,481,490,491,-1,484,482,491,492,-1,486,484,492,493,-1,488,486,493,494,-1,489,333,340,495,-1,490,489,495,496,-1,491,490,496,497,-1,492,491,497,498,-1,493,492,498,499,-1,494,493,499,500,-1,495,340,347,501,-1,496,495,501,502,-1,497,496,502,503,-1,498,497,503,504,-1,499,498,504,505,-1,500,499,505,506,-1,501,347,354,507,-1,502,501,507,508,-1,503,502,508,509,-1,504,503,509,510,-1,505,504,510,511,-1,506,505,511,512,-1,507,354,361,513,-1,508,507,513,514,-1,509,508,514,515,-1,510,509,515,516,-1,511,510,516,517,-1,512,511,517,518,-1,513,361,368,519,-1,514,513,519,520,-1,515,514,520,521,-1,516,515,521,522,-1,517,516,522,523,-1,518,517,523,524,-1,519,368,375,525,-1,520,519,525,526,-1,521,520,526,527,-1,522,521,527,528,-1,523,522,528,529,-1,524,523,529,530,-1,525,375,382,531,-1,526,525,531,532,-1,527,526,532,533,-1,528,527,533,534,-1,529,528,534,535,-1,530,529,535,536,-1,531,382,389,537,-1,532,531,537,538,-1,533,532,538,539,-1,534,533,539,540,-1,535,534,540,541,-1,536,535,541,542,-1,539,538,543,544,-1,540,539,544,545,-1,541,540,545,546,-1,544,543,547,548,-1,545,544,548,549,-1,546,545,549,550,-1,551,403,410,552,-1,547,551,552,553,-1,548,547,553,554,-1,549,548,554,555,-1,550,549,555,556,-1,557,550,556,558,-1,552,410,417,559,-1,553,552,559,560,-1,554,553,560,561,-1,555,554,561,562,-1,556,555,562,563,-1,558,556,563,564,-1,559,417,424,565,-1,560,559,565,566,-1,561,560,566,567,-1,562,561,567,568,-1,563,562,568,569,-1,564,563,569,570,-1,565,424,431,571,-1,566,565,571,572,-1,567,566,572,573,-1,568,567,573,574,-1,569,568,574,575,-1,570,569,575,576,-1,571,431,438,577,-1,572,571,577,578,-1,573,572,578,579,-1,574,573,579,580,-1,575,574,580,581,-1,576,575,581,582,-1,577,438,445,583,-1,578,577,583,584,-1,579,578,584,585,-1,580,579,585,586,-1,581,580,586,587,-1,582,581,587,588,-1,583,445,452,589,-1,584,583,589,590,-1,585,584,590,591,-1,586,585,591,592,-1,587,586,592,593,-1,588,587,593,594,-1,589,452,459,595,-1,590,589,595,596,-1,591,590,596,597,-1,592,591,597,598,-1,593,592,598,599,-1,594,593,599,600,-1,595,459,466,601,-1,596,595,601,602,-1,597,596,602,603,-1,598,597,603,604,-1,599,598,604,605,-1,600,599,605,606,-1,601,466,473,607,-1,602,601,607,608,-1,603,602,608,609,-1,604,603,609,610,-1,605,604,610,611,-1,606,605,611,612,-1,607,473,318,474,-1,608,607,474,476,-1,609,608,476,478,-1,613,614,615,616,-1,617,613,616,618,-1,619,617,618,620,-1,621,619,620,622,-1,623,487,488,624,-1,615,623,624,625,-1,616,615,625,626,-1,618,616,626,627,-1,620,618,627,628,-1,622,620,628,629,-1,624,488,494,630,-1,625,624,630,631,-1,626,625,631,632,-1,627,626,632,633,-1,628,627,633,634,-1,629,628,634,635,-1,630,494,500,636,-1,631,630,636,637,-1,632,631,637,638,-1,633,632,638,639,-1,634,633,639,640,-1,635,634,640,641,-1,636,500,506,642,-1,637,636,642,643,-1,638,637,643,644,-1,639,638,644,645,-1,640,639,645,646,-1,641,640,646,647,-1,642,506,512,648,-1,643,642,648,649,-1,644,643,649,650,-1,645,644,650,651,-1,646,645,651,652,-1,647,646,652,653,-1,648,512,518,654,-1,649,648,654,655,-1,650,649,655,656,-1,651,650,656,657,-1,652,651,657,658,-1,653,652,658,659,-1,654,518,524,660,-1,655,654,660,661,-1,656,655,661,662,-1,657,656,662,663,-1,658,657,663,664,-1,659,658,664,665,-1,660,524,530,666,-1,661,660,666,667,-1,662,661,667,668,-1,663,662,668,669,-1,664,663,669,670,-1,665,664,670,671,-1,666,530,536,672,-1,667,666,672,673,-1,668,667,673,674,-1,669,668,674,675,-1,670,669,675,676,-1,671,670,676,677,-1,672,536,542,678,-1,673,672,678,679,-1,674,673,679,680,-1,675,674,680,681,-1,676,675,681,682,-1,677,676,682,683,-1,680,679,684,685,-1,681,680,685,686,-1,682,681,686,687,-1,683,682,687,688,-1,685,684,689,690,-1,686,685,690,691,-1,687,686,691,692,-1,688,687,692,693,-1,694,557,558,695,-1,689,694,695,696,-1,690,689,696,697,-1,691,690,697,698,-1,692,691,698,699,-1,693,692,699,700,-1,695,558,564,701,-1,696,695,701,702,-1,697,696,702,703,-1,698,697,703,704,-1,699,698,704,705,-1,700,699,705,706,-1,701,564,570,707,-1,702,701,707,708,-1,703,702,708,709,-1,704,703,709,710,-1,705,704,710,711,-1,706,705,711,712,-1,707,570,576,713,-1,708,707,713,714,-1,709,708,714,715,-1,710,709,715,716,-1,711,710,716,717,-1,712,711,717,718,-1,713,576,582,719,-1,714,713,719,720,-1,715,714,720,721,-1,716,715,721,722,-1,717,716,722,723,-1,718,717,723,724,-1,719,582,588,725,-1,720,719,725,726,-1,721,720,726,727,-1,722,721,727,728,-1,723,722,728,729,-1,724,723,729,730,-1,725,588,594,731,-1,726,725,731,732,-1,727,726,732,733,-1,728,727,733,734,-1,729,728,734,735,-1,730,729,735,736,-1,731,594,600,737,-1,732,731,737,738,-1,733,732,738,739,-1,734,733,739,740,-1,735,734,740,741,-1,736,735,741,742,-1,737,600,606,743,-1,738,737,743,744,-1,739,738,744,745,-1,740,739,745,746,-1,741,740,746,747,-1,742,741,747,748,-1,743,606,612,749,-1,744,743,749,750,-1,745,744,750,751,-1,746,745,751,752,-1,747,746,752,753,-1,748,747,753,754,-1,751,750,614,613,-1,752,751,613,617,-1,753,752,617,619,-1,754,753,619,621,-1,755,756,757,-1,758,755,757,759,-1,760,758,759,761,-1,762,760,761,763,-1,764,762,763,765,-1,621,764,765,754,-1,757,756,766,-1,759,757,766,767,-1,761,759,767,768,-1,763,761,768,769,-1,765,763,769,770,-1,754,765,770,748,-1,766,756,771,-1,767,766,771,772,-1,768,767,772,773,-1,769,768,773,774,-1,770,769,774,775,-1,748,770,775,742,-1,771,756,776,-1,772,771,776,777,-1,773,772,777,778,-1,774,773,778,779,-1,775,774,779,780,-1,742,775,780,736,-1,776,756,781,-1,777,776,781,782,-1,778,777,782,783,-1,779,778,783,784,-1,780,779,784,785,-1,736,780,785,730,-1,781,756,786,-1,782,781,786,787,-1,783,782,787,788,-1,784,783,788,789,-1,785,784,789,790,-1,730,785,790,724,-1,786,756,791,-1,787,786,791,792,-1,788,787,792,793,-1,789,788,793,794,-1,790,789,794,795,-1,724,790,795,718,-1,791,756,796,-1,792,791,796,797,-1,793,792,797,798,-1,794,793,798,799,-1,795,794,799,800,-1,718,795,800,712,-1,796,756,801,-1,797,796,801,802,-1,798,797,802,803,-1,799,798,803,804,-1,800,799,804,805,-1,712,800,805,706,-1,801,756,806,-1,802,801,806,807,-1,803,802,807,808,-1,804,803,808,809,-1,805,804,809,810,-1,706,805,810,700,-1,806,756,811,-1,807,806,811,812,-1,808,807,812,813,-1,809,808,813,814,-1,810,809,814,815,-1,700,810,815,693,-1,811,756,816,-1,812,811,816,817,-1,813,812,817,818,-1,814,813,818,819,-1,815,814,819,820,-1,693,815,820,688,-1,816,756,821,-1,817,816,821,822,-1,818,817,822,823,-1,819,818,823,824,-1,820,819,824,825,-1,688,820,825,683,-1,821,756,826,-1,822,821,826,827,-1,823,822,827,828,-1,824,823,828,829,-1,825,824,829,830,-1,683,825,830,677,-1,826,756,831,-1,827,826,831,832,-1,828,827,832,833,-1,829,828,833,834,-1,830,829,834,835,-1,677,830,835,671,-1,831,756,836,-1,832,831,836,837,-1,833,832,837,838,-1,834,833,838,839,-1,835,834,839,840,-1,671,835,840,665,-1,836,756,841,-1,837,836,841,842,-1,838,837,842,843,-1,839,838,843,844,-1,840,839,844,845,-1,665,840,845,659,-1,841,756,846,-1,842,841,846,847,-1,843,842,847,848,-1,844,843,848,849,-1,845,844,849,850,-1,659,845,850,653,-1,846,756,851,-1,847,846,851,852,-1,848,847,852,853,-1,849,848,853,854,-1,850,849,854,855,-1,653,850,855,647,-1,851,756,856,-1,852,851,856,857,-1,853,852,857,858,-1,854,853,858,859,-1,855,854,859,860,-1,647,855,860,641,-1,856,756,861,-1,857,856,861,862,-1,858,857,862,863,-1,859,858,863,864,-1,860,859,864,865,-1,641,860,865,635,-1,861,756,866,-1,862,861,866,867,-1,863,862,867,868,-1,864,863,868,869,-1,865,864,869,870,-1,635,865,870,629,-1,866,756,871,-1,867,866,871,872,-1,868,867,872,873,-1,869,868,873,874,-1,870,869,874,875,-1,629,870,875,622,-1,871,756,755,-1,872,871,755,758,-1,873,872,758,760,-1,874,873,760,762,-1,875,874,762,764,-1,622,875,764,621,-1,537,389,292,-1,538,537,290,-1,538,290,289,543,-1,542,541,546,-1,542,546,305,-1,542,305,1189,-1,403,551,296,-1,295,396,403,296,-1,547,543,299,-1,298,551,547,299,-1,1187,546,550,557,-1,679,678,1184,-1,679,1184,302,-1,679,302,684,-1,389,396,293,-1,389,293,292,-1,301,543,289,-1,290,537,291,-1,296,551,297,-1,543,300,299,-1,305,546,1187,-1,1185,684,302,-1,694,876,1188,-1,1188,557,694,-1,684,1185,876,-1,684,876,694,689,-1,396,295,294,-1,537,292,291,-1,551,298,297,-1,543,301,300,-1,303,557,1186,-1,557,1188,1186,-1,1184,678,1183,-1,678,1182,1183,-1,1187,557,303,-1,146,483,147,-1,148,485,149,-1,609,478,156,-1,610,609,156,-1,611,610,153,152,-1,877,487,623,-1,614,151,623,615,-1,750,749,151,614,-1,478,145,154,-1,154,156,478,-1,483,146,145,-1,478,479,145,-1,145,479,483,-1,483,485,147,-1,147,485,148,-1,149,485,1179,-1,485,487,149,1179,-1,149,487,877,-1,610,156,153,-1,611,152,1181,-1,155,612,1181,-1,612,611,1181,-1,623,150,877,-1,749,612,1180,-1,151,749,1180,-1,623,151,150,-1,1180,612,155,-1,467,460,878,-1,327,320,879,-1,467,878,879,-1,467,879,320,-1,467,320,308,-1,467,308,307,-1,334,327,880,-1,880,327,879,-1,341,334,881,-1,881,334,880,-1,348,341,882,-1,882,341,881,-1,355,348,883,-1,883,348,882,-1,362,355,884,-1,884,355,883,-1,369,362,885,-1,885,362,884,-1,376,369,886,-1,886,369,885,-1,383,376,887,-1,887,376,886,-1,390,383,888,-1,888,383,887,-1,397,390,889,-1,889,390,888,-1,404,397,890,-1,890,397,889,-1,411,404,891,-1,891,404,890,-1,418,411,892,-1,892,411,891,-1,425,418,893,-1,893,418,892,-1,432,425,894,-1,894,425,893,-1,439,432,895,-1,895,432,894,-1,446,439,896,-1,896,439,895,-1,453,446,897,-1,897,446,896,-1,460,453,898,-1,898,453,897,-1,899,460,898,-1,900,460,899,-1,878,460,901,-1,901,460,900,-1,902,903,904,905,-1,906,902,905,907,-1,908,906,907,909,-1,910,908,909,911,-1,912,910,911,913,-1,905,904,914,915,-1,907,905,915,916,-1,909,907,916,917,-1,911,909,917,918,-1,913,911,918,919,-1,915,914,920,921,-1,916,915,921,922,-1,917,916,922,923,-1,918,917,923,924,-1,919,918,924,925,-1,921,920,926,927,-1,922,921,927,928,-1,923,922,928,929,-1,924,923,929,930,-1,925,924,930,931,-1,927,926,932,933,-1,928,927,933,934,-1,929,928,934,935,-1,930,929,935,936,-1,931,930,936,937,-1,933,932,938,939,-1,934,933,939,940,-1,935,934,940,941,-1,936,935,941,942,-1,937,936,942,943,-1,939,938,944,945,-1,940,939,945,946,-1,941,940,946,947,-1,942,941,947,948,-1,943,942,948,949,-1,945,944,950,951,-1,946,945,951,952,-1,947,946,952,953,-1,948,947,953,954,-1,949,948,954,955,-1,951,950,956,957,-1,952,951,957,958,-1,953,952,958,959,-1,954,953,959,960,-1,955,954,960,961,-1,957,956,962,963,-1,958,957,963,964,-1,959,958,964,965,-1,960,959,965,966,-1,961,960,966,967,-1,963,962,968,969,-1,964,963,969,970,-1,965,964,970,971,-1,966,965,971,972,-1,967,966,972,973,-1,969,968,974,975,-1,970,969,975,976,-1,971,970,976,977,-1,972,971,977,978,-1,973,972,978,979,-1,975,974,980,981,-1,976,975,981,982,-1,977,976,982,983,-1,978,977,983,984,-1,979,978,984,985,-1,981,980,986,987,-1,982,981,987,988,-1,983,982,988,989,-1,984,983,989,990,-1,985,984,990,991,-1,987,986,992,993,-1,988,987,993,994,-1,989,988,994,995,-1,990,989,995,996,-1,991,990,996,997,-1,993,992,998,999,-1,994,993,999,1000,-1,995,994,1000,1001,-1,996,995,1001,1002,-1,997,996,1002,1003,-1,999,998,1004,1005,-1,1000,999,1005,1006,-1,1001,1000,1006,1007,-1,1002,1001,1007,1008,-1,1003,1002,1008,1009,-1,1005,1004,1010,1011,-1,1006,1005,1011,1012,-1,1007,1006,1012,1013,-1,1008,1007,1013,1014,-1,1009,1008,1014,1015,-1,1011,1010,1016,1017,-1,1012,1011,1017,1018,-1,1013,1012,1018,1019,-1,1014,1013,1019,1020,-1,1015,1014,1020,1021,-1,1017,1016,1022,1023,-1,1018,1017,1023,1024,-1,1019,1018,1024,1025,-1,1020,1019,1025,1026,-1,1021,1020,1026,1027,-1,1023,1022,1028,1029,-1,1024,1023,1029,1030,-1,1025,1024,1030,1031,-1,1026,1025,1031,1032,-1,1027,1026,1032,1033,-1,1029,1028,1034,1035,-1,1030,1029,1035,1036,-1,1031,1030,1036,1037,-1,1032,1031,1037,1038,-1,1033,1032,1038,1039,-1,1035,1034,1040,1041,-1,1036,1035,1041,1042,-1,1037,1036,1042,1043,-1,1038,1037,1043,1044,-1,1039,1038,1044,1045,-1,1041,1040,903,902,-1,1042,1041,902,906,-1,1043,1042,906,908,-1,1044,1043,908,910,-1,1045,1044,910,912,-1,903,1046,1047,904,-1,904,1048,1049,914,-1,914,1049,1050,920,-1,920,1050,1051,926,-1,926,1051,1052,932,-1,932,1052,938,-1,938,1053,944,-1,944,1054,950,-1,950,1055,956,-1,956,1056,962,-1,962,1057,1058,968,-1,968,1059,1060,974,-1,974,1061,1062,980,-1,980,1063,1064,986,-1,986,1065,992,-1,992,1066,998,-1,998,1067,1004,-1,1004,1080,1068,1010,-1,1010,1069,1070,1016,-1,1016,1071,1072,1022,-1,1022,1073,1074,1028,-1,1028,1075,1076,1034,-1,1034,1077,1078,1040,-1,1040,1079,1046,903,-1,1048,904,1047,-1,1053,938,1052,-1,1054,944,1053,-1,1055,950,1054,-1,1056,956,1055,-1,1057,962,1056,-1,1059,968,1058,-1,1061,974,1060,-1,1063,980,1062,-1,1065,986,1064,-1,1066,992,1065,-1,1067,998,1066,-1,1080,1004,1067,-1,1069,1010,1068,-1,1071,1016,1070,-1,1073,1022,1072,-1,1075,1028,1074,-1,1077,1034,1076,-1,1081,1040,1078,-1,1040,1081,1079,-1,1082,1083,1084,-1,1085,1082,1084,1086,-1,1087,1085,1086,1088,-1,1089,1087,1088,1090,-1,1084,1083,1091,-1,1086,1084,1091,1092,-1,1088,1086,1092,1093,-1,1090,1088,1093,1094,-1,1091,1083,1095,-1,1092,1091,1095,1096,-1,1093,1092,1096,1097,-1,1094,1093,1097,1098,-1,1095,1083,1099,-1,1096,1095,1099,1100,-1,1097,1096,1100,1101,-1,1098,1097,1101,1102,-1,1099,1083,1103,-1,1100,1099,1103,1104,-1,1101,1100,1104,1105,-1,1102,1101,1105,1106,-1,1103,1083,1107,-1,1104,1103,1107,1108,-1,1105,1104,1108,1109,-1,1106,1105,1109,1110,-1,1107,1083,1111,-1,1108,1107,1111,1112,-1,1109,1108,1112,1113,-1,1110,1109,1113,1114,-1,1111,1083,1115,-1,1112,1111,1115,1116,-1,1113,1112,1116,1117,-1,1114,1113,1117,1118,-1,1115,1083,1119,-1,1116,1115,1119,1120,-1,1117,1116,1120,1121,-1,1118,1117,1121,1122,-1,1119,1083,1123,-1,1120,1119,1123,1124,-1,1121,1120,1124,1125,-1,1122,1121,1125,1126,-1,1123,1083,1127,-1,1124,1123,1127,1128,-1,1125,1124,1128,1129,-1,1126,1125,1129,1130,-1,1127,1083,1131,-1,1128,1127,1131,1132,-1,1129,1128,1132,1133,-1,1130,1129,1133,1134,-1,1131,1083,1135,-1,1132,1131,1135,1136,-1,1133,1132,1136,1137,-1,1134,1133,1137,1138,-1,1135,1083,1139,-1,1136,1135,1139,1140,-1,1137,1136,1140,1141,-1,1138,1137,1141,1142,-1,1139,1083,1143,-1,1140,1139,1143,1144,-1,1141,1140,1144,1145,-1,1142,1141,1145,1146,-1,1143,1083,1147,-1,1144,1143,1147,1148,-1,1145,1144,1148,1149,-1,1146,1145,1149,1150,-1,1147,1083,1151,-1,1148,1147,1151,1152,-1,1149,1148,1152,1153,-1,1150,1149,1153,1154,-1,1151,1083,1155,-1,1152,1151,1155,1156,-1,1153,1152,1156,1157,-1,1154,1153,1157,1158,-1,1155,1083,1159,-1,1156,1155,1159,1160,-1,1157,1156,1160,1161,-1,1158,1157,1161,1162,-1,1159,1083,1163,-1,1160,1159,1163,1164,-1,1161,1160,1164,1165,-1,1162,1161,1165,1166,-1,1163,1083,1167,-1,1164,1163,1167,1168,-1,1165,1164,1168,1169,-1,1166,1165,1169,1170,-1,1167,1083,1171,-1,1168,1167,1171,1172,-1,1169,1168,1172,1173,-1,1170,1169,1173,1174,-1,1171,1083,1175,-1,1172,1171,1175,1176,-1,1173,1172,1176,1177,-1,1174,1173,1177,1178,-1,1175,1083,1082,-1,1176,1175,1082,1085,-1,1177,1176,1085,1087,-1,1178,1177,1087,1089,-1,1046,1089,1090,1047,-1,1047,1090,1094,1048,-1,1049,1094,1098,-1,1050,1098,1102,-1,1051,1102,1106,-1,1052,1106,1110,1053,-1,1053,1110,1114,1054,-1,1054,1114,1118,1055,-1,1055,1118,1122,1056,-1,1056,1122,1126,1057,-1,1058,1126,1130,1059,-1,1060,1130,1134,1061,-1,1062,1134,1138,1063,-1,1064,1138,1142,1065,-1,1065,1142,1146,1066,-1,1066,1146,1150,1067,-1,1067,1150,1154,1080,-1,1068,1158,1162,1069,-1,1070,1162,1166,1071,-1,1072,1166,1170,1073,-1,1074,1170,1174,1075,-1,1076,1174,1178,1077,-1,1078,1178,1089,1081,-1,1079,1089,1046,-1,1094,1049,1048,-1,1098,1050,1049,-1,1102,1051,1050,-1,1106,1052,1051,-1,1126,1058,1057,-1,1130,1060,1059,-1,1134,1062,1061,-1,1138,1064,1063,-1,1158,1068,1080,-1,1162,1070,1069,-1,1166,1072,1071,-1,1170,1074,1073,-1,1174,1076,1075,-1,1178,1078,1077,-1,1089,1079,1081,-1,878,912,913,879,-1,879,913,919,880,-1,880,919,925,881,-1,881,925,931,882,-1,882,931,937,883,-1,883,937,943,884,-1,884,943,949,885,-1,885,949,955,886,-1,886,955,961,887,-1,887,961,967,888,-1,888,967,973,889,-1,889,973,979,890,-1,890,979,985,891,-1,891,985,991,892,-1,892,991,997,893,-1,893,997,1003,894,-1,894,1003,1009,895,-1,895,1009,1015,896,-1,896,1015,1021,897,-1,897,1021,1027,898,-1,898,1027,1033,899,-1,899,1033,1039,900,-1,900,1039,1045,901,-1,901,1045,912,878,-1,1154,1158,1080,-1,237,238,1189,-1,237,1189,305,-1,237,305,304,-1,1189,1182,542,-1,1182,678,542,-1,294,293,396,-1};
2721static int teapot_coordindex_n = 6302;
2722static float teapot_coord_p [] = {0.000000f,-0.750000f,0.000000f,1.148825f,0.059635f,0.010277f,1.043040f,-0.007725f,0.010277f,1.049830f,-0.033315f,0.141457f,1.158700f,0.040090f,0.125638f,1.207390f,0.154080f,0.010277f,1.218500f,0.140885f,0.105073f,1.245120f,0.261025f,0.010277f,1.257465f,0.253720f,0.084509f,1.288410f,0.365885f,0.010277f,1.303840f,0.363235f,0.068691f,1.363650f,0.454090f,0.010277f,1.385870f,0.454090f,0.062364f,1.066805f,-0.097305f,0.220164f,1.183395f,-0.008780f,0.194855f,1.246280f,0.107900f,0.161951f,1.288330f,0.235460f,0.129049f,1.342430f,0.356615f,0.103739f,1.441430f,0.454090f,0.093615f,1.088870f,-0.180480f,0.246400f,1.215490f,-0.072320f,0.217927f,1.282390f,0.065015f,0.180911f,1.328465f,0.211720f,0.143895f,1.392585f,0.348005f,0.115422f,1.513650f,0.454090f,0.104032f,1.110940f,-0.263651f,0.220164f,1.247590f,-0.135850f,0.194855f,1.318510f,0.022135f,0.161952f,1.368590f,0.187980f,0.129049f,1.442740f,0.339395f,0.103739f,1.585880f,0.454090f,0.093616f,1.127915f,-0.327631f,0.141457f,1.272280f,-0.184715f,0.125639f,1.346290f,-0.010850f,0.105074f,1.399450f,0.169720f,0.084510f,1.481320f,0.332770f,0.068691f,1.641440f,0.454090f,0.062364f,1.134705f,-0.353224f,0.010277f,1.282160f,-0.204265f,0.010278f,1.357400f,-0.024045f,0.010278f,1.411800f,0.162415f,0.010278f,1.496750f,0.330120f,0.010278f,1.663660f,0.454090f,0.010278f,1.127915f,-0.327631f,-0.120902f,1.272280f,-0.184715f,-0.105083f,1.346290f,-0.010850f,-0.084519f,1.399450f,0.169720f,-0.063955f,1.481320f,0.332770f,-0.048136f,1.641440f,0.454090f,-0.041808f,1.110940f,-0.263651f,-0.199610f,1.247590f,-0.135850f,-0.174300f,1.318510f,0.022135f,-0.141397f,1.368590f,0.187980f,-0.108494f,1.442740f,0.339395f,-0.083184f,1.585870f,0.454090f,-0.073060f,1.088870f,-0.180480f,-0.225846f,1.215490f,-0.072320f,-0.197372f,1.282390f,0.065015f,-0.160357f,1.328465f,0.211720f,-0.123341f,1.392585f,0.348005f,-0.094867f,1.513650f,0.454090f,-0.083477f,1.066805f,-0.097305f,-0.199610f,1.183395f,-0.008780f,-0.174300f,1.246280f,0.107900f,-0.141397f,1.288330f,0.235460f,-0.108494f,1.342430f,0.356615f,-0.083185f,1.441430f,0.454090f,-0.073060f,1.049830f,-0.033315f,-0.120902f,1.158700f,0.040090f,-0.105084f,1.218500f,0.140885f,-0.084519f,1.257465f,0.253720f,-0.063955f,1.303840f,0.363235f,-0.048136f,1.385870f,0.454090f,-0.041809f,1.388185f,0.469715f,0.010277f,1.411855f,0.470055f,0.060796f,1.409945f,0.479090f,0.010278f,1.433540f,0.479705f,0.056769f,1.426150f,0.482215f,0.010278f,1.448490f,0.482995f,0.051295f,1.434020f,0.479090f,0.010278f,1.454255f,0.479860f,0.045387f,1.430780f,0.469715f,0.010278f,1.448395f,0.470245f,0.040058f,1.413650f,0.454090f,0.010278f,1.428465f,0.454090f,0.036320f,1.471020f,0.470895f,0.091069f,1.492525f,0.481250f,0.084355f,1.504335f,0.484950f,0.074865f,1.504835f,0.481790f,0.063984f,1.492430f,0.471570f,0.053104f,1.465500f,0.454090f,0.043613f,1.547940f,0.471995f,0.101124f,1.569205f,0.483255f,0.093268f,1.576930f,0.487490f,0.081766f,1.570595f,0.484300f,0.067920f,1.549675f,0.473295f,0.053032f,1.513650f,0.454090f,0.038404f,1.624865f,0.473090f,0.090992f,1.645895f,0.485265f,0.083739f,1.649540f,0.490025f,0.072781f,1.636360f,0.486805f,0.059046f,1.606930f,0.475020f,0.043459f,1.561800f,0.454090f,0.026945f,1.684035f,0.473935f,0.060700f,1.704880f,0.486805f,0.055998f,1.705385f,0.491980f,0.048692f,1.686945f,0.488735f,0.039215f,1.650965f,0.476345f,0.028002f,1.598845f,0.454090f,0.015487f,1.707700f,0.474270f,0.010278f,1.728475f,0.487425f,0.010278f,1.727725f,0.492760f,0.010278f,1.707180f,0.489505f,0.010278f,1.668580f,0.476875f,0.010278f,1.613660f,0.454090f,0.010278f,1.684035f,0.473935f,-0.040264f,1.704880f,0.486805f,-0.036406f,1.705385f,0.491980f,-0.031390f,1.686945f,0.488735f,-0.026375f,1.650965f,0.476345f,-0.022517f,1.598845f,0.454090f,-0.020974f,1.624865f,0.473090f,-0.070590f,1.645895f,0.485265f,-0.064417f,1.649540f,0.490025f,-0.056392f,1.636360f,0.486805f,-0.048367f,1.606930f,0.475020f,-0.042194f,1.561800f,0.454090f,-0.039725f,1.547940f,0.471995f,-0.080699f,1.569205f,0.483255f,-0.073754f,1.576930f,0.487490f,-0.064726f,1.570595f,0.484300f,-0.055698f,1.549675f,0.473295f,-0.048753f,1.513650f,0.454090f,-0.045975f,1.471020f,0.470895f,-0.070591f,1.492525f,0.481250f,-0.064417f,1.504335f,0.484950f,-0.056392f,1.504835f,0.481790f,-0.048367f,1.492430f,0.471570f,-0.042194f,1.465500f,0.454090f,-0.039725f,1.411855f,0.470055f,-0.040265f,1.433540f,0.479705f,-0.036407f,1.448490f,0.482995f,-0.031391f,1.454255f,0.479860f,-0.026376f,1.448395f,0.470245f,-0.022517f,1.428465f,0.454090f,-0.020974f,0.947765f,-0.050712f,0.145199f,0.949770f,-0.061850f,0.157877f,0.954494f,-0.122208f,0.225588f,0.965825f,-0.182515f,0.242866f,0.967288f,-0.213253f,0.251729f,0.973877f,-0.379134f,0.145447f,0.986036f,-0.402350f,0.016630f,0.966995f,-0.182515f,-0.223702f,0.955408f,-0.120540f,-0.205494f,0.955634f,-0.019872f,0.007642f,0.978411f,-0.302964f,-0.204801f,0.949180f,-0.052564f,-0.128725f,-1.076185f,0.264745f,0.005367f,-0.940300f,0.268390f,0.005368f,-0.941550f,0.276685f,0.067870f,-1.081260f,0.272770f,0.067870f,-1.184285f,0.254845f,0.005367f,-1.192155f,0.262140f,0.067870f,-1.263220f,0.235575f,0.005367f,-1.272960f,0.241440f,0.067869f,-1.311600f,0.203805f,0.005367f,-1.322390f,0.207315f,0.067869f,-1.328040f,0.156405f,0.005367f,-1.339150f,0.156405f,0.067869f,-0.944680f,0.297420f,0.105371f,-1.093945f,0.292830f,0.105371f,-1.211830f,0.280370f,0.105370f,-1.297310f,0.256100f,0.105370f,-1.349355f,0.216095f,0.105370f,-1.366930f,0.156405f,0.105371f,-0.948750f,0.324380f,0.117872f,-1.110440f,0.318910f,0.117871f,-1.237410f,0.304065f,0.117871f,-1.328965f,0.275160f,0.117871f,-1.384405f,0.227505f,0.117871f,-1.403040f,0.156405f,0.117871f,-0.952815f,0.351335f,0.105371f,-1.126940f,0.344990f,0.105371f,-1.262990f,0.327765f,0.105370f,-1.360620f,0.294220f,0.105370f,-1.419460f,0.238915f,0.105370f,-1.439150f,0.156405f,0.105371f,-0.955945f,0.372075f,0.067870f,-1.139625f,0.365050f,0.067870f,-1.282665f,0.345995f,0.067869f,-1.384965f,0.308880f,0.067869f,-1.446425f,0.247690f,0.067869f,-1.466935f,0.156405f,0.067869f,-0.957195f,0.380370f,0.005368f,-1.144700f,0.373075f,0.005367f,-1.290535f,0.353285f,0.005367f,-1.394705f,0.314745f,0.005367f,-1.457210f,0.251200f,0.005367f,-1.478045f,0.156405f,0.005367f,-0.955945f,0.372075f,-0.057135f,-1.139625f,0.365050f,-0.057135f,-1.282665f,0.345995f,-0.057135f,-1.384965f,0.308880f,-0.057135f,-1.446425f,0.247690f,-0.057135f,-1.466935f,0.156405f,-0.057135f,-0.952815f,0.351335f,-0.094636f,-1.126940f,0.344990f,-0.094636f,-1.262990f,0.327765f,-0.094636f,-1.360620f,0.294220f,-0.094636f,-1.419460f,0.238915f,-0.094636f,-1.439155f,0.156405f,-0.094636f,-0.948750f,0.324380f,-0.107136f,-1.110440f,0.318910f,-0.107136f,-1.237410f,0.304065f,-0.107136f,-1.328965f,0.275160f,-0.107137f,-1.384405f,0.227505f,-0.107137f,-1.403040f,0.156405f,-0.107137f,-0.944680f,0.297420f,-0.094636f,-1.093945f,0.292830f,-0.094636f,-1.211830f,0.280370f,-0.094636f,-1.297310f,0.256100f,-0.094636f,-1.349355f,0.216095f,-0.094636f,-1.366930f,0.156405f,-0.094636f,-0.941550f,0.276685f,-0.057134f,-1.081260f,0.272770f,-0.057134f,-1.192155f,0.262140f,-0.057135f,-1.272960f,0.241440f,-0.057135f,-1.322390f,0.207315f,-0.057135f,-1.339150f,0.156405f,-0.057135f,-1.319470f,0.091820f,0.005367f,-1.330130f,0.088395f,0.067869f,-1.292850f,0.014735f,0.005368f,-1.302180f,0.009075f,0.067870f,-1.246785f,-0.068600f,0.005368f,-1.253960f,-0.075720f,0.067870f,-1.179885f,-0.151935f,0.005368f,-1.184140f,-0.160165f,0.067871f,-1.090765f,-0.229015f,0.005368f,-1.091375f,-0.238435f,0.067871f,-1.356775f,0.079825f,0.105371f,-1.325495f,-0.005070f,0.105371f,-1.271900f,-0.093515f,0.105371f,-1.194770f,-0.180740f,0.105372f,-1.092895f,-0.261988f,0.105372f,-1.391410f,0.068690f,0.117871f,-1.355820f,-0.023460f,0.117872f,-1.295220f,-0.116645f,0.117872f,-1.208590f,-0.207490f,0.117872f,-1.094875f,-0.292604f,0.117872f,-1.426040f,0.057550f,0.105371f,-1.386135f,-0.041850f,0.105371f,-1.318545f,-0.139780f,0.105371f,-1.222410f,-0.234240f,0.105371f,-1.096855f,-0.323220f,0.105372f,-1.452690f,0.048980f,0.067869f,-1.409455f,-0.055995f,0.067870f,-1.336485f,-0.157575f,0.067870f,-1.233040f,-0.254816f,0.067871f,-1.098375f,-0.346770f,0.067871f,-1.463345f,0.045555f,0.005367f,-1.418780f,-0.061655f,0.005368f,-1.343665f,-0.164695f,0.005368f,-1.237295f,-0.263047f,0.005368f,-1.098985f,-0.356191f,0.005369f,-1.452690f,0.048980f,-0.057135f,-1.409455f,-0.055995f,-0.057134f,-1.336490f,-0.157575f,-0.057134f,-1.233040f,-0.254816f,-0.057134f,-1.098375f,-0.346771f,-0.057133f,-1.426040f,0.057550f,-0.094636f,-1.386135f,-0.041850f,-0.094636f,-1.318545f,-0.139780f,-0.094635f,-1.222410f,-0.234240f,-0.094635f,-1.096855f,-0.323220f,-0.094635f,-1.391410f,0.068690f,-0.107137f,-1.355820f,-0.023460f,-0.107136f,-1.295220f,-0.116645f,-0.107136f,-1.208590f,-0.207490f,-0.107135f,-1.094875f,-0.292604f,-0.107135f,-1.356775f,0.079825f,-0.094636f,-1.325500f,-0.005070f,-0.094636f,-1.271900f,-0.093515f,-0.094636f,-1.194770f,-0.180740f,-0.094635f,-1.092895f,-0.261989f,-0.094635f,-1.330130f,0.088395f,-0.057135f,-1.302180f,0.009075f,-0.057134f,-1.253960f,-0.075720f,-0.057134f,-1.184140f,-0.160165f,-0.057134f,-1.091375f,-0.238435f,-0.057133f,-0.828580f,0.268745f,0.005368f,-0.816635f,0.277110f,0.067869f,-0.802355f,0.297945f,0.105367f,-0.789532f,0.322995f,0.116933f,-0.777300f,0.352090f,0.105376f,-0.772385f,0.372900f,0.067873f,-0.776680f,0.381178f,0.005252f,-0.772445f,0.372895f,-0.057134f,-0.777370f,0.352085f,-0.094633f,-0.789598f,0.322992f,-0.106200f,-0.802420f,0.297940f,-0.094636f,-0.816705f,0.277090f,-0.057140f,-0.828600f,0.268770f,0.005135f,-0.956322f,-0.420173f,0.067328f,-0.974981f,-0.326715f,-0.094709f,-0.992085f,-0.284905f,0.005292f,-0.992115f,-0.285221f,0.005252f,0.697495f,0.479390f,0.005137f,0.706810f,0.452045f,0.005137f,0.682180f,0.452045f,0.193105f,0.673190f,0.479390f,0.190603f,0.698940f,0.495795f,0.005137f,0.674585f,0.495795f,0.190992f,0.708370f,0.501265f,0.005137f,0.683690f,0.501265f,0.193525f,0.723015f,0.495795f,0.005137f,0.697815f,0.495795f,0.197456f,0.740085f,0.479390f,0.005137f,0.714285f,0.479390f,0.202040f,0.756810f,0.452045f,0.005137f,0.730420f,0.452045f,0.206532f,0.612440f,0.452045f,0.360850f,0.604380f,0.479390f,0.356115f,0.605630f,0.495795f,0.356851f,0.613790f,0.501265f,0.361644f,0.626460f,0.495795f,0.369084f,0.641230f,0.479390f,0.377759f,0.655700f,0.452045f,0.386258f,0.503810f,0.452045f,0.502149f,0.497193f,0.479390f,0.495535f,0.498219f,0.495795f,0.496562f,0.504915f,0.501265f,0.503259f,0.515315f,0.495795f,0.513654f,0.527435f,0.479390f,0.525774f,0.539310f,0.452045f,0.537649f,0.362509f,0.452045f,0.610784f,0.357774f,0.479390f,0.602724f,0.358510f,0.495795f,0.603974f,0.363302f,0.501265f,0.612134f,0.370742f,0.495795f,0.624804f,0.379418f,0.479390f,0.639574f,0.387917f,0.452045f,0.654044f,0.194765f,0.452045f,0.680524f,0.192263f,0.479390f,0.671534f,0.192651f,0.495795f,0.672929f,0.195184f,0.501265f,0.682034f,0.199116f,0.495795f,0.696159f,0.203700f,0.479390f,0.712629f,0.208191f,0.452045f,0.728764f,0.006799f,0.452045f,0.705154f,0.006799f,0.479390f,0.695839f,0.006799f,0.495795f,0.697284f,0.006799f,0.501266f,0.706714f,0.006799f,0.495795f,0.721359f,0.006799f,0.479391f,0.738429f,0.006799f,0.452045f,0.755154f,-0.181168f,0.452045f,0.680524f,-0.178666f,0.479390f,0.671534f,-0.179055f,0.495795f,0.672929f,-0.181588f,0.501265f,0.682034f,-0.185520f,0.495795f,0.696159f,-0.190104f,0.479390f,0.712629f,-0.194595f,0.452045f,0.728764f,-0.348912f,0.452045f,0.610779f,-0.344178f,0.479390f,0.602719f,-0.344913f,0.495795f,0.603969f,-0.349706f,0.501265f,0.612129f,-0.357146f,0.495795f,0.624799f,-0.365822f,0.479390f,0.639574f,-0.374320f,0.452045f,0.654044f,-0.490211f,0.452045f,0.502149f,-0.483597f,0.479390f,0.495533f,-0.484623f,0.495795f,0.496560f,-0.491321f,0.501265f,0.503259f,-0.501715f,0.495795f,0.513654f,-0.513835f,0.479390f,0.525774f,-0.525710f,0.452045f,0.537649f,-0.598845f,0.452045f,0.360848f,-0.590785f,0.479390f,0.356114f,-0.592035f,0.495795f,0.356849f,-0.600195f,0.501265f,0.361642f,-0.612865f,0.495795f,0.369082f,-0.627635f,0.479390f,0.377758f,-0.642105f,0.452045f,0.386256f,-0.668585f,0.452045f,0.193103f,-0.659595f,0.479390f,0.190601f,-0.660990f,0.495795f,0.190990f,-0.670095f,0.501265f,0.193523f,-0.684220f,0.495795f,0.197454f,-0.700690f,0.479390f,0.202039f,-0.716825f,0.452045f,0.206530f,-0.693215f,0.452045f,0.005136f,-0.683900f,0.479390f,0.005136f,-0.685345f,0.495795f,0.005136f,-0.694775f,0.501265f,0.005136f,-0.709420f,0.495795f,0.005136f,-0.726490f,0.479390f,0.005136f,-0.743215f,0.452045f,0.005136f,-0.668585f,0.452045f,-0.182832f,-0.659595f,0.479390f,-0.180330f,-0.660990f,0.495795f,-0.180719f,-0.670095f,0.501265f,-0.183252f,-0.684220f,0.495795f,-0.187183f,-0.700690f,0.479390f,-0.191767f,-0.716825f,0.452045f,-0.196259f,-0.598845f,0.452045f,-0.350577f,-0.590785f,0.479390f,-0.345842f,-0.592035f,0.495795f,-0.346578f,-0.600195f,0.501265f,-0.351371f,-0.612865f,0.495795f,-0.358811f,-0.627635f,0.479390f,-0.367486f,-0.642105f,0.452045f,-0.375985f,-0.490213f,0.452045f,-0.491877f,-0.483597f,0.479390f,-0.485262f,-0.484625f,0.495795f,-0.486289f,-0.491322f,0.501265f,-0.492986f,-0.501720f,0.495795f,-0.503381f,-0.513840f,0.479390f,-0.515501f,-0.525715f,0.452045f,-0.527376f,-0.348913f,0.452045f,-0.600511f,-0.344179f,0.479390f,-0.592451f,-0.344914f,0.495795f,-0.593701f,-0.349708f,0.501265f,-0.601861f,-0.357148f,0.495795f,-0.614531f,-0.365823f,0.479390f,-0.629301f,-0.374321f,0.452045f,-0.643771f,-0.181170f,0.452045f,-0.670251f,-0.178668f,0.479390f,-0.661261f,-0.179056f,0.495795f,-0.662656f,-0.181589f,0.501265f,-0.671761f,-0.185521f,0.495795f,-0.685886f,-0.190105f,0.479390f,-0.702356f,-0.194596f,0.452045f,-0.718491f,0.006797f,0.452045f,-0.694881f,0.006797f,0.479390f,-0.685566f,0.006797f,0.495795f,-0.687011f,0.006797f,0.501265f,-0.696441f,0.006797f,0.495795f,-0.711086f,0.006797f,0.479390f,-0.728156f,0.006797f,0.452044f,-0.744881f,0.194763f,0.452045f,-0.670251f,0.192261f,0.479390f,-0.661261f,0.192649f,0.495795f,-0.662656f,0.195183f,0.501265f,-0.671761f,0.199114f,0.495795f,-0.685886f,0.203699f,0.479390f,-0.702356f,0.208190f,0.452045f,-0.718491f,0.362507f,0.452045f,-0.600511f,0.357772f,0.479390f,-0.592446f,0.358508f,0.495795f,-0.593696f,0.363301f,0.501265f,-0.601861f,0.370741f,0.495795f,-0.614531f,0.379416f,0.479390f,-0.629301f,0.387915f,0.452045f,-0.643771f,0.503805f,0.452045f,-0.491875f,0.497191f,0.479390f,-0.485260f,0.498218f,0.495795f,-0.486287f,0.504915f,0.501265f,-0.492985f,0.515310f,0.495795f,-0.503381f,0.527430f,0.479390f,-0.515501f,0.539305f,0.452045f,-0.527376f,0.612440f,0.452045f,-0.350575f,0.604380f,0.479390f,-0.345841f,0.605630f,0.495795f,-0.346576f,0.613790f,0.501265f,-0.351369f,0.626460f,0.495795f,-0.358809f,0.641230f,0.479390f,-0.367485f,0.655700f,0.452045f,-0.375983f,0.682180f,0.452045f,-0.182830f,0.673190f,0.479390f,-0.180328f,0.674585f,0.495795f,-0.180717f,0.683690f,0.501265f,-0.183250f,0.697815f,0.495795f,-0.187181f,0.714285f,0.479390f,-0.191766f,0.730420f,0.452045f,-0.196257f,0.818735f,0.320965f,0.005138f,0.790170f,0.320965f,0.223159f,0.877185f,0.190930f,0.005138f,0.846560f,0.190930f,0.238854f,0.928690f,0.062975f,0.005138f,0.896255f,0.062980f,0.252685f,0.709270f,0.320965f,0.417724f,0.759845f,0.190930f,0.447426f,0.804410f,0.062980f,0.473598f,0.935895f,-0.061850f,0.263718f,0.839955f,-0.061850f,0.494478f,0.962140f,-0.182515f,0.271022f,0.863490f,-0.182515f,0.508300f,0.971630f,-0.297965f,0.273664f,0.872000f,-0.297965f,0.513300f,0.583275f,0.320965f,0.581619f,0.624775f,0.190930f,0.623119f,0.661340f,0.062975f,0.659684f,0.690515f,-0.061850f,0.688860f,0.709825f,-0.182515f,0.708170f,0.716815f,-0.297965f,0.715155f,0.419383f,0.320971f,0.707614f,0.449084f,0.190931f,0.758184f,0.475257f,0.062981f,0.802754f,0.496136f,-0.061849f,0.838300f,0.509960f,-0.182514f,0.861835f,0.514960f,-0.297964f,0.870345f,0.224819f,0.320971f,0.788509f,0.240514f,0.190931f,0.844904f,0.254344f,0.062976f,0.894599f,0.265377f,-0.061849f,0.934240f,0.272682f,-0.182514f,0.960485f,0.275323f,-0.297964f,0.969975f,0.006799f,0.320971f,0.817079f,0.006799f,0.190931f,0.875529f,0.006799f,0.062976f,0.927034f,0.006799f,-0.061849f,0.968125f,0.006799f,-0.182514f,0.995320f,0.006799f,-0.297963f,1.005165f,-0.211222f,0.320971f,0.788509f,-0.226916f,0.190931f,0.844904f,-0.240746f,0.062981f,0.894599f,-0.251779f,-0.061849f,0.934240f,-0.259083f,-0.182514f,0.960485f,-0.261724f,-0.297963f,0.969975f,-0.405786f,0.320971f,0.707614f,-0.435487f,0.190931f,0.758184f,-0.461659f,0.062981f,0.802749f,-0.482538f,-0.061849f,0.838300f,-0.496361f,-0.182509f,0.861835f,-0.501360f,-0.297963f,0.870345f,-0.569680f,0.320970f,0.581614f,-0.611180f,0.190930f,0.623114f,-0.647745f,0.062975f,0.659684f,-0.676920f,-0.061850f,0.688860f,-0.696230f,-0.182510f,0.708170f,-0.703215f,-0.297963f,0.715155f,-0.695675f,0.320970f,0.417723f,-0.746245f,0.190930f,0.447424f,-0.790810f,0.062980f,0.473596f,-0.826355f,-0.061850f,0.494476f,-0.849895f,-0.182510f,0.508300f,-0.858405f,-0.297963f,0.513300f,-0.776570f,0.320970f,0.223157f,-0.832965f,0.190930f,0.238852f,-0.882660f,0.062975f,0.252683f,-0.922300f,-0.061850f,0.263716f,-0.948545f,-0.182510f,0.271020f,-0.958035f,-0.297963f,0.273661f,-0.863590f,0.190930f,0.005135f,-0.915095f,0.062975f,0.005135f,-0.956185f,-0.061850f,0.005136f,-0.983380f,-0.182510f,0.005136f,-0.832965f,0.190930f,-0.228581f,-0.882660f,0.062980f,-0.242411f,-0.922300f,-0.061850f,-0.253444f,-0.948545f,-0.182510f,-0.260748f,-0.776575f,0.320970f,-0.212886f,-0.695675f,0.320970f,-0.407451f,-0.746245f,0.190930f,-0.437153f,-0.790815f,0.062980f,-0.463325f,-0.826360f,-0.061850f,-0.484204f,-0.849895f,-0.182510f,-0.498027f,-0.958035f,-0.297963f,-0.263389f,-0.858405f,-0.297964f,-0.503025f,-0.569680f,0.320970f,-0.571346f,-0.611180f,0.190930f,-0.612846f,-0.647745f,0.062975f,-0.649411f,-0.676920f,-0.061850f,-0.678585f,-0.696230f,-0.182510f,-0.697895f,-0.703215f,-0.297964f,-0.704880f,-0.405787f,0.320970f,-0.697341f,-0.435488f,0.190930f,-0.747911f,-0.461661f,0.062979f,-0.792481f,-0.482540f,-0.061851f,-0.828025f,-0.496363f,-0.182511f,-0.851560f,-0.501365f,-0.297964f,-0.860070f,-0.211223f,0.320970f,-0.778241f,-0.226919f,0.190929f,-0.834631f,-0.240748f,0.062974f,-0.884326f,-0.251781f,-0.061851f,-0.923965f,-0.259085f,-0.182516f,-0.950210f,-0.261726f,-0.297965f,-0.959700f,0.006797f,0.320970f,-0.806806f,0.006797f,0.190929f,-0.865256f,0.006797f,0.062974f,-0.916761f,0.006797f,-0.061851f,-0.957850f,0.006797f,-0.182516f,-0.985050f,0.006797f,-0.297965f,-0.994890f,0.224817f,0.320970f,-0.778236f,0.240512f,0.190929f,-0.834631f,0.254342f,0.062979f,-0.884326f,0.265375f,-0.061851f,-0.923965f,0.272679f,-0.182516f,-0.950210f,0.275321f,-0.297965f,-0.959700f,0.419381f,0.320970f,-0.697341f,0.449082f,0.190930f,-0.747911f,0.475255f,0.062979f,-0.792476f,0.496134f,-0.061851f,-0.828025f,0.509955f,-0.182516f,-0.851560f,0.514955f,-0.297965f,-0.860070f,0.583275f,0.320965f,-0.571341f,0.624775f,0.190930f,-0.612846f,0.661340f,0.062975f,-0.649411f,0.690515f,-0.061850f,-0.678585f,0.709825f,-0.182515f,-0.697895f,0.716810f,-0.297965f,-0.704880f,0.709270f,0.320965f,-0.407450f,0.759840f,0.190930f,-0.437151f,0.804405f,0.062980f,-0.463323f,0.839955f,-0.061850f,-0.484202f,0.863490f,-0.182515f,-0.498025f,0.872000f,-0.297965f,-0.503025f,0.790165f,0.320965f,-0.212884f,0.846560f,0.190930f,-0.228579f,0.896255f,0.062975f,-0.242409f,0.935895f,-0.061850f,-0.253442f,0.962140f,-0.182515f,-0.260745f,0.971630f,-0.297965f,-0.263387f,0.881815f,-0.555781f,0.005138f,0.942000f,-0.486856f,0.005138f,0.909095f,-0.486856f,0.256259f,0.851030f,-0.555780f,0.240098f,0.821630f,-0.609079f,0.005138f,0.792960f,-0.609079f,0.223937f,0.775335f,-0.647795f,0.005138f,0.748295f,-0.647795f,0.211505f,0.756815f,-0.672969f,0.005138f,0.730425f,-0.672969f,0.206532f,0.953765f,-0.401264f,0.268691f,0.855980f,-0.401264f,0.503890f,0.815925f,-0.486856f,0.480363f,0.763850f,-0.555780f,0.449779f,0.711775f,-0.609079f,0.419195f,0.671720f,-0.647795f,0.395669f,0.655700f,-0.672969f,0.386258f,0.703660f,-0.401264f,0.702005f,0.670790f,-0.486856f,0.669135f,0.628060f,-0.555780f,0.626405f,0.585330f,-0.609079f,0.583675f,0.552460f,-0.647795f,0.550800f,0.539310f,-0.672969f,0.537650f,0.505545f,-0.401264f,0.854325f,0.482021f,-0.486856f,0.814270f,0.451438f,-0.555780f,0.762190f,0.420854f,-0.609079f,0.710120f,0.397328f,-0.647795f,0.670065f,0.387917f,-0.672969f,0.654045f,0.270350f,-0.401263f,0.952110f,0.257919f,-0.486855f,0.907440f,0.241757f,-0.555779f,0.849375f,0.225597f,-0.609079f,0.791300f,0.213165f,-0.647795f,0.746635f,0.208192f,-0.672968f,0.728765f,0.006799f,-0.401263f,0.986640f,0.006799f,-0.486855f,0.940345f,0.006799f,-0.555779f,0.880160f,0.006799f,-0.609078f,0.819975f,0.006799f,-0.647794f,0.773675f,0.006799f,-0.672968f,0.755155f,-0.256752f,-0.401263f,0.952110f,-0.244320f,-0.486854f,0.907440f,-0.228159f,-0.555779f,0.849375f,-0.211997f,-0.609078f,0.791300f,-0.199566f,-0.647794f,0.746635f,-0.194594f,-0.672968f,0.728765f,-0.491948f,-0.401263f,0.854325f,-0.468422f,-0.486854f,0.814265f,-0.437838f,-0.555779f,0.762190f,-0.407255f,-0.609078f,0.710120f,-0.383729f,-0.647794f,0.670065f,-0.374319f,-0.672968f,0.654045f,-0.690065f,-0.401263f,0.702005f,-0.657195f,-0.486854f,0.669135f,-0.614465f,-0.555779f,0.626400f,-0.571730f,-0.609078f,0.583670f,-0.538860f,-0.647794f,0.550800f,-0.525710f,-0.672968f,0.537650f,-0.842380f,-0.401263f,0.503885f,-0.802325f,-0.486854f,0.480361f,-0.750250f,-0.555779f,0.449777f,-0.698180f,-0.609078f,0.419193f,-0.658125f,-0.647794f,0.395668f,-0.642105f,-0.672968f,0.386257f,-0.940170f,-0.401263f,0.268688f,-0.895500f,-0.486854f,0.256257f,-0.837430f,-0.555779f,0.240095f,-0.779360f,-0.609078f,0.223935f,-0.734695f,-0.647794f,0.211503f,-0.716825f,-0.672967f,0.206530f,-0.928405f,-0.486854f,0.005136f,-0.868220f,-0.555779f,0.005136f,-0.808030f,-0.609078f,0.005136f,-0.761735f,-0.647794f,0.005136f,-0.743215f,-0.672967f,0.005136f,-0.895500f,-0.486855f,-0.245985f,-0.837435f,-0.555779f,-0.229823f,-0.779360f,-0.609078f,-0.213663f,-0.734695f,-0.647794f,-0.201231f,-0.716825f,-0.672968f,-0.196258f,-0.940170f,-0.401263f,-0.258417f,-0.842385f,-0.401263f,-0.493615f,-0.802330f,-0.486855f,-0.470089f,-0.750250f,-0.555779f,-0.439505f,-0.698180f,-0.609078f,-0.408921f,-0.658125f,-0.647794f,-0.385395f,-0.642105f,-0.672968f,-0.375984f,-0.690065f,-0.401263f,-0.691730f,-0.657195f,-0.486855f,-0.658860f,-0.614465f,-0.555779f,-0.616130f,-0.571735f,-0.609078f,-0.573400f,-0.538865f,-0.647794f,-0.540525f,-0.525710f,-0.672968f,-0.527375f,-0.491951f,-0.401264f,-0.844050f,-0.468424f,-0.486856f,-0.803995f,-0.437840f,-0.555779f,-0.751915f,-0.407257f,-0.609079f,-0.699845f,-0.383732f,-0.647794f,-0.659790f,-0.374321f,-0.672968f,-0.643770f,-0.256754f,-0.401264f,-0.941835f,-0.244322f,-0.486856f,-0.897165f,-0.228161f,-0.555780f,-0.839100f,-0.212000f,-0.609079f,-0.781030f,-0.199568f,-0.647795f,-0.736360f,-0.194595f,-0.672969f,-0.718490f,0.006797f,-0.401265f,-0.976370f,0.006797f,-0.486856f,-0.930070f,0.006797f,-0.555780f,-0.869885f,0.006797f,-0.609079f,-0.809700f,0.006797f,-0.647795f,-0.763400f,0.006797f,-0.672969f,-0.744880f,0.270348f,-0.401265f,-0.941835f,0.257917f,-0.486856f,-0.897165f,0.241756f,-0.555781f,-0.839100f,0.225595f,-0.609079f,-0.781025f,0.213163f,-0.647795f,-0.736360f,0.208191f,-0.672969f,-0.718490f,0.505545f,-0.401265f,-0.844050f,0.482019f,-0.486856f,-0.803995f,0.451436f,-0.555780f,-0.751915f,0.420852f,-0.609079f,-0.699845f,0.397326f,-0.647795f,-0.659790f,0.387916f,-0.672969f,-0.643770f,0.703660f,-0.401265f,-0.691730f,0.670790f,-0.486856f,-0.658860f,0.628060f,-0.555780f,-0.616130f,0.585330f,-0.609079f,-0.573395f,0.552460f,-0.647795f,-0.540525f,0.539310f,-0.672969f,-0.527375f,0.855980f,-0.401265f,-0.493612f,0.815925f,-0.486856f,-0.470086f,0.763845f,-0.555781f,-0.439503f,0.711775f,-0.609080f,-0.408919f,0.671720f,-0.647795f,-0.385393f,0.655700f,-0.672969f,-0.375983f,0.953765f,-0.401265f,-0.258414f,0.909095f,-0.486856f,-0.245983f,0.851030f,-0.555781f,-0.229821f,0.792960f,-0.609080f,-0.213660f,0.748290f,-0.647796f,-0.201229f,0.730420f,-0.672969f,-0.196256f,0.309756f,-0.745018f,0.005137f,0.006799f,-0.747970f,0.005137f,0.299096f,-0.745018f,-0.076213f,0.517920f,-0.736858f,0.005138f,0.499936f,-0.736859f,-0.132108f,0.648995f,-0.724532f,0.005138f,0.626400f,-0.724532f,-0.167306f,0.720700f,-0.709081f,0.005138f,0.695580f,-0.709081f,-0.186559f,0.750740f,-0.691546f,0.005138f,0.724560f,-0.691546f,-0.194625f,0.268912f,-0.745018f,-0.148811f,0.449012f,-0.736859f,-0.254589f,0.562420f,-0.724532f,-0.321196f,0.624455f,-0.709081f,-0.357633f,0.650440f,-0.691546f,-0.372895f,0.221898f,-0.745018f,-0.209964f,0.369694f,-0.736859f,-0.357760f,0.462759f,-0.724532f,-0.450826f,0.513670f,-0.709081f,-0.501735f,0.534995f,-0.691546f,-0.523060f,0.160745f,-0.745018f,-0.256978f,0.266523f,-0.736859f,-0.437079f,0.333131f,-0.724532f,-0.550485f,0.369566f,-0.709080f,-0.612525f,0.384829f,-0.691546f,-0.638510f,0.088148f,-0.745018f,-0.287162f,0.144044f,-0.736858f,-0.488003f,0.179240f,-0.724532f,-0.614470f,0.198494f,-0.709080f,-0.683650f,0.206559f,-0.691546f,-0.712630f,0.006798f,-0.745018f,-0.297822f,0.006798f,-0.736858f,-0.505985f,0.006798f,-0.724532f,-0.637065f,0.006797f,-0.709080f,-0.708770f,0.006797f,-0.691545f,-0.738805f,-0.074552f,-0.745018f,-0.287162f,-0.130448f,-0.736858f,-0.488003f,-0.165644f,-0.724532f,-0.614470f,-0.184898f,-0.709080f,-0.683650f,-0.192963f,-0.691545f,-0.712630f,-0.147149f,-0.745018f,-0.256979f,-0.252927f,-0.736858f,-0.437080f,-0.319535f,-0.724531f,-0.550485f,-0.355971f,-0.709080f,-0.612525f,-0.371233f,-0.691545f,-0.638510f,-0.208301f,-0.745018f,-0.209964f,-0.356098f,-0.736858f,-0.357762f,-0.449163f,-0.724531f,-0.450828f,-0.500070f,-0.709080f,-0.501735f,-0.521395f,-0.691545f,-0.523060f,-0.255316f,-0.745018f,-0.148811f,-0.435416f,-0.736858f,-0.254590f,-0.548820f,-0.724531f,-0.321198f,-0.610860f,-0.709080f,-0.357634f,-0.636845f,-0.691545f,-0.372897f,-0.285499f,-0.745018f,-0.076213f,-0.486338f,-0.736858f,-0.132110f,-0.612805f,-0.724531f,-0.167307f,-0.681985f,-0.709079f,-0.186561f,-0.710965f,-0.691545f,-0.194626f,-0.296158f,-0.745018f,0.005137f,-0.504320f,-0.736857f,0.005136f,-0.635400f,-0.724531f,0.005136f,-0.707105f,-0.709079f,0.005136f,-0.737140f,-0.691544f,0.005136f,-0.285499f,-0.745017f,0.086487f,-0.486338f,-0.736857f,0.142383f,-0.612805f,-0.724531f,0.177580f,-0.681985f,-0.709079f,0.196833f,-0.710965f,-0.691544f,0.204899f,-0.255315f,-0.745017f,0.159085f,-0.435416f,-0.736858f,0.264863f,-0.548820f,-0.724531f,0.331472f,-0.610860f,-0.709079f,0.367907f,-0.636845f,-0.691544f,0.383169f,-0.208301f,-0.745017f,0.220238f,-0.356097f,-0.736858f,0.368035f,-0.449163f,-0.724531f,0.461101f,-0.500070f,-0.709079f,0.512010f,-0.521395f,-0.691544f,0.533335f,-0.147148f,-0.745017f,0.267253f,-0.252926f,-0.736858f,0.447354f,-0.319533f,-0.724531f,0.560760f,-0.355969f,-0.709079f,0.622795f,-0.371231f,-0.691545f,0.648785f,-0.074551f,-0.745017f,0.297437f,-0.130446f,-0.736858f,0.498277f,-0.165643f,-0.724531f,0.624745f,-0.184896f,-0.709079f,0.693925f,-0.192962f,-0.691545f,0.722905f,0.006799f,-0.745018f,0.308096f,0.006799f,-0.736858f,0.516260f,0.006799f,-0.724531f,0.647340f,0.006799f,-0.709080f,0.719045f,0.006799f,-0.691545f,0.749080f,0.088148f,-0.745018f,0.297437f,0.144045f,-0.736858f,0.498277f,0.179241f,-0.724531f,0.624745f,0.198496f,-0.709080f,0.693925f,0.206561f,-0.691545f,0.722905f,0.160746f,-0.745018f,0.267253f,0.266524f,-0.736858f,0.447355f,0.333132f,-0.724532f,0.560760f,0.369568f,-0.709080f,0.622800f,0.384830f,-0.691545f,0.648785f,0.221898f,-0.745018f,0.220239f,0.369695f,-0.736858f,0.368036f,0.462761f,-0.724532f,0.461102f,0.513670f,-0.709080f,0.512010f,0.534995f,-0.691545f,0.533335f,0.268913f,-0.745018f,0.159085f,0.449014f,-0.736858f,0.264865f,0.562420f,-0.724532f,0.331472f,0.624455f,-0.709080f,0.367908f,0.650440f,-0.691546f,0.383171f,0.299096f,-0.745018f,0.086488f,0.499936f,-0.736858f,0.142384f,0.626400f,-0.724532f,0.177581f,0.695580f,-0.709080f,0.196835f,0.724560f,-0.691546f,0.204901f,-0.956670f,-0.419490f,-0.057225f,0.977196f,-0.301304f,0.226629f,0.628770f,0.452045f,0.001636f,0.607010f,0.452045f,0.167685f,0.545405f,0.452045f,0.315871f,0.449443f,0.452045f,0.440694f,0.324623f,0.452045f,0.536659f,0.176442f,0.452045f,0.598264f,0.010397f,0.452045f,0.620029f,-0.155648f,0.452045f,0.598264f,-0.303831f,0.452045f,0.536659f,-0.428650f,0.452045f,0.440691f,-0.524610f,0.452045f,0.315867f,-0.586220f,0.452045f,0.167681f,-0.607980f,0.452045f,0.001631f,-0.586220f,0.452045f,-0.164418f,-0.524615f,0.452045f,-0.312604f,-0.428652f,0.452045f,-0.437426f,-0.303833f,0.452045f,-0.533391f,-0.155652f,0.452045f,-0.595001f,0.010392f,0.452045f,-0.616761f,0.176436f,0.452045f,-0.595001f,0.324618f,0.452045f,-0.533386f,0.449437f,0.452045f,-0.437423f,0.545400f,0.452045f,-0.312599f,0.607010f,0.452045f,-0.164414f,0.185873f,0.540155f,0.001634f,0.110403f,0.572105f,0.001634f,0.106884f,0.572105f,0.028489f,0.179699f,0.540155f,0.048755f,0.297457f,0.516545f,0.001635f,0.287357f,0.516545f,0.078719f,0.422931f,0.497100f,0.001635f,0.408417f,0.497100f,0.112412f,0.540075f,0.477655f,0.001635f,0.521435f,0.477655f,0.143868f,0.626655f,0.454045f,0.001636f,0.604970f,0.454045f,0.167117f,0.096920f,0.572105f,0.052455f,0.162216f,0.540155f,0.090806f,0.258758f,0.516545f,0.147510f,0.367316f,0.497100f,0.211271f,0.468664f,0.477655f,0.270798f,0.543575f,0.454045f,0.314796f,0.081401f,0.572105f,0.072642f,0.134984f,0.540155f,0.126227f,0.214210f,0.516545f,0.205455f,0.303297f,0.497100f,0.294545f,0.386467f,0.477655f,0.377717f,0.447940f,0.454045f,0.439192f,0.061214f,0.572105f,0.088163f,0.099564f,0.540155f,0.153460f,0.156266f,0.516545f,0.250004f,0.220025f,0.497100f,0.358566f,0.279550f,0.477655f,0.459917f,0.323548f,0.454045f,0.534829f,0.037249f,0.572105f,0.098127f,0.057514f,0.540155f,0.170943f,0.087477f,0.516545f,0.278605f,0.121170f,0.497100f,0.399668f,0.152625f,0.477655f,0.512689f,0.175874f,0.454045f,0.596224f,0.010394f,0.572105f,0.101646f,0.010395f,0.540155f,0.177117f,0.010395f,0.516545f,0.288705f,0.010396f,0.497100f,0.414183f,0.010397f,0.477655f,0.531324f,0.010397f,0.454045f,0.617914f,-0.016460f,0.572105f,0.098126f,-0.036725f,0.540155f,0.170943f,-0.066687f,0.516545f,0.278604f,-0.100378f,0.497100f,0.399667f,-0.131832f,0.477655f,0.512689f,-0.155080f,0.454045f,0.596224f,-0.040425f,0.572105f,0.088162f,-0.078774f,0.540155f,0.153459f,-0.135476f,0.516545f,0.250003f,-0.199234f,0.497100f,0.358564f,-0.258758f,0.477655f,0.459915f,-0.302755f,0.454045f,0.534824f,-0.060612f,0.572105f,0.072642f,-0.114195f,0.540155f,0.126226f,-0.193420f,0.516545f,0.205454f,-0.282506f,0.497100f,0.294543f,-0.365676f,0.477655f,0.377714f,-0.427148f,0.454045f,0.439188f,-0.076132f,0.572105f,0.052455f,-0.141427f,0.540155f,0.090805f,-0.237968f,0.516545f,0.147507f,-0.346526f,0.497100f,0.211268f,-0.447874f,0.477655f,0.270795f,-0.522780f,0.454045f,0.314792f,-0.086096f,0.572105f,0.028489f,-0.158910f,0.540155f,0.048753f,-0.266568f,0.516545f,0.078717f,-0.387627f,0.497100f,0.112409f,-0.500645f,0.477655f,0.143864f,-0.584180f,0.454045f,0.167113f,-0.089615f,0.572105f,0.001633f,-0.165084f,0.540155f,0.001633f,-0.276668f,0.516545f,0.001633f,-0.402143f,0.497100f,0.001632f,-0.519285f,0.477655f,0.001631f,-0.605865f,0.454045f,0.001631f,-0.086096f,0.572105f,-0.025222f,-0.158910f,0.540155f,-0.045488f,-0.266569f,0.516545f,-0.075452f,-0.387628f,0.497100f,-0.109145f,-0.500650f,0.477655f,-0.140601f,-0.584180f,0.454045f,-0.163850f,-0.076132f,0.572105f,-0.049188f,-0.141428f,0.540155f,-0.087538f,-0.237969f,0.516545f,-0.144243f,-0.346527f,0.497100f,-0.208004f,-0.447875f,0.477655f,-0.267531f,-0.522785f,0.454045f,-0.311529f,-0.060612f,0.572105f,-0.069375f,-0.114196f,0.540155f,-0.122960f,-0.193421f,0.516545f,-0.202188f,-0.282508f,0.497100f,-0.291278f,-0.365678f,0.477655f,-0.374450f,-0.427151f,0.454045f,-0.435925f,-0.040426f,0.572105f,-0.084895f,-0.078776f,0.540155f,-0.150193f,-0.135477f,0.516545f,-0.246736f,-0.199237f,0.497100f,-0.355299f,-0.258763f,0.477655f,-0.456650f,-0.302759f,0.454040f,-0.531561f,-0.016461f,0.572105f,-0.094859f,-0.036725f,0.540155f,-0.167676f,-0.066689f,0.516545f,-0.275338f,-0.100381f,0.497100f,-0.396401f,-0.131836f,0.477655f,-0.509421f,-0.155085f,0.454040f,-0.592961f,0.010394f,0.572105f,-0.098378f,0.010394f,0.540155f,-0.173850f,0.010393f,0.516545f,-0.285438f,0.010393f,0.497100f,-0.410916f,0.010393f,0.477655f,-0.528061f,0.010392f,0.454040f,-0.614646f,0.037248f,0.572105f,-0.094859f,0.057513f,0.540155f,-0.167676f,0.087475f,0.516545f,-0.275337f,0.121166f,0.497100f,-0.396400f,0.152620f,0.477655f,-0.509421f,0.175869f,0.454040f,-0.592961f,0.061213f,0.572105f,-0.084895f,0.099563f,0.540155f,-0.150192f,0.156264f,0.516545f,-0.246736f,0.220023f,0.497100f,-0.355297f,0.279548f,0.477655f,-0.456648f,0.323543f,0.454040f,-0.531561f,0.081400f,0.572105f,-0.069375f,0.134983f,0.540155f,-0.122959f,0.214208f,0.516545f,-0.202186f,0.303295f,0.497100f,-0.291276f,0.386463f,0.477655f,-0.374447f,0.447937f,0.454040f,-0.435922f,0.096920f,0.572105f,-0.049187f,0.162216f,0.540155f,-0.087538f,0.258756f,0.516545f,-0.144240f,0.367314f,0.497100f,-0.208001f,0.468662f,0.477655f,-0.267528f,0.543570f,0.454040f,-0.311525f,0.106884f,0.572105f,-0.025221f,0.179698f,0.540155f,-0.045486f,0.287356f,0.516545f,-0.075450f,0.408416f,0.497100f,-0.109142f,0.521435f,0.477655f,-0.140597f,0.604970f,0.454045f,-0.163846f,0.101773f,0.597790f,0.001634f,0.099541f,0.597780f,0.018733f,0.097930f,0.599735f,0.026012f,0.089809f,0.600477f,0.044924f,0.075533f,0.601728f,0.064055f,0.056708f,0.602448f,0.078849f,0.034144f,0.602580f,0.088296f,0.008794f,0.602075f,0.091365f,-0.016399f,0.600928f,0.087737f,-0.038665f,0.599268f,0.078078f,-0.057200f,0.597255f,0.063309f,-0.069141f,0.596180f,0.048360f,-0.073328f,0.593830f,0.040319f,-0.079051f,0.593840f,0.026539f,-0.081028f,0.591445f,0.017577f,-0.083117f,0.591440f,0.001633f,-0.082740f,0.589205f,-0.007009f,-0.080561f,0.589185f,-0.023691f,-0.078309f,0.587215f,-0.030832f,-0.070176f,0.586437f,-0.049086f,-0.055962f,0.585182f,-0.067445f,-0.037572f,0.584492f,-0.081609f,0.007194f,0.584505f,-0.093787f,0.010394f,0.585330f,-0.093934f,0.030672f,0.585320f,-0.091287f,0.035937f,0.586735f,-0.090118f,0.052092f,0.586720f,-0.083416f,0.058412f,0.588580f,-0.080112f,0.070786f,0.588575f,-0.070605f,0.076964f,0.590745f,-0.064939f,0.085922f,0.590750f,-0.053278f,0.090819f,0.593120f,-0.045614f,0.096508f,0.593130f,-0.031898f,0.101392f,0.595545f,-0.007007f,-0.015723f,0.584400f,-0.090724f,0.099286f,0.595545f,-0.023119f,0.146564f,0.753670f,-0.007006f,0.007192f,0.765130f,-0.007007f,0.141685f,0.753670f,0.030540f,0.188700f,0.723465f,-0.007006f,0.182344f,0.723465f,0.041889f,0.169716f,0.680750f,-0.007006f,0.164024f,0.680755f,0.036766f,0.125728f,0.631785f,-0.007007f,0.121573f,0.631785f,0.024901f,0.127852f,0.753670f,0.063973f,0.164329f,0.723465f,0.085428f,0.147889f,0.680755f,0.075750f,0.109798f,0.631785f,0.053328f,0.106277f,0.753670f,0.092083f,0.136230f,0.723465f,0.122036f,0.122725f,0.680755f,0.108531f,0.091436f,0.631785f,0.077240f,0.078169f,0.753670f,0.113659f,0.099624f,0.723465f,0.150137f,0.089946f,0.680755f,0.133696f,0.067525f,0.631785f,0.095602f,0.044737f,0.753670f,0.127492f,0.056086f,0.723465f,0.168153f,0.050964f,0.680755f,0.149831f,0.039099f,0.631785f,0.107379f,0.007194f,0.753670f,0.132372f,0.007194f,0.723465f,0.174509f,0.007194f,0.680755f,0.155524f,0.007194f,0.631785f,0.111533f,-0.030351f,0.753670f,0.127492f,-0.041699f,0.723465f,0.168153f,-0.036577f,0.680755f,0.149831f,-0.024712f,0.631785f,0.107378f,-0.063782f,0.753670f,0.113658f,-0.085236f,0.723465f,0.150136f,-0.075559f,0.680755f,0.133695f,-0.053138f,0.631785f,0.095602f,-0.091891f,0.753670f,0.092082f,-0.121844f,0.723465f,0.122035f,-0.108338f,0.680755f,0.108529f,-0.077050f,0.631785f,0.077239f,-0.113467f,0.753670f,0.063971f,-0.149943f,0.723465f,0.085427f,-0.133502f,0.680755f,0.075748f,-0.095412f,0.631785f,0.053327f,-0.127299f,0.753670f,0.030539f,-0.167959f,0.723465f,0.041887f,-0.149638f,0.680755f,0.036765f,-0.107187f,0.631785f,0.024900f,-0.132179f,0.753670f,-0.007007f,-0.174314f,0.723465f,-0.007008f,-0.155330f,0.680755f,-0.007008f,-0.111342f,0.631785f,-0.007008f,-0.127300f,0.753670f,-0.044554f,-0.167959f,0.723465f,-0.055903f,-0.149638f,0.680755f,-0.050781f,-0.107188f,0.631785f,-0.038915f,-0.113467f,0.753670f,-0.077986f,-0.149944f,0.723465f,-0.099442f,-0.133503f,0.680750f,-0.089764f,-0.095412f,0.631785f,-0.067343f,-0.091892f,0.753670f,-0.106096f,-0.121845f,0.723465f,-0.136051f,-0.108340f,0.680750f,-0.122545f,-0.077051f,0.631785f,-0.091255f,-0.063783f,0.753670f,-0.127673f,-0.085238f,0.723465f,-0.164151f,-0.075560f,0.680750f,-0.147710f,-0.053140f,0.631785f,-0.109617f,-0.030352f,0.753670f,-0.141505f,-0.041701f,0.723465f,-0.182167f,-0.036578f,0.680750f,-0.163846f,-0.024714f,0.631785f,-0.121393f,0.007192f,0.753670f,-0.146385f,0.007192f,0.723465f,-0.188523f,0.007192f,0.680750f,-0.169538f,0.007192f,0.631785f,-0.125548f,0.044737f,0.753670f,-0.141505f,0.056084f,0.723465f,-0.182167f,0.050963f,0.680750f,-0.163845f,0.039099f,0.631785f,-0.121393f,0.078167f,0.753670f,-0.127672f,0.099622f,0.723465f,-0.164150f,0.089944f,0.680750f,-0.147709f,0.067525f,0.631785f,-0.109616f,0.106276f,0.753670f,-0.106095f,0.136229f,0.723465f,-0.136049f,0.122724f,0.680750f,-0.122544f,0.091436f,0.631785f,-0.091254f,0.127852f,0.753670f,-0.077985f,0.164329f,0.723465f,-0.099440f,0.147888f,0.680750f,-0.089763f,0.109797f,0.631785f,-0.067342f,0.141685f,0.753670f,-0.044552f,0.182344f,0.723465f,-0.055901f,0.164023f,0.680750f,-0.050779f,0.121573f,0.631785f,-0.038914f,0.967115f,-0.212480f,0.252557f,0.975462f,-0.378000f,-0.124659f,0.968446f,-0.212076f,-0.231835f,-0.974724f,-0.328037f,0.105130f,-0.967126f,-0.361197f,0.117749f,-0.962988f,-0.395476f,0.102458f,-0.960654f,-0.427175f,0.005343f,-0.967270f,-0.360816f,-0.106910f,-0.985147f,-0.297940f,-0.056185f,-0.963310f,-0.394371f,-0.091242f,-0.984843f,-0.299288f,0.067252f};
2723static int teapot_coord_n = 1190;
2724struct X3D_PolyRep * create_polyrep();
2725void compile_Teapot (struct X3D_Teapot *tnode){
2726 if(tnode->__ifsnode == NULL){
2727 if(teapotifs == NULL){
2728 teapotifs = createNewX3DNode0(NODE_IndexedFaceSet); //IIRC createnewX3DNode0 doesn't add to nodelist or garbage collection
2729 teapotifs->_intern = (struct X3D_GeomRep*) create_polyrep();
2730 teapot_coord = createNewX3DNode0(NODE_Coordinate);
2731 teapotifs->creaseAngle = (float)PI;
2732 teapotifs->normalPerVertex = FALSE;
2733 teapotifs->ccw = TRUE;
2734 teapotifs->coord = X3D_NODE(teapot_coord);
2735 teapot_coord->point.p = (struct SFVec3f*)teapot_coord_p;
2736 teapot_coord->point.n = teapot_coord_n;
2737 teapotifs->coordIndex.p = teapot_coordindex_p;
2738 teapotifs->coordIndex.n = teapot_coordindex_n;
2739 teapotifs->solid = tnode->solid;
2740 }
2741 tnode->__ifsnode = teapotifs;
2742 make_IndexedFaceSet(tnode->__ifsnode);
2743 }
2744}
2745void render_Teapot (struct X3D_Teapot *node){
2746 if(node->__ifsnode == NULL) compile_Teapot(node);
2747 render_IndexedFaceSet(X3D_INDEXEDFACESET(node->__ifsnode));
2748}
2749void rendray_Teapot(struct X3D_Teapot* node) {
2750 if (node->__ifsnode == NULL) return; //compile on render pass
2751 rendray_IndexedFaceSet(X3D_INDEXEDFACESET(node->__ifsnode));
2752
2753}
2754
2755void collide_Teapot (struct X3D_Teapot *node){
2756 if (node->__ifsnode == NULL) return;
2757 collide_IndexedFaceSet(X3D_INDEXEDFACESET(node->__ifsnode));
2758}
2759
2760//PYRAMID
2761static struct X3D_IndexedFaceSet *pyramidifs = NULL;
2762static struct X3D_Coordinate *pyramid_coord;
2763static struct X3D_TextureCoordinate *pyramid_texcoord;
2764static int pyramid_coordindex_p [] = {3, 2, 1, 0, -1, 0, 1, 4, -1, 1, 2, 4, -1, 2, 3, 4, -1, 3, 0, 4, -1};
2765static int pyramid_coordindex_n = 21;
2766static float pyramid_coord_p [] = {-1.0f,-1.0f,1.0f, 1.0f,-1.0f,1.0f, 1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f, 0.0f,1.0f,0.0f};
2767static int pyramid_coord_n = 5;
2768//texture coord rule: first linesegment of face is bottom of image
2769static int pyramid_texcoordindex_p [] = {0, 1, 2, 3, -1, 0, 1, 4, -1, 0, 1, 4, -1, 0, 1, 4, -1, 0, 1, 4, -1};
2770static int pyramid_texcoordindex_n = 21;
2771static float pyramid_texcoord_p [] = {0.0f,0.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f,1.0f, .5f,1.0f};
2772static int pyramid_texcoord_n = 5;
2773struct X3D_PolyRep * create_polyrep();
2774void compile_Pyramid (struct X3D_Pyramid *tnode){
2775 if(tnode->__ifsnode == NULL){
2776 if(pyramidifs == NULL){
2777 pyramidifs = createNewX3DNode0(NODE_IndexedFaceSet); //IIRC createnewX3DNode0 doesn't add to nodelist or garbage collection
2778 pyramidifs->_intern = (struct X3D_GeomRep*) create_polyrep();
2779 pyramid_coord = createNewX3DNode0(NODE_Coordinate);
2780 pyramid_texcoord = createNewX3DNode0(NODE_TextureCoordinate);
2781 pyramidifs->creaseAngle = 0.0F; //(float)PI;
2782 pyramidifs->normalPerVertex = FALSE;
2783 pyramidifs->ccw = TRUE;
2784 pyramidifs->coord = X3D_NODE(pyramid_coord);
2785 pyramid_coord->point.p = (struct SFVec3f*)pyramid_coord_p;
2786 pyramid_coord->point.n = pyramid_coord_n;
2787 pyramidifs->coordIndex.p = pyramid_coordindex_p;
2788 pyramidifs->coordIndex.n = pyramid_coordindex_n;
2789
2790 pyramid_texcoord->point.p = (struct SFVec2f*)pyramid_texcoord_p;
2791 pyramid_texcoord->point.n = pyramid_texcoord_n;
2792 pyramidifs->texCoord = X3D_NODE(pyramid_texcoord);
2793 pyramidifs->texCoordIndex.p = pyramid_texcoordindex_p;
2794 pyramidifs->texCoordIndex.n = pyramid_texcoordindex_n;
2795 pyramidifs->solid = tnode->solid;
2796 }
2797 tnode->__ifsnode = pyramidifs;
2798 make_IndexedFaceSet(tnode->__ifsnode);
2799 }
2800}
2801void rendray_Pyramid (struct X3D_Pyramid *node){
2802 if (node->__ifsnode == NULL) return;
2803 rendray_IndexedFaceSet(X3D_INDEXEDFACESET(node->__ifsnode));
2804
2805}
2806void render_Pyramid (struct X3D_Pyramid *node){
2807 if(node->__ifsnode == NULL) compile_Pyramid(node);
2808 render_IndexedFaceSet(X3D_INDEXEDFACESET(node->__ifsnode));
2809}
2810void collide_Pyramid (struct X3D_Pyramid *node){
2811 if(node->__ifsnode == NULL) return;
2812 collide_IndexedFaceSet(X3D_INDEXEDFACESET(node->__ifsnode));
2813}
2814
2815
2816void delete_glbuffers(struct X3D_Node *node){
2817 //polyrep done in delete_polyrep
2818 switch(node->_nodeType){
2819 case NODE_Cylinder:
2820 clear_Cylinder(node); break;
2821 case NODE_Cone:
2822 clear_Cone(node); break;
2823 case NODE_Sphere:
2824 clear_Sphere(node); break;
2825 default:
2826 break;
2827 }
2828}