34#include <libFreeWRL.h>
36#include "../vrml_parser/Structs.h"
37#include "../main/headers.h"
38#include "../opengl/Frustum.h"
39#include "../opengl/Material.h"
40#include "../opengl/OpenGL_Utils.h"
41#include "../opengl/Textures.h"
42#include "../scenegraph/Component_Shape.h"
43#include "../scenegraph/RenderFuncs.h"
46#include "LinearAlgebra.h"
51static void recalculateColorField(
struct X3D_PolyRep *r) {
57 r->transparency = getAppearanceProperties()->transparency;
61 np = (
float *)newcolors;
63 for (n=0; n<r->ntri*3; n++) {
64 *np = *op; np++; op++;
65 *np = *op; np++; op++;
66 *np = *op; np++; op++;
67 *np = getAppearanceProperties()->transparency; np++; op++;
70 r->color = (
float *)newcolors;
74 if (r->VBO_buffers[COLOR_VBO] == 0) glGenBuffers(1,&r->VBO_buffers[COLOR_VBO]);
75 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,r->VBO_buffers[COLOR_VBO]);
76 glBufferData(GL_ARRAY_BUFFER,r->ntri*
sizeof(
struct SFColorRGBA)*3,r->color, GL_STATIC_DRAW);
82int count_IFS_faces(
int cin,
struct Multi_Int32 *coordIndex) {
85 int max_points_per_face = 0;
86 int min_points_per_face = 99999;
90 if (coordIndex == NULL)
return 0;
91 if (coordIndex->n == 0)
return 0;
93 for(i=0; i<cin; i++) {
95 if((coordIndex->p[i] == -1) || (i==cin-1)) {
96 if(coordIndex->p[i] != -1) {
101 if (pointctr > max_points_per_face)
102 max_points_per_face = pointctr;
103 if (pointctr < min_points_per_face)
104 min_points_per_face = pointctr;
129int IFS_face_normals (
140 int tmp_a = 0, this_face_finished;
143 int pt_1, pt_2, pt_3;
146 float a[3];
float b[3];
156 for(i=0; i<faces; i++) {
161 for(i=0; i<faces; i++) {
169 vecset3f(facenormals[i].c,0.0f, 0.0f, 1.0f);
172 if (tmp_a >= cin-2) {
173 printf (
"last face in Indexed Geometry has not enough vertexes\n");
177 if ((coordIndex->p[tmp_a] == -1) ||
178 (coordIndex->p[tmp_a+1] == -1) ||
179 (coordIndex->p[tmp_a+2] == -1)) {
180 printf (
"IndexedFaceNormals: have a face with two or less vertexes\n");
183 if (coordIndex->p[tmp_a] != -1) tmp_a++;
188 while (checkpoint < cin) {
189 if (coordIndex->p[checkpoint] == -1) {
193 if ((coordIndex->p[checkpoint] < 0) ||
194 (coordIndex->p[checkpoint] >= npoints)) {
195 printf (
"Indexed Geometry face %d has a point out of range,",i);
196 printf (
" point is %d, should be between 0 and %d\n",
197 coordIndex->p[checkpoint],npoints-1);
212 this_face_finished = FALSE;
216 pt_2 = tmp_a+1; pt_3 = tmp_a+2;
219 pt_3 = tmp_a+1; pt_2 = tmp_a+2;
223 float fnorm[3], fnormlen, delta[3];
225 c1 = &(points[coordIndex->p[pt_1]]);
226 c2 = &(points[coordIndex->p[pt_2]]);
227 c3 = &(points[coordIndex->p[pt_3]]);
235 vecdif3f(a,c2->c,c1->c);
236 vecdif3f(b,c3->c,c1->c);
243 veccross3f(fnorm,a,b);
248 fnormlen= veclength3f(fnorm);
249 if(fnormlen > this_vl) {
252 veccopy3f(facenormals[i].c,fnorm);
262 AC = veclength3f(vecdif3f(delta,c1->c,c2->c));
263 BC = veclength3f(vecdif3f(delta,c2->c,c3->c));
274 if (AC < BC) { pt_2++; }
285 if ((tmp_a >= cin-2) || (coordIndex->p[tmp_a+2] == -1)) {
286 this_face_finished = TRUE; tmp_a +=2;
288 }
while (!this_face_finished);
290 if (APPROX(this_vl,0.0)) {
296 vecnormalize3f(facenormals[i].c,facenormals[i].c);
320 while (((coordIndex->p[tmp_a-1]) != -1) && (tmp_a < cin-2)) {
331 for(i=0; i<faces; i++) {
332 if (faceok[i] == TRUE) {
336 if (!retval)
return retval;
343 for (i=0; i<npoints; i++) { pointfaces[i*POINT_FACES]=0; }
345 for(i=0; i<cin; i++) {
346 tmp_a=coordIndex->p[i];
351 if (faceok[facectr]) {
353 add_to_face (tmp_a,facectr,pointfaces);
381void Extru_check_normal (
390 float a[3], b[3], fnorm[3], fnormlen;
403 c1 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[0]];
404 c2 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[zz1]];
405 c3 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[zz2]];
415 a[0] = c2->c[0] - c1->c[0];
416 a[1] = c2->c[1] - c1->c[1];
417 a[2] = c2->c[2] - c1->c[2];
418 b[0] = c3->c[0] - c1->c[0];
419 b[1] = c3->c[1] - c1->c[1];
420 b[2] = c3->c[2] - c1->c[2];
421 vecdif3f(a,c2->c,c1->c);
422 vecdif3f(b,c3->c,c1->c);
423 veccross3f(fnorm,a,b);
428 fnormlen = veclength3f(fnorm);
430 if (APPROX(fnormlen,0.0f)) {
431 ConsoleMessage (
"WARNING: FreeWRL got degenerate triangle; OpenGL tesselator should not give degenerate triangles back %f\n",
434 vecnormalize3f(facenormals[this_face].c,fnorm);
444void IFS_check_normal (
447 struct SFVec3f *points,
int base,
451 float a[3], b[3], fnorm[3], fnormlen;
461 c1 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[0]]]);
463 c2 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[1]]]);
464 c3 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[2]]]);
466 c3 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[1]]]);
467 c2 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[2]]]);
470 a[0] = c2->c[0] - c1->c[0];
471 a[1] = c2->c[1] - c1->c[1];
472 a[2] = c2->c[2] - c1->c[2];
473 b[0] = c3->c[0] - c1->c[0];
474 b[1] = c3->c[1] - c1->c[1];
475 b[2] = c3->c[2] - c1->c[2];
476 vecdif3f(a,c2->c,c1->c);
477 vecdif3f(b,c3->c,c1->c);
478 veccross3f(fnorm,a,b);
479 fnormlen = veclength3f(fnorm);
480 veccopy3f(facenormals[this_face].c,fnorm);
488 if (APPROX(fnormlen,0.0f)) {
493 vecnormalize3f(facenormals[this_face].c,facenormals[this_face].c);
512 if (pointfaces[point] < (POINT_FACES-1)) {
514 for (count = 1; count <= pointfaces[point]; count++) {
515 if (pointfaces[point+count] == face)
return;
519 pointfaces[point+ pointfaces[point]] = face;
541 float a[3], b[3], fnorm[3], fnormlen;
554 this_Elev->cindex[vertex_ind] = (GLuint)A;
555 this_Elev->cindex[vertex_ind+1] = (GLuint)D;
556 this_Elev->cindex[vertex_ind+2] = (GLuint)E;
572 c1 = (
struct SFVec3f *) &this_Elev->actualCoord[3*A];
573 c2 = (
struct SFVec3f *) &this_Elev->actualCoord[3*D];
574 c3 = (
struct SFVec3f *) &this_Elev->actualCoord[3*E];
582 a[0] = c2->c[0] - c1->c[0];
583 a[1] = c2->c[1] - c1->c[1];
584 a[2] = c2->c[2] - c1->c[2];
585 b[0] = c3->c[0] - c1->c[0];
586 b[1] = c3->c[1] - c1->c[1];
587 b[2] = c3->c[2] - c1->c[2];
588 vecdif3f(a,c2->c,c1->c);
589 vecdif3f(b,c3->c,c1->c);
590 veccross3f(fnorm,a,b);
591 vecnormalize3f(fnorm,fnorm);
592 veccopy3f(facenormals[this_face].c,fnorm);
603 add_to_face (A*POINT_FACES,this_face,pointfaces);
604 add_to_face (D*POINT_FACES,this_face,pointfaces);
605 add_to_face (E*POINT_FACES,this_face,pointfaces);
631 if (vertex_ind+2 >= tcindexsize) {
632 printf (
"INTERNAL ERROR: Extru_tex, bounds check %d >= %d\n",vertex_ind+2,tcindexsize);
636 if (!(ccw)) { j = B; B = C; C = j; }
639 tcindex[vertex_ind] = (GLuint)(tci_ct+A);
640 tcindex[vertex_ind+1] =(GLuint)(tci_ct+B);
641 tcindex[vertex_ind+2] =(GLuint)(tci_ct+C);
660 float *GeneratedTexCoords,
664 GLfloat minS = 9999.9f;
665 GLfloat maxS = -9999.9f;
666 GLfloat minT = 9999.9f;
667 GLfloat maxT = -9999.9f;
669 GLfloat Srange = 0.0f;
670 GLfloat Trange = 0.0f;
677 for (x=0; x<nsec; x++) {
679 if (Vals[x*2+0] < minS) minS = Vals[x*2+0];
680 if (Vals[x*2+0] > maxS) maxS = Vals[x*2+0];
681 if (Vals[x*2+1] < minT) minT = Vals[x*2+1];
682 if (Vals[x*2+1] > maxT) maxT = Vals[x*2+1];
685 Trange = maxT - minT;
688 if (APPROX(Srange, 0.0)) Srange = 0.001f;
689 if (APPROX(Trange, 0.0)) Trange = 0.001f;
699 for(x=start; x<end; x++) {
715 tci = tcindex[triind_start*3];
719 if ((tci*3+2) >= tcoordsize) {
720 printf (
"INTERNAL ERROR: Extru_ST_map(1), index %d greater than %d \n",(tci*3+2),tcoordsize);
725 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
728 GeneratedTexCoords[tci*3+1] = 0;
731 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
735 tci = tcindex[triind_start*3+1];
738 if ((tci*3+2) >= tcoordsize) {
739 printf (
"INTERNAL ERROR: Extru_ST_map(2), index %d greater than %d \n",(tci*3+2),tcoordsize);
744 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
747 GeneratedTexCoords[tci*3+1] = 0;
750 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
754 tci = tcindex[triind_start*3+2];
756 if ((tci*3+2) >= tcoordsize) {
757 printf (
"INTERNAL ERROR: Extru_ST_map(3), index %d greater than %d \n",(tci*3+2),tcoordsize);
762 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
765 GeneratedTexCoords[tci*3+1] = 0;
768 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
775void do_glNormal3fv(
struct SFVec3f *dest, GLfloat *param) {
780 myp.x = param[0]; myp.y = param[1]; myp.z = param[2];
782 normalize_vector (&myp);
784 dest->c[0] = (float) myp.x; dest->c[1] = (float) myp.y; dest->c[2] = (float) myp.z;
797#define DESIRE(whichOne,zzz) ((whichOne & zzz)==zzz)
799void render_polyrep(
void *node) {
808 renderedNodePtr = X3D_NODE(node);
810 pr = renderedNodePtr->_intern;
813 printf (
"\nrender_polyrep, _nodeType %s\n",stringNodeType(renderedNodePtr->_nodeType));
814 printf (
"ntri %d\n",pr->ntri);
823 if ((pr->VBO_buffers[VERTEX_VBO]) == 0)
return;
826 printf (
"render_polyrep, not streamed, returning\n");
831 tg->Textures.global_tcin = pr->tcindex;
832 tg->Textures.global_tcin_count = pr->ntri*3;
833 tg->Textures.global_tcin_lastParent = node;
837 static int count = 0;
839 {extent6f_printf(renderedNodePtr->_extent);printf(
" r_p\n");}
842 if(1) setExtent( renderedNodePtr->EXTENT_MAX_X, renderedNodePtr->EXTENT_MIN_X, renderedNodePtr->EXTENT_MAX_Y,
843 renderedNodePtr->EXTENT_MIN_Y, renderedNodePtr->EXTENT_MAX_Z, renderedNodePtr->EXTENT_MIN_Z,
849 glEnable(GL_CULL_FACE);
850 glCullFace(GL_FRONT);
854 hasc = ((pr->VBO_buffers[COLOR_VBO]!=0) || pr->color) && (tg->RenderFuncs.last_texture_type!=TEXTURE_NO_ALPHA);
858 if (!pr->isRGBAcolorNode)
859 if (!APPROX(pr->transparency,getAppearanceProperties()->transparency)) {
860 recalculateColorField(pr);
867 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,0);
868 if (pr->VBO_buffers[NORMAL_VBO]!=0 ) {
869 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[NORMAL_VBO]);
870 FW_GL_NORMAL_POINTER(GL_FLOAT,0,0);
871 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_FLAT) ) {
872 if(pr->last_normal_type != 1)
873 glBufferData(GL_ARRAY_BUFFER,
sizeof (GLfloat)*3*pr->ntri*3,pr->flat_normal,GL_STATIC_DRAW);
874 pr->last_normal_type = 1;
876 if(pr->last_normal_type != 0)
877 glBufferData(GL_ARRAY_BUFFER,
sizeof (GLfloat)*3*pr->ntri*3,pr->normal,GL_STATIC_DRAW);
878 pr->last_normal_type = 0;
882 if (pr->VBO_buffers[FOG_VBO]!=0) {
883 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[FOG_VBO]);
884 FW_GL_FOG_POINTER(GL_FLOAT,0,0);
890 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,pr->VBO_buffers[COLOR_VBO]);
891 FW_GL_COLOR_POINTER(4,GL_FLOAT,0,0);
896 if (pr->VBO_buffers[TEXTURE_VBO0] != 0) {
899 {NULL,2,GL_FLOAT,0, NULL,NULL},{NULL,2,GL_FLOAT,0, NULL,NULL},{NULL,2,GL_FLOAT,0, NULL,NULL}};
900 for(k=0;k<max(1,pr->ntcoord);k++){
902 mtf[k].VBO = pr->VBO_buffers[TEXTURE_VBO0+k];
903 mtf[k].TC_size = pr->ntexdim[k];
904 if(k > 0) mtf[k-1].next = &mtf[k];
906 textureCoord_send(mtf);
908 ConsoleMessage(
"skipping tds of textures");
911 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[VERTEX_VBO]);
912 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER,pr->VBO_buffers[INDEX_VBO]);
913 FW_GL_VERTEX_POINTER(3,GL_FLOAT,0,0);
915 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
917 if(pr->last_index_type != 1)
918 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof (GLushort)*pr->ntri*3*2,pr->wire_indices,GL_STATIC_DRAW);
919 pr->last_index_type = 1;
922 sendElementsToGPU(GL_LINES,pr->ntri*3*2,NULL);
928 pr->last_index_type = 0;
929 sendArraysToGPU(GL_TRIANGLES,0,pr->ntri*3);
936 tg->Mainloop.trisThisLoop += pr->ntri;
940PRINT_GL_ERROR_IF_ANY(
"");
945 glDisable(GL_CULL_FACE);
954 tcod = pr->GeneratedTexCoords;
955 cod = pr->actualCoord;
957 printf (
"\n\nrender_polyrep:\n");
958 for (i=0; i<pr->ntri*3; i++) {
959 printf (
"i %d cindex %d vertex %f %f %f",i,cin[i],
965 printf (
" tex %f %f",
974PRINT_GL_ERROR_IF_ANY(
"");
1001void render_ray_polyrep_A(
void *node) {
1011 float pt1, pt2, pt3;
1014 float v1len, v2len, v3len;
1024 get_current_ray(&t_r1, &t_r2);
1032 genericNodePtr = X3D_NODE(node);
1036 if (!(genericNodePtr->_intern)) {
1041 polyRep = genericNodePtr->_intern;
1050 for(i=0; i<polyRep->ntri; i++) {
1051 for(pt = 0; pt<3; pt++) {
1052 int ind = polyRep->cindex[i*3+pt];
1053 point[pt] = (polyRep->actualCoord+3*ind);
1067 v1.x = point[1][0] - point[0][0];
1068 v1.y = point[1][1] - point[0][1];
1069 v1.z = point[1][2] - point[0][2];
1070 v2.x = point[2][0] - point[0][0];
1071 v2.y = point[2][1] - point[0][1];
1072 v2.z = point[2][2] - point[0][2];
1073 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1074 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1075 v12pt = (float) VECPT(v1,v2);
1078 if (fabs(v12pt-1.0) < 0.00001)
continue;
1081 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1085 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1086 pt1 = (float) VECPT(t_r1,v3);
1087 pt2 = (float) VECPT(t_r2,v3);
1088 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1093 if(!APPROX(tmp1,0)) {
1098 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1099 hitpoint.x = MRATX(tmp2);
1100 hitpoint.y = MRATY(tmp2);
1101 hitpoint.z = MRATZ(tmp2);
1104 p0h.x = hitpoint.x - point[0][0];
1105 p0h.y = hitpoint.y - point[0][1];
1106 p0h.z = hitpoint.z - point[0][2];
1107 ra = (float) VECPT(v1, p0h);
1108 if(ra < 0.0f) {
continue;}
1109 rb = (float) VECPT(v2, p0h);
1110 if(rb < 0.0f) {
continue;}
1119 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1120 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1121 k /= v1len; l /= v2len;
1122 if(k+l > 1 || k < 0 || l < 0) {
1125 rayhit(((
float)(tmp2)),
1126 ((
float)(hitpoint.x)),
1127 ((
float)(hitpoint.y)),
1128 ((
float)(hitpoint.z)),
1132 ((
float)-1),((
float)-1),
"polyrep");
1142int triangle_intersection(
float * V1,
1149void render_ray_polyrep_B(
void *node) {
1158 double d1[3], d2[3], dO[3], dD[3];
1159 float p2[3], O[3], D[3], H[3], scale;
1161 float pt1, pt2, pt3;
1164 float v1len, v2len, v3len;
1171 get_current_ray(&t_r1, &t_r2);
1172 genericNodePtr = X3D_NODE(node);
1175 if (!(genericNodePtr->_intern)) {
1180 polyRep = genericNodePtr->_intern;
1187 pointxyz2double(dO,&t_r1);
1188 pointxyz2double(d2,&t_r2);
1193 double2float(O,dO,3);
1194 double2float(D,dD,3);
1201 for(i=0; i<polyRep->ntri; i++) {
1202 for(pt = 0; pt<3; pt++) {
1203 int ind = polyRep->cindex[i*3+pt];
1204 point[pt] = (polyRep->actualCoord+3*ind);
1206 if(triangle_intersection(point[0],point[1],point[2],O,D,&scale)){
1207 vecadd3f(H,O,vecscale3f(H,D,scale));
1215 -1.0f,-1.0f,
"polyrep2");
1220void render_ray_polyrep(
void *node) {
1223 double p1[3], p2[3], dd[3], dlength;
1225 get_current_ray(&t_r1, &t_r2);
1226 pointxyz2double(p1,&t_r1);
1229 dlength = veclengthd(p1);
1230 if(dlength > 1000.0){
1231 render_ray_polyrep_B(node);
1236 render_ray_polyrep_A(node);
1245#define EPSILON 0.000001
1246int triangle_intersection(
float * V1,
1254 float P[3], Q[3], T[3];
1255 float det, inv_det, u, v;
1259 vecdif3f(e1, V2, V1);
1260 vecdif3f(e2, V3, V1);
1262 veccross3f(P, D, e2);
1264 det = vecdot3f(e1, P);
1266 if(det > -EPSILON && det < EPSILON)
return 0;
1267 inv_det = 1.f / det;
1273 u = vecdot3f(T, P) * inv_det;
1275 if(u < 0.f || u > 1.f)
return 0;
1278 veccross3f(Q, T, e1);
1281 v = vecdot3f(D, Q) * inv_det;
1283 if(v < 0.f || u + v > 1.f)
return 0;
1285 t = vecdot3f(e2, Q) * inv_det;
1297 RAYTRIALGO_DEFAULT = 1,
1298 RAYTRIALGO_MULLER = 2,
1301static int raytrialgo = RAYTRIALGO_MULLER;
1302int intersect_polyrep(
struct X3D_Node *node,
float *p1,
float *p2,
float *nearest,
float *normal){
1314 int i, nintersections, ihavehit;
1316 float nearestdist, delta[3];
1320 float pt1, pt2, pt3;
1323 float v1len, v2len, v3len;
1331 if (!node)
return 0;
1336 vecdif3f(delta,p2,p1);
1337 nearestdist = veclength3f(delta) + .000001f;
1351 genericNodePtr = X3D_NODE(node);
1355 if (!(genericNodePtr->_intern)) {
1360 polyRep = genericNodePtr->_intern;
1368 for(i=0; i<polyRep->ntri; i++) {
1369 for(pt = 0; pt<3; pt++) {
1370 int ind = polyRep->cindex[i*3+pt];
1371 point[pt] = (polyRep->actualCoord+3*ind);
1373 if(raytrialgo == RAYTRIALGO_MULLER){
1375 float tscale, d2[3],delta[3];
1376 vecdif3f(delta,p2,p1);
1377 vecnormalize3f(d2,delta);
1378 if(triangle_intersection(point[0],point[1],point[2],p1,d2,&tscale)){
1381 if(tscale > 0.0f && tscale < nearestdist){
1383 float e1[3],e2[3],nn[3],pd[3];
1384 vecscale3f(pd,d2,tscale);
1385 vecadd3f(nearest,p1,pd);
1387 vecdif3f(e1,point[1],point[0]);
1388 vecdif3f(e2,point[2],point[0]);
1389 veccross3f(nn,e1,e2);
1390 vecnormalize3f(normal,nn);
1391 nearestdist = tscale;
1395 }
else if(raytrialgo == RAYTRIALGO_DEFAULT){
1409 v1.x = point[1][0] - point[0][0];
1410 v1.y = point[1][1] - point[0][1];
1411 v1.z = point[1][2] - point[0][2];
1412 v2.x = point[2][0] - point[0][0];
1413 v2.y = point[2][1] - point[0][1];
1414 v2.z = point[2][2] - point[0][2];
1415 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1416 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1417 v12pt = (float) VECPT(v1,v2);
1420 if (fabs(v12pt-1.0) < 0.00001)
1425 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1429 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1431 pt1 = (float) VECPT(t_r1,v3);
1432 pt2 = (float) VECPT(t_r2,v3);
1433 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1438 if(!APPROX(tmp1,0)) {
1443 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1444 hitpoint.x = MRATX(tmp2);
1445 hitpoint.y = MRATY(tmp2);
1446 hitpoint.z = MRATZ(tmp2);
1449 p0h.x = hitpoint.x - point[0][0];
1450 p0h.y = hitpoint.y - point[0][1];
1451 p0h.z = hitpoint.z - point[0][2];
1452 ra = (float) VECPT(v1, p0h);
1456 rb = (float) VECPT(v2, p0h);
1468 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1469 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1470 k /= v1len; l /= v2len;
1471 if(k+l > 1 || k < 0 || l < 0) {
1476 if(tmp2 >= 0.0 && tmp2 < nearestdist){
1478 nearest[0] = (float)hitpoint.x;
1479 nearest[1] = (float)hitpoint.y;
1480 nearest[2] = (float)hitpoint.z;
1481 normal[0] = (float)v3.x;
1482 normal[1] = (float)v3.y;
1483 normal[2] = (float)v3.z;
1499 return nintersections*ihavehit;
1502int intersect_polyrep2(
struct X3D_Node *node,
float *p1,
float *p2,
Stack *intersection_stack){
1517 int i, nintersections, ihavehit;
1519 float nearestdist, delta[3];
1523 float pt1, pt2, pt3;
1526 float v1len, v2len, v3len;
1534 if (!node)
return 0;
1539 vecdif3f(delta,p2,p1);
1540 nearestdist = veclength3f(delta) + .000001f;
1554 genericNodePtr = X3D_NODE(node);
1558 if (!(genericNodePtr->_intern)) {
1563 polyRep = genericNodePtr->_intern;
1572 for(i=0; i<polyRep->ntri; i++) {
1573 for(pt = 0; pt<3; pt++) {
1574 int ind = polyRep->cindex[i*3+pt];
1575 point[pt] = (polyRep->actualCoord+3*ind);
1577 if(raytrialgo == RAYTRIALGO_MULLER){
1579 float tscale, d2[3],delta[3];
1580 vecdif3f(delta,p2,p1);
1581 vecnormalize3f(d2,delta);
1582 if(triangle_intersection(point[0],point[1],point[2],p1,d2,&tscale)){
1585 if(tscale > 0.0f && tscale < veclength3f(delta)){
1587 float e1[3],e2[3],nn[3],pd[3],pi[3],normi[3];
1589 vecscale3f(pd,d2,tscale);
1592 vecdif3f(e1,point[1],point[0]);
1593 vecdif3f(e2,point[2],point[0]);
1594 veccross3f(nn,e1,e2);
1595 vecnormalize3f(normi,nn);
1596 veccopy3f(iinfo.p,pi);
1597 veccopy3f(iinfo.normal,normi);
1599 if(tscale < nearestdist) {
1602 nearestdist = tscale;
1607 }
else if(raytrialgo == RAYTRIALGO_DEFAULT){
1621 v1.x = point[1][0] - point[0][0];
1622 v1.y = point[1][1] - point[0][1];
1623 v1.z = point[1][2] - point[0][2];
1624 v2.x = point[2][0] - point[0][0];
1625 v2.y = point[2][1] - point[0][1];
1626 v2.z = point[2][2] - point[0][2];
1627 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1628 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1629 v12pt = (float) VECPT(v1,v2);
1632 if (fabs(v12pt-1.0) < 0.00001)
1637 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1641 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1643 pt1 = (float) VECPT(t_r1,v3);
1644 pt2 = (float) VECPT(t_r2,v3);
1645 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1650 if(!APPROX(tmp1,0)) {
1655 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1656 hitpoint.x = MRATX(tmp2);
1657 hitpoint.y = MRATY(tmp2);
1658 hitpoint.z = MRATZ(tmp2);
1661 p0h.x = hitpoint.x - point[0][0];
1662 p0h.y = hitpoint.y - point[0][1];
1663 p0h.z = hitpoint.z - point[0][2];
1664 ra = (float) VECPT(v1, p0h);
1668 rb = (float) VECPT(v2, p0h);
1680 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1681 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1682 k /= v1len; l /= v2len;
1683 if(k+l > 1 || k < 0 || l < 0) {
1688 if(tmp2 >= 0.0 && tmp2 < nearestdist){
1711 return nintersections*ihavehit;
1715int getPolyrepTriangleCount(
struct X3D_Node *node){
1720 iret = polyrep->ntri;
1724int getPolyrepTriangleByIndex(
struct X3D_Node *node,
int index,
float *v1,
float *v2,
float *v3){
1729 veccopy3f(v1,&polyrep->actualCoord[(index*3 + 0)*3]);
1730 veccopy3f(v2,&polyrep->actualCoord[(index*3 + 1)*3]);
1731 veccopy3f(v3,&polyrep->actualCoord[(index*3 + 2)*3]);
1738void compile_polyrep(
void *innode,
void *coord,
void *fogCoord,
void *color,
void *normal,
struct X3D_TextureCoordinate *texCoord) {
1745 node = X3D_NODE(innode);
1746 virt = virtTable[node->_nodeType];
1749 if(!node->_intern) {
1754 memset(node->_intern,0,
sizeof(
struct X3D_PolyRep));
1755 polyrep = node->_intern;
1762 polyrep->streamed = FALSE;
1767 polyrep->minVals[0] = 999999.9f;
1768 polyrep->minVals[1] = 999999.9f;
1769 polyrep->minVals[2] = 999999.9f;
1770 polyrep->maxVals[0] = -999999.9f;
1771 polyrep->maxVals[1] = -999999.9f;
1772 polyrep->maxVals[2] = -999999.9f;
1774 for (i=0; i<VBO_COUNT; i++)
1775 polyrep->VBO_buffers[i] = 0;
1778 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
1779 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
1785 polyrep = node->_intern;
1788 if (polyrep->VBO_buffers[VERTEX_VBO] == 0) {
1790 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
1791 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
1796 polyrep->streamed = FALSE;
1798 FREE_IF_NZ(polyrep->cindex);
1799 FREE_IF_NZ(polyrep->actualCoord);
1800 FREE_IF_NZ(polyrep->GeneratedTexCoords[0]);
1801 FREE_IF_NZ(polyrep->colindex);
1802 FREE_IF_NZ(polyrep->color);
1803 FREE_IF_NZ(polyrep->norindex);
1804 FREE_IF_NZ(polyrep->normal);
1805 FREE_IF_NZ(polyrep->flat_normal);
1806 FREE_IF_NZ(polyrep->tcindex);
1810 virt->mkpolyrep(node);
1814 if (polyrep->ntri != 0) {
1816 stream_polyrep(node, coord, fogCoord, color, normal, texCoord);
1820 polyrep->irep_change = node->_change;
1824void delete_polyrep(
struct X3D_Node *node){
1837 glDeleteBuffers(VBO_COUNT,pr->VBO_buffers);
1840 FREE_IF_NZ(pr->cindex);
1841 FREE_IF_NZ(pr->colindex);
1842 FREE_IF_NZ(pr->norindex);
1843 FREE_IF_NZ(pr->tcindex);
1844 FREE_IF_NZ(pr->tri_indices);
1845 FREE_IF_NZ(pr->wire_indices);
1846 FREE_IF_NZ(pr->actualCoord);
1847 FREE_IF_NZ(pr->actualFog);
1848 FREE_IF_NZ(pr->color);
1849 FREE_IF_NZ(pr->normal);
1850 FREE_IF_NZ(pr->flat_normal);
1851 FREE_IF_NZ(pr->GeneratedTexCoords[0]);
1853 node->_intern = NULL;