35#include <libFreeWRL.h>
37#include "../vrml_parser/Structs.h"
38#include "../main/headers.h"
40#include "../x3d_parser/Bindable.h"
41#include "LinearAlgebra.h"
43#include "quaternion.h"
45#include "../opengl/Frustum.h"
47#include "../opengl/OpenGL_Utils.h"
48#include "../scenegraph/RenderFuncs.h"
51struct X3D_Node *getActiveLayerBoundViewpoint();
56 if (!renderstate()->render_vp)
return;
63 if((
struct X3D_Node*)node == getActiveLayerBoundViewpoint() && !node->_donethispass){
64 node->_donethispass = 1;
71 vrmlrot_to_quaternion(&q3,node->orientation.c[0],node->orientation.c[1],node->orientation.c[2],-node->orientation.c[3]);
74 FW_GL_TRANSLATE_D(-node->position.c[0],-node->position.c[1],-node->position.c[2]);
77 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
78 if(viewPort[2] > viewPort[3]) {
80 viewer->fieldofview = node->fieldOfView/3.1415926536*180;
82 a1 = node->fieldOfView;
83 a1 = atan2(sin(a1),viewPort[2]/((
float)viewPort[3]) * cos(a1));
84 viewer->fieldofview = a1/3.1415926536*180;
94 if (!renderstate()->render_vp)
return;
101 if((
struct X3D_Node*)node == getActiveLayerBoundViewpoint() && !node->_donethispass){
102 node->_donethispass = 1;
106 FW_GL_ROTATE_RADIANS(-node->orientation.c[3],node->orientation.c[0],node->orientation.c[1],
107 node->orientation.c[2]);
108 FW_GL_TRANSLATE_D(-node->position.c[0],-node->position.c[1],-node->position.c[2]);
111 if (node->fieldOfView.n == 4) {
112 for (ind=0; ind<4; ind++) {
113 Viewer()->orthoField[ind] = (double) node->fieldOfView.p[ind];
128 double mod[16], modi[16], axis[3];
135 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, mod);
136 float2double(axis,node->axisOfRotation.c,3);
137 align = (APPROX(veclengthd(axis),0.0f));
141 double modb[16], modbi[16];
142 matrixAFFINE2RotationMatrix(modb,mod);
143 matinverseAFFINE(modbi,modb);
144 FW_GL_TRANSFORM_D(modbi);
153 double vpos[3], zvec[3], perpa[3], perpb[3], matr[16];
155 vecsetd(vpos,0.0,0.0,0.0);
156 matinverseAFFINE(modi,mod);
157 transformAFFINEd(vpos,vpos,modi);
158 vecnormald(vpos,vpos);
160 vecsetd(zvec,0.0,0.0,1.0);
162 veccrossd(perpa,axis,vpos);
163 veccrossd(perpb,axis,zvec);
165 matrotate2vd(matr,perpa,perpb);
166 FW_GL_TRANSFORM_D(matr);
171 struct point_XYZ vpos, ax, cp, cp2, arcp;
172 static const struct point_XYZ orig = {0.0, 0.0, 0.0};
173 static const struct point_XYZ zvec = {0.0, 0.0, 1.0};
178 double len, len2, angle;
183 ax.x = node->axisOfRotation.c[0];
184 ax.y = node->axisOfRotation.c[1];
185 ax.z = node->axisOfRotation.c[2];
186 align = (APPROX(VECSQ(ax),0));
188 viewer_fetch_LCS(Viewer());
189 quaternion_to_vrmlrot(&(Viewer()->Quat),
190 &(viewer_orient.x), &(viewer_orient.y),
191 &(viewer_orient.z), &(viewer_orient.a));
195 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, mod);
197 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
198 FW_GLU_UNPROJECT(orig.x, orig.y, orig.z, mod, proj, viewport, &vpos.x, &vpos.y, &vpos.z);
203 matinverseAFFINE(modi,mod);
204 transform(&vpos,&orig,modi);
207 if (APPROX(len, 0)) {
return; }
208 VECSCALE(vpos, 1/sqrt(len));
211 ax.x = viewer_orient.x;
212 ax.y = viewer_orient.y;
213 ax.z = viewer_orient.z;
216 VECCP(ax, zvec, arcp);
218 if (APPROX(len, 0)) {
return; }
221 if (APPROX(len, 0)) {
return; }
222 VECSCALE(ax, 1/sqrt(len));
225 len = sqrt(VECSQ(cp));
226 if (APPROX(len, 0)) {
227 FW_GL_ROTATE_RADIANS(-viewer_orient.a, ax.x, ax.y, ax.z);
233 VECCP(cp, zvec, cp2);
235 len2 = VECPT(cp, zvec);
236 len = sqrt(VECSQ(cp2));
239 if (VECPT(cp, arcp) > 0)
245 angle = atan2(len2, sign*len);
247 FW_GL_ROTATE_RADIANS(angle, ax.x, ax.y, ax.z);
258 int nc = node->children.n;
266 printf(
"RENDER BILLBOARD START %d (%d)\n",node, nc);
271 prep_sibAffectors((
struct X3D_Node*)node,&node->__sibAffectors);
274 normalChildren(node->children);
276 if (renderstate()->render_geom && (!renderstate()->render_blend)) {
281 printf(
"RENDER BILLBOARD END %d\n",node);
283 fin_sibAffectors((
struct X3D_Node*)node,&node->__sibAffectors);
315 int nc = node->children.n;
319 if(renderstate()->render_collision) {
321 if((node->collide) && (node->enabled) && !(node->proxy)) {
324 OldCollisionInfo = *ci;
325 for(i=0; i<nc; i++) {
326 void *p = ((node->children).p[i]);
328 printf(
"RENDER COLLISION %d CHILD %d\n",node, p);
332 if((!APPROX(ci->Offset.x,
333 OldCollisionInfo.Offset.x)) ||
334 (!APPROX(ci->Offset.y,
335 OldCollisionInfo.Offset.y)) ||
336 (!APPROX(ci->Offset.z,
337 OldCollisionInfo.Offset.z))) {
344 node->__hit = (node->__hit & 1) ? 1 : 3;
346 node->__hit = (node->__hit & 1) ? 2 : 0;
350 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->proxy,tmpN)
358 printf(
"RENDER COLLISIONCHILD START %d (%d)\n",node, nc);
363 prep_sibAffectors((
struct X3D_Node*)node,&node->__sibAffectors);
366 normalChildren(node->children);
369 printf(
"RENDER COLLISIONCHILD END %d\n",node);
372 fin_sibAffectors((
struct X3D_Node*)node,&node->__sibAffectors);
378void child_LOD (
struct X3D_LOD *node) {
397 render_node(node->_selected);
402void proximity_LOD (
struct X3D_LOD *node) {
407 int nran = (node->range).n;
408 int nnod = (node->level).n;
409 int xnod = (node->children).n;
416 if (nnod > 0) node->_selected = (node->children).p[0];
417 else node->_selected = NULL;
419 if (xnod > 0) node->_selected = (node->level).p[0];
420 else node->_selected = NULL;
426 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, mod);
430 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
431 FW_GLU_UNPROJECT(0,0,0,mod,proj,viewport, &vec.x,&vec.y,&vec.z);
439 matinverseAFFINE(modi,mod);
440 transform(&vec,&orig,modi);
444 vec.x -= (node->center).c[0];
445 vec.y -= (node->center).c[1];
446 vec.z -= (node->center).c[2];
448 dist = sqrt(VECSQ(vec));
452 if(dist < ((node->range).p[i])) {
break; }
460 if(i >= xnod) i = xnod-1;
461 node->_selected = (node->children).p[i];
463 }
else node->_selected = NULL;
468 if(i >= nnod) i = nnod-1;
469 node->_selected = (node->level).p[i];
471 }
else { node->_selected = NULL; }
473 if(i != node->level_changed){
474 node->level_changed = i;
475 MARK_EVENT(X3D_NODE(node),offsetof(
struct X3D_LOD,level_changed));
486 void add_node_to_broto_context(
struct X3D_Proto *currentContext,
struct X3D_Node *node);
492 if (node->__proxNode == NULL) {
495 if(node->_executionContext)
496 add_node_to_broto_context(X3D_PROTO(node->_executionContext),X3D_NODE(pn));
499 node->__proxNode = (
void *)pn;
502 ADD_PARENT(X3D_NODE(pn),X3D_NODE(node));
506 pn = X3D_PROXIMITYSENSOR(node->__proxNode);
509 memcpy (&pn->center, &node->center, sizeof (
float)*3);
510 memcpy (&pn->size, &node->size, sizeof (
float)*3);
532 if (renderstate()->render_proximity) {
533 if (node->__proxNode != NULL) {
535 render_node(X3D_NODE(node->__proxNode));
542 if (!renderstate()->render_vp)
return;
545 for(i=0; i<node->children.n; i++) {
546 struct X3D_Node *p = X3D_NODE(node->children.p[i]);