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"
49void * compile_poly_if_required(
void* node,
void* coord,
void* fogCoord,
void* color,
void* normal,
void* texCoord) {
52 struct X3D_Node* nd = X3D_NODE(node);
53 if(!nd->_intern || nd->_change != ((
struct X3D_PolyRep *)(nd->_intern))->irep_change) { \
54 compileNode ((
void *)compile_polyrep,node,coord,fogCoord,color,normal,texCoord);
64 int max_points_per_face = 0;
65 int min_points_per_face = 99999;
69 if (coordIndex == NULL)
return 0;
70 if (coordIndex->n == 0)
return 0;
71 faceok[faces].start = 0;
72 for(i=0; i<cin; i++) {
74 if((coordIndex->p[i] == -1) || (i==cin-1)) {
75 faceok[faces].end = i-1;
77 if(coordIndex->p[i] != -1) {
78 faceok[faces].end = i;
83 faceok[faces].start = i+1;
84 if (pointctr > max_points_per_face)
85 max_points_per_face = pointctr;
86 if (pointctr < min_points_per_face)
87 min_points_per_face = pointctr;
112int IFS_face_normals (
123 int tmp_a = 0, this_face_finished;
126 int pt_1, pt_2, pt_3;
129 float a[3];
float b[3];
140 for(i=0; i<faces; i++) {
146 for(i=0; i<faces; i++) {
154 vecset3f(facenormals[i].c,0.0f, 0.0f, 1.0f);
156 if((faceok[i].end - faceok[i].start + 1) < 3) {
157 printf (
"IndexedFaceNormals: have a face with two or less vertexes\n");
158 faceok[i].OK = FALSE;
163 for(
int k=faceok[i].start;k<=faceok[i].end;k++){
164 checkpoint = coordIndex->p[k];
165 if (checkpoint < 0 || checkpoint >= npoints) {
166 printf (
"Indexed Geometry face %d has a point out of range,",i);
167 printf (
" point is %d, should be between 0 and %d\n", checkpoint,npoints-1);
168 faceok[i].OK = FALSE;
177 this_face_finished = FALSE;
178 tmp_a = faceok[i].start;
183 pt_2 = tmp_a+1; pt_3 = tmp_a+2;
186 pt_3 = tmp_a+1; pt_2 = tmp_a+2;
190 float fnorm[3], fnormlen, delta[3];
194 c1 = &(points[coordIndex->p[pt_1]]);
195 c2 = &(points[coordIndex->p[pt_2]]);
196 c3 = &(points[coordIndex->p[pt_3]]);
204 vecdif3f(a,c2->c,c1->c);
205 vecdif3f(b,c3->c,c1->c);
212 veccross3f(fnorm,a,b);
217 fnormlen= veclength3f(fnorm);
218 if(fnormlen > this_vl) {
221 veccopy3f(facenormals[i].c,fnorm);
231 AC = veclength3f(vecdif3f(delta,c1->c,c2->c));
232 BC = veclength3f(vecdif3f(delta,c2->c,c3->c));
243 if (AC < BC) { pt_2++; }
254 this_face_finished = tmp_a + 2 > faceok[i].end;
255 }
while (!this_face_finished);
257 if (APPROX(this_vl,0.0)) {
259 faceok[i].OK = FALSE;
263 vecnormalize3f(facenormals[i].c,facenormals[i].c);
283 for(i=0; i<faces; i++) {
284 if (faceok[i].OK == TRUE) {
296 for (i=0; i<npoints; i++) { pointfaces[i*POINT_FACES]=0; }
298 for(i=0;i<faces;i++){
300 for(
int j=faceok[i].start;j<=faceok[i].end;j++){
301 tmp_a = coordIndex->p[j];
303 tmp_a *= POINT_FACES;
304 add_to_face (tmp_a,i,pointfaces);
309 for(i=0; i<cin; i++) {
310 tmp_a=coordIndex->p[i];
314 if (faceok[facectr].OK) {
317 add_to_face (tmp_a,facectr,pointfaces);
346void Extru_check_normal (
355 float a[3], b[3], fnorm[3], fnormlen;
357 ttglobal tg = gglobal();
368 c1 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[0]];
369 c2 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[zz1]];
370 c3 = (
struct SFVec3f *) &rep_->actualCoord[3*tg->Tess.global_IFS_Coords[zz2]];
380 a[0] = c2->c[0] - c1->c[0];
381 a[1] = c2->c[1] - c1->c[1];
382 a[2] = c2->c[2] - c1->c[2];
383 b[0] = c3->c[0] - c1->c[0];
384 b[1] = c3->c[1] - c1->c[1];
385 b[2] = c3->c[2] - c1->c[2];
386 vecdif3f(a,c2->c,c1->c);
387 vecdif3f(b,c3->c,c1->c);
388 veccross3f(fnorm,a,b);
393 fnormlen = veclength3f(fnorm);
395 if (APPROX(fnormlen,0.0f)) {
396 ConsoleMessage (
"WARNING: FreeWRL got degenerate triangle; OpenGL tesselator should not give degenerate triangles back %f\n",
399 vecnormalize3f(facenormals[this_face].c,fnorm);
409void IFS_check_normal (
412 struct SFVec3f *points,
int base,
416 float a[3], b[3], fnorm[3], fnormlen;
417 ttglobal tg = gglobal();
427 c1 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[0]]]);
429 c2 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[1]]]);
430 c3 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[2]]]);
432 c3 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[1]]]);
433 c2 = &(points[coordIndex->p[base+tg->Tess.global_IFS_Coords[2]]]);
436 a[0] = c2->c[0] - c1->c[0];
437 a[1] = c2->c[1] - c1->c[1];
438 a[2] = c2->c[2] - c1->c[2];
439 b[0] = c3->c[0] - c1->c[0];
440 b[1] = c3->c[1] - c1->c[1];
441 b[2] = c3->c[2] - c1->c[2];
442 vecdif3f(a,c2->c,c1->c);
443 vecdif3f(b,c3->c,c1->c);
444 veccross3f(fnorm,a,b);
445 fnormlen = veclength3f(fnorm);
446 veccopy3f(facenormals[this_face].c,fnorm);
454 if (APPROX(fnormlen,0.0f)) {
459 vecnormalize3f(facenormals[this_face].c,facenormals[this_face].c);
477 if (pointfaces[point] < (POINT_FACES-1)) {
479 for (count = 1; count <= pointfaces[point]; count++) {
480 if (pointfaces[point+count] == face)
return;
484 pointfaces[point+ pointfaces[point]] = face;
506 float a[3], b[3], fnorm[3], fnormlen;
519 this_Elev->cindex[vertex_ind] = (GLuint)A;
520 this_Elev->cindex[vertex_ind+1] = (GLuint)D;
521 this_Elev->cindex[vertex_ind+2] = (GLuint)E;
537 c1 = (
struct SFVec3f *) &this_Elev->actualCoord[3*A];
538 c2 = (
struct SFVec3f *) &this_Elev->actualCoord[3*D];
539 c3 = (
struct SFVec3f *) &this_Elev->actualCoord[3*E];
547 a[0] = c2->c[0] - c1->c[0];
548 a[1] = c2->c[1] - c1->c[1];
549 a[2] = c2->c[2] - c1->c[2];
550 b[0] = c3->c[0] - c1->c[0];
551 b[1] = c3->c[1] - c1->c[1];
552 b[2] = c3->c[2] - c1->c[2];
553 vecdif3f(a,c2->c,c1->c);
554 vecdif3f(b,c3->c,c1->c);
555 veccross3f(fnorm,a,b);
556 vecnormalize3f(fnorm,fnorm);
557 veccopy3f(facenormals[this_face].c,fnorm);
568 add_to_face (A*POINT_FACES,this_face,pointfaces);
569 add_to_face (D*POINT_FACES,this_face,pointfaces);
570 add_to_face (E*POINT_FACES,this_face,pointfaces);
596 if (vertex_ind+2 >= tcindexsize) {
597 printf (
"INTERNAL ERROR: Extru_tex, bounds check %d >= %d\n",vertex_ind+2,tcindexsize);
601 if (!(ccw)) { j = B; B = C; C = j; }
604 tcindex[vertex_ind] = (GLuint)(tci_ct+A);
605 tcindex[vertex_ind+1] =(GLuint)(tci_ct+B);
606 tcindex[vertex_ind+2] =(GLuint)(tci_ct+C);
625 float *GeneratedTexCoords,
629 GLfloat minS = 9999.9f;
630 GLfloat maxS = -9999.9f;
631 GLfloat minT = 9999.9f;
632 GLfloat maxT = -9999.9f;
634 GLfloat Srange = 0.0f;
635 GLfloat Trange = 0.0f;
642 for (x=0; x<nsec; x++) {
644 if (Vals[x*2+0] < minS) minS = Vals[x*2+0];
645 if (Vals[x*2+0] > maxS) maxS = Vals[x*2+0];
646 if (Vals[x*2+1] < minT) minT = Vals[x*2+1];
647 if (Vals[x*2+1] > maxT) maxT = Vals[x*2+1];
650 Trange = maxT - minT;
653 if (APPROX(Srange, 0.0)) Srange = 0.001f;
654 if (APPROX(Trange, 0.0)) Trange = 0.001f;
664 for(x=start; x<end; x++) {
680 tci = tcindex[triind_start*3];
684 if ((tci*3+2) >= tcoordsize) {
685 printf (
"INTERNAL ERROR: Extru_ST_map(1), index %d greater than %d \n",(tci*3+2),tcoordsize);
690 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
693 GeneratedTexCoords[tci*3+1] = 0;
696 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
700 tci = tcindex[triind_start*3+1];
703 if ((tci*3+2) >= tcoordsize) {
704 printf (
"INTERNAL ERROR: Extru_ST_map(2), index %d greater than %d \n",(tci*3+2),tcoordsize);
709 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
712 GeneratedTexCoords[tci*3+1] = 0;
715 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
719 tci = tcindex[triind_start*3+2];
721 if ((tci*3+2) >= tcoordsize) {
722 printf (
"INTERNAL ERROR: Extru_ST_map(3), index %d greater than %d \n",(tci*3+2),tcoordsize);
727 GeneratedTexCoords[tci*3+0] = (Vals[(tci-Point_Zero)*2+0] - minS) / Srange ;
730 GeneratedTexCoords[tci*3+1] = 0;
733 GeneratedTexCoords[tci*3+2] = (Vals[(tci-Point_Zero)*2+1] - minT) / Trange;
740void do_glNormal3fv(
struct SFVec3f *dest, GLfloat *param) {
745 myp.x = param[0]; myp.y = param[1]; myp.z = param[2];
747 normalize_vector (&myp);
749 dest->c[0] = (float) myp.x; dest->c[1] = (float) myp.y; dest->c[2] = (float) myp.z;
762#define DESIRE(whichOne,zzz) ((whichOne & zzz)==zzz)
765void render_polyrep(
void* node) {
772 ttglobal tg = gglobal();
774 renderedNodePtr = X3D_NODE(node);
776 pr = (
struct X3D_PolyRep*) renderedNodePtr->_intern;
779 printf(
"\nrender_polyrep, _nodeType %s\n", stringNodeType(renderedNodePtr->_nodeType));
780 printf(
"ntri %d\n", pr->ntri);
789 if ((pr->VBO_buffers[VERTEX_VBO]) == 0)
return;
792 printf(
"render_polyrep, not streamed, returning\n");
797 tg->Textures.global_tcin = pr->tcindex;
798 tg->Textures.global_tcin_count = pr->ntri * 3;
799 tg->Textures.global_tcin_lastParent = node;
803 static int count = 0;
806 extent6f_printf(renderedNodePtr->_extent); printf(
" r_p\n");
810 if (1) setExtent(renderedNodePtr->EXTENT_MAX_X, renderedNodePtr->EXTENT_MIN_X, renderedNodePtr->EXTENT_MAX_Y,
811 renderedNodePtr->EXTENT_MIN_Y, renderedNodePtr->EXTENT_MAX_Z, renderedNodePtr->EXTENT_MIN_Z,
817 glEnable(GL_CULL_FACE);
818 glCullFace(GL_FRONT);
822 hasc = ((pr->VBO_buffers[COLOR_VBO] != 0) || pr->color);
830 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
831 if (pr->VBO_buffers[NORMAL_VBO] != 0) {
832 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[NORMAL_VBO]);
833 FW_GL_NORMAL_POINTER(GL_FLOAT, 0, 0);
834 if (DESIRE(getShaderFlags().base, SHADINGSTYLE_FLAT)) {
835 if (pr->last_normal_type != 1)
836 glBufferData(GL_ARRAY_BUFFER,
sizeof(GLfloat) * 3 * pr->ntri * 3, pr->flat_normal, GL_STATIC_DRAW);
837 pr->last_normal_type = 1;
840 if (pr->last_normal_type != 0)
841 glBufferData(GL_ARRAY_BUFFER,
sizeof(GLfloat) * 3 * pr->ntri * 3, pr->normal, GL_STATIC_DRAW);
842 pr->last_normal_type = 0;
846 if (pr->VBO_buffers[FOG_VBO] != 0) {
847 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[FOG_VBO]);
848 FW_GL_FOG_POINTER(GL_FLOAT, 0, 0);
854 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[COLOR_VBO]);
855 FW_GL_COLOR_POINTER(4, GL_FLOAT, 0, 0);
860 if (pr->VBO_buffers[TEXTURE_VBO0] != 0) {
863 {NULL,2,GL_FLOAT,0, NULL,NULL},{NULL,2,GL_FLOAT,0, NULL,NULL},{NULL,2,GL_FLOAT,0, NULL,NULL} };
864 for (k = 0; k < max(1, pr->ntcoord); k++) {
866 mtf[k].VBO = pr->VBO_buffers[TEXTURE_VBO0 + k];
867 mtf[k].TC_size = pr->ntexdim[k];
868 if (k > 0) mtf[k - 1].next = &mtf[k];
870 textureCoord_send(mtf);
873 ConsoleMessage(
"skipping tds of textures");
876 if (pr->VBO_buffers[CINDEX_VBO] != 0) {
881 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[CINDEX_VBO]);
883 FW_GL_CINDEX_POINTER(GL_INT, 0, 0);
888 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, pr->VBO_buffers[VERTEX_VBO]);
889 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, pr->VBO_buffers[INDEX_VBO]);
890 FW_GL_VERTEX_POINTER(3, GL_FLOAT, 0, 0);
892 if (DESIRE(getShaderFlags().base, SHADINGSTYLE_WIRE)) {
894 if (pr->last_index_type != 1)
895 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(GLuint) * pr->ntri * 3 * 2, pr->wire_indices, GL_STATIC_DRAW);
896 pr->last_index_type = 1;
899 sendElementsToGPU(GL_LINES, pr->ntri * 3 * 2, NULL);
906 pr->last_index_type = 0;
907 sendArraysToGPU(GL_TRIANGLES, 0, pr->ntri * 3);
914 tg->Mainloop.trisThisLoop += pr->ntri;
918 PRINT_GL_ERROR_IF_ANY(
"");
923 glDisable(GL_CULL_FACE);
932 tcod = pr->GeneratedTexCoords;
933 cod = pr->actualCoord;
935 printf(
"\n\nrender_polyrep:\n");
936 for (i = 0; i < pr->ntri * 3; i++) {
937 printf(
"i %d cindex %d vertex %f %f %f", i, cin[i],
940 cod[cin[i] * 3 + 2]);
944 tcod[cin[i] * 2 + 0],
945 tcod[cin[i] * 2 + 1]);
952 PRINT_GL_ERROR_IF_ANY(
"");
979void render_ray_polyrep_A(
void *node) {
992 float v1len, v2len, v3len;
1002 get_current_ray(&t_r1, &t_r2);
1010 genericNodePtr = X3D_NODE(node);
1014 if (!(genericNodePtr->_intern)) {
1019 polyRep = (
struct X3D_PolyRep*) genericNodePtr->_intern;
1020 if (!polyRep->ntri || !polyRep->actualCoord)
return;
1028 for(i=0; i<polyRep->ntri; i++) {
1029 for(pt = 0; pt<3; pt++) {
1030 int ind = polyRep->cindex[i*3+pt];
1031 point[pt] = (polyRep->actualCoord+3*ind);
1045 v1.x = point[1][0] - point[0][0];
1046 v1.y = point[1][1] - point[0][1];
1047 v1.z = point[1][2] - point[0][2];
1048 v2.x = point[2][0] - point[0][0];
1049 v2.y = point[2][1] - point[0][1];
1050 v2.z = point[2][2] - point[0][2];
1051 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1052 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1053 v12pt = (float) VECPT(v1,v2);
1056 if (fabs(v12pt-1.0) < 0.00001)
continue;
1059 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1063 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1064 pt1 = (float) VECPT(t_r1,v3);
1065 pt2 = (float) VECPT(t_r2,v3);
1066 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1071 if(!APPROX(tmp1,0)) {
1076 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1077 hitpoint.x = MRATX(tmp2);
1078 hitpoint.y = MRATY(tmp2);
1079 hitpoint.z = MRATZ(tmp2);
1082 p0h.x = hitpoint.x - point[0][0];
1083 p0h.y = hitpoint.y - point[0][1];
1084 p0h.z = hitpoint.z - point[0][2];
1085 ra = (float) VECPT(v1, p0h);
1086 if(ra < 0.0f) {
continue;}
1087 rb = (float) VECPT(v2, p0h);
1088 if(rb < 0.0f) {
continue;}
1097 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1098 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1099 k /= v1len; l /= v2len;
1100 if(k+l > 1 || k < 0 || l < 0) {
1103 rayhit(((
float)(tmp2)),
1104 ((
float)(hitpoint.x)),
1105 ((
float)(hitpoint.y)),
1106 ((
float)(hitpoint.z)),
1110 ((
float)-1),((
float)-1),
"polyrep");
1120int triangle_intersection(
float * V1,
1127void render_ray_polyrep_B(
void *node) {
1136 double d1[3], d2[3], dO[3], dD[3];
1137 float p2[3], O[3], D[3], H[3], scale;
1139 float pt1, pt2, pt3;
1142 float v1len, v2len, v3len;
1149 get_current_ray(&t_r1, &t_r2);
1150 genericNodePtr = X3D_NODE(node);
1153 if (!(genericNodePtr->_intern)) {
1158 polyRep = (
struct X3D_PolyRep*) genericNodePtr->_intern;
1165 pointxyz2double(dO,&t_r1);
1166 pointxyz2double(d2,&t_r2);
1171 double2float(O,dO,3);
1172 double2float(D,dD,3);
1179 for(i=0; i<polyRep->ntri; i++) {
1180 for(pt = 0; pt<3; pt++) {
1181 int ind = polyRep->cindex[i*3+pt];
1182 point[pt] = (polyRep->actualCoord+3*ind);
1184 if(triangle_intersection(point[0],point[1],point[2],O,D,&scale)){
1185 vecadd3f(H,O,vecscale3f(H,D,scale));
1193 -1.0f,-1.0f,
"polyrep2");
1198void render_ray_polyrep(
void *node) {
1201 double p1[3], p2[3], dd[3], dlength;
1203 get_current_ray(&t_r1, &t_r2);
1204 pointxyz2double(p1,&t_r1);
1207 dlength = veclengthd(p1);
1208 if(dlength > 1000.0){
1209 render_ray_polyrep_B(node);
1214 render_ray_polyrep_A(node);
1223#define EPSILON 0.000001
1224int triangle_intersection(
float * V1,
1232 float P[3], Q[3], T[3];
1233 float det, inv_det, u, v;
1237 vecdif3f(e1, V2, V1);
1238 vecdif3f(e2, V3, V1);
1240 veccross3f(P, D, e2);
1242 det = vecdot3f(e1, P);
1244 if(det > -EPSILON && det < EPSILON)
return 0;
1245 inv_det = 1.f / det;
1251 u = vecdot3f(T, P) * inv_det;
1253 if(u < 0.f || u > 1.f)
return 0;
1256 veccross3f(Q, T, e1);
1259 v = vecdot3f(D, Q) * inv_det;
1261 if(v < 0.f || u + v > 1.f)
return 0;
1263 t = vecdot3f(e2, Q) * inv_det;
1275 RAYTRIALGO_DEFAULT = 1,
1276 RAYTRIALGO_MULLER = 2,
1279static int raytrialgo = RAYTRIALGO_MULLER;
1280int intersect_polyrep(
struct X3D_Node *node,
float *p1,
float *p2,
float *nearest,
float *normal){
1292 int i, nintersections, ihavehit;
1294 float nearestdist, delta[3];
1298 float pt1, pt2, pt3;
1301 float v1len, v2len, v3len;
1309 if (!node)
return 0;
1314 vecdif3f(delta,p2,p1);
1315 nearestdist = veclength3f(delta) + .000001f;
1329 genericNodePtr = X3D_NODE(node);
1333 if (!(genericNodePtr->_intern)) {
1338 polyRep = (
struct X3D_PolyRep*) genericNodePtr->_intern;
1346 for(i=0; i<polyRep->ntri; i++) {
1347 for(pt = 0; pt<3; pt++) {
1348 int ind = polyRep->cindex[i*3+pt];
1349 point[pt] = (polyRep->actualCoord+3*ind);
1351 if(raytrialgo == RAYTRIALGO_MULLER){
1353 float tscale, d2[3],delta[3];
1354 vecdif3f(delta,p2,p1);
1355 vecnormalize3f(d2,delta);
1356 if(triangle_intersection(point[0],point[1],point[2],p1,d2,&tscale)){
1359 if(tscale > 0.0f && tscale < nearestdist){
1361 float e1[3],e2[3],nn[3],pd[3];
1362 vecscale3f(pd,d2,tscale);
1363 vecadd3f(nearest,p1,pd);
1365 vecdif3f(e1,point[1],point[0]);
1366 vecdif3f(e2,point[2],point[0]);
1367 veccross3f(nn,e1,e2);
1368 vecnormalize3f(normal,nn);
1369 nearestdist = tscale;
1373 }
else if(raytrialgo == RAYTRIALGO_DEFAULT){
1387 v1.x = point[1][0] - point[0][0];
1388 v1.y = point[1][1] - point[0][1];
1389 v1.z = point[1][2] - point[0][2];
1390 v2.x = point[2][0] - point[0][0];
1391 v2.y = point[2][1] - point[0][1];
1392 v2.z = point[2][2] - point[0][2];
1393 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1394 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1395 v12pt = (float) VECPT(v1,v2);
1398 if (fabs(v12pt-1.0) < 0.00001)
1403 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1407 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1409 pt1 = (float) VECPT(t_r1,v3);
1410 pt2 = (float) VECPT(t_r2,v3);
1411 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1416 if(!APPROX(tmp1,0)) {
1421 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1422 hitpoint.x = MRATX(tmp2);
1423 hitpoint.y = MRATY(tmp2);
1424 hitpoint.z = MRATZ(tmp2);
1427 p0h.x = hitpoint.x - point[0][0];
1428 p0h.y = hitpoint.y - point[0][1];
1429 p0h.z = hitpoint.z - point[0][2];
1430 ra = (float) VECPT(v1, p0h);
1434 rb = (float) VECPT(v2, p0h);
1446 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1447 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1448 k /= v1len; l /= v2len;
1449 if(k+l > 1 || k < 0 || l < 0) {
1454 if(tmp2 >= 0.0 && tmp2 < nearestdist){
1456 nearest[0] = (float)hitpoint.x;
1457 nearest[1] = (float)hitpoint.y;
1458 nearest[2] = (float)hitpoint.z;
1459 normal[0] = (float)v3.x;
1460 normal[1] = (float)v3.y;
1461 normal[2] = (float)v3.z;
1477 return nintersections*ihavehit;
1480int intersect_polyrep2(
struct X3D_Node *node,
float *p1,
float *p2, Stack *intersection_stack){
1495 int i, nintersections, ihavehit;
1497 float nearestdist, delta[3];
1501 float pt1, pt2, pt3;
1504 float v1len, v2len, v3len;
1512 if (!node)
return 0;
1517 vecdif3f(delta,p2,p1);
1518 nearestdist = veclength3f(delta) + .000001f;
1532 genericNodePtr = X3D_NODE(node);
1536 if (!(genericNodePtr->_intern)) {
1541 polyRep = (
struct X3D_PolyRep*) genericNodePtr->_intern;
1550 for(i=0; i<polyRep->ntri; i++) {
1551 for(pt = 0; pt<3; pt++) {
1552 int ind = polyRep->cindex[i*3+pt];
1553 point[pt] = (polyRep->actualCoord+3*ind);
1555 if(raytrialgo == RAYTRIALGO_MULLER){
1557 float tscale, d2[3],delta[3];
1558 vecdif3f(delta,p2,p1);
1559 vecnormalize3f(d2,delta);
1560 if(triangle_intersection(point[0],point[1],point[2],p1,d2,&tscale)){
1563 if(tscale > 0.0f && tscale < veclength3f(delta)){
1565 float e1[3],e2[3],nn[3],pd[3],pi[3],normi[3];
1567 vecscale3f(pd,d2,tscale);
1570 vecdif3f(e1,point[1],point[0]);
1571 vecdif3f(e2,point[2],point[0]);
1572 veccross3f(nn,e1,e2);
1573 vecnormalize3f(normi,nn);
1574 veccopy3f(iinfo.p,pi);
1575 veccopy3f(iinfo.normal,normi);
1577 if(tscale < nearestdist) {
1580 nearestdist = tscale;
1585 }
else if(raytrialgo == RAYTRIALGO_DEFAULT){
1599 v1.x = point[1][0] - point[0][0];
1600 v1.y = point[1][1] - point[0][1];
1601 v1.z = point[1][2] - point[0][2];
1602 v2.x = point[2][0] - point[0][0];
1603 v2.y = point[2][1] - point[0][1];
1604 v2.z = point[2][2] - point[0][2];
1605 v1len = (float) sqrt(VECSQ(v1)); VECSCALE(v1, 1/v1len);
1606 v2len = (float) sqrt(VECSQ(v2)); VECSCALE(v2, 1/v2len);
1607 v12pt = (float) VECPT(v1,v2);
1610 if (fabs(v12pt-1.0) < 0.00001)
1615 if ((fabs(v1len) > 0.00001) && (fabs(v2len) > 0.00001)) {
1619 v3len = (float) sqrt(VECSQ(v3)); VECSCALE(v3, 1/v3len);
1621 pt1 = (float) VECPT(t_r1,v3);
1622 pt2 = (float) VECPT(t_r2,v3);
1623 pt3 = (float) (v3.x * point[0][0] + v3.y * point[0][1] + v3.z * point[0][2]);
1628 if(!APPROX(tmp1,0)) {
1633 tmp2 = (float) ((pt1-pt3) / (pt1-pt2));
1634 hitpoint.x = MRATX(tmp2);
1635 hitpoint.y = MRATY(tmp2);
1636 hitpoint.z = MRATZ(tmp2);
1639 p0h.x = hitpoint.x - point[0][0];
1640 p0h.y = hitpoint.y - point[0][1];
1641 p0h.z = hitpoint.z - point[0][2];
1642 ra = (float) VECPT(v1, p0h);
1646 rb = (float) VECPT(v2, p0h);
1658 k = (ra - v12pt * rb) / (1-v12pt*v12pt);
1659 l = (rb - v12pt * ra) / (1-v12pt*v12pt);
1660 k /= v1len; l /= v2len;
1661 if(k+l > 1 || k < 0 || l < 0) {
1666 if(tmp2 >= 0.0 && tmp2 < nearestdist){
1689 return nintersections*ihavehit;
1693int getPolyrepTriangleCount(
struct X3D_Node *node){
1698 iret = polyrep->ntri;
1702int getPolyrepTriangleByIndex(
struct X3D_Node *node,
int index,
float *v1,
float *v2,
float *v3){
1707 veccopy3f(v1,&polyrep->actualCoord[(index*3 + 0)*3]);
1708 veccopy3f(v2,&polyrep->actualCoord[(index*3 + 1)*3]);
1709 veccopy3f(v3,&polyrep->actualCoord[(index*3 + 2)*3]);
1716void compile_polyrep(
void *innode,
void *coord,
void *fogCoord,
void *color,
void *normal,
struct X3D_TextureCoordinate *texCoord) {
1723 node = X3D_NODE(innode);
1724 virt = virtTable[node->_nodeType];
1727 if(!node->_intern) {
1732 memset(node->_intern,0,
sizeof(
struct X3D_PolyRep));
1742 polyrep->streamed = FALSE;
1747 polyrep->minVals[0] = 999999.9f;
1748 polyrep->minVals[1] = 999999.9f;
1749 polyrep->minVals[2] = 999999.9f;
1750 polyrep->maxVals[0] = -999999.9f;
1751 polyrep->maxVals[1] = -999999.9f;
1752 polyrep->maxVals[2] = -999999.9f;
1754 for (i=0; i<VBO_COUNT; i++)
1755 polyrep->VBO_buffers[i] = 0;
1758 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
1759 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
1766 polyrep->coordinate_node = coord;
1769 if (polyrep->VBO_buffers[VERTEX_VBO] == 0) {
1771 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
1772 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
1777 polyrep->streamed = FALSE;
1779 FREE_IF_NZ(polyrep->cindex);
1780 FREE_IF_NZ(polyrep->actualCoord);
1781 FREE_IF_NZ(polyrep->GeneratedTexCoords[0]);
1782 FREE_IF_NZ(polyrep->colindex);
1783 FREE_IF_NZ(polyrep->color);
1784 FREE_IF_NZ(polyrep->norindex);
1785 FREE_IF_NZ(polyrep->normal);
1786 FREE_IF_NZ(polyrep->flat_normal);
1787 FREE_IF_NZ(polyrep->tcindex);
1791 virt->mkpolyrep(node);
1795 if (polyrep->ntri != 0) {
1797 stream_polyrep(node, coord, fogCoord, color, normal, texCoord);
1801 polyrep->irep_change = node->_change;
1805void delete_geomrep(
struct X3D_Node *node){
1812 if (!node->_intern)
return;
1814 switch(node->_intern->itype){
1817 if (node->_nodeType != NODE_PointSet && node->_nodeType != NODE_Polypoint2D) {
1818 printf(
"attempting to delete PointRep for nodetype %s\n", stringNodeType(node->_nodeType));
1821 delete_PointRep(node->_intern);
1822 node->_intern = NULL;
1839 glDeleteBuffers(VBO_COUNT, pr->VBO_buffers);
1842 FREE_IF_NZ(pr->cindex);
1843 FREE_IF_NZ(pr->colindex);
1844 FREE_IF_NZ(pr->norindex);
1845 FREE_IF_NZ(pr->tcindex);
1846 FREE_IF_NZ(pr->tri_indices);
1847 FREE_IF_NZ(pr->wire_indices);
1848 FREE_IF_NZ(pr->actualCoord);
1849 FREE_IF_NZ(pr->actualFog);
1850 FREE_IF_NZ(pr->color);
1851 FREE_IF_NZ(pr->normal);
1852 FREE_IF_NZ(pr->flat_normal);
1853 FREE_IF_NZ(pr->GeneratedTexCoords[0]);
1855 node->_intern = NULL;
1860 if (node->_nodeType != NODE_BufferGeometry) {
1861 printf(
"attempting to delete MeshRep for nodetype %s\n", stringNodeType(node->_nodeType));
1864 delete_MeshRep(node->_intern);
1865 node->_intern = NULL;
1871 delete_LightRep(node->_intern);
1872 node->_intern = NULL;
1876 delete_HanimRep(node->_intern);
1877 node->_intern = NULL;