35#include <libFreeWRL.h>
37#include "../vrml_parser/Structs.h"
38#include "../main/headers.h"
41#include "LinearAlgebra.h"
42#include "../opengl/Frustum.h"
43#include "../opengl/Material.h"
44#include "Component_Geometry3D.h"
45#include "../opengl/OpenGL_Utils.h"
46#include "../opengl/Textures.h"
48#include "Component_Shape.h"
49#include "../scenegraph/RenderFuncs.h"
50#include "../x3d_parser/Bindable.h"
54#if defined(_MSC_VER) && _MSC_VER < 1500
58#define SEGMENTS_PER_CIRCLE 36
63static void *createLines (
float start,
float end,
float radius,
int closed,
int *size,
float *_extent);
65#define COMPILE_AND_GET_BOUNDS(myType,myField) \
66void compile_##myType (struct X3D_##myType *node){ \
67 float myminx = FLT_MAX; \
68 float mymaxx = -FLT_MAX; \
69 float myminy = FLT_MAX; \
70 float mymaxy = -FLT_MAX; \
73 if (node->myField.n<=0) { \
74 node->EXTENT_MIN_X = 0.0f; \
75 node->EXTENT_MAX_X = 0.0f; \
76 node->EXTENT_MIN_Y = 0.0f; \
77 node->EXTENT_MAX_Y = 0.0f; \
79 for (count = 0; count < node->myField.n; count++) { \
80 if (node->myField.p[count].c[0] > mymaxx) mymaxx = node->myField.p[count].c[0]; \
81 if (node->myField.p[count].c[0] < myminx) myminx = node->myField.p[count].c[0]; \
82 if (node->myField.p[count].c[1] > mymaxy) mymaxy = node->myField.p[count].c[1]; \
83 if (node->myField.p[count].c[1] < myminy) myminy = node->myField.p[count].c[1]; \
85 node->EXTENT_MAX_X = mymaxx; \
86 node->EXTENT_MIN_X = myminx; \
87 node->EXTENT_MAX_Y = mymaxy; \
88 node->EXTENT_MIN_Y = myminy; \
94void* set_LineRep(
void *_linerep,
struct SFVec3f *points,
struct SFVec2f *points2D,
96 int nsegments,
int *counts,
int *starts,
int *skindex);
97void clear_LineRep(
void *_linerep);
100void compile_Arc2D (
struct X3D_Arc2D *node) {
102 struct SFVec2f *tmpptr_a, *tmpptr_b;
109 clear_LineRep(node->_intern);
110 tmpptr_a = createLines (node->startAngle, node->endAngle, node->radius, NONE, &tmpint, node->_extent);
113 node->__numPoints = 0;
114 tmpptr_b = node->__points.p;
115 node->__points.p = tmpptr_a;
116 node->__numPoints = tmpint;
117 FREE_IF_NZ (tmpptr_b);
120 node->_intern = set_LineRep(node->_intern,NULL,node->__points.p,NULL,NULL,NULL,1,&node->__numPoints,start, NULL);
124void render_Arc2D (
struct X3D_Arc2D *node) {
125 ttglobal tg = gglobal();
127 if (node->__numPoints>0) {
129 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
130 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
134 render_LineRep((
struct X3D_LineRep*)node->_intern);
135 tg->Mainloop.trisThisLoop += node->__numPoints;
156 float start, end, radius, angle, angle_increment;
157 int numPoints, arcpoints;
162 ct = node->closureType->strptr;
166 if (strcmp(ct,
"PIE") == 0) {
168 }
else if (strcmp(ct,
"CHORD") == 0) {
171 printf (
"ArcClose2D, closureType %s invalid\n",node->closureType->strptr);
173 start = node->startAngle;
174 end = node->endAngle;
175 radius = node->radius;
177 simpleDisc = APPROX(start,end);
183 if (radius < 0.0) radius = 1.0f;
185 if(0)
if (start > end) {
192 numPoints = SEGMENTS_PER_CIRCLE;
194 numPoints = (int) ((
float)(SEGMENTS_PER_CIRCLE * (end - start))/(PI*2.0f));
196 if (numPoints>SEGMENTS_PER_CIRCLE) numPoints=SEGMENTS_PER_CIRCLE;
198 arcpoints = numPoints;
202 tmpint = SEGMENTS_PER_CIRCLE+2;
203 fp = sfp = MALLOC (
struct SFVec2f *,
sizeof(
struct SFVec2f) * (numPoints));
204 tp = stp = MALLOC (
struct SFVec2f *,
sizeof(
struct SFVec2f) * (numPoints));
205 lindex = MALLOC (
int *,
sizeof(
int) * (numPoints*2)*2);
210 (*fp).c[0] = 0.0f; (*fp).c[1] = 0.0f; fp++;
211 (*tp).c[0] = 0.5f; (*tp).c[1] = 0.5f; tp++;
214 angle_increment = (end - start)/(
float)(arcpoints -1);
215 for (i=0,k=0,j=1;i<arcpoints;i++,k+=4,j++) {
219 (*fp).c[0] = node->radius * x;
220 (*fp).c[1] = node->radius * y;
228 (*tp).c[0] = 0.5f + x*.5f;
229 (*tp).c[1] = 0.5f + y*.5f;
231 angle += angle_increment;
232 angle = max(angle, start);
234 if(closure == CHORD){
235 sfp[0].c[0] = .5f * (sfp[1].c[0] + sfp[arcpoints].c[0]);
236 sfp[0].c[1] = .5f * (sfp[1].c[1] + sfp[arcpoints].c[1]);
237 stp[0].c[0] = .5f * (stp[1].c[0] + stp[arcpoints].c[0]);
238 stp[0].c[1] = .5f * (stp[1].c[1] + stp[arcpoints].c[1]);
240 node->__wireindices = lindex;
244 node->__numPoints = 0;
245 ofp = node->__points.p;
246 otp = node->__texCoords.p;
247 node->__points.p = sfp;
248 node->__points.n = numPoints;
249 node->__texCoords.p = stp;
250 node->__simpleDisk = simpleDisc;
251 node->__numPoints = numPoints;
257 float myminx = FLT_MAX;
258 float mymaxx = -FLT_MAX;
259 float myminy = FLT_MAX;
260 float mymaxy = -FLT_MAX;
261 for (i=0; i<numPoints; i++) {
263 if (sfp[i].c[0] > mymaxx) mymaxx = sfp[i].c[0];
264 if (sfp[i].c[0] < myminx) myminx = sfp[i].c[0];
267 if (sfp[i].c[1] > mymaxy) mymaxy = sfp[i].c[1];
268 if (sfp[i].c[1] < myminy) myminy = sfp[i].c[1];
271 node->EXTENT_MAX_X = myminx;
272 node->EXTENT_MIN_X = mymaxx;
273 node->EXTENT_MAX_Y = myminy;
274 node->EXTENT_MIN_Y = mymaxy;
277#define DESIRE(whichOne,zzz) ((whichOne & zzz)==zzz)
280 if (node->__numPoints>0) {
281 struct textureVertexInfo mtf = {(GLfloat *)node->__texCoords.p,2,GL_FLOAT,0,NULL,NULL};
283 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
284 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
286 CULL_FACE(node->solid)
288 textureCoord_send(&mtf);
289 FW_GL_VERTEX_POINTER (2,GL_FLOAT,0,(GLfloat *)node->__points.p);
293 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
295 sendElementsToGPU(GL_LINES,((node->__numPoints-1)*4 -1 ),node->__wireindices);
297 sendArraysToGPU (GL_TRIANGLE_FAN, 0, node->__numPoints);
300 gglobal()->Mainloop.trisThisLoop += node->__numPoints;
307 struct SFVec2f *tmpptr_a, *tmpptr_b;
313 ct = node->closureType->strptr;
318 if (strcmp(ct,
"PIE") == 0) {
319 tmpptr_a = createLines (node->startAngle,
320 node->endAngle, node->radius, PIE, &tmpint,node->_extent);
321 }
else if (strcmp(ct,
"CHORD") == 0) {
322 tmpptr_a = createLines (node->startAngle,
323 node->endAngle, node->radius, CHORD, &tmpint,node->_extent);
325 printf (
"ArcClose2D, closureType %s invalid\n",node->closureType->strptr);
329 node->__numPoints = 0;
330 tmpptr_b = node->__points.p;
331 node->__points.p = tmpptr_a;
332 node->__numPoints = tmpint;
333 FREE_IF_NZ (tmpptr_b);
339 ttglobal tg = gglobal();
341 if (node->__numPoints>0) {
343 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
344 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
350 FW_GL_VERTEX_POINTER (2,GL_FLOAT,0,(GLfloat *)node->__points.p);
351 sendArraysToGPU (GL_LINE_STRIP, 0, node->__numPoints);
353 gglobal()->Mainloop.trisThisLoop += node->__numPoints;
356int isLeftSide2f(
float* p1,
float* p2,
float* px) {
365 vecset3f(v1, 0.0f, 0.0f, 0.0f);
366 vecset3f(v2, 0.0f, 0.0f, 0.0f);
367 vecdif2f(v1, p2, p1);
368 vecdif2f(v2, px, p1);
369 veccross3f(v3, v1, v2);
370 vecscale3f(v3, v3, 1.0f / (veclength3f(v1) * veclength3f(v2)));
371 float sineangle = v3[2];
372 return sineangle < 0 ? -1 : (sineangle > 0 ? 1 : 0);
374BOOL angleCounterClockwiseBetween(
float a0,
float a1,
float angle) {
378 float na0, na1, nangle;
379 na0 = atan2(sin(a0), cos(a0)) + 2*PI;
380 na1 = atan2(sin(a1), cos(a1)) + 2*PI;
381 nangle = atan2(sin(angle), cos(angle)) + 2*PI;
382 if (na1 < na0) na1 += 2 * PI;
383 if (nangle < na0) nangle += 2 * PI;
384 if (nangle > na0 && nangle < na1)
return TRUE;
391 get_current_ray(&t_r1, &t_r2);
394 a0 = node->startAngle;
399 float zrat0 = (float)ZRAT(z);
401 float cx = (float)MRATX(zrat0);
402 float cy = (float)MRATY(zrat0);
403 float rhit2 = cx * cx + cy * cy;
404 if (r * r > rhit2 ) {
406 float angle = atan2(cy, cx);
407 if(angleCounterClockwiseBetween(a0,a1,angle)){
409 if(!strcmp(node->closureType->strptr,
"PIE"))
410 rayhit(zrat0, cx, cy, z, 0, 0, 1, -1, -1,
"arcclose2dpie");
414 float p1[2], p2[2], px[2];
421 if (isLeftSide2f(p1, p2, px) < 0) {
422 rayhit(zrat0, cx, cy, z, 0, 0, 1, -1, -1,
"arcclose2dchord");
434 struct SFVec2f *tmpptr_a, *tmpptr_b;
440 clear_LineRep(node->_intern);
441 tmpptr_a = createLines (0.0f, 0.0f, node->radius, NONE, &tmpint,node->_extent);
444 node->__numPoints = 0;
445 tmpptr_b = node->__points.p;
446 node->__points.p = tmpptr_a;
447 node->__numPoints = tmpint;
448 FREE_IF_NZ (tmpptr_b);
451 node->_intern = set_LineRep(node->_intern,NULL,node->__points.p,NULL,NULL,NULL,1,&node->__numPoints,start,NULL);
455 ttglobal tg = gglobal();
457 if (node->__numPoints>0) {
459 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
460 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
464 render_LineRep((
struct X3D_LineRep*)node->_intern);
465 gglobal()->Mainloop.trisThisLoop += node->__numPoints;
473float * extent6f_from_box2fn(
float *extent6,
float *p,
int n);
476 extent6f_from_box2fn(node->_extent,(
float*)node->lineSegments.p,node->lineSegments.n);
479 node->_intern = set_LineRep(node->_intern,NULL,node->lineSegments.p,NULL,NULL,NULL,1,&node->lineSegments.n,start,NULL);
483 ttglobal tg = gglobal();
486 if (node->lineSegments.n>0) {
488 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
489 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
494 render_LineRep((
struct X3D_LineRep*)node->_intern);
495 gglobal()->Mainloop.trisThisLoop += node->lineSegments.n;
503 float* points = NULL;
507 if (node->point.n > 0) {
508 points = (
float *)node->point.p;
509 npoint = node->point.n;
511 findExtentInCoord0(X3D_NODE(node), npoint, points, 2);
513 node->_intern = set_PointRep(node->_intern, points, 2, npoint, NULL, 4,0,NULL,0);
517 ttglobal tg = gglobal();
523 setExtent(node->EXTENT_MAX_X, node->EXTENT_MIN_X, node->EXTENT_MAX_Y,
524 node->EXTENT_MIN_Y, node->EXTENT_MAX_Z, node->EXTENT_MIN_Z,
527 if (!node->_intern)
return;
528 render_PointRep(node->_intern);
552 if (node->innerRadius<0) {node->__numPoints = 0;
return;}
553 if (node->outerRadius<0) {node->__numPoints = 0;
return;}
556 if ((APPROX (node->innerRadius, 0.0)) ||
557 (APPROX(node->innerRadius,node->outerRadius))) simpleDisc = TRUE;
558 else simpleDisc = FALSE;
562 tmpint = SEGMENTS_PER_CIRCLE+2;
563 fp = sfp = MALLOC (
struct SFVec2f *,
sizeof(
struct SFVec2f) * (tmpint));
564 tp = stp = MALLOC (
struct SFVec2f *,
sizeof(
struct SFVec2f) * (tmpint));
565 lindex = MALLOC (
int *,
sizeof(
int) * (tmpint*2)*2);
570 (*fp).c[0] = 0.0f; (*fp).c[1] = 0.0f; fp++;
571 (*tp).c[0] = 0.5f; (*tp).c[1] = 0.5f; tp++;
574 for (i=SEGMENTS_PER_CIRCLE,j=1,k=0,m=0; i >= 0; i--,j++,k+=4,m++) {
575 (*fp).c[0] = node->outerRadius * sinf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
576 (*fp).c[1] = node->outerRadius * cosf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
584 (*tp).c[0] = 0.5f + (sinf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE))/id);
585 (*tp).c[1] = 0.5f + (cosf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE))/id);
589 node->__wireindices = lindex;
591 tmpint = (SEGMENTS_PER_CIRCLE+1) * 2;
592 fp = sfp = MALLOC (
struct SFVec2f *,
sizeof(
struct SFVec2f) * 2 * tmpint);
593 tp = stp = MALLOC (
struct SFVec2f *,
sizeof(
struct SFVec2f) * (tmpint));
594 lindex = MALLOC (
int *,
sizeof(
int) * (tmpint*2) *2);
600 id = node->outerRadius * 2.0f / node->innerRadius;
602 for (i=SEGMENTS_PER_CIRCLE,j=0,k=0,m=0; i >= 0; i--,j+=2,k+=8,m++) {
603 (*fp).c[0] = node->innerRadius * (float) sinf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
604 (*fp).c[1] = node->innerRadius * (float) cosf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
606 (*fp).c[0] = node->outerRadius * (float) sinf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
607 (*fp).c[1] = node->outerRadius * (float) cosf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
619 (*tp).c[0] = 0.5f + ((float)sinf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE))/id);
620 (*tp).c[1] = 0.5f + ((float)cosf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE))/id);
622 (*tp).c[0] = 0.5f + ((float)sinf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE))/od);
623 (*tp).c[1] = 0.5f + ((float)cosf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE))/od);
626 node->__wireindices = lindex;
631 node->__numPoints = 0;
632 ofp = node->__points.p;
633 otp = node->__texCoords.p;
634 node->__points.p = sfp;
635 node->__points.n = tmpint;
636 node->__texCoords.p = stp;
637 node->__simpleDisk = simpleDisc;
638 node->__numPoints = tmpint;
643 node->EXTENT_MAX_X = node->outerRadius;
644 node->EXTENT_MIN_X = -node->outerRadius;
645 node->EXTENT_MAX_Y = node->outerRadius;
646 node->EXTENT_MIN_Y = -node->outerRadius;
651 if (node->__numPoints>0) {
652 struct textureVertexInfo mtf = {(GLfloat *)node->__texCoords.p,2,GL_FLOAT,0,NULL,NULL};
654 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
655 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
657 CULL_FACE(node->solid)
659 textureCoord_send(&mtf);
660 FW_GL_VERTEX_POINTER (2,GL_FLOAT,0,(GLfloat *)node->__points.p);
664 if (node->__simpleDisk) {
665 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
667 sendElementsToGPU(GL_LINES,((node->__numPoints-1)*4 -1 ),node->__wireindices);
669 sendArraysToGPU (GL_TRIANGLE_FAN, 0, node->__numPoints);
673 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
675 sendElementsToGPU(GL_LINES,(node->__numPoints*4 -4 -1),node->__wireindices);
677 sendArraysToGPU (GL_TRIANGLE_STRIP, 0, node->__numPoints);
681 gglobal()->Mainloop.trisThisLoop += node->__numPoints;
688 get_current_ray(&t_r1, &t_r2);
690 ri = node->innerRadius;
691 ro = node->outerRadius;
695 float zrat0 = (float)ZRAT(z);
697 float cx = (float)MRATX(zrat0);
698 float cy = (float)MRATY(zrat0);
699 float rhit2 = cx * cx + cy * cy;
700 if (ro * ro > rhit2 && ri * ri < rhit2) {
701 rayhit(zrat0, cx, cy, z, 0, 0, 1, -1, -1,
"disk2d");
713 GLfloat Ssize, Tsize;
722 if ((node->vertices.n %3) != 0) {
723 printf (
"TriangleSet2D, have incorrect vertex count, %d\n",node->vertices.n);
724 node->vertices.n -= node->vertices.n % 3;
728 tmpint = node->vertices.n;
729 node->vertices.n = 0;
732 FREE_IF_NZ (node->__texCoords.p);
733 node->__texCoords.p = fp = MALLOC (
struct SFVec2f *,
sizeof(
struct SFVec2f) * (tmpint));
734 node->__texCoords.n = tmpint;
735 node->__wireindices = lindex = MALLOC (
int *,
sizeof(
int)*(tmpint+1)*2);
737 minY = minX = FLT_MAX;
738 maxY = maxX = -FLT_MAX;
739 for (i=0; i<tmpint; i++) {
740 if (node->vertices.p[i].c[0] < minX) minX = node->vertices.p[i].c[0];
741 if (node->vertices.p[i].c[1] < minY) minY = node->vertices.p[i].c[1];
742 if (node->vertices.p[i].c[0] > maxX) maxX = node->vertices.p[i].c[0];
743 if (node->vertices.p[i].c[1] > maxY) maxY = node->vertices.p[i].c[1];
747 node->EXTENT_MAX_X = maxX;
748 node->EXTENT_MIN_X = minX;
749 node->EXTENT_MAX_Y = maxY;
750 node->EXTENT_MIN_Y = minY;
757 for (i=0,j=0; i<tmpint/3; i++,j+=6) {
761 lindex[j + 1] = i3+1;
762 lindex[j + 2] = i3+1;
763 lindex[j + 3] = i3+2;
764 lindex[j + 4] = i3+2;
768 for (i=0; i<tmpint; i++) {
769 (*fp).c[0] = (node->vertices.p[i].c[0] - minX) / Ssize;
770 (*fp).c[1] = (node->vertices.p[i].c[1] - minY) / Tsize;
775 node->vertices.n = tmpint;
780 if (node->vertices.n>0) {
781 struct textureVertexInfo mtf = {(GLfloat *)node->__texCoords.p,2,GL_FLOAT,0,NULL,NULL};
783 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
784 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
786 CULL_FACE(node->solid)
788 textureCoord_send(&mtf);
789 FW_GL_VERTEX_POINTER (2,GL_FLOAT,0,(GLfloat *)node->vertices.p);
792 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
794 sendElementsToGPU(GL_LINES,(node->vertices.n*2),node->__wireindices);
796 sendArraysToGPU (GL_TRIANGLES, 0, node->vertices.n);
799 gglobal()->Mainloop.trisThisLoop += node->vertices.n;
807 get_current_ray(&t_r1, &t_r2);
811 float zrat0 = (float)ZRAT(z);
813 float cx = (float)MRATX(zrat0);
814 float cy = (float)MRATY(zrat0);
819 struct SFVec2f* pp = node->vertices.p;
820 for (
int i = 0; i < node->vertices.n; i += 3) {
823 iside[0] = isLeftSide2f(pp[i].c, pp[i + 1].c, px);
824 iside[1] = isLeftSide2f(pp[i + 1].c, pp[i + 2].c, px);
825 iside[2] = isLeftSide2f(pp[i + 2].c, pp[i].c, px);
827 if (iside[0] <= 0 && iside[1] <=0 && iside[2] <= 0) {
828 rayhit(zrat0, cx, cy, z, 0, 0, 1, -1, -1,
"triangleset2d");
833 if (iside[0] >= 0 && iside[1] >= 0 && iside[2] >= 0) {
834 rayhit(zrat0, cx, cy, z, 0, 0, 1, -1, -1,
"triangleset2d");
851 float x = ((node->size).c[0])/2;
852 float y = ((node->size).c[1])/2;
857 if (!node->__points.p) ptr = MALLOC (
struct SFVec3f *,
sizeof(
struct SFVec3f)*(6));
858 else ptr = node->__points.p;
862 #define PTF0 *pt++ = x; *pt++ = y; *pt++ = 0.0f;
863 #define PTF1 *pt++ = -x; *pt++ = y; *pt++ = 0.0f;
864 #define PTF2 *pt++ = -x; *pt++ = -y; *pt++ = 0.0f;
865 #define PTF3 *pt++ = x; *pt++ = -y; *pt++ = 0.0f;
867 PTF0 PTF1 PTF2 PTF0 PTF2 PTF3
869 node->__points.p = (
struct SFVec3f*) ptr;
879 extern GLfloat boxtex[];
880 extern GLfloat boxnorms[];
883 float x = ((node->size).c[0])/2;
884 float y = ((node->size).c[1])/2;
887 if ((x < 0) || (y < 0))
return;
890 if (!node->__points.p)
return;
893 setExtent(x,-x,y,-y,0.0f,0.0f,X3D_NODE(node));
895 CULL_FACE(node->solid)
898 textureCoord_send(&mtf);
899 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,(GLfloat *)node->__points.p);
900 FW_GL_NORMAL_POINTER (GL_FLOAT,0,boxnorms);
903 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
905 static int wireindices [] = { 0, 1, 1, 2, 2, 0, 3, 4, 4, 5, 5, 3 };
906 sendElementsToGPU(GL_LINES,6*2,wireindices);
908 sendArraysToGPU (GL_TRIANGLES, 0, 6);
910 gglobal()->Mainloop.trisThisLoop += 2;
917 get_current_ray(&t_r1, &t_r2);
919 sx = node->size.c[0];
920 sy = node->size.c[1];
923 float zrat0 = (float)ZRAT(z);
925 float cx = (float)MRATX(zrat0);
926 float cy = (float)MRATY(zrat0);
927 if (fabs(cx) < fabs(sx) && fabs(cy) < fabs(sy)) {
928 rayhit(zrat0, cx, cy, z, 0, 0, 1, -1, -1,
"disk2d");
940static void *createLines (
float start,
float end,
float radius,
int closed,
int *size,
float *_extent) {
949 float myminx = FLT_MAX;
950 float mymaxx = -FLT_MAX;
951 float myminy = FLT_MAX;
952 float mymaxy = -FLT_MAX;
957 isCircle = APPROX(start,end);
960 if ((start < PI*2.0) || (start > PI*2.0)) start = 0.0f;
961 if ((end < PI*2.0) || (end > PI*2.0)) end = (float) (PI/2.0);
962 if (radius<0.0) radius = 1.0f;
972 numPoints = SEGMENTS_PER_CIRCLE;
975 numPoints = (int) ((
float)(SEGMENTS_PER_CIRCLE * (start-end))/(PI*2.0f));
976 if (numPoints>SEGMENTS_PER_CIRCLE) numPoints=SEGMENTS_PER_CIRCLE;
982 arcpoints = numPoints;
985 if (closed == CHORD) numPoints+=2;
986 if (closed == PIE) numPoints+=2;
988 points = MALLOC (
float *,
sizeof(
float)*numPoints*2);
991 for (i=0; i<arcpoints; i++) {
992 *fp = radius * cosf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
994 *fp = radius * sinf(((
float)PI * 2.0f * (
float)i)/((
float)SEGMENTS_PER_CIRCLE));
999 if (closed == CHORD) {
1001 *fp = .5f*(points[0] + points[(arcpoints-1)*2]);
1003 *fp = .5f*(points[1] + points[(arcpoints-1)*2 +1]);
1007 *fp = radius * cosf(0.0f/((
float)SEGMENTS_PER_CIRCLE));
1009 *fp = radius * sinf(0.0f/((
float)SEGMENTS_PER_CIRCLE));
1011 }
else if (closed == PIE) {
1013 *fp = 0.0f; fp++; *fp=0.0f; fp++;
1015 *fp = radius * cosf(0.0f/((
float)SEGMENTS_PER_CIRCLE));
1017 *fp = radius * sinf(0.0f/((
float)SEGMENTS_PER_CIRCLE));
1025 EXTENT_MAX_X = 0.0f;
1026 EXTENT_MIN_X = 0.0f;
1027 EXTENT_MAX_Y = 0.0f;
1028 EXTENT_MIN_Y = 0.0f;
1032 for (i=0; i<numPoints; i++) {
1034 if (*fp > mymaxx) mymaxx = *fp;
1035 if (*fp < myminx) myminx = *fp;
1038 if (*fp > mymaxy) mymaxy = *fp;
1039 if (*fp < myminy) myminy = *fp;
1042 EXTENT_MIN_X = myminx;
1043 EXTENT_MAX_X = mymaxx;
1044 EXTENT_MIN_Y = myminy;
1045 EXTENT_MAX_Y = mymaxy;
1048 return (
void *)points;
1052#define FLOAT_TOLERANCE 0.00000001
1054 GLDOUBLE modelMatrix[16];
1056 ttglobal tg = gglobal();
1057 union upoint_XYZ maxdispv = { .c = {0,0,0} };
1058 double maxdisp = 0.0;
1061 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1063 matmultiplyAFFINE(modelMatrix, modelMatrix, FallInfo()->avatar2collision);
1066 float center[3], size[3], bboxmin[3], bboxmax[3];
1067 extent6f2bbox(node->_extent, center, size);
1068 vecdif3f(bboxmin, center, size);
1069 vecadd3f(bboxmax, center, size);
1070 double shapeMBBmin[3], shapeMBBmax[3];
1071 float2double(shapeMBBmin, bboxmin, 3);
1072 float2double(shapeMBBmax, bboxmax, 3);
1073 if (!avatarCollisionVolumeIntersectMBB(modelMatrix, shapeMBBmin, shapeMBBmax))
return;
1076 vertices[0].c[0] = -node->size.c[0] * .5f;
1077 vertices[0].c[1] = -node->size.c[1] * .5f;
1078 vertices[1].c[0] = -node->size.c[0] * .5f;
1079 vertices[1].c[1] = node->size.c[1] * .5f;
1080 vertices[2].c[0] = node->size.c[0] * .5f;
1081 vertices[2].c[1] = node->size.c[1] * .5f;
1082 vertices[3].c[0] = node->size.c[0] * .5f;
1083 vertices[3].c[1] = -node->size.c[1] * .5f;
1087 for (
int j = 0; j < 4; j++) {
1088 float2double(pts[j].c, vertices[j].c, 2);
1090 transform(&pts[j].p, &pts[j].p, modelMatrix);
1092 vecdifd(v1.c, pts[1].c, pts[0].c);
1093 vecdifd(v2.c, pts[3].c, pts[0].c);
1094 veccrossd(nn.c, v2.c, v1.c);
1096 dispv.p = get_poly_disp_2((
struct point_XYZ*)pts, 4, nn.p);
1097 disp = vecdot(&dispv.p, &dispv.p);
1102 if ((disp > FLOAT_TOLERANCE) && (disp > maxdisp)) {
1106 vecscale(&maxdispv.p, &maxdispv.p, -1);
1108 accumulate_disp(CollisionInfo(), maxdispv.p);
1113 GLDOUBLE modelMatrix[16];
1115 ttglobal tg = gglobal();
1116 union upoint_XYZ maxdispv = { .c = {0,0,0} };
1117 double maxdisp = 0.0;
1120 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1122 matmultiplyAFFINE(modelMatrix, modelMatrix, FallInfo()->avatar2collision);
1125 float center[3], size[3], bboxmin[3], bboxmax[3];
1126 extent6f2bbox(node->_extent, center, size);
1127 vecdif3f(bboxmin, center, size);
1128 vecadd3f(bboxmax, center, size);
1129 double shapeMBBmin[3], shapeMBBmax[3];
1130 float2double(shapeMBBmin, bboxmin, 3);
1131 float2double(shapeMBBmax, bboxmax, 3);
1132 if (!avatarCollisionVolumeIntersectMBB(modelMatrix, shapeMBBmin, shapeMBBmax))
return;
1134 for(
int i=0;i<node->vertices.n;i+=3){
1137 for (
int j = 0; j < 3; j++) {
1138 float2double(pts[j].c, node->vertices.p[i + j].c, 2);
1140 transform(&pts[j].p, &pts[j].p, modelMatrix);
1142 vecdifd(v1.c, pts[1].c, pts[0].c);
1143 vecdifd(v2.c, pts[2].c, pts[0].c);
1144 veccrossd(nn.c, v2.c, v1.c);
1146 dispv.p = get_poly_disp_2((
struct point_XYZ*)pts, 3, nn.p);
1147 disp = vecdot(&dispv.p, &dispv.p);
1152 if ((disp > FLOAT_TOLERANCE) && (disp > maxdisp)) {
1157 vecscale(&maxdispv.p, &maxdispv.p, -1);
1159 accumulate_disp(CollisionInfo(), maxdispv.p);
1164 GLDOUBLE modelMatrix[16];
1166 ttglobal tg = gglobal();
1167 union upoint_XYZ maxdispv = { .c = {0,0,0} };
1168 double maxdisp = 0.0;
1171 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1173 matmultiplyAFFINE(modelMatrix, modelMatrix, FallInfo()->avatar2collision);
1176 float center[3], size[3], bboxmin[3], bboxmax[3];
1177 extent6f2bbox(node->_extent, center, size);
1178 vecdif3f(bboxmin, center, size);
1179 vecadd3f(bboxmax, center, size);
1180 double shapeMBBmin[3], shapeMBBmax[3];
1181 float2double(shapeMBBmin, bboxmin, 3);
1182 float2double(shapeMBBmax, bboxmax, 3);
1183 if (!avatarCollisionVolumeIntersectMBB(modelMatrix, shapeMBBmin, shapeMBBmax))
return;
1189 float2double(pts[0].c, node->__points.p[0].c, 2);
1191 transform(&pts[0].p, &pts[0].p, modelMatrix);
1193 for (
int i = 1; i < node->__points.n; i++) {
1194 float2double(pts[1].c, node->__points.p[i].c, 2);
1196 transform(&pts[1].p, &pts[1].p, modelMatrix);
1197 float2double(pts[2].c, node->__points.p[2].c, 2);
1199 transform(&pts[2].p, &pts[2].p, modelMatrix);
1201 vecdifd(v1.c, pts[1].c, pts[0].c);
1202 vecdifd(v2.c, pts[2].c, pts[0].c);
1203 veccrossd(nn.c, v2.c, v1.c);
1205 dispv.p = get_poly_disp_2((
struct point_XYZ*)pts, 3, nn.p);
1206 disp = vecdot(&dispv.p, &dispv.p);
1211 if ((disp > FLOAT_TOLERANCE) && (disp > maxdisp)) {
1216 vecscale(&maxdispv.p, &maxdispv.p, -1);
1218 accumulate_disp(CollisionInfo(), maxdispv.p);
1222void collide_Disk2D(
struct X3D_Disk2D* node) {
1223 GLDOUBLE modelMatrix[16];
1225 ttglobal tg = gglobal();
1226 union upoint_XYZ maxdispv = { .c = {0,0,0} };
1227 double maxdisp = 0.0;
1230 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1232 matmultiplyAFFINE(modelMatrix, modelMatrix, FallInfo()->avatar2collision);
1235 float center[3], size[3], bboxmin[3], bboxmax[3];
1236 extent6f2bbox(node->_extent, center, size);
1237 vecdif3f(bboxmin, center, size);
1238 vecadd3f(bboxmax, center, size);
1239 double shapeMBBmin[3], shapeMBBmax[3];
1240 float2double(shapeMBBmin, bboxmin, 3);
1241 float2double(shapeMBBmax, bboxmax, 3);
1242 if (!avatarCollisionVolumeIntersectMBB(modelMatrix, shapeMBBmin, shapeMBBmax))
return;
1247 if (node->__simpleDisk) {
1250 float2double(pts[0].c, node->__points.p[0].c, 2);
1252 transform(&pts[0].p, &pts[0].p, modelMatrix);
1254 for (
int i = 1; i < node->__points.n; i++) {
1255 float2double(pts[1].c, node->__points.p[i].c, 2);
1257 transform(&pts[1].p, &pts[1].p, modelMatrix);
1258 float2double(pts[2].c, node->__points.p[2].c, 2);
1260 transform(&pts[2].p, &pts[2].p, modelMatrix);
1262 vecdifd(v1.c, pts[1].c, pts[0].c);
1263 vecdifd(v2.c, pts[2].c, pts[0].c);
1264 veccrossd(nn.c, v2.c, v1.c);
1266 dispv.p = get_poly_disp_2((
struct point_XYZ*)pts, 3, nn.p);
1267 disp = vecdot(&dispv.p, &dispv.p);
1272 if ((disp > FLOAT_TOLERANCE) && (disp > maxdisp)) {
1279 for (
int i = 0; i < node->__points.n -1; i++) {
1280 for (
int j = 0; j < 3; j++) {
1281 float2double(pts[j].c, node->__points.p[i + j].c, 2);
1283 transform(&pts[j].p, &pts[j].p, modelMatrix);
1285 vecdifd(v1.c, pts[1].c, pts[0].c);
1286 vecdifd(v2.c, pts[2].c, pts[0].c);
1287 veccrossd(nn.c, v2.c, v1.c);
1289 dispv.p = get_poly_disp_2((
struct point_XYZ*)pts, 3, nn.p);
1290 disp = vecdot(&dispv.p, &dispv.p);
1295 if ((disp > FLOAT_TOLERANCE) && (disp > maxdisp)) {
1301 vecscale(&maxdispv.p, &maxdispv.p, -1);
1303 accumulate_disp(CollisionInfo(), maxdispv.p);