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"
51 static 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);
82 int 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;
129 int 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++) {
166 facenormals[i].x = 0.0;
167 facenormals[i].y = 0.0;
168 facenormals[i].z = 1.0;
171 if (tmp_a >= cin-2) {
172 printf (
"last face in Indexed Geometry has not enough vertexes\n");
176 if ((coordIndex->p[tmp_a] == -1) ||
177 (coordIndex->p[tmp_a+1] == -1) ||
178 (coordIndex->p[tmp_a+2] == -1)) {
179 printf (
"IndexedFaceNormals: have a face with two or less vertexes\n");
182 if (coordIndex->p[tmp_a] != -1) tmp_a++;
187 while (checkpoint < cin) {
188 if (coordIndex->p[checkpoint] == -1) {
192 if ((coordIndex->p[checkpoint] < 0) ||
193 (coordIndex->p[checkpoint] >= npoints)) {
194 printf (
"Indexed Geometry face %d has a point out of range,",i);
195 printf (
" point is %d, should be between 0 and %d\n",
196 coordIndex->p[checkpoint],npoints-1);
211 this_face_finished = FALSE;
215 pt_2 = tmp_a+1; pt_3 = tmp_a+2;
218 pt_3 = tmp_a+1; pt_2 = tmp_a+2;
223 c1 = &(points[coordIndex->p[pt_1]]);
224 c2 = &(points[coordIndex->p[pt_2]]);
225 c3 = &(points[coordIndex->p[pt_3]]);
227 a[0] = c2->c[0] - c1->c[0];
228 a[1] = c2->c[1] - c1->c[1];
229 a[2] = c2->c[2] - c1->c[2];
230 b[0] = c3->c[0] - c1->c[0];
231 b[1] = c3->c[1] - c1->c[1];
232 b[2] = c3->c[2] - c1->c[2];
236 thisfaceNorms.x = a[1]*b[2] - b[1]*a[2];
237 thisfaceNorms.y = -(a[0]*b[2] - b[0]*a[2]);
238 thisfaceNorms.z = a[0]*b[1] - b[0]*a[1];
243 if (calc_vector_length(thisfaceNorms) > this_vl) {
245 this_vl = calc_vector_length(thisfaceNorms);
246 facenormals[i].x = thisfaceNorms.x;
247 facenormals[i].y = thisfaceNorms.y;
248 facenormals[i].z = thisfaceNorms.z;
253 AC=(c1->c[0]-c3->c[0])*(c1->c[1]-c3->c[1])*(c1->c[2]-c3->c[2]);
254 BC=(c2->c[0]-c3->c[0])*(c2->c[1]-c3->c[1])*(c2->c[2]-c3->c[2]);
264 if (fabs(AC) < fabs(BC)) { pt_2++; }
275 if ((tmp_a >= cin-2) || (coordIndex->p[tmp_a+2] == -1)) {
276 this_face_finished = TRUE; tmp_a +=2;
278 }
while (!this_face_finished);
280 if (APPROX(this_vl,0.0)) {
285 normalize_vector(&facenormals[i]);
309 while (((coordIndex->p[tmp_a-1]) != -1) && (tmp_a < cin-2)) {
320 for(i=0; i<faces; i++) {
321 if (faceok[i] == TRUE) {
325 if (!retval)
return retval;
332 for (i=0; i<npoints; i++) { pointfaces[i*POINT_FACES]=0; }
334 for(i=0; i<cin; i++) {
335 tmp_a=coordIndex->p[i];
340 if (faceok[facectr]) {
342 add_to_face (tmp_a,facectr,pointfaces);
370 void Extru_check_normal (
379 float a[3];
float b[3];
392 c1 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[0]];
393 c2 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[zz1]];
394 c3 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[zz2]];
404 a[0] = c2->c[0] - c1->c[0];
405 a[1] = c2->c[1] - c1->c[1];
406 a[2] = c2->c[2] - c1->c[2];
407 b[0] = c3->c[0] - c1->c[0];
408 b[1] = c3->c[1] - c1->c[1];
409 b[2] = c3->c[2] - c1->c[2];
411 facenormals[this_face].x = a[1]*b[2] - b[1]*a[2] * direction;
412 facenormals[this_face].y = -(a[0]*b[2] - b[0]*a[2]) * direction;
413 facenormals[this_face].z = a[0]*b[1] - b[0]*a[1] * direction;
415 if (APPROX(calc_vector_length (facenormals[this_face]),0.0)) {
416 ConsoleMessage (
"WARNING: FreeWRL got degenerate triangle; OpenGL tesselator should not give degenerate triangles back %f\n",
417 fabs(calc_vector_length (facenormals[this_face])));
420 normalize_vector(&facenormals[this_face]);
428 void IFS_check_normal (
431 struct SFVec3f *points,
int base,
435 float a[3];
float b[3];
445 c1 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[0]]]);
447 c2 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[1]]]);
448 c3 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[2]]]);
450 c3 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[1]]]);
451 c2 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[2]]]);
454 a[0] = c2->c[0] - c1->c[0];
455 a[1] = c2->c[1] - c1->c[1];
456 a[2] = c2->c[2] - c1->c[2];
457 b[0] = c3->c[0] - c1->c[0];
458 b[1] = c3->c[1] - c1->c[1];
459 b[2] = c3->c[2] - c1->c[2];
461 facenormals[this_face].x = a[1]*b[2] - b[1]*a[2];
462 facenormals[this_face].y = -(a[0]*b[2] - b[0]*a[2]);
463 facenormals[this_face].z = a[0]*b[1] - b[0]*a[1];
467 if (APPROX(calc_vector_length (facenormals[this_face]),0.0)) {
471 normalize_vector(&facenormals[this_face]);
491 if (pointfaces[point] < (POINT_FACES-1)) {
493 for (count = 1; count <= pointfaces[point]; count++) {
494 if (pointfaces[point+count] == face)
return;
498 pointfaces[point+ pointfaces[point]] = face;
520 float a[3];
float b[3];
533 this_Elev->cindex[vertex_ind] = (GLuint)A;
534 this_Elev->cindex[vertex_ind+1] = (GLuint)D;
535 this_Elev->cindex[vertex_ind+2] = (GLuint)E;
551 c1 = (
struct SFVec3f *) &this_Elev->actualCoord[3*A];
552 c2 = (
struct SFVec3f *) &this_Elev->actualCoord[3*D];
553 c3 = (
struct SFVec3f *) &this_Elev->actualCoord[3*E];
561 a[0] = c2->c[0] - c1->c[0];
562 a[1] = c2->c[1] - c1->c[1];
563 a[2] = c2->c[2] - c1->c[2];
564 b[0] = c3->c[0] - c1->c[0];
565 b[1] = c3->c[1] - c1->c[1];
566 b[2] = c3->c[2] - c1->c[2];
568 facenormals[this_face].x = a[1]*b[2] - b[1]*a[2];
569 facenormals[this_face].y = -(a[0]*b[2] - b[0]*a[2]);
570 facenormals[this_face].z = a[0]*b[1] - b[0]*a[1];
578 add_to_face (A*POINT_FACES,this_face,pointfaces);
579 add_to_face (D*POINT_FACES,this_face,pointfaces);
580 add_to_face (E*POINT_FACES,this_face,pointfaces);
606 if (vertex_ind+2 >= tcindexsize) {
607 printf (
"INTERNAL ERROR: Extru_tex, bounds check %d >= %d\n",vertex_ind+2,tcindexsize);
611 if (!(ccw)) { j = B; B = C; C = j; }
614 tcindex[vertex_ind] = (GLuint)(tci_ct+A);
615 tcindex[vertex_ind+1] =(GLuint)(tci_ct+B);
616 tcindex[vertex_ind+2] =(GLuint)(tci_ct+C);
635 float *GeneratedTexCoords,
639 GLfloat minS = 9999.9f;
640 GLfloat maxS = -9999.9f;
641 GLfloat minT = 9999.9f;
642 GLfloat maxT = -9999.9f;
644 GLfloat Srange = 0.0f;
645 GLfloat Trange = 0.0f;
652 for (x=0; x<nsec; x++) {
654 if (Vals[x*2+0] < minS) minS = Vals[x*2+0];
655 if (Vals[x*2+0] > maxS) maxS = Vals[x*2+0];
656 if (Vals[x*2+1] < minT) minT = Vals[x*2+1];
657 if (Vals[x*2+1] > maxT) maxT = Vals[x*2+1];
660 Trange = maxT - minT;
663 if (APPROX(Srange, 0.0)) Srange = 0.001f;
664 if (APPROX(Trange, 0.0)) Trange = 0.001f;
674 for(x=start; x<end; x++) {
690 tci = tcindex[triind_start*3];
694 if ((tci*3+2) >= tcoordsize) {
695 printf (
"INTERNAL ERROR: Extru_ST_map(1), index %d greater than %d \n",(tci*3+2),tcoordsize);
700 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
703 GeneratedTexCoords[tci*3+1] = 0;
706 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
710 tci = tcindex[triind_start*3+1];
713 if ((tci*3+2) >= tcoordsize) {
714 printf (
"INTERNAL ERROR: Extru_ST_map(2), index %d greater than %d \n",(tci*3+2),tcoordsize);
719 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
722 GeneratedTexCoords[tci*3+1] = 0;
725 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
729 tci = tcindex[triind_start*3+2];
731 if ((tci*3+2) >= tcoordsize) {
732 printf (
"INTERNAL ERROR: Extru_ST_map(3), index %d greater than %d \n",(tci*3+2),tcoordsize);
737 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
740 GeneratedTexCoords[tci*3+1] = 0;
743 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
750 void do_glNormal3fv(
struct SFVec3f *dest, GLfloat *param) {
755 myp.x = param[0]; myp.y = param[1]; myp.z = param[2];
757 normalize_vector (&myp);
759 dest->c[0] = (float) myp.x; dest->c[1] = (
float) myp.y; dest->c[2] = (float) myp.z;
772 #define DESIRE(whichOne,zzz) ((whichOne & zzz)==zzz)
774 void render_polyrep(
void *node) {
783 renderedNodePtr = X3D_NODE(node);
785 pr = renderedNodePtr->_intern;
788 printf (
"\nrender_polyrep, _nodeType %s\n",stringNodeType(renderedNodePtr->_nodeType));
789 printf (
"ntri %d\n",pr->ntri);
798 if ((pr->VBO_buffers[VERTEX_VBO]) == 0)
return;
801 printf (
"render_polyrep, not streamed, returning\n");
806 tg->Textures.global_tcin = pr->tcindex;
807 tg->Textures.global_tcin_count = pr->ntri*3;
808 tg->Textures.global_tcin_lastParent = node;
811 setExtent( renderedNodePtr->EXTENT_MAX_X, renderedNodePtr->EXTENT_MIN_X, renderedNodePtr->EXTENT_MAX_Y,
812 renderedNodePtr->EXTENT_MIN_Y, renderedNodePtr->EXTENT_MAX_Z, renderedNodePtr->EXTENT_MIN_Z,
816 if (!pr->ccw) { FW_GL_FRONTFACE(GL_CW); }
819 hasc = ((pr->VBO_buffers[COLOR_VBO]!=0) || pr->color) && (tg->RenderFuncs.last_texture_type!=TEXTURE_NO_ALPHA);
823 if (!pr->isRGBAcolorNode)
824 if (!APPROX(pr->transparency,getAppearanceProperties()->transparency)) {
825 recalculateColorField(pr);
832 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,0);
833 if (pr->VBO_buffers[NORMAL_VBO]!=0 ) {
834 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[NORMAL_VBO]);
835 FW_GL_NORMAL_POINTER(GL_FLOAT,0,0);
836 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_FLAT) ) {
837 if(pr->last_normal_type != 1)
838 glBufferData(GL_ARRAY_BUFFER,
sizeof (GLfloat)*3*pr->ntri*3,pr->flat_normal,GL_STATIC_DRAW);
839 pr->last_normal_type = 1;
841 if(pr->last_normal_type != 0)
842 glBufferData(GL_ARRAY_BUFFER,
sizeof (GLfloat)*3*pr->ntri*3,pr->normal,GL_STATIC_DRAW);
843 pr->last_normal_type = 0;
847 if (pr->VBO_buffers[FOG_VBO]!=0) {
848 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[FOG_VBO]);
849 FW_GL_FOG_POINTER(GL_FLOAT,0,0);
855 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,pr->VBO_buffers[COLOR_VBO]);
856 FW_GL_COLOR_POINTER(4,GL_FLOAT,0,0);
861 if (pr->VBO_buffers[TEXTURE_VBO0] != 0) {
864 {NULL,2,GL_FLOAT,0, NULL,NULL},{NULL,2,GL_FLOAT,0, NULL,NULL},{NULL,2,GL_FLOAT,0, NULL,NULL}};
865 for(k=0;k<max(1,pr->ntcoord);k++){
867 mtf[k].VBO = pr->VBO_buffers[TEXTURE_VBO0+k];
868 mtf[k].TC_size = pr->ntexdim[k];
869 if(k > 0) mtf[k-1].next = &mtf[k];
871 textureCoord_send(mtf);
873 ConsoleMessage(
"skipping tds of textures");
876 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[VERTEX_VBO]);
877 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER,pr->VBO_buffers[INDEX_VBO]);
878 FW_GL_VERTEX_POINTER(3,GL_FLOAT,0,0);
880 if(DESIRE(getShaderFlags().base,SHADINGSTYLE_WIRE)){
882 if(pr->last_index_type != 1)
883 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof (GLushort)*pr->ntri*3*2,pr->wire_indices,GL_STATIC_DRAW);
884 pr->last_index_type = 1;
887 sendElementsToGPU(GL_LINES,pr->ntri*3*2,NULL);
893 pr->last_index_type = 0;
894 sendArraysToGPU(GL_TRIANGLES,0,pr->ntri*3);
901 tg->Mainloop.trisThisLoop += pr->ntri;
905 PRINT_GL_ERROR_IF_ANY(
"");
907 if (!pr->ccw) FW_GL_FRONTFACE(GL_CCW);
915 tcod = pr->GeneratedTexCoords;
916 cod = pr->actualCoord;
918 printf (
"\n\nrender_polyrep:\n");
919 for (i=0; i<pr->ntri*3; i++) {
920 printf (
"i %d cindex %d vertex %f %f %f",i,cin[i],
926 printf (
" tex %f %f",
935 PRINT_GL_ERROR_IF_ANY(
"");
962 void render_ray_polyrep(
void *node) {
974 float v1len, v2len, v3len;
984 get_current_ray(&t_r1, &t_r2);
991 genericNodePtr = X3D_NODE(node);
995 if (!(genericNodePtr->_intern)) {
1000 polyRep = genericNodePtr->_intern;
1009 for(i=0; i<polyRep->ntri; i++) {
1010 for(pt = 0; pt<3; pt++) {
1011 int ind = polyRep->cindex[i*3+pt];
1012 point[pt] = (polyRep->actualCoord+3*ind);
1026 v1.x = point[1][0] - point[0][0];
1027 v1.y = point[1][1] - point[0][1];
1028 v1.z = point[1][2] - point[0][2];
1029 v2.x = point[2][0] - point[0][0];
1030 v2.y = point[2][1] - point[0][1];
1031 v2.z = point[2][2] - point[0][2];
1032 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1033 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1034 v12pt = (float) VECPT(v1,v2);
1037 if (fabs(v12pt-1.0) < 0.00001)
continue;
1041 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1045 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1047 pt1 = (float) VECPT(t_r1,v3);
1048 pt2 = (float) VECPT(t_r2,v3);
1049 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1054 if(!APPROX(tmp1,0)) {
1059 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1060 hitpoint.x = MRATX(tmp2);
1061 hitpoint.y = MRATY(tmp2);
1062 hitpoint.z = MRATZ(tmp2);
1065 p0h.x = hitpoint.x - point[0][0];
1066 p0h.y = hitpoint.y - point[0][1];
1067 p0h.z = hitpoint.z - point[0][2];
1068 ra = (float) VECPT(v1, p0h);
1069 if(ra < 0.0f) {
continue;}
1070 rb = (float) VECPT(v2, p0h);
1071 if(rb < 0.0f) {
continue;}
1080 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1081 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1082 k /= v1len; l /= v2len;
1083 if(k+l > 1 || k < 0 || l < 0) {
1086 rayhit(((
float)(tmp2)),
1087 ((
float)(hitpoint.x)),
1088 ((
float)(hitpoint.y)),
1089 ((
float)(hitpoint.z)),
1093 ((
float)-1),((
float)-1),
"polyrep");
1104 #define EPSILON 0.000001
1105 int triangle_intersection(
float * V1,
1113 float P[3], Q[3], T[3];
1114 float det, inv_det, u, v;
1118 vecdif3f(e1, V2, V1);
1119 vecdif3f(e2, V3, V1);
1121 veccross3f(P, D, e2);
1123 det = vecdot3f(e1, P);
1125 if(det > -EPSILON && det < EPSILON)
return 0;
1126 inv_det = 1.f / det;
1132 u = vecdot3f(T, P) * inv_det;
1134 if(u < 0.f || u > 1.f)
return 0;
1137 veccross3f(Q, T, e1);
1140 v = vecdot3f(D, Q) * inv_det;
1142 if(v < 0.f || u + v > 1.f)
return 0;
1144 t = vecdot3f(e2, Q) * inv_det;
1156 RAYTRIALGO_DEFAULT = 1,
1157 RAYTRIALGO_MULLER = 2,
1160 static int raytrialgo = RAYTRIALGO_MULLER;
1161 int intersect_polyrep(
struct X3D_Node *node,
float *p1,
float *p2,
float *nearest,
float *normal){
1173 int i, nintersections, ihavehit;
1175 float nearestdist, delta[3];
1179 float pt1, pt2, pt3;
1182 float v1len, v2len, v3len;
1190 if (!node)
return 0;
1195 vecdif3f(delta,p2,p1);
1196 nearestdist = veclength3f(delta) + .000001f;
1210 genericNodePtr = X3D_NODE(node);
1214 if (!(genericNodePtr->_intern)) {
1219 polyRep = genericNodePtr->_intern;
1228 for(i=0; i<polyRep->ntri; i++) {
1229 for(pt = 0; pt<3; pt++) {
1230 int ind = polyRep->cindex[i*3+pt];
1231 point[pt] = (polyRep->actualCoord+3*ind);
1233 if(raytrialgo == RAYTRIALGO_MULLER){
1235 float tscale, d2[3],delta[3];
1236 vecdif3f(delta,p2,p1);
1237 vecnormalize3f(d2,delta);
1238 if(triangle_intersection(point[0],point[1],point[2],p1,d2,&tscale)){
1241 if(tscale > 0.0f && tscale < nearestdist){
1243 float e1[3],e2[3],nn[3],pd[3];
1244 vecscale3f(pd,d2,tscale);
1245 vecadd3f(nearest,p1,pd);
1247 vecdif3f(e1,point[1],point[0]);
1248 vecdif3f(e2,point[2],point[0]);
1249 veccross3f(nn,e1,e2);
1250 vecnormalize3f(normal,nn);
1251 nearestdist = tscale;
1255 }
else if(raytrialgo == RAYTRIALGO_DEFAULT){
1269 v1.x = point[1][0] - point[0][0];
1270 v1.y = point[1][1] - point[0][1];
1271 v1.z = point[1][2] - point[0][2];
1272 v2.x = point[2][0] - point[0][0];
1273 v2.y = point[2][1] - point[0][1];
1274 v2.z = point[2][2] - point[0][2];
1275 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1276 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1277 v12pt = (float) VECPT(v1,v2);
1280 if (fabs(v12pt-1.0) < 0.00001)
1285 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1289 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1291 pt1 = (float) VECPT(t_r1,v3);
1292 pt2 = (float) VECPT(t_r2,v3);
1293 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1298 if(!APPROX(tmp1,0)) {
1303 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1304 hitpoint.x = MRATX(tmp2);
1305 hitpoint.y = MRATY(tmp2);
1306 hitpoint.z = MRATZ(tmp2);
1309 p0h.x = hitpoint.x - point[0][0];
1310 p0h.y = hitpoint.y - point[0][1];
1311 p0h.z = hitpoint.z - point[0][2];
1312 ra = (float) VECPT(v1, p0h);
1316 rb = (float) VECPT(v2, p0h);
1328 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1329 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1330 k /= v1len; l /= v2len;
1331 if(k+l > 1 || k < 0 || l < 0) {
1336 if(tmp2 >= 0.0 && tmp2 < nearestdist){
1338 nearest[0] = (float)hitpoint.x;
1339 nearest[1] = (
float)hitpoint.y;
1340 nearest[2] = (float)hitpoint.z;
1341 normal[0] = (
float)v3.x;
1342 normal[1] = (float)v3.y;
1343 normal[2] = (
float)v3.z;
1359 return nintersections*ihavehit;
1362 int intersect_polyrep2(
struct X3D_Node *node,
float *p1,
float *p2,
Stack *intersection_stack){
1377 int i, nintersections, ihavehit;
1379 float nearestdist, delta[3];
1383 float pt1, pt2, pt3;
1386 float v1len, v2len, v3len;
1394 if (!node)
return 0;
1399 vecdif3f(delta,p2,p1);
1400 nearestdist = veclength3f(delta) + .000001f;
1414 genericNodePtr = X3D_NODE(node);
1418 if (!(genericNodePtr->_intern)) {
1423 polyRep = genericNodePtr->_intern;
1432 for(i=0; i<polyRep->ntri; i++) {
1433 for(pt = 0; pt<3; pt++) {
1434 int ind = polyRep->cindex[i*3+pt];
1435 point[pt] = (polyRep->actualCoord+3*ind);
1437 if(raytrialgo == RAYTRIALGO_MULLER){
1439 float tscale, d2[3],delta[3];
1440 vecdif3f(delta,p2,p1);
1441 vecnormalize3f(d2,delta);
1442 if(triangle_intersection(point[0],point[1],point[2],p1,d2,&tscale)){
1446 if(tscale > 0.0f && tscale < veclength3f(delta)){
1448 float e1[3],e2[3],nn[3],pd[3],pi[3],normi[3];
1450 vecscale3f(pd,d2,tscale);
1453 vecdif3f(e1,point[1],point[0]);
1454 vecdif3f(e2,point[2],point[0]);
1455 veccross3f(nn,e1,e2);
1456 vecnormalize3f(normi,nn);
1457 veccopy3f(iinfo.p,pi);
1458 veccopy3f(iinfo.normal,normi);
1460 if(tscale < nearestdist) {
1463 nearestdist = tscale;
1468 }
else if(raytrialgo == RAYTRIALGO_DEFAULT){
1482 v1.x = point[1][0] - point[0][0];
1483 v1.y = point[1][1] - point[0][1];
1484 v1.z = point[1][2] - point[0][2];
1485 v2.x = point[2][0] - point[0][0];
1486 v2.y = point[2][1] - point[0][1];
1487 v2.z = point[2][2] - point[0][2];
1488 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1489 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1490 v12pt = (float) VECPT(v1,v2);
1493 if (fabs(v12pt-1.0) < 0.00001)
1498 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1502 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1504 pt1 = (float) VECPT(t_r1,v3);
1505 pt2 = (float) VECPT(t_r2,v3);
1506 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1511 if(!APPROX(tmp1,0)) {
1516 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1517 hitpoint.x = MRATX(tmp2);
1518 hitpoint.y = MRATY(tmp2);
1519 hitpoint.z = MRATZ(tmp2);
1522 p0h.x = hitpoint.x - point[0][0];
1523 p0h.y = hitpoint.y - point[0][1];
1524 p0h.z = hitpoint.z - point[0][2];
1525 ra = (float) VECPT(v1, p0h);
1529 rb = (float) VECPT(v2, p0h);
1541 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1542 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1543 k /= v1len; l /= v2len;
1544 if(k+l > 1 || k < 0 || l < 0) {
1549 if(tmp2 >= 0.0 && tmp2 < nearestdist){
1572 return nintersections*ihavehit;
1576 int getPolyrepTriangleCount(
struct X3D_Node *node){
1581 iret = polyrep->ntri;
1585 int getPolyrepTriangleByIndex(
struct X3D_Node *node,
int index,
float *v1,
float *v2,
float *v3){
1590 veccopy3f(v1,&polyrep->actualCoord[(index*3 + 0)*3]);
1591 veccopy3f(v2,&polyrep->actualCoord[(index*3 + 1)*3]);
1592 veccopy3f(v3,&polyrep->actualCoord[(index*3 + 2)*3]);
1599 void compile_polyrep(
void *innode,
void *coord,
void *fogCoord,
void *color,
void *normal,
struct X3D_TextureCoordinate *texCoord) {
1606 node = X3D_NODE(innode);
1607 virt = virtTable[node->_nodeType];
1610 if(!node->_intern) {
1615 memset(node->_intern,0,
sizeof(
struct X3D_PolyRep));
1616 polyrep = node->_intern;
1623 polyrep->streamed = FALSE;
1628 polyrep->minVals[0] = 999999.9f;
1629 polyrep->minVals[1] = 999999.9f;
1630 polyrep->minVals[2] = 999999.9f;
1631 polyrep->maxVals[0] = -999999.9f;
1632 polyrep->maxVals[1] = -999999.9f;
1633 polyrep->maxVals[2] = -999999.9f;
1635 for (i=0; i<VBO_COUNT; i++)
1636 polyrep->VBO_buffers[i] = 0;
1639 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
1640 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
1646 polyrep = node->_intern;
1649 if (polyrep->VBO_buffers[VERTEX_VBO] == 0) {
1651 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
1652 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
1657 polyrep->streamed = FALSE;
1659 FREE_IF_NZ(polyrep->cindex);
1660 FREE_IF_NZ(polyrep->actualCoord);
1661 FREE_IF_NZ(polyrep->GeneratedTexCoords[0]);
1662 FREE_IF_NZ(polyrep->colindex);
1663 FREE_IF_NZ(polyrep->color);
1664 FREE_IF_NZ(polyrep->norindex);
1665 FREE_IF_NZ(polyrep->normal);
1666 FREE_IF_NZ(polyrep->flat_normal);
1667 FREE_IF_NZ(polyrep->tcindex);
1671 virt->mkpolyrep(node);
1675 if (polyrep->ntri != 0) {
1677 stream_polyrep(node, coord, fogCoord, color, normal, texCoord);
1681 polyrep->irep_change = node->_change;
1685 void delete_polyrep(
struct X3D_Node *node){
1698 glDeleteBuffers(VBO_COUNT,pr->VBO_buffers);
1701 FREE_IF_NZ(pr->cindex);
1702 FREE_IF_NZ(pr->colindex);
1703 FREE_IF_NZ(pr->norindex);
1704 FREE_IF_NZ(pr->tcindex);
1705 FREE_IF_NZ(pr->tri_indices);
1706 FREE_IF_NZ(pr->wire_indices);
1707 FREE_IF_NZ(pr->actualCoord);
1708 FREE_IF_NZ(pr->actualFog);
1709 FREE_IF_NZ(pr->color);
1710 FREE_IF_NZ(pr->normal);
1711 FREE_IF_NZ(pr->flat_normal);
1712 FREE_IF_NZ(pr->GeneratedTexCoords[0]);
1714 node->_intern = NULL;