30 #include <system_threads.h>
34 #include <libFreeWRL.h>
38 # include <sys/time.h>
47 #include "../vrml_parser/Structs.h"
48 #include "../vrml_parser/CRoutes.h"
50 #include "../vrml_parser/CParseGeneral.h"
51 #include "../world_script/JScript.h"
52 #include "../world_script/CScripts.h"
54 #include "../scenegraph/LinearAlgebra.h"
55 #include "../scenegraph/Collision.h"
57 #include "../scenegraph/Viewer.h"
58 #include "../input/SensInterps.h"
59 #include "../x3d_parser/Bindable.h"
60 #include "../input/EAIHeaders.h"
62 #include "../scenegraph/Component_KeyDevice.h"
63 #include "../opengl/Frustum.h"
64 #include "../input/InputFunctions.h"
66 #include "../opengl/LoadTextures.h"
67 #include "../opengl/OpenGL_Utils.h"
68 #include "../ui/statusbar.h"
69 #include "../ui/CursorDraw.h"
70 #include "../scenegraph/RenderFuncs.h"
72 #include "../ui/common.h"
73 #include "../io_files.h"
76 #include "../scenegraph/quaternion.h"
78 ivec2 ivec2_init(
int x,
int y);
79 ivec4 ivec4_init(
int x,
int y,
int w,
int h);
81 int getRayHitAndSetLookatTarget();
82 void transformMBB(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax);
85 #if !defined(_MSC_VER)
89 void (*newResetGeometry) (void) = NULL;
98 OLDCODE #
if defined(_ANDROID )
99 OLDCODE
void setAquaCursor(
int ctype) { };
104 #include "MainLoop.h"
106 static int debugging_trigger_state;
107 void toggle_debugging_trigger(){
109 debugging_trigger_state = 1 - debugging_trigger_state;
111 int get_debugging_trigger_once(){
112 int iret = debugging_trigger_state;
113 if(iret) debugging_trigger_state = 0;
116 int get_debugging_trigger(){
117 return debugging_trigger_state;
122 return gglobal()->Mainloop.TickTime;
126 return gglobal()->Mainloop.lastTime;
133 void (*interpptr)(
void *, int, int, int);
147 TOUCHCLAIMANT_UNCLAIMED = 0,
148 TOUCHCLAIMANT_PEDAL = 1,
149 TOUCHCLAIMANT_SENSOR = 2,
150 TOUCHCLAIMANT_NAVIGATION = 4,
151 TOUCHCLAIMANT_NONE = 8,
172 struct X3D_Node* CursorOverSensitive;
176 int lastOverButtonPressed;
178 void *hypersensitive;
180 double justModel[16];
192 stack_push(
ivec4,vpstack,vp);
194 void popviewport(
Stack *vpstack){
195 stack_pop(
ivec4,vpstack);
200 inside = vp1.X >= vp2.X && (vp1.X+vp1.W) <= (vp2.X+vp2.W) ? 1 : 0;
202 inside = vp2.X >= vp1.X && (vp2.X+vp2.W) <= (vp1.X+vp1.W) ? -1 : 0;
205 inside = vp1.X > (vp2.X+vp2.W) || vp1.X > (vp1.X+vp1.W) || vp1.Y > (vp2.Y+vp2.H) || vp2.Y > (vp1.Y+vp1.H) ? 0 : 2;
211 vpo.X = max(vp1.X,vp2.X);
212 vpo.W = min(vp1.X+vp1.W,vp2.X+vp2.W) - vpo.X;
213 vpo.Y = max(vp1.Y,vp2.Y);
214 vpo.H = min(vp1.Y+vp1.H,vp2.Y+vp2.H) - vpo.Y;
218 int visibleviewport(
ivec4 vp){
219 int ok = vp.W > 0 && vp.H > 0;
224 inside = inside && pt.X <= (vp.X + vp.W) && (pt.X >= vp.X);
225 inside = inside && pt.Y <= (vp.Y + vp.H) && (pt.Y >= vp.Y);
228 int pointinsidecurrentviewport(
Stack *vpstack,
ivec2 pt){
230 return pointinsideviewport(vp,pt);
232 void intersectandpushviewport(
Stack *vpstack,
ivec4 childvp){
234 ivec4 olap = intersectviewports(childvp,currentvp);
235 pushviewport(vpstack, olap);
238 return stack_top(
ivec4,vpstack);
240 int currentviewportvisible(
Stack *vpstack){
242 return visibleviewport(currentvp);
244 void setcurrentviewport(
Stack *_vpstack){
246 glViewport(vp.X,vp.Y,vp.W,vp.H);
248 ivec4 viewportFraction(
ivec4 vp,
float *fraction){
267 L = (int)(vp.X + vp.W*fraction[0]);
268 R = (int)(vp.X + vp.W*fraction[1]);
269 B = (int)(vp.Y + vp.H*fraction[2]);
270 T = (int)(vp.Y + vp.H*fraction[3]);
313 CONTENT_STEREO_SIDEBYSIDE,
314 CONTENT_STEREO_ANAGLYPH,
315 CONTENT_STEREO_UPDOWN,
316 CONTENT_STEREO_SHUTTER,
330 int haveFrameBufferObject()
333 #if defined(GLEW) || defined(GLEW_MX)
334 iret = GLEW_ARB_framebuffer_object != 0;
339 void pushnset_framebuffer(
int ibuffer){
340 Stack *framebufferstack;
342 framebufferstack = (
Stack *)gglobal()->Mainloop._framebufferstack;
344 stack_push(
int,framebufferstack,ibuffer);
347 if (haveFrameBufferObject() ){
348 glBindFramebuffer(GL_FRAMEBUFFER,0);
349 glBindFramebuffer(GL_FRAMEBUFFER, ibuffer);
353 void popnset_framebuffer(){
356 Stack *framebufferstack;
357 framebufferstack = (
Stack *)gglobal()->Mainloop._framebufferstack;
359 stack_pop(
int,framebufferstack);
360 ibuffer = stack_top(
int,framebufferstack);
362 if (haveFrameBufferObject()){
363 glBindFramebuffer(GL_FRAMEBUFFER,0);
364 glBindFramebuffer(GL_FRAMEBUFFER, ibuffer);
368 void pushnset_viewport(
float *vpFraction){
372 vportstack = (
Stack *)gglobal()->Mainloop._vportstack;
373 ivport = currentViewport(vportstack);
374 ivport = viewportFraction(ivport, vpFraction);
375 pushviewport(vportstack,ivport);
376 setcurrentviewport(vportstack);
378 void popnset_viewport(){
381 vportstack = (
Stack *)gglobal()->Mainloop._vportstack;
382 popviewport(vportstack);
383 setcurrentviewport(vportstack);
385 int checknpush_viewport(
float *vpfraction,
int mouseX,
int mouseY){
387 ivec4 ivport, ivport1;
391 vportstack = (
Stack *)gglobal()->Mainloop._vportstack;
392 ivport = currentViewport(vportstack);
393 ivport1 = viewportFraction(ivport, vpfraction);
396 iret = pointinsideviewport(ivport1,pt);
397 if(iret) pushviewport(vportstack,ivport1);
408 vportstack = (
Stack *)gglobal()->Mainloop._vportstack;
409 popviewport(vportstack);
412 ivec4 get_current_viewport(){
414 vportstack = (
Stack *)gglobal()->Mainloop._vportstack;
415 return stack_top(
ivec4,vportstack);
417 float defaultClipBoundary [] = {0.0f, 1.0f, 0.0f, 1.0f};
444 void register_contenttype(
void *ct);
445 void free_contenttypes();
454 void (*render)(
void *
self);
455 int (*pick)(
void *
self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex);
460 void content_render(
void *_self){
465 pushnset_viewport(self->t1.viewport);
466 c =
self->t1.contents;
474 int content_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
481 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
482 c =
self->t1.contents;
484 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
493 self->itype = CONTENT_GENERIC;
494 self->contents = NULL;
495 self->render = content_render;
496 self->pick = content_pick;
497 memcpy(self->viewport,defaultClipBoundary,4*
sizeof(
float));
509 static void render();
510 int setup_pickside0(
int x,
int y,
int *iside,
ivec4 *vportleft,
ivec4 *vportright);
511 void scene_render(
void *
self){
514 void setup_picking();
515 void fwl_handle_aqua_multiNORMAL(
const int mev,
const unsigned int button,
int x,
int y,
unsigned int ID,
int windex);
516 int scene_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
522 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
526 inside = setup_pickside0(mouseX,mouseY,&iside,&vport[0],&vport[1]);
528 Stack *vpstack = (
Stack*)gglobal()->Mainloop._vportstack;
529 pushviewport(vpstack,vport[iside]);
530 fwl_handle_aqua_multiNORMAL(mev,butnum,mouseX,mouseY,ID,windex);
532 popviewport(vpstack);
540 register_contenttype(
self);
541 init_tcontenttype(&self->t1);
542 self->t1.itype = CONTENT_SCENE;
543 self->t1.render = scene_render;
544 self->t1.pick = scene_pick;
547 int statusbar_getClipPlane();
552 void render_statusbar0();
553 void statusbar_render(
void *_self){
561 pushnset_viewport(self->t1.viewport);
562 self->clipplane = statusbar_getClipPlane();
566 if(self->clipplane != 0){
571 vportstack = (
Stack*)tg->Mainloop._vportstack;
572 ivport = stack_top(
ivec4,vportstack);
573 ivport.H -=
self->clipplane;
574 ivport.Y +=
self->clipplane;
575 stack_push(
ivec4,vportstack,ivport);
578 c =
self->t1.contents;
585 stack_pop(
ivec4,vportstack);
590 int statusbar_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
599 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
600 iret = statusbar_handle_mouse1(mev,butnum,mouseX,mouseY,windex);
606 if(self->clipplane != 0){
611 vportstack = (
Stack*)tg->Mainloop._vportstack;
612 ivport = stack_top(
ivec4,vportstack);
613 ivport.H -=
self->clipplane;
614 ivport.Y +=
self->clipplane;
615 stack_push(
ivec4,vportstack,ivport);
619 c =
self->t1.contents;
621 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
626 stack_pop(
ivec4,vportstack);
635 register_contenttype(
self);
636 init_tcontenttype(&self->t1);
637 self->t1.itype = CONTENT_STATUSBAR;
638 self->t1.render = statusbar_render;
639 self->t1.pick = statusbar_pick;
651 void render_switch0();
652 void switch_render(
void *_self){
659 pushnset_viewport(self->t1.viewport);
660 c =
self->t1.contents;
663 iwhich = *(
self->whichPtr);
672 int switch_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
681 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
683 c =
self->t1.contents;
685 if(i == *(self->whichPtr)){
686 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
698 register_contenttype(
self);
699 init_tcontenttype(&self->t1);
700 self->t1.itype = CONTENT_SWITCH;
701 self->t1.render = switch_render;
702 self->t1.pick = switch_pick;
703 self->whichCase = -1;
704 self->whichPtr = &
self->whichCase;
707 void contenttype_switch_set_which(
contenttype *_self,
int which){
709 self->whichCase = which;
710 self->whichPtr = &
self->whichCase;
712 void contenttype_switch_set_which_ptr(
contenttype *_self,
int *whichPtr){
714 self->whichPtr = whichPtr;
725 AtlasFont *searchAtlasTableOrLoad(
char *facename,
int EMpixels);
727 typedef struct vec4 {
float X;
float Y;
float Z;
float W;}
vec4;
728 vec4 vec4_init(
float x,
float y,
float z,
float w);
729 int render_captiontext(
AtlasFont *font,
int *utf32,
int len32,
vec4 color);
747 void captiontext_render(
void *_self){
751 pushnset_viewport(self->t1.viewport);
753 render_captiontext(self->font, self->utf32, self->len32, self->color);
756 int captiontext_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
760 contenttype *new_contenttype_captiontext(
char *fontname,
int EMpixels,
vec4 color){
762 register_contenttype(
self);
763 init_tcontenttype(&self->t1);
764 self->t1.itype = CONTENT_CAPTIONTEXT;
765 self->t1.render = captiontext_render;
766 self->t1.pick = captiontext_pick;
768 self->EMpixels = EMpixels;
771 self->fontname = fontname;
772 self->caption = NULL;
777 self->font = (
AtlasFont*)searchAtlasTableOrLoad(fontname,EMpixels);
779 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
786 unsigned int *utf8_to_utf32(
unsigned char *utf8string,
unsigned int *str32,
unsigned int *len32);
787 void captiontext_setString(
void *_self,
char *utf8string){
790 lenstr = strlen(utf8string);
791 if(self->nalloc < lenstr){
792 self->caption = realloc(self->caption,lenstr+1);
794 self->utf32 = realloc(self->utf32,(lenstr+1)*
sizeof(
int));
795 self->nalloc = lenstr;
797 strcpy(self->caption,utf8string);
799 self->utf32 = utf8_to_utf32(self->caption,self->utf32,&self->len32);
835 unsigned char *Ablob;
837 unsigned char *S, *E;
846 void textpanel_render(
void *
self);
847 contenttype *new_contenttype_textpanel(
char* fontname,
int EMpixels,
int maxlines,
int maxlen,
int wrap){
850 register_contenttype(
self);
851 init_tcontenttype(&self->t1);
852 self->t1.itype = CONTENT_TEXTPANEL;
853 self->t1.render = textpanel_render;
856 self->color = vec4_init(1.0f,1.0f,1.0f,0.0f);
858 self->maxlines = maxlines;
859 self->maxlen = maxlen;
864 self->blobsize =
self->maxlines *
self->maxlen;
865 self->Ablob = (
unsigned char*)MALLOCV(self->blobsize+1);
866 register_contenttype(self->Ablob);
867 memset(self->Ablob,0,self->blobsize+1);
868 self->Z =
self->z =
self->Ablob;
869 self->S =
self->Ablob;
870 self->E =
self->Ablob +
self->blobsize;
871 self->Blist = MALLOCV(
sizeof(
BUTitem)*self->maxlines);
872 register_contenttype(self->Blist);
873 self->rowsize =
self->maxlen;
874 self->row = MALLOCV(self->rowsize +1);
875 register_contenttype(self->row);
877 for(i=0;i<
self->maxlines;i++){
881 if(prev < 0) prev =
self->maxlines -1;
882 if(next > self->maxlines -1) next = 0;
883 self->Blist[i].next = &
self->Blist[next];
884 self->Blist[i].prev = &
self->Blist[prev];
885 self->Blist[i].B =
self->Z;
887 self->bhead = &
self->Blist[0];
890 self->fontname = fontname;
891 iem = (int)(EMpixels * fwl_getDensityFactor());
892 self->fontSize = iem;
893 self->maxadvancepx = iem/2;
894 self->initialized = FALSE;
896 self->fontname = fontname;
897 self->font = (
AtlasFont*)searchAtlasTableOrLoad(fontname,iem);
899 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
990 unsigned char *T, *U, *B;
991 int lenT, lenU, haveTU;
994 T = min(self->Z + len, self->E);
995 U = T ==
self->E ?
self->S : T;
999 memcpy(self->Z,line,lenT);
1001 memcpy(U,&line[lenT],lenU);
1003 BUTI = endline?
self->bhead->next :
self->bhead;
1007 self->added = min(self->added + len, self->blobsize + 1);
1008 if(self->added > self->blobsize){
1010 self->z =
self->z + 1;
1011 if(self->z > self->E)
self->z =
self->S;
1014 void TextPanel_AddString(
void *_self,
char *
string){
1018 int endline, endstring;
1020 if(s == NULL)
return;
1021 endstring = (*s) ==
'\0';
1024 while( (*ln) !=
'\0' && (*ln) !=
'\n') ln++;
1025 endline = (*ln) ==
'\n';
1026 endstring = (*ln) ==
'\0';
1027 TextPanel_AddLine_blobMethodB(
self,s,ln-s,endline);
1032 void fwg_register_consolemessage_callbackB(
void *data,
void(*callback)(
void*,
char *));
1033 void textpanel_register_as_console(
void *_self){
1034 fwg_register_consolemessage_callbackB(_self,TextPanel_AddString);
1036 ivec2 pixel2text(
int x,
int y,
int rowheight,
int maxadvancepx){
1038 int w = maxadvancepx;
1039 ivec2 ret = ivec2_init(x/w,y/h);
1042 ivec2 text2pixel(
int x,
int y,
int rowheight,
int maxadvancepx){
1044 int w = maxadvancepx;
1045 ivec2 ret = ivec2_init(x*w, y*h);
1049 void atlasfont_get_rowheight_charwidth_px(
AtlasFont *font,
int *rowheight,
int *maxadvancepx);
1050 static int show_ringtext = 0;
1051 int before_textpanel_render_rows(
AtlasFont *font,
vec4 color);
1052 int textpanel_render_row(
AtlasFont *font,
char * cText,
int len,
int *pen_x,
int *pen_y);
1053 void after_textpanel_render_rows();
1069 int jline, jrow, nrows, isFull, moredata, rowheight, maxadvancepx, atlasOK;
1071 ivec2 panelsizechars;
1077 if(self->t1.itype != CONTENT_TEXTPANEL)
return;
1078 if(!self->font )
return;
1080 atlasfont_get_rowheight_charwidth_px(self->font,&rowheight,&maxadvancepx);
1081 panelsizechars = ivec2_init(ivport.W / maxadvancepx, ivport.H / rowheight);
1082 panelsizechars.X = min(panelsizechars.X,self->maxlen);
1083 panelsizechars.Y = min(panelsizechars.Y,self->maxlines);
1098 isFull =
self->added >
self->blobsize;
1099 moredata = min(self->added,self->blobsize);
1101 int i, nchars, bchars, achars, hasTU, Trow;
1102 unsigned char *B, *A, *U, *T, *P;
1115 nchars = (B - U + T - A);
1117 bchars = nchars - achars;
1119 nrows = (int)ceil((
float)nchars/(float)panelsizechars.X);
1120 Trow = nrows -1 - (T - A)/panelsizechars.X;
1135 atlasOK = before_textpanel_render_rows(self->font, self->color);
1139 for(i=0;i<nrows;i++){
1141 int l0, l1, i0, lenrow, pen_x, pen_y;
1144 i0 = (nrows-i-1)*panelsizechars.X;
1145 lenrow = min(nchars - i0,panelsizechars.X);
1150 if(jrow > panelsizechars.Y)
1152 row = &P[-nchars + i0];
1153 if(hasTU && Trow == i){
1157 memcpy(&row[l0],U,l1);
1158 memcpy(row,&A[i0],l0);
1159 P = &
self->E[bchars];
1163 if(!strncmp(row,
"`~",2)){
1166 printf(
"===========\n");
1167 printf(
"%s",self->Ablob);
1168 printf(
"\n===========\n");
1175 for(k=0;k<lenrow;k++){
1177 printf(
"T-A=%d B-U=%d Z=%d S=%d E=%d A=%d B=%d &Aio= %d\n",(
int)(T-A),(
int)(B-U),(
int)self->Z, (
int)self->S,(
int)self->E,(
int)A,(
int)B,(
int)&A[i0]);
1184 xy = text2pixel(0,jrow,rowheight,maxadvancepx);
1199 textpanel_render_row(self->font, row, lenrow,&pen_x, &pen_y);
1202 memcpy(self->row,row,lenrow);
1203 self->row[lenrow] =
'\n';
1204 self->row[lenrow+1] =
'\0';
1205 printf(
"%s",self->row);
1211 }
while(jrow < panelsizechars.Y && moredata > 0);
1212 after_textpanel_render_rows();
1213 if(0) printf(
"======================\n");
1232 void textpanel_render(
void *_self){
1241 pushnset_viewport(self->t1.viewport);
1242 c =
self->t1.contents;
1248 if(getShowConsoleText()){
1250 vportstack = (
Stack*)tg->Mainloop._vportstack;
1251 ivport = stack_top(
ivec4,vportstack);
1252 textpanel_render_blobmethod(
self,ivport);
1278 void layer_render(
void *_self){
1282 pushnset_viewport(self->t1.viewport);
1283 c =
self->t1.contents;
1290 int layer_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1295 c =
self->t1.contents;
1304 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1308 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID,windex);
1318 register_contenttype(
self);
1319 init_tcontenttype(&self->t1);
1320 self->t1.itype = CONTENT_LAYER;
1321 self->t1.render = layer_render;
1322 self->t1.pick = layer_pick;
1326 int emulate_multitouch2(
struct Touch *touchlist,
int ntouch,
int *IDD,
int *lastbut,
int *mev,
unsigned int *button,
int x,
int y,
int *ID,
int windex);
1327 void record_multitouch(
struct Touch *touchlist,
int mev,
int butnum,
int mouseX,
int mouseY,
int ID,
int windex,
int ihandle);
1328 int fwl_get_emulate_multitouch();
1330 void render_multitouch2(
struct Touch* touchlist,
int ntouch);
1337 struct Touch touchlist[20];
1342 void multitouch_render(
void *_self){
1347 pushnset_viewport(self->t1.viewport);
1348 c =
self->t1.contents;
1357 int multitouch_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1365 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1369 if(fwl_get_emulate_multitouch()){
1370 ihandle = emulate_multitouch2(self->touchlist,self->ntouch,&self->IDD,&self->lastbut,&mev,&butnum,mouseX,mouseY,&ID,windex);
1371 iret = ihandle < 0 ? 0 : 1;
1375 c =
self->t1.contents;
1378 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID,windex);
1383 record_multitouch(self->touchlist,mev,butnum,mouseX,mouseY,ID,windex,ihandle);
1392 register_contenttype(
self);
1393 init_tcontenttype(&self->t1);
1394 self->t1.itype = CONTENT_MULTITOUCH;
1395 self->t1.render = multitouch_render;
1396 self->t1.pick = multitouch_pick;
1399 memset(self->touchlist,0,20*
sizeof(
struct Touch));
1414 void e3dmouse_render(
void *_self){
1417 content_render(_self);
1425 vportstack = (
Stack*)tg->Mainloop._vportstack;
1426 ivport = stack_top(
ivec4,vportstack);
1427 x = ivport.W/2 + ivport.X;
1428 y = ivport.H/2 + ivport.Y;
1430 fiducialDrawB(CURSOR_DOWN,x,y);
1434 int e3dmouse_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1445 int iret, but2, x,y;
1446 unsigned int ID0, ID1;
1452 vportstack = (
Stack*)tg->Mainloop._vportstack;
1454 ivport = stack_top(
ivec4,vportstack);
1455 x = ivport.W/2 + ivport.X;
1456 y = ivport.H/2 + ivport.Y;
1462 ivport = stack_top(
ivec4,vportstack);
1464 if(mev == ButtonRelease){
1465 self->sphericalmode = 1 -
self->sphericalmode;
1466 if(self->sphericalmode){
1467 printf(
"turning on spherical mode\n");
1468 self->navigationMode = fwl_getNavMode();
1469 fwl_setNavMode(
"SPHERICAL");
1472 iret = content_pick(_self,ButtonPress,but2,mouseX,mouseY,ID0,windex);
1474 printf(
"turning off spherical mode\n");
1475 fwl_set_viewer_type(self->navigationMode);
1478 iret = content_pick(_self,ButtonRelease,but2,mouseX,mouseY,ID0,windex);
1480 self->waste = FALSE;
1481 }
else if(mev == ButtonPress){
1486 if(self->waste)
return 1;
1487 if(self->sphericalmode){
1488 iret = content_pick(_self,mev,butnum,x,y,ID1,windex);
1491 iret = content_pick(_self,MotionNotify,0,mouseX,mouseY,ID0,windex);
1495 iret = content_pick(_self,mev,butnum,mouseX,mouseY,ID0,windex);
1504 register_contenttype(
self);
1505 init_tcontenttype(&self->t1);
1506 self->t1.itype = CONTENT_E3DMOUSE;
1507 self->t1.render = e3dmouse_render;
1508 self->t1.pick = e3dmouse_pick;
1509 self->sphericalmode = 0;
1517 float offset_fraction[2];
1519 void loadIdentityMatrix (
double *mat);
1520 void get_view_matrix(
double *savePosOri,
double *saveView);
1521 static void set_view_matrix(
double *savePosOri,
double *saveView);
1523 static void set_quadrant_viewmatrix(
double *savePosOri,
double *saveView,
int iq) {
1527 double viewmatrix[16], tmat[16], pomat[16], vmat[16], bothinverse[16];
1528 double xyz[3], zero[3];
1530 get_view_matrix(savePosOri,saveView);
1532 zero[0] = zero[1] = zero[2] = 0.0;
1533 matmultiplyAFFINE(viewmatrix,saveView,savePosOri);
1534 matinverseAFFINE(bothinverse,viewmatrix);
1536 transformAFFINEd(xyz, zero, bothinverse);
1538 loadIdentityMatrix (pomat);
1539 loadIdentityMatrix (vmat);
1540 if(0) mattranslate(vmat, -Viewer()->Dist,0.0,0.0);
1542 mattranslate(tmat,-xyz[0],-xyz[1],-xyz[2]);
1543 matmultiplyAFFINE(vmat,tmat,vmat);
1547 case 1: matrotate(tmat, 0.0, 0.0,0.0,1.0);
1549 case 2: matrotate(tmat, PI * .5, 1.0,0.0,0.0);
1551 case 3: matrotate(tmat, PI * .5, 0.0,1.0,0.0);
1556 matmultiplyAFFINE(vmat,vmat,tmat);
1557 set_view_matrix(pomat,vmat);
1559 void quadrant_render(
void *_self){
1566 pushnset_viewport(self->t1.viewport);
1567 c =
self->t1.contents;
1570 double savePosOri[16], saveView[16];
1572 memcpy(viewport,defaultClipBoundary,4*
sizeof(
float));
1574 viewport[0] = i==0 || i==2 ? 0.0f :
self->offset_fraction[0];
1575 viewport[1] = i==0 || i==2 ?
self->offset_fraction[0] : 1.0f;
1576 viewport[2] = i==0 || i==1 ? 0.0f :
self->offset_fraction[1];
1577 viewport[3] = i==0 || i==1 ?
self->offset_fraction[1] : 1.0f;
1578 pushnset_viewport(viewport);
1581 set_quadrant_viewmatrix(savePosOri, saveView, i);
1584 set_view_matrix(savePosOri,saveView);
1592 int quadrant_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1601 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1602 c =
self->t1.contents;
1607 memcpy(viewport,defaultClipBoundary,4*
sizeof(
float));
1609 viewport[0] = i==0 || i==2 ? 0.0f :
self->offset_fraction[0];
1610 viewport[1] = i==0 || i==2 ?
self->offset_fraction[0] : 1.0f;
1611 viewport[2] = i==0 || i==1 ? 0.0f :
self->offset_fraction[1];
1612 viewport[3] = i==0 || i==1 ?
self->offset_fraction[1] : 1.0f;
1613 if(checknpush_viewport(viewport,mouseX,mouseY)){
1615 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1630 register_contenttype(
self);
1631 init_tcontenttype(&self->t1);
1632 self->t1.itype = CONTENT_QUADRANT;
1633 self->t1.render = quadrant_render;
1634 self->t1.pick = quadrant_pick;
1635 self->offset_fraction[0] = .5f;
1636 self->offset_fraction[1] = .5f;
1649 void loadIdentityMatrix (
double *mat);
1650 void get_view_matrix(
double *savePosOri,
double *saveView);
1651 static void set_view_matrix(
double *savePosOri,
double *saveView);
1652 void compute_sidebyside_viewport_and_fiducial(
int iside,
ivec4 *ivport,
ivec2 *fidcenter){
1663 vportstack = (
Stack*)tg->Mainloop._vportstack;
1664 vport = stack_top(
ivec4,vportstack);
1666 screenwidth2 = vport.W/2;
1667 ivport->W = screenwidth2;
1668 ivport->H = vport.H;
1669 ivport->Y = vport.Y;
1671 ivport->X = vport.X;
1673 ivport->X = vport.X + screenwidth2;
1675 fidcenter->Y = vport.Y + vport.H;
1679 expansion = viewer->screendist - .5;
1680 iexpand = (GLint)(expansion * ivport->W);
1682 fidcenter->X = ivport->X + screenwidth2/2;
1684 fidcenter->X -= iexpand;
1686 fidcenter->X += iexpand;
1689 void stereo_sidebyside_render(
void *_self){
1699 viewer->isStereoB = 1;
1701 pushnset_viewport(self->t1.viewport);
1702 c =
self->t1.contents;
1714 vportstack = (
Stack*)tg->Mainloop._vportstack;
1717 compute_sidebyside_viewport_and_fiducial(viewer->isideB,&ivport2,&fidcenter);
1721 halfW = ivport2.W / 2;
1722 vpc = halfW + ivport2.X;
1723 viewer->xcenter = (double)(fidcenter.X - vpc)/(double)halfW;
1724 pushviewport(vportstack,ivport2);
1726 setcurrentviewport(vportstack);
1730 fiducialDrawB(CURSOR_FIDUCIALS,fidcenter.X,fidcenter.Y);
1733 viewer->xcenter = 0.0;
1737 viewer->isStereoB = 0;
1740 int stereo_sidebyside_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1750 viewer->isStereoB = 1;
1753 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1754 c =
self->t1.contents;
1760 ivec2 fidcenter, pt;
1763 compute_sidebyside_viewport_and_fiducial(viewer->isideB,&ivport2,&fidcenter);
1768 iret = pointinsideviewport(ivport2,pt);
1770 pushviewport(gglobal()->Mainloop._vportstack,ivport2);
1771 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1780 viewer->isStereoB = 0;
1785 register_contenttype(
self);
1786 init_tcontenttype(&self->t1);
1787 self->t1.itype = CONTENT_STEREO_SIDEBYSIDE;
1788 self->t1.render = stereo_sidebyside_render;
1789 self->t1.pick = stereo_sidebyside_pick;
1801 void loadIdentityMatrix (
double *mat);
1802 void clear_shader_table();
1803 void setStereoBufferStyle(
int);
1804 void stereo_anaglyph_render(
void *_self){
1817 viewer->isStereoB = 1;
1818 viewer->anaglyphB = 1;
1819 clear_shader_table();
1822 pushnset_viewport(self->t1.viewport);
1823 c =
self->t1.contents;
1826 Viewer_anaglyph_clearSides();
1828 glClearColor(0.0f,0.0f,0.0f,1.0f);
1829 BackEndClearBuffer(2);
1833 Viewer_anaglyph_setSide(i);
1834 viewer->xcenter = 0.0;
1841 Viewer_anaglyph_clearSides();
1843 clear_shader_table();
1845 viewer->anaglyphB = 0;
1846 viewer->isStereoB = 0;
1849 int stereo_anaglyph_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1859 viewer->isStereoB = 1;
1862 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1863 c =
self->t1.contents;
1868 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1875 viewer->isStereoB = 0;
1880 register_contenttype(
self);
1881 init_tcontenttype(&self->t1);
1882 self->t1.itype = CONTENT_STEREO_ANAGLYPH;
1883 self->t1.render = stereo_anaglyph_render;
1884 self->t1.pick = stereo_anaglyph_pick;
1895 void stereo_updown_render(
void *_self){
1906 viewer->isStereoB = 1;
1907 viewer->updownB = 1;
1909 vportstack = (
Stack*)tg->Mainloop._vportstack;
1912 pushnset_viewport(self->t1.viewport);
1913 c =
self->t1.contents;
1917 ivport = stack_top(
ivec4,vportstack);
1919 ivport.Y += (1-i)*ivport.H;
1920 pushviewport(vportstack,ivport);
1921 setcurrentviewport(vportstack);
1925 viewer->xcenter = 0.0;
1934 viewer->updownB = 0;
1935 viewer->isStereoB = 0;
1938 int stereo_updown_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1950 viewer->isStereoB = 1;
1951 vportstack = (
Stack*)tg->Mainloop._vportstack;
1954 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1955 c =
self->t1.contents;
1963 ivport = stack_top(
ivec4,vportstack);
1965 ivport.Y += (1-i)*ivport.H;
1968 iret = pointinsideviewport(ivport,pt);
1971 pushviewport(vportstack,ivport);
1972 setcurrentviewport(vportstack);
1974 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1983 viewer->isStereoB = 0;
1988 register_contenttype(
self);
1989 init_tcontenttype(&self->t1);
1990 self->t1.itype = CONTENT_STEREO_UPDOWN;
1991 self->t1.render = stereo_updown_render;
1992 self->t1.pick = stereo_updown_pick;
2002 void setStereoBufferStyleB(
int itype,
int iside,
int ibuffer);
2003 void stereo_shutter_render(
void *_self){
2005 int i, shutterGlasses;
2010 static double shuttertime;
2011 static int shutterside;
2016 viewer->isStereoB = 1;
2020 if(viewer->haveQuadbuffer)
2023 pushnset_viewport(self->t1.viewport);
2024 c =
self->t1.contents;
2029 viewer->xcenter = 0.0;
2030 if(shutterGlasses == 2)
2032 if(TickTime() - shuttertime > 2.0)
2034 shuttertime = TickTime();
2035 shutterside = 1 - shutterside;
2037 setStereoBufferStyleB(1,i,0);
2040 setStereoBufferStyleB(0,i,0);
2051 setStereoBufferStyleB(1,0,0);
2052 viewer->isStereoB = 0;
2055 int stereo_shutter_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2067 viewer->isStereoB = 1;
2071 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2072 c =
self->t1.contents;
2076 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
2084 viewer->isStereoB = 0;
2089 register_contenttype(
self);
2090 init_tcontenttype(&self->t1);
2091 self->t1.itype = CONTENT_STEREO_SHUTTER;
2092 self->t1.render = stereo_shutter_render;
2093 self->t1.pick = stereo_shutter_pick;
2110 float offset_fraction;
2116 register_contenttype(
self);
2117 init_tcontenttype(&self->t1);
2118 self->t1.itype = CONTENT_SPLITTER;
2131 unsigned int ibuffer;
2132 unsigned int itexturebuffer;
2133 unsigned int idepthbuffer;
2153 void push_stageId(
void *stageId){
2154 Stack *stagestack = (
Stack*)gglobal()->Mainloop._stagestack;
2155 stack_push(
void*,stagestack,stageId);
2157 void *current_stageId(){
2158 Stack *stagestack = (
Stack*)gglobal()->Mainloop._stagestack;
2159 return stack_top(
void*,stagestack);
2162 Stack *stagestack = (
Stack*)gglobal()->Mainloop._stagestack;
2163 stack_pop(
void*,stagestack);
2166 void stage_render(
void *_self){
2171 pushnset_framebuffer(self->ibuffer);
2172 vportstack = (
Stack*)gglobal()->Mainloop._vportstack;
2173 pushviewport(vportstack,self->ivport);
2175 setcurrentviewport(vportstack);
2178 if(self->ibuffer != FW_GL_BACK)
2179 glClearColor(.3f,.4f,.5f,1.0f);
2181 glClearColor(1.0f,0.0f,0.0f,1.0f);
2182 BackEndClearBuffer(2);
2183 content_render(_self);
2186 popnset_framebuffer();
2188 int stage_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2190 ivec4 ivport_parent;
2195 ivport_parent = get_current_viewport();
2196 x = mouseX - ivport_parent.X;
2197 y = mouseY - ivport_parent.Y;
2199 x = x +
self->ivport.X;
2200 y = y +
self->ivport.Y;
2201 vportstack = (
Stack*)gglobal()->Mainloop._vportstack;
2202 pushviewport(vportstack,self->ivport);
2204 iret = content_pick(_self,mev,butnum,x,y,ID,windex);
2212 register_contenttype(
self);
2213 init_tcontenttype(&self->t1);
2214 self->t1.itype = CONTENT_STAGE;
2215 self->t1.render = stage_render;
2216 self->t1.pick = stage_pick;
2217 self->type = STAGETYPE_BACKBUF;
2218 self->ibuffer = FW_GL_BACK;
2219 self->clear_zbuffer = TRUE;
2220 self->ivport = ivec4_init(0,0,100,100);
2224 #ifdef GL_DEPTH_COMPONENT32
2225 #define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT32
2227 #define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT16
2229 contenttype *new_contenttype_stagefbo(
int width,
int height){
2234 _self = new_contenttype_stage();
2235 self = (
stage*)_self;
2236 self->type = STAGETYPE_FBO;
2237 self->ivport.W = width;
2238 self->ivport.H = height;
2242 if ( !haveFrameBufferObject() )
2245 glGenTextures(1, &self->itexturebuffer);
2247 glBindTexture(GL_TEXTURE_2D, self->itexturebuffer);
2248 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2251 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2252 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
2254 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2256 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2257 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2258 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->ivport.W, self->ivport.H, 0, GL_RGBA , GL_UNSIGNED_BYTE, 0);
2261 glBindTexture(GL_TEXTURE_2D, 0);
2263 glGenFramebuffers(1, &self->ibuffer);
2264 glBindFramebuffer(GL_FRAMEBUFFER, self->ibuffer);
2272 glGenRenderbuffers(1, &self->idepthbuffer);
2274 glBindRenderbuffer(GL_RENDERBUFFER, self->idepthbuffer);
2275 glRenderbufferStorage(GL_RENDERBUFFER, FW_GL_DEPTH_COMPONENT, self->ivport.W, self->ivport.H);
2277 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2280 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->itexturebuffer, 0);
2283 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self->idepthbuffer);
2285 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2289 void stage_resize(
void *_self,
int width,
int height){
2291 self = (
stage*)_self;
2292 if(self->type == STAGETYPE_FBO){
2293 if(width != self->ivport.W || height != self->ivport.H){
2294 self->ivport.W = width;
2295 self->ivport.H = height;
2296 glBindTexture(GL_TEXTURE_2D, self->itexturebuffer);
2297 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->ivport.W, self->ivport.H, 0, GL_RGBA , GL_UNSIGNED_BYTE, NULL);
2299 glBindTexture(GL_TEXTURE_2D, 0);
2301 glBindRenderbuffer(GL_RENDERBUFFER, self->idepthbuffer);
2302 glRenderbufferStorage(GL_RENDERBUFFER, FW_GL_DEPTH_COMPONENT, self->ivport.W, self->ivport.H);
2305 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2308 glBindFramebuffer(GL_FRAMEBUFFER, self->ibuffer);
2310 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->itexturebuffer, 0);
2313 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self->idepthbuffer);
2315 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2322 self->ivport.W = width;
2323 self->ivport.H = height;
2331 int nx, ny, nelements, nvert;
2333 GLfloat *vert, *vert2, *tex, *norm, dx, tx;
2335 int usingDistortions;
2339 void render_texturegrid(
void *_self);
2340 void texturegrid_render(
void *_self){
2343 pushnset_viewport(self->t1.viewport);
2344 c =
self->t1.contents;
2347 if(c->t1.itype == CONTENT_STAGE){
2353 vpstack = (
Stack*)gglobal()->Mainloop._vportstack;
2354 ivport = stack_top(
ivec4,vpstack);
2355 if(s->ivport.W != ivport.W || s->ivport.H != ivport.H)
2356 stage_resize(c,ivport.W,ivport.H);
2361 render_texturegrid(_self);
2364 static GLfloat matrixIdentity[] = {
2365 1.0f, 0.0f, 0.0f, 0.0f,
2366 0.0f, 1.0f, 0.0f, 0.0f,
2367 0.0f, 0.0f, 1.0f, 0.0f,
2368 0.0f, 0.0f, 0.0f, 1.0f
2370 int texturegrid_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex);
2371 contenttype *new_contenttype_texturegrid(
int nx,
int ny){
2373 register_contenttype(
self);
2374 init_tcontenttype(&self->t1);
2375 self->t1.itype = CONTENT_TEXTUREGRID;
2376 self->t1.render = texturegrid_render;
2377 self->t1.pick = texturegrid_pick;
2386 GLfloat *vert, *vert2, *tex, *norm;
2387 GLfloat dx,dy, tx,ty;
2389 index = (GLushort*)MALLOCV((nx-1)*(ny-1)*2*3 *
sizeof(GLushort));
2390 vert = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2391 vert2 = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2392 tex = (GLfloat*)MALLOCV(nx*ny*2*
sizeof(GLfloat));
2393 norm = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2394 register_contenttype(index);
2395 register_contenttype(vert);
2396 register_contenttype(vert2);
2397 register_contenttype(tex);
2398 register_contenttype(norm);
2401 dx = 2.0f / (float)(nx-1);
2402 dy = 2.0f / (float)(ny-1);
2403 tx = 1.0f / (float)(nx-1);
2404 ty = 1.0f / (float)(ny-1);
2407 vert[(i*nx + j)*3 + 0] = -1.0f + j*dy;
2408 vert[(i*nx + j)*3 + 1] = -1.0f + i*dx;
2409 vert[(i*nx + j)*3 + 2] = 0.0f;
2410 tex[(i*nx + j)*2 + 0] = 0.0f + j*ty;
2411 tex[(i*nx + j)*2 + 1] = 0.0f + i*tx;
2412 norm[(i*nx + j)*3 + 0] = 0.0f;
2413 norm[(i*nx + j)*3 + 1] = 0.0f;
2414 norm[(i*nx + j)*3 + 2] = 1.0f;
2421 for(j=0;j<ny-1;j++){
2423 index[k++] = i*nx + j;
2424 index[k++] = i*nx + j + 1;
2425 index[k++] = (i+1)*nx + j + 1;
2427 index[k++] = i*nx + j;
2428 index[k++] = (i+1)*nx + j + 1;
2429 index[k++] = (i+1)*nx + j;
2431 self->index = index;
2435 self->vert2 = vert2;
2436 self->nelements = k;
2437 self->nvert = nx*ny;
2439 for(i=0;i<
self->nvert;i++){
2440 self->vert2[i*3 +0] =
self->vert[i*3 +0];
2441 self->vert2[i*3 +1] =
self->vert[i*3 +1];
2442 self->vert2[i*3 +2] =
self->vert[i*3 +2];
2447 void texturegrid_barrel_distort(
void *_self,
float k1){
2454 for(i=0;i<
self->nvert;i++){
2455 float radius2, x, y;
2456 x =
self->vert[i*3 +0];
2457 y =
self->vert[i*3 +1];
2458 radius2 = x*x + y*y;
2459 self->vert2[i*3 +0] = x*(1.0f - k1*radius2);
2460 self->vert2[i*3 +1] = y*(1.0f - k1*radius2);
2468 float aspect, scale, xshift, yshift;
2475 for(i=0;i<
self->nvert;i++){
2476 self->vert2[i*3 +0] += xshift;
2477 self->vert2[i*3 +1] += yshift;
2478 self->vert2[i*3 +0] *= 1.0;
2479 self->vert2[i*3 +1] *= aspect;
2480 self->vert2[i*3 +0] *= scale;
2481 self->vert2[i*3 +1] *= scale;
2482 self->vert2[i*3 +2] =
self->vert[i*3 +2];
2488 void texturegrid_barrel_distort2(
void *_self,
float xc,
float k1){
2498 float xc2 = xc * 2.0f - 1.0f;
2499 for(i=0;i<
self->nvert;i++){
2500 float radius2, x, y;;
2501 x =
self->vert[i*3 +0];
2502 y =
self->vert[i*3 +1];
2503 radius2 = (x-xc2)*(x-xc2) + y*y;
2504 self->vert2[i*3 +0] = x*(1.0f - k1*radius2);
2505 self->vert2[i*3 +1] = y*(1.0f - k1*radius2);
2509 self->usingDistortions = TRUE;
2512 void texturegrid_barrel_undistort2(
void *_self,
ivec4 vport,
ivec2 *xy){
2523 x = (float)(xy->X - vport.X) / (float)vport.W;
2524 y = (
float)(xy->Y - vport.Y) / (
float)vport.H;
2530 float xb, yb, xa,ya, deltax, deltay, xc2, k1, tolerance;
2537 radius2 = (xb-xc2)*(xb-xc2) + yb*yb;
2538 xa = xb*(1.0f - k1*radius2);
2539 ya = yb*(1.0f - k1*radius2);
2544 if(fabs(deltax) + fabs(deltay) < tolerance )
break;
2551 xy->X = (int)(x*vport.W) + vport.X;
2552 xy->Y = (int)(y*vport.H) + vport.Y;
2554 int texturegrid_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2562 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2568 ivport = get_current_viewport();
2576 if(self->usingDistortions) texturegrid_barrel_undistort2(
self, ivport, &xy );
2579 c =
self->t1.contents;
2581 iret = c->t1.pick(c,mev,butnum,x,y,ID, windex);
2589 #include "../scenegraph/Component_Shape.h"
2590 void render_texturegrid(
void *_self){
2592 int useMip,haveTexture;
2594 GLint positionLoc, texCoordLoc, textureLoc;
2595 GLint textureMatrix0;
2600 haveTexture = FALSE;
2601 if(self->t1.contents && self->t1.contents->t1.itype == CONTENT_STAGE){
2603 if(s->type == STAGETYPE_FBO){
2604 textureID = s->itexturebuffer;
2608 if(!haveTexture)
return;
2611 FW_GL_DEPTHMASK(GL_FALSE);
2612 glDisable(GL_DEPTH_TEST);
2652 scap = getMyShader(ONE_TEX_APPEARANCE_SHADER);
2653 enableGlobalShader(scap);
2654 positionLoc = scap->Vertices;
2655 glVertexAttribPointer (positionLoc, 3, GL_FLOAT,
2656 GL_FALSE, 0, self->vert2 );
2658 texCoordLoc = scap->TexCoords[0];
2659 glVertexAttribPointer ( texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex );
2660 glEnableVertexAttribArray (positionLoc );
2661 glEnableVertexAttribArray ( texCoordLoc);
2664 glActiveTexture ( GL_TEXTURE0 );
2665 glBindTexture ( GL_TEXTURE_2D, textureID );
2668 glGenerateMipmap(GL_TEXTURE_2D);
2672 textureLoc = scap->TextureUnit[0];
2673 textureMatrix0 = scap->TextureMatrix[0];
2674 glUniformMatrix4fv(textureMatrix0, 1, GL_FALSE, matrixIdentity);
2676 glUniform1i ( textureLoc, 0 );
2681 glUniformMatrix4fv(scap->ProjectionMatrix, 1, GL_FALSE, matrixIdentity);
2683 glUniformMatrix4fv(scap->ModelViewMatrix, 1, GL_FALSE, matrixIdentity);
2686 glDrawArrays(GL_TRIANGLES,0,self->nelements);
2688 glDrawElements(GL_TRIANGLES,self->nelements,GL_UNSIGNED_SHORT,self->index);
2691 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
2692 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
2694 restoreGlobalShader();
2695 FW_GL_DEPTHMASK(GL_TRUE);
2696 glEnable(GL_DEPTH_TEST);
2704 int nx, ny, nelements, nvert;
2706 GLfloat *vert, *vert2, *tex, *norm, dx, tx;
2710 void render_orientation(
void *_self);
2711 void orientation_render(
void *_self){
2714 pushnset_viewport(self->t1.viewport);
2715 c =
self->t1.contents;
2718 if(c->t1.itype == CONTENT_STAGE){
2720 int fbowidth,fboheight;
2726 vpstack = (
Stack*)tg->Mainloop._vportstack;
2727 ivport = stack_top(
ivec4,vpstack);
2728 switch(tg->Mainloop.screenOrientation2){
2732 fbowidth = ivport.H;
2733 fboheight = ivport.W;
2739 fbowidth = ivport.W;
2740 fboheight = ivport.H;
2744 if(s->ivport.W != fbowidth || s->ivport.H != fboheight)
2745 stage_resize(c,fbowidth,fboheight);
2750 render_orientation(_self);
2755 int orientation_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2762 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2766 ivport = stack_top(
ivec4,(
Stack*)tg->Mainloop._vportstack);
2767 switch(tg->Mainloop.screenOrientation2){
2769 x = ivport.H - mouseY;
2773 x = ivport.W - mouseX;
2774 y = ivport.H - mouseY;
2778 y = ivport.W - mouseX;
2788 c =
self->t1.contents;
2790 iret = c->t1.pick(c,mev,butnum,x,y,ID, windex);
2798 void render_orientation(
void *_self);
2803 GLfloat quad1Vert[] = {
2809 GLfloat quad1Tex[] = {
2815 GLushort quad1TriangleInd[] = {
2821 register_contenttype(
self);
2822 init_tcontenttype(&self->t1);
2823 self->t1.itype = CONTENT_ORIENTATION;
2824 self->t1.render = orientation_render;
2825 self->t1.pick = orientation_pick;
2830 self->vert = quad1Vert;
2831 self->tex = quad1Tex;
2832 self->index = quad1TriangleInd;
2833 self->nelements = 6;
2839 static GLfloat matrix180[] = {
2840 -1.f, 0.0f, 0.0f, 0.0f,
2841 0.0f,-1.0f, 0.0f, 0.0f,
2842 0.0f, 0.0f, 1.0f, 0.0f,
2843 0.0f, 0.0f, 0.0f, 1.0f
2845 static GLfloat matrix270[] = {
2846 0.0f, 1.0f, 0.0f, 0.0f,
2847 -1.f, 0.0f, 0.0f, 0.0f,
2848 0.0f, 0.0f, 1.0f, 0.0f,
2849 0.0f, 0.0f, 0.0f, 1.0f
2851 static GLfloat matrix90[] = {
2852 0.0f, -1.0f, 0.0f, 0.0f,
2853 1.0f, 0.0f, 0.0f, 0.0f,
2854 0.0f, 0.0f, 1.0f, 0.0f,
2855 0.0f, 0.0f, 0.0f, 1.0f
2859 unsigned int getCircleCursorTextureID();
2860 void render_orientation(
void *_self){
2863 GLint positionLoc, texCoordLoc, textureLoc;
2864 GLint textureMatrix0;
2866 float *orientationMatrix;
2870 haveTexture = FALSE;
2871 if(self->t1.contents && self->t1.contents->t1.itype == CONTENT_STAGE){
2873 if(s->type == STAGETYPE_FBO){
2875 textureID = s->itexturebuffer;
2885 switch(gglobal()->Mainloop.screenOrientation2){
2887 orientationMatrix = matrix180;
2890 orientationMatrix = matrix270;
2893 orientationMatrix = matrix90;
2899 orientationMatrix = matrixIdentity;
2903 FW_GL_DEPTHMASK(GL_FALSE);
2904 glDisable(GL_DEPTH_TEST);
2910 scap = getMyShader(ONE_TEX_APPEARANCE_SHADER);
2911 enableGlobalShader(scap);
2912 positionLoc = scap->Vertices;
2913 glVertexAttribPointer (positionLoc, 3, GL_FLOAT,
2914 GL_FALSE, 0, self->vert );
2916 texCoordLoc = scap->TexCoords[0];
2917 glVertexAttribPointer ( texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex );
2918 glEnableVertexAttribArray (positionLoc );
2919 glEnableVertexAttribArray ( texCoordLoc);
2922 glActiveTexture ( GL_TEXTURE0 );
2923 glBindTexture ( GL_TEXTURE_2D, textureID );
2926 textureLoc = scap->TextureUnit[0];
2927 textureMatrix0 = scap->TextureMatrix[0];
2928 glUniformMatrix4fv(textureMatrix0, 1, GL_FALSE, matrixIdentity);
2930 glUniform1i ( textureLoc, 0 );
2935 glUniformMatrix4fv(scap->ProjectionMatrix, 1, GL_FALSE, matrixIdentity);
2936 glUniformMatrix4fv(scap->ModelViewMatrix, 1, GL_FALSE, orientationMatrix);
2939 glDrawElements(GL_TRIANGLES, self->nelements, GL_UNSIGNED_SHORT, self->index);
2942 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
2943 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
2945 restoreGlobalShader();
2946 FW_GL_DEPTHMASK(GL_TRUE);
2947 glEnable(GL_DEPTH_TEST);
2955 int frame_increment_even_odd_frame_count(
int ieo){
2957 ieo = ieo > 1 ? 0 : 1;
2971 void init_targetwindow(
void *_self){
2975 self->swapbuf = TRUE;
3005 char* PluginFullPath;
3007 int num_SensorEvents;
3010 GLint viewPort2[10];
3011 GLint viewpointScreenX[2], viewpointScreenY[2];
3017 double BrowserStartTime;
3018 double BrowserInitTime;
3021 int keypress_wait_for_settle;
3022 char * keypress_string;
3026 unsigned int loop_count;
3028 unsigned int slowloop_count;
3037 unsigned int currentTouch;
3038 struct Touch touchlist[20];
3039 int EMULATE_MULTITOUCH;
3046 int draw_initialized;
3048 char keywaitstring[25];
3049 int fps_sleep_remainder;
3050 double screenorientationmatrix[16];
3051 double viewtransformmatrix[16];
3052 double posorimatrix[16];
3053 double stereooffsetmatrix[2][16];
3054 int targets_initialized;
3056 void *hyper_switch[4];
3062 Stack *_framebufferstack;
3063 struct Vector *contenttype_registry;
3068 void *Mainloop_constructor(){
3069 void *v = MALLOCV(
sizeof(
struct pMainloop));
3073 void Mainloop_init(
struct tMainloop *t){
3076 t->gl_linewidth= 1.0f;
3079 t->BrowserFPS = 100.0;
3080 t->BrowserSpeed = 0.0;
3081 t->BrowserDescription =
"libfreewrl opensource virtual reality player library";
3082 t->trisThisLoop = 0;
3085 t->currentFileVersion = 0;
3087 t->HaveSensitive = FALSE;
3092 t->tmpFileLocation = MALLOC(
char *, 5);
3093 strcpy(t->tmpFileLocation,
"/tmp");
3094 t->replaceWorldRequest = NULL;
3095 t->replaceWorldRequestMulti = NULL;
3097 t->prv = Mainloop_constructor();
3106 p->doEvents = FALSE;
3113 p->num_SensorEvents = 0;
3116 p->bufferarray[0] = FW_GL_BACK;
3117 p->bufferarray[1] = 0;
3120 p->BrowserInitTime = 0.0;
3123 p->keypress_wait_for_settle = 100;
3124 p->keypress_string=NULL;
3126 p->SensorEvents = 0;
3129 p->slowloop_count = 0;
3140 p->currentTouch = 0;
3142 p->EMULATE_MULTITOUCH = 0;
3143 memset(p->touchlist,0,20*
sizeof(
struct Touch));
3150 p->keySensorMode = 1;
3151 p->draw_initialized = FALSE;
3153 p->keywaitstring[0] = (char)0;
3154 p->fps_sleep_remainder = 0;
3157 p->targets_initialized = 0;
3158 for(i=0;i<4;i++) init_targetwindow(&p->cwindows[i]);
3160 p->_vportstack = newStack(
ivec4);
3161 t->_vportstack = (
void *)p->_vportstack;
3162 p->_stagestack = newStack(
void*);
3163 t->_stagestack = (
void *)p->_stagestack;
3164 p->_framebufferstack = newStack(
int);
3165 t->_framebufferstack = (
void*)p->_framebufferstack;
3166 stack_push(
int,p->_framebufferstack,FW_GL_BACK);
3167 p->contenttype_registry = NULL;
3170 memset(&p->pedalstate,0,
sizeof(
struct pedal_state));
3173 void Mainloop_clear(
struct tMainloop *t){
3174 FREE_IF_NZ(t->scene_name);
3175 FREE_IF_NZ(t->scene_suff);
3176 FREE_IF_NZ(t->replaceWorldRequest);
3177 FREE_IF_NZ(t->tmpFileLocation);
3180 FREE_IF_NZ(p->SensorEvents);
3181 deleteVector(
ivec4,p->_vportstack);
3182 deleteVector(
void*,p->_stagestack);
3183 deleteVector(
int,p->_framebufferstack);
3184 free_contenttypes();
3185 deleteVector(
contenttype*,p->contenttype_registry);
3197 int fwl_hwnd_to_windex(
void *hWnd){
3207 if(!targets[i].hwnd){
3209 targets[i].hwnd = hWnd;
3210 targets[i].swapbuf = TRUE;
3212 if(targets[i].hwnd == hWnd)
return i;
3217 void get_view_matrix(
double *savePosOri,
double *saveView) {
3226 bstack = getActiveBindableStacks(tg);
3227 matcopy(saveView,bstack->viewtransformmatrix);
3228 matcopy(savePosOri,bstack->posorimatrix);
3231 static void set_view_matrix(
double *savePosOri,
double *saveView){
3237 matcopy(p->viewtransformmatrix,saveView);
3238 matcopy(p->posorimatrix,savePosOri);
3241 bstack = getActiveBindableStacks(tg);
3242 matcopy(bstack->viewtransformmatrix,saveView);
3243 matcopy(bstack->posorimatrix,savePosOri);
3248 void fwl_getWindowSize(
int *width,
int *height){
3253 *width = tg->display.screenWidth;
3254 *height = tg->display.screenHeight;
3257 void fwl_getWindowSize1(
int windex,
int *width,
int *height){
3265 ivport = p->cwindows[windex].ivport;
3272 int isBrowserPlugin = FALSE;
3273 void fwl_set_emulate_multitouch(
int ion){
3275 p->EMULATE_MULTITOUCH = ion;
3281 int fwl_get_emulate_multitouch(){
3283 return p->EMULATE_MULTITOUCH;
3301 #define SEND_BIND_IF_REQUIRED(node) \
3302 if (node != NULL) { send_bind_to(X3D_NODE(node),1); node = NULL; }
3306 void setup_viewpoint();
3307 void set_viewmatrix();
3310 static void sendDescriptionToStatusBar(
struct X3D_Node *CursorOverSensitive);
3312 void render_collisions(
int Viewer_type);
3313 int slerp_viewpoint(
int itype);
3314 static void render_pre(
void);
3316 static int setup_pickside(
int x,
int y);
3317 void setup_projection();
3318 void setup_pickray(
int x,
int y);
3320 void get_hyperhit(
void);
3321 static void sendSensorEvents(
struct X3D_Node *COS,
int ev,
int butStatus,
int status);
3323 void activate_OSCsensors();
3335 #if !defined(_MSC_VER)
3338 double Time1970sec(
void) {
3339 struct timeval mytime;
3340 gettimeofday(&mytime, NULL);
3341 return (
double) mytime.tv_sec + (double)mytime.tv_usec/1000000.0;
3348 #define DJ_KEEP_COMPILER_WARNING 0
3349 #if DJ_KEEP_COMPILER_WARNING
3350 #define TI(_tv) gettimeofdat(&_tv)
3351 #define TID(_tv) ((double)_tv.tv_sec + (double)_tv.tv_usec/1000000.0)
3356 void fwl_do_keyPress0(
int key,
int type);
3357 void handle0(
const int mev,
const unsigned int button,
const float x,
const float y);
3358 void fwl_handle_aqua_multi(
const int mev,
const unsigned int button,
int x,
int y,
int ID,
int windex);
3360 void fwl_RenderSceneUpdateScene0(
double dtime);
3361 void splitpath_local_suffix(
const char *url,
char **local_name,
char **suff);
3363 void fwl_gotoCurrentViewPoint()
3365 struct tProdCon *t = &gglobal()->ProdCon;
3368 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes, t->currboundvpno),cn);
3374 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,t->viewpointNodes, t->currboundvpno);
3379 int fw_exit(
int val)
3381 printf(
"exiting with value=%d hit Enter:",val);
3386 void render_statusbar0(
void){
3387 #if defined(STATUSBAR_HUD)
3389 finishedWithGlobalShader();
3391 restoreGlobalShader();
3429 void fwl_RenderSceneUpdateSceneNORMAL() {
3434 dtime = Time1970sec();
3435 fwl_RenderSceneUpdateScene0(dtime);
3444 ivec4 childViewport(
ivec4 parentViewport,
float *clipBoundary);
3493 twindows = p->cwindows;
3494 twindows[itargetwindow].params = *params;
3495 if(itargetwindow > 0){
3496 twindows[itargetwindow -1].next = &twindows[itargetwindow];
3498 p->nwindow = max(p->nwindow,itargetwindow+1);
3502 printf(
"windex=%d t->next = %p\n",itargetwindow,t->next);
3505 printf(
"hows that?\n");
3513 twindows = p->cwindows;
3514 return &twindows[itargetwindow].params;
3517 void fwl_setScreenDim1(
int wi,
int he,
int itargetwindow){
3528 twindows = p->cwindows;
3529 twindows[itargetwindow].ivport = window_rect;
3536 void register_contenttype(
void *ct){
3539 if(!p->contenttype_registry)
3540 p->contenttype_registry = newVector(
void *,4);
3546 vector_pushBack(
void*,p->contenttype_registry,ct);
3549 void free_contenttypes(){
3552 if(p->contenttype_registry){
3554 for(i=0;i<p->contenttype_registry->n;i++){
3556 ct = vector_get(
void*,p->contenttype_registry,i);
3565 void setup_stagesNORMAL(){
3575 for(i=0;i<p->nwindow;i++){
3583 if(t->params.context != dp->context){
3584 tg->display.params = (
void*)&t->params;
3589 cstage = new_contenttype_stage();
3590 cswitch = new_contenttype_switch();
3591 p->hyper_switch[i] = cswitch;
3592 cstage->t1.contents = cswitch;
3593 last = &cswitch->t1.contents;
3595 p->hyper_case[i] = 8;
3597 p->EMULATE_MULTITOUCH = FALSE;
3604 csbh = new_contenttype_statusbar();
3605 cscene = new_contenttype_scene();
3607 csbh->t1.contents = cscene;
3610 last = &csbh->t1.next;
3618 cmultitouch = new_contenttype_multitouch();
3619 cscene = new_contenttype_scene();
3620 csbh = new_contenttype_statusbar();
3622 cmultitouch->t1.contents = csbh;
3623 csbh->t1.contents = cscene;
3625 *last = cmultitouch;
3626 last = &cmultitouch->t1.next;
3627 p->EMULATE_MULTITOUCH = TRUE;
3636 csbh = new_contenttype_statusbar();
3637 cscene = new_contenttype_scene();
3638 ctextpanel = new_contenttype_textpanel(
"VeraMono",8,60,120,TRUE);
3639 ccolor = vec4_init(1.0f,.6f,0.0f,1.0f);
3640 ctext = new_contenttype_captiontext(
"VeraMono",12,ccolor);
3644 captiontext_setString(ctext,
"ABCDEDFGHIJKLMNOPQRSTUVWXYZabcd");
3645 ctext->t1.viewport[0] = .1f;
3646 ctext->t1.viewport[1] = .6f;
3647 ctext->t1.viewport[2] = 1.0f;
3648 ctext->t1.viewport[3] = .5f;
3651 textpanel_register_as_console(ctextpanel);
3654 csbh->t1.contents = ctextpanel;
3655 ctextpanel->t1.contents = cscene;
3656 ctextpanel->t1.next = ctext;
3659 last = &csbh->t1.next;
3667 csbh = new_contenttype_statusbar();
3668 ccolor = vec4_init(1.0f,.6f,0.0f,1.0f);
3670 ctext = new_contenttype_captiontext(
"freewrl_wingding",10,ccolor);
3672 cscene = new_contenttype_scene();
3681 captiontext_setString(ctext,
"abcdABCDEDFGHIJKLMNOPQRSTUVWXYZ");
3683 ctext->t1.viewport[0] = .1f;
3684 ctext->t1.viewport[1] = .6f;
3685 ctext->t1.viewport[2] = .4f;
3686 ctext->t1.viewport[3] = .5f;
3688 csbh->t1.contents = cscene;
3689 cscene->t1.next = ctext;
3692 last = &csbh->t1.next;
3699 csbh = new_contenttype_statusbar();
3700 ce3dmouse = new_contenttype_e3dmouse();
3702 cscene = new_contenttype_scene();
3704 csbh->t1.contents = ce3dmouse;
3705 ce3dmouse->t1.contents = cscene;
3706 cscene->t1.next = NULL;
3708 last = &csbh->t1.next;
3714 contenttype *csbh, *cscene, *cstagefbo, *ctexturegrid, *cmultitouch;
3716 cmultitouch = new_contenttype_multitouch();
3717 ctexturegrid = new_contenttype_texturegrid(2,2);
3718 cstagefbo = new_contenttype_stagefbo(512,512);
3719 csbh = new_contenttype_statusbar();
3720 cscene = new_contenttype_scene();
3722 cmultitouch->t1.contents = ctexturegrid;
3723 ctexturegrid->t1.contents = cstagefbo;
3724 cstagefbo->t1.contents = csbh;
3725 csbh->t1.contents = cscene;
3727 *last = cmultitouch;
3728 last = &cmultitouch->t1.next;
3733 contenttype *csbh, *cscene, *corientation, *cmultitouch, *cstagefbo;
3735 cmultitouch = new_contenttype_multitouch();
3736 corientation = new_contenttype_orientation();
3737 cstagefbo = new_contenttype_stagefbo(512,512);
3738 csbh = new_contenttype_statusbar();
3739 cscene = new_contenttype_scene();
3741 cmultitouch->t1.contents = corientation;
3742 corientation->t1.contents = cstagefbo;
3743 cstagefbo->t1.contents = csbh;
3744 csbh->t1.contents = cscene;
3746 *last = cmultitouch;
3747 last = &cmultitouch->t1.next;
3753 contenttype *csbh, *cscene, *corientation, *cmultitouch, *cstagefbo;
3755 cmultitouch = new_contenttype_multitouch();
3756 csbh = new_contenttype_statusbar();
3757 corientation = new_contenttype_orientation();
3758 cstagefbo = new_contenttype_stagefbo(512,512);
3759 cscene = new_contenttype_scene();
3761 cmultitouch->t1.contents = csbh;
3762 csbh->t1.contents = corientation;
3763 corientation->t1.contents = cstagefbo;
3764 cstagefbo->t1.contents = cscene;
3766 *last = cmultitouch;
3767 last = &cmultitouch->t1.next;
3773 contenttype *cstereo1, *cstereo2, *cstereo3, *cstereo4, *cswitch0;
3776 csbh = new_contenttype_statusbar();
3777 ctextpanel = new_contenttype_textpanel(
"VeraMono",8,60,120,TRUE);
3778 cswitch0 = new_contenttype_switch();
3779 cstereo1 = new_contenttype_stereo_shutter();
3780 cstereo2 = new_contenttype_stereo_sidebyside();
3781 cstereo3 = new_contenttype_stereo_anaglyph();
3782 cstereo4 = new_contenttype_stereo_updown();
3784 contenttype_switch_set_which_ptr(cswitch0,&tg->Viewer.stereotype);
3788 cscene0 = new_contenttype_scene();
3789 cscene1 = new_contenttype_scene();
3790 cscene0->t1.next = cscene1;
3792 cscene2 = new_contenttype_scene();
3796 textpanel_register_as_console(ctextpanel);
3799 csbh->t1.contents = ctextpanel;
3800 ctextpanel->t1.contents = cswitch0;
3801 cswitch0->t1.contents = cscene2;
3802 cscene2->t1.next = cstereo1;
3803 cstereo1->t1.contents = cscene0;
3804 cstereo2->t1.contents = cscene0;
3805 cstereo3->t1.contents = cscene0;
3806 cstereo4->t1.contents = cscene0;
3807 cstereo1->t1.next = cstereo2;
3808 cstereo2->t1.next = cstereo3;
3809 cstereo3->t1.next = cstereo4;
3812 last = &csbh->t1.next;
3823 csbh = new_contenttype_statusbar();
3824 cstereo = new_contenttype_stereo_sidebyside();
3826 cstagefbo0 = new_contenttype_stagefbo(512,512);
3827 ctexturegrid0 = new_contenttype_texturegrid(5,5);
3829 cstagefbo1 = new_contenttype_stagefbo(512,512);
3830 ctexturegrid1 = new_contenttype_texturegrid(5,5);
3831 cscene0 = new_contenttype_scene();
3832 cscene1 = new_contenttype_scene();
3840 xc = 1.0f - (float) viewer->screendist;
3841 texturegrid_barrel_distort2(ctexturegrid0, xc,.1f);
3842 xc = (float)viewer->screendist;
3843 texturegrid_barrel_distort2(ctexturegrid1, xc,.1f);
3847 csbh->t1.contents = cstereo;
3848 cstereo->t1.contents = ctexturegrid0;
3849 ctexturegrid0->t1.next = ctexturegrid1;
3850 ctexturegrid0->t1.contents = cstagefbo0;
3851 ctexturegrid1->t1.contents = cstagefbo1;
3852 cstagefbo0->t1.contents = cscene0;
3853 cstagefbo1->t1.contents = cscene1;
3856 last = &csbh->t1.next;
3861 contenttype *cscene0, *cscene1, *cscene2, *cscene3;
3864 csbh = new_contenttype_statusbar();
3865 cquadrant = new_contenttype_quadrant();
3867 cscene0 = new_contenttype_scene();
3868 cscene1 = new_contenttype_scene();
3869 cscene2 = new_contenttype_scene();
3870 cscene3 = new_contenttype_scene();
3872 csbh->t1.contents = cquadrant;
3873 cquadrant->t1.contents = cscene0;
3874 cscene0->t1.next = cscene1;
3875 cscene1->t1.next = cscene2;
3876 cscene2->t1.next = cscene3;
3879 last = &csbh->t1.next;
3887 int fwl_hyper_option(
char *val){
3896 if(iopt >= 0 && iopt <=10)
3897 for(i=0;i<p->nwindow;i++){
3898 p->hyper_case[i] = iopt;
3902 void initialize_targets_simple(){
3910 setup_stagesNORMAL();
3914 p->targets_initialized = 1;
3917 void update_navigation();
3918 void fwl_RenderSceneUpdateSceneTARGETWINDOWS() {
3927 if(!p->targets_initialized)
3928 initialize_targets_simple();
3930 dtime = Time1970sec();
3931 vportstack = (
Stack *)tg->Mainloop._vportstack;
3932 defaultvport = ivec4_init(0,0,100,100);
3933 pushviewport(vportstack,defaultvport);
3935 fwl_RenderSceneUpdateScene0(dtime);
3936 popviewport(vportstack);
3941 for(i=0;i<p->nwindow;i++){
3948 hyper_switch = p->hyper_switch[i];
3949 hyper_case = p->hyper_case[i];
3950 contenttype_switch_set_which(hyper_switch,hyper_case);
3955 s = (
stage*)(t->stage);
3956 if(s->type == STAGETYPE_BACKBUF){
3957 s->ivport = t->ivport;
3962 fwl_setScreenDim0(s->ivport.W, s->ivport.H);
3964 if(t->params.context != dp->context){
3965 tg->display.params = (
void*)&t->params;
3970 vportstack = (
Stack *)tg->Mainloop._vportstack;
3971 pushviewport(vportstack,t->ivport);
3974 popviewport(vportstack);
3976 if(t->swapbuf) { FW_GL_SWAPBUFFERS }
3983 int fwl_handle_mouse_multi_yup(
int mev,
int butnum,
int mouseX,
int yup,
unsigned int ID,
int windex){
3992 if (mev == MotionNotify) butnum = 0;
3994 t = &p->cwindows[windex];
3995 s = (
stage*)t->stage;
3997 if(s->type == STAGETYPE_BACKBUF)
3998 s->ivport = t->ivport;
3999 vportstack = (
Stack *)tg->Mainloop._vportstack;
4000 pushviewport(vportstack,s->ivport);
4001 ihit = s->t1.pick(s,mev,butnum,mouseX,yup,ID,windex);
4002 popviewport(vportstack);
4006 void emulate_multitouch(
int mev,
unsigned int button,
int x,
int ydown,
int windex)
4013 struct Touch *touch;
4014 static int buttons[4] = {0,0,0,0};
4015 static int idone = 0;
4021 t = &p->cwindows[windex];
4024 y = t->ivport.H - ydown;
4027 printf(
"Use RMB (right mouse button) to create and delete touches\n");
4028 printf(
"Use LMB to drag touches (+- 5 pixel selection window)\n");
4031 buttons[button] = mev == ButtonPress;
4036 for(i=0;i<p->ntouch;i++){
4037 touch = &p->touchlist[i];
4039 if(touch->windex == windex && touch->stageId == current_stageId())
4040 if((abs(x - touch->rx) < 10) && (abs(y - touch->ry) < 10)){
4048 if( mev == ButtonPress && button == RMB )
4051 if(ifound && touch){
4052 fwl_handle_mouse_multi_yup(ButtonRelease,LMB,x,y,ID,windex);
4055 printf(
"delete ID=%d windex=%d\n",ID,windex);
4060 for(i=0;i<p->ntouch;i++){
4061 touch = &p->touchlist[i];
4063 fwl_handle_mouse_multi_yup(mev, LMB, x, y, i,windex);
4066 printf(
"create ID=%d windex=%d\n",i,windex);
4071 }
else if( mev == MotionNotify && buttons[LMB]) {
4074 fwl_handle_mouse_multi_yup(MotionNotify,0,x,y,ID,windex);
4075 touch = &p->touchlist[ID];
4100 void render_multitouch2(
struct Touch *touchlist,
int ntouch){
4105 if(p->EMULATE_MULTITOUCH) {
4107 for(i=0;i<ntouch;i++){
4108 if(touchlist[i].ID > -1)
4109 if(touchlist[i].windex == p->windex )
4111 struct Touch *touch;
4112 touch = &touchlist[i];
4113 cursorDraw(touch->ID,touch->rx,touch->ry,touch->angle);
4118 void record_multitouch(
struct Touch *touchlist,
int mev,
int butnum,
int mouseX,
int mouseY,
int ID,
int windex,
int ihandle){
4119 struct Touch *touch;
4124 touch = &touchlist[ID];
4130 touch->windex = windex;
4131 touch->stageId = current_stageId();
4132 touch->buttonState = mev == ButtonPress;
4135 touch->angle = 0.0f;
4141 int emulate_multitouch2(
struct Touch *touchlist,
int ntouch,
int *IDD,
int *lastbut,
int *mev,
unsigned int *button,
int x,
int y,
int *ID,
int windex)
4148 struct Touch *touch;
4149 static int idone = 0;
4155 printf(
"Use RMB (right mouse button) to create and delete touches\n");
4156 printf(
"Use LMB to drag touches (+- 5 pixel selection window)\n");
4162 if(*mev == ButtonPress && (*button == LMB || *button == RMB)){
4166 for(i=0;i<ntouch;i++){
4167 touch = &touchlist[i];
4169 if(touch->windex == windex )
4170 if((abs(x - touch->rx) < 10) && (abs(y - touch->ry) < 10)){
4172 printf(
"drag found ID %d\n",*IDD);
4179 if(*lastbut == LMB){
4180 if( *mev == MotionNotify ) {
4184 *mev = MotionNotify;
4188 touch = &touchlist[*IDD];
4191 printf(
"drag ID=%d \n",*IDD);
4193 }
else if(*mev == ButtonRelease){
4196 }
else if(*lastbut == RMB){
4197 if( *mev == ButtonPress )
4200 if(*IDD > -1 && touch){
4202 *mev = ButtonRelease;
4208 printf(
"delete ID=%d windex=%d ihandle=%d\n",*IDD,windex,ihandle);
4213 for(i=1;i<p->ntouch;i++){
4214 touch = &touchlist[i];
4215 if(touch->inUse == FALSE) {
4223 touch->inUse = TRUE;
4224 printf(
"create ID=%d windex=%d\n",i,windex);
4236 int fwl_handle_mouse_multi(
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
4243 t = &p->cwindows[windex];
4246 yup = t->ivport.H - mouseY;
4247 fwl_handle_mouse_multi_yup(mev,butnum,mouseX,yup,ID,windex);
4248 return getCursorStyle();
4250 int fwl_handle_mouse(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex){
4251 int cstyle, tactic_up_drag;
4252 static unsigned int ID = 1;
4268 if(!p->mouseDown && !p->mouseOver){
4270 p->mouseOver = TRUE;
4283 fwl_handle_mouse_multi(ButtonRelease, 0, mouseX, mouseY, 2, windex);
4284 p->mouseOver = FALSE;
4286 p->mouseDown = TRUE;
4291 cstyle = fwl_handle_mouse_multi(mev,butnum,mouseX,mouseY,ID,windex);
4292 if(mev == ButtonRelease){
4293 p->mouseDown = FALSE;
4297 cstyle = fwl_handle_mouse_multi(mev,butnum,mouseX,mouseY,ID,windex);
4301 int fwl_handle_touch(
int mev,
unsigned int ID,
int mouseX,
int mouseY,
int windex) {
4311 cstyle = fwl_handle_mouse_multi(mev, ibut, mouseX, mouseY, ID, windex);
4317 void viewer_getpose(
double *quat4,
double *vec3);
4318 void viewer_setpose(
double *quat4,
double *vec3);
4319 static int using_sensors_for_navigation = 1;
4320 static int using_magnetic = 0;
4321 static int using_gyro = 1;
4324 void fwl_handle_gyro(
float rx,
float ry,
float rz) {
4325 if(using_sensors_for_navigation && using_gyro){
4326 double axyz[3], dd[3], quat4[4], vec3[3];
4327 static double dt, lasttime, curtime;
4329 static int initialized = 0;
4332 lasttime = Time1970sec();
4336 curtime = Time1970sec();
4337 dt = curtime - lasttime;
4340 viewer_getpose(quat4, vec3);
4341 double2quat(&qq0, quat4);
4342 quaternion_normalize(&qq0);
4344 axyz[0] = (double)rx;
4345 axyz[2] = -(double)ry;
4346 axyz[1] = -(double)rz;
4349 if (fabs(axyz[0]) < .01) axyz[0] = 0.0;
4350 if (fabs(axyz[1]) < .01) axyz[1] = 0.0;
4351 if (fabs(axyz[2]) < .01) axyz[2] = 0.0;
4352 vecscaled(dd, axyz, dt);
4356 euler2quat(&qq2, dd[0], dd[1], dd[2]);
4357 quaternion_multiply(&qq, &qq2, &qq0);
4358 quaternion_normalize(&qq);
4360 quat2double(quat4, &qq);
4361 viewer_setpose(quat4, vec3);
4365 void fwl_handle_accelerometer(
float ax,
float ay,
float az){
4369 void fwl_handle_magnetic(
float azimuth,
float pitch,
float roll) {
4370 if (using_sensors_for_navigation && using_magnetic) {
4374 double rxyz[3], dd[3], Rxyz[3], quat4[4], vec3[3];
4375 static double ddlast[3];
4377 static int initialized = 0;
4381 Rxyz[0] = (double)azimuth;
4382 Rxyz[2] = -(double)roll;
4383 Rxyz[1] = -(double)pitch;
4384 vecscaled(ddlast,ddlast,0.0);
4388 viewer_getpose(quat4, vec3);
4389 double2quat(&qq0, quat4);
4390 quaternion_normalize(&qq0);
4392 rxyz[0] = (double)azimuth;
4393 rxyz[2] = -(double)roll;
4394 rxyz[1] = -(double)pitch;
4396 vecdifd(dd,rxyz,Rxyz);
4397 vecscaled(dd, dd, .05);
4399 euler2quat(&qqlast,ddlast[0],ddlast[1],ddlast[2]);
4400 quaternion_normalize(&qqlast);
4401 quaternion_inverse(&qqlast,&qqlast);
4402 quaternion_normalize(&qqlast);
4403 quaternion_multiply(&qq0,&qqlast,&qq0);
4404 quaternion_normalize(&qq0);
4407 euler2quat(&qq2, dd[0], dd[1], dd[2]);
4408 quaternion_multiply(&qq, &qq2, &qq0);
4409 quaternion_normalize(&qq);
4411 quat2double(quat4, &qq);
4412 viewer_setpose(quat4, vec3);
4413 veccopyd(ddlast,dd);
4418 OLDCODE
void fwl_handle_magnetic_old(
float azimuth,
float pitch,
float roll) {
4419 OLDCODE ConsoleMessage(
"hi from handle_magnetic %f %f %f\n", azimuth, pitch, roll);
4420 OLDCODE
if(using_sensors_for_navigation && using_magnetic){
4421 OLDCODE
static int initialized = 0;
4422 OLDCODE
static float home_azimuth = 0.0f, home_pitch = 0.0f, home_roll = 0.0f;
4423 OLDCODE
static double lasttime, curtime, dt;
4426 OLDCODE
float dazimuth,ddazimuth, dpitch, droll;
4427 OLDCODE
double quat4[4], vec3[3], rxyz[3];
4428 OLDCODE
static double ypr[3];
4429 OLDCODE
static float lazimuth, lpitch, lroll;
4435 OLDCODE
if(!initialized){
4436 OLDCODE home_azimuth = azimuth;
4437 OLDCODE home_pitch = pitch;
4438 OLDCODE home_roll = roll;
4439 OLDCODE lazimuth = azimuth;
4440 OLDCODE lpitch = pitch;
4441 OLDCODE lroll = roll;
4442 OLDCODE lasttime = Time1970sec();
4443 OLDCODE initialized = 1;
4445 OLDCODE viewer_getpose(quat4, vec3);
4446 OLDCODE double2quat(&qq0, quat4);
4447 OLDCODE quaternion_normalize(&qq0);
4449 OLDCODE quat2euler(ypr,0,&qq0);
4463 OLDCODE curtime = Time1970sec();
4464 OLDCODE dt = curtime - lasttime;
4465 OLDCODE lasttime = curtime;
4468 OLDCODE viewer_getpose(quat4, vec3);
4469 OLDCODE double2quat(&qq0,quat4);
4470 OLDCODE quaternion_normalize(&qq0);
4472 OLDCODE quat2euler(ypr,0,&qq0);
4475 OLDCODE dazimuth = (azimuth - home_azimuth);
4476 OLDCODE ddazimuth = dazimuth - lazimuth;
4477 OLDCODE lazimuth = dazimuth;
4478 OLDCODE
if (fabs(ddazimuth) < .7f)
4479 OLDCODE dazimuth = 0.0;
4480 OLDCODE
if(fabs(ddazimuth) < 2.0f)
4481 OLDCODE dazimuth = .01f * dazimuth;
4482 OLDCODE
if(fabs(ddazimuth) < 10.0f)
4483 OLDCODE dazimuth = .1f * dazimuth;
4485 OLDCODE dpitch = (pitch - home_pitch);
4486 OLDCODE droll = (roll - home_roll);
4490 OLDCODE rxyz[2] = dazimuth*PI/180.0;
4491 OLDCODE rxyz[1] = (50.0 - droll )*PI/50.0*dt;
4493 OLDCODE rxyz[0] = 0.0;
4494 OLDCODE rxyz[1] = 0.0;
4499 OLDCODE euler2quat(&qq2,rxyz[0],rxyz[1],-rxyz[2]);
4500 OLDCODE quaternion_multiply(&qq,&qq2,&qq0);
4501 OLDCODE quaternion_normalize(&qq);
4503 OLDCODE quat2double(quat4,&qq);
4504 OLDCODE viewer_setpose(quat4,vec3);
4506 OLDCODE home_pitch = pitch;
4513 void (*fwl_RenderSceneUpdateScenePTR)() = fwl_RenderSceneUpdateSceneTARGETWINDOWS;
4522 void fwl_RenderSceneUpdateScene(
void){
4524 fwl_RenderSceneUpdateScenePTR();
4526 void setup_picking();
4527 void setup_projection();
4528 void rbp_run_physics();
4529 void fwl_RenderSceneUpdateScene0(
double dtime) {
4545 PRINT_GL_ERROR_IF_ANY(
"start of renderSceneUpdateScene");
4547 DEBUG_RENDER(
"start of MainLoop (parsing=%s) (url loaded=%s)\n",
4548 BOOL_STR(fwl_isinputThreadParsing()), BOOL_STR(resource_is_root_loaded()));
4551 p->doEvents = (!fwl_isinputThreadParsing()) && (!fwl_isTextureParsing()) && fwl_isInputThreadInitialized();
4555 p->BrowserStartTime = dtime;
4556 tg->Mainloop.TickTime = p->BrowserStartTime;
4557 tg->Mainloop.lastTime = tg->Mainloop.TickTime - 0.01;
4558 if(p->BrowserInitTime == 0.0)
4559 p->BrowserInitTime = dtime;
4565 if(!((
freewrl_params_t*)(tg->display.params))->frontend_handles_display_thread){
4580 double elapsed_time_per_frame, suggested_wait_time, target_time_per_frame, kludgefactor;
4581 int wait_time_micro_sec, target_frames_per_second;
4583 target_frames_per_second = fwl_get_target_fps();
4584 elapsed_time_per_frame = TickTime() - lastTime();
4585 if(target_frames_per_second > 0)
4586 target_time_per_frame = 1.0/(double)target_frames_per_second;
4588 target_time_per_frame = 1.0/30.0;
4589 suggested_wait_time = target_time_per_frame - elapsed_time_per_frame;
4590 suggested_wait_time *= kludgefactor;
4592 wait_time_micro_sec = (int)(suggested_wait_time * 1000000.0);
4593 if(wait_time_micro_sec > 1)
4594 usleep(wait_time_micro_sec);
4599 tg->Mainloop.lastTime = tg->Mainloop.TickTime;
4600 tg->Mainloop.TickTime = dtime;
4602 #if !defined(FRONTEND_DOES_SNAPSHOTS)
4604 if (tg->Snapshot.doSnapshot) {
4607 #endif //FRONTEND_DOES_SNAPSHOTS
4616 initializeAnyScripts();
4622 if (tg->RenderFuncs.BrowserAction) {
4623 tg->RenderFuncs.BrowserAction = doBrowserAction ();
4629 OcclusionStartofRenderSceneUpdateScene();
4631 startOfLoopNodeUpdates();
4633 if (p->loop_count == 25) {
4634 tg->Mainloop.BrowserFPS = 25.0 / (TickTime()-p->BrowserStartTime);
4635 setMenuFps((
float)tg->Mainloop.BrowserFPS);
4639 p->BrowserStartTime = TickTime();
4645 tg->Mainloop.trisThisLoop = 0;
4647 if(p->slowloop_count == 1009) p->slowloop_count = 0 ;
4649 if ((p->slowloop_count % 256) == 0) {
4655 activate_OSCsensors() ;
4661 p->slowloop_count++ ;
4664 if (p->keypress_string && p->doEvents) {
4665 if (p->keypress_wait_for_settle > 0) {
4666 p->keypress_wait_for_settle--;
4669 if (*p->keypress_string) {
4671 #if !defined( _MSC_VER )
4672 DEBUG_XEV(
"CMD LINE GEN EVENT: %c\n", *p->keypress_string);
4673 fwl_do_keyPress(*p->keypress_string,KeyPress);
4675 p->keypress_string++;
4677 p->keypress_string=NULL;
4688 #if defined(TARGET_X11)
4692 for(kw=0;kw<p->nwindow;kw++)
4694 void * xdpy = p->cwindows[kw].params.display;
4696 while(XPending(xdpy)) {
4697 XNextEvent(xdpy, &event);
4698 DEBUG_XEV(
"EVENT through XNextEvent\n");
4699 handle_Xevents(event);
4706 PRINT_GL_ERROR_IF_ANY(
"before xtdispatch");
4707 #if defined(TARGET_MOTIF)
4710 frontendUpdateButtons();
4713 while (XtAppPending(Xtcx)!= 0) {
4714 XtAppNextEvent(Xtcx, &event);
4715 #ifdef XEVENT_VERBOSE
4718 switch (event.type) {
4720 mev = &
event.xmotion;
4721 TRACE_MSG(
"mouse motion event: win=%u, state=%d\n",mev->window, mev->state);
4725 bev = &
event.xbutton;
4726 TRACE_MSG(
"mouse button event: win=%u, state=%d\n",bev->window, bev->state);
4731 DEBUG_XEV(
"EVENT through XtDispatchEvent\n");
4732 XtDispatchEvent (&event);
4742 PRINT_GL_ERROR_IF_ANY(
"after handle_tick")
4753 SEND_BIND_IF_REQUIRED(tg->ProdCon.setViewpointBindInRender)
4754 SEND_BIND_IF_REQUIRED(tg->ProdCon.setFogBindInRender)
4755 SEND_BIND_IF_REQUIRED(tg->ProdCon.setBackgroundBindInRender)
4756 SEND_BIND_IF_REQUIRED(tg->ProdCon.setNavigationBindInRender)
4762 process_eventsProcessed();
4764 #if !defined(EXCLUDE_EAI)
4775 int socketVerbose = fwlio_RxTx_control(CHANNEL_EAI, RxTx_GET_VERBOSITY) ;
4777 if ( socketVerbose <= 1 || (socketVerbose > 1 && ((p->slowloop_count % 256) == 0)) ) {
4778 if(fwlio_RxTx_control(CHANNEL_EAI, RxTx_REFRESH) == 0) {
4780 if ( socketVerbose > 1 ) {
4781 printf(
"%s:%d Nothing to be done\n",__FILE__,__LINE__) ;
4784 if ( socketVerbose > 1 ) {
4785 printf(
"%s:%d Test RxTx_PENDING\n",__FILE__,__LINE__) ;
4787 if(fwlio_RxTx_control(CHANNEL_EAI, RxTx_PENDING) > 0) {
4789 if ( socketVerbose != 0 ) {
4790 printf(
"%s:%d Something pending\n",__FILE__,__LINE__) ;
4792 tempEAIdata = fwlio_RxTx_getbuffer(CHANNEL_EAI) ;
4793 if(tempEAIdata != (
char *)NULL) {
4796 if ( socketVerbose != 0 ) {
4797 printf(
"%s:%d Something for EAI to do with buffer addr %p\n",__FILE__,__LINE__,tempEAIdata ) ;
4801 replyData = fwl_EAI_handleBuffer(tempEAIdata);
4805 if(replyData != NULL && strlen(replyData) != 0) {
4806 fwlio_RxTx_sendbuffer(__FILE__,__LINE__,CHANNEL_EAI, replyData) ;
4812 EAI_StillToDo = fwl_EAI_allDone();
4814 if ( socketVerbose != 0 ) {
4815 printf(
"%s:%d Something still in EAI buffer? %d\n",__FILE__,__LINE__,EAI_StillToDo ) ;
4817 replyData = fwl_EAI_handleRest();
4819 }
while(EAI_StillToDo) ;
4825 #endif //EXCLUDE_EAI
4828 #ifdef RENDERVERBOSE
4829 printf(
"RENDER STEP----------\n");
4839 void set_viewmatrix0(
int iplace);
4840 struct Touch *currentTouch();
4841 void setup_picking(){
4854 if (tg->Mainloop.HaveSensitive && !Viewer()->LookatMode && !tg->Mainloop.SHIFT) {
4856 int x,yup,ktouch,priorclaimants;
4857 struct Touch *touch;
4859 priorclaimants = TOUCHCLAIMANT_PEDAL;
4860 for(ktouch=0;ktouch<p->ntouch;ktouch++){
4861 touch = &p->touchlist[ktouch];
4862 if(!touch->inUse)
continue;
4864 if(touch->windex != windex)
continue;
4865 if(touch->stageId != current_stageId())
continue;
4869 if(touch->claimant == TOUCHCLAIMANT_SENSOR || (touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants)) {
4871 if(setup_pickside(x,yup)){
4879 setup_pickray(x,yup);
4882 tg->RenderFuncs.hypersensitive = touch->hypersensitive;
4883 tg->RenderFuncs.hyperhit = touch->hyperhit;
4885 if(!touch->hyperhit){
4887 render_hier(rootNode(),VF_Sensitive | VF_Geom);
4888 touch->CursorOverSensitive = getRayHit();
4889 memcpy( touch->justModel, ((
struct currayhit *)(tg->RenderFuncs.rayHit))->justModel, 16 *
sizeof(
double));
4890 memcpy( &touch->hp, tg->RenderFuncs.hp,
sizeof(
struct point_XYZ));
4893 touch->CursorOverSensitive = NULL;
4894 memcpy(((
struct currayhit *)(tg->RenderFuncs.rayHit))->justModel, touch->justModel, 16 *
sizeof(
double));
4895 memcpy( tg->RenderFuncs.hp, &touch->hp,
sizeof(
struct point_XYZ));
4899 if(touch->dragStart){
4900 if(touch->CursorOverSensitive || fwl_getHover()){
4901 touch->claimant = TOUCHCLAIMANT_SENSOR;
4903 touch->passed |= TOUCHCLAIMANT_SENSOR;
4910 if (touch->lastOver != touch->CursorOverSensitive) {
4912 printf (
"%lf over changed, p->lastOver %u p->cursorOverSensitive %u, p->butDown1 %d\n",
4913 TickTime(), (
unsigned int) touch->lastOver, (
unsigned int) touch->CursorOverSensitive,
4914 touch->ButDown[p->currentCursor][1]);
4918 if (touch->buttonState == 0) {
4923 if (!touch->lastOverButtonPressed) {
4924 sendSensorEvents(touch->lastOver, overMark, 0, FALSE);
4925 sendSensorEvents(touch->CursorOverSensitive, overMark, 0, TRUE);
4926 touch->lastOver = touch->CursorOverSensitive;
4928 touch->lastOverButtonPressed = FALSE;
4930 touch->lastOverButtonPressed = TRUE;
4934 if (p->CursorOverSensitive != NULL)
4935 printf(
"COS %d (%s)\n", (
unsigned int) p->CursorOverSensitive, stringNodeType(p->CursorOverSensitive->_nodeType));
4938 if(touch->claimant != TOUCHCLAIMANT_SENSOR)
continue;
4943 if (touch->dragStart && touch->buttonState && (touch->lastPressedOver==NULL)) {
4946 touch->lastPressedOver = touch->CursorOverSensitive;
4947 sendSensorEvents(touch->lastPressedOver, ButtonPress, touch->dragStart, TRUE);
4951 if(touch->dragEnd && touch->lastPressedOver!=NULL) {
4956 sendSensorEvents(touch->lastPressedOver, ButtonRelease, touch->buttonState, TRUE);
4957 touch->lastPressedOver = NULL;
4968 sendSensorEvents(touch->CursorOverSensitive,MotionNotify, touch->buttonState, TRUE);
4971 sendSensorEvents(touch->lastPressedOver,MotionNotify, touch->buttonState, TRUE);
4977 sensornode = touch->lastPressedOver ? touch->lastPressedOver : touch->CursorOverSensitive;
4978 sendDescriptionToStatusBar(sensornode);
4979 if (touch->CursorOverSensitive!= NULL) {
4984 if ((touch->lastPressedOver==NULL) && (touch->CursorOverSensitive != touch->oldCOS)) {
4986 sendSensorEvents(touch->oldCOS,MapNotify,touch->buttonState, FALSE);
4988 sendSensorEvents(touch->CursorOverSensitive,MapNotify,touch->buttonState, TRUE);
4989 touch->oldCOS = touch->CursorOverSensitive;
5003 if ((touch->oldCOS != NULL) && touch->buttonState == 0) {
5004 sendSensorEvents(touch->oldCOS, MapNotify, touch->buttonState, FALSE);
5007 touch->oldCOS = NULL;
5011 touch->hypersensitive = tg->RenderFuncs.hypersensitive;
5012 touch->hyperhit = tg->RenderFuncs.hyperhit;
5014 if(touch->dragStart){
5015 touch->dragStart = FALSE;
5018 touch->dragEnd = FALSE;
5019 touch->inUse = FALSE;
5025 else if(Viewer()->LookatMode){
5027 int ktouch, kcount, priorclaimants;
5029 struct Touch *touch;
5030 priorclaimants = TOUCHCLAIMANT_PEDAL;
5037 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5038 touch = &p->touchlist[ktouch];
5039 if(!touch->inUse)
continue;
5040 if(touch->windex != windex)
continue;
5041 if(touch->stageId != current_stageId())
continue;
5043 if(touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants)
5044 touch->passed |= TOUCHCLAIMANT_SENSOR;
5046 if(Viewer()->LookatMode == 2 ){
5050 if(setup_pickside(x,yup)){
5052 setup_pickray(x,yup);
5055 render_hier(rootNode(),VF_Sensitive | VF_Geom);
5056 getRayHitAndSetLookatTarget();
5063 int ktouch, priorclaimants;
5064 struct Touch *touch;
5065 priorclaimants = TOUCHCLAIMANT_PEDAL;
5066 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5067 touch = &p->touchlist[ktouch];
5068 if(!touch->inUse)
continue;
5069 if(touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants)
5070 touch->passed |= TOUCHCLAIMANT_SENSOR;
5078 void (*handlePTR)(
const int mev,
const unsigned int button,
const float x,
const float y) = handle0;
5079 void handle(
const int mev,
const unsigned int button,
const float x,
const float y)
5081 handlePTR(mev, button, x, y);
5086 void SSR_test_cumulative_pose();
5087 static void render_pre() {
5098 if (fwl_get_headlight()) {
5099 setLightState(HEADLIGHT_LIGHT,TRUE);
5100 setLightType(HEADLIGHT_LIGHT,2);
5112 static double toggleTime = 0.0;
5113 static int runTest = 0;
5116 if(dtime - toggleTime > 5.0){
5118 runTest = 1 - runTest;
5121 if(runTest) SSR_test_cumulative_pose();
5127 if (fwl_getCollision() == 1) {
5128 profile_start(
"collision");
5129 render_collisions(Viewer()->type);
5130 profile_end(
"collision");
5142 profile_start(
"hier_prox");
5143 render_hier(rootNode(), VF_Proximity);
5144 profile_end(
"hier_prox");
5148 PRINT_GL_ERROR_IF_ANY(
"GLBackend::render_pre");
5151 int setup_pickside0(
int x,
int y,
int *iside,
ivec4 *vportleft,
ivec4 *vportright){
5158 int sideleft, sideright, userPreferredPickSide, ieither;
5159 ivec4 vport, vportscene;
5166 userPreferredPickSide = viewer->dominantEye;
5167 ieither = viewer->eitherDominantEye;
5170 pt = ivec2_init(x,y);
5171 vportstack = (
Stack*)tg->Mainloop._vportstack;
5172 vport = stack_top(
ivec4,vportstack);
5174 vportscene.Y = vport.Y + tg->Mainloop.clipPlane;
5175 vportscene.H = vport.H - tg->Mainloop.clipPlane;
5177 *vportleft = vportscene;
5178 *vportright = vportscene;
5179 if(viewer->isStereo)
5181 if (viewer->sidebyside){
5184 vportright->X = vportleft->X + vportleft->W;
5186 if(viewer->updown) {
5189 *vportright = vportscene;
5190 vportright->Y += tg->Mainloop.clipPlane;
5191 vportright->H -= tg->Mainloop.clipPlane;
5192 *vportleft = *vportright;
5194 vportleft->Y += vportscene.H;
5198 sideleft = sideright=0;
5199 sideleft = pointinsideviewport(*vportleft,pt);
5200 sideright = pointinsideviewport(*vportright,pt);;
5201 if(sideleft && sideright)
5202 *iside = userPreferredPickSide;
5204 *iside = sideleft? 0 : sideright ? 1 : 0;
5205 if(!ieither) *iside = userPreferredPickSide;
5206 return sideleft || sideright;
5208 static int setup_pickside(
int x,
int y){
5209 ivec4 vpleft, vpright;
5212 inside = setup_pickside0(x,y,&iside,&vpleft,&vpright);
5216 void fw_gluPerspective_2(GLDOUBLE xcenter, GLDOUBLE fovy, GLDOUBLE aspect, GLDOUBLE zNear, GLDOUBLE zFar);
5217 void setup_projection()
5226 GLDOUBLE fieldofview2;
5228 GLint scissorxl,scissorxr;
5234 GLsizei screenwidth2;
5235 GLsizei screenheight, bottom, top;
5236 static int counter = 0;
5240 vportstack = (
Stack*)tg->Mainloop._vportstack;
5241 vport = stack_top(
ivec4,vportstack);
5243 screenwidth2 = vport.W;
5245 top = vport.Y + vport.H;
5246 bottom = vport.Y + tg->Mainloop.clipPlane;
5247 screenheight = top - bottom;
5249 PRINT_GL_ERROR_IF_ANY(
"XEvents::start of setup_projection");
5252 scissorxr = xvp + screenwidth2;
5253 fieldofview2 = viewer->fieldofview;
5255 aspect2 = (double)(scissorxr - scissorxl)/(double)(screenheight);
5257 if(viewer->type==VIEWER_SPHERICAL)
5258 fieldofview2*=viewer->fovZoom;
5259 if(viewer->isStereo)
5263 xr = xvp + screenwidth2;
5265 if (viewer->sidebyside){
5284 expand = viewer->screendist > .5f;
5285 expansion = viewer->screendist - .5;
5286 expansion = fabs(expansion);
5287 iexpand = (GLint)(expansion * screenwidth2);
5289 xr -= screenwidth2/4;
5290 xl -= screenwidth2/4;
5291 scissorxr = xvp + screenwidth2/2;
5292 if(viewer->iside ==1)
5294 xl += screenwidth2/2;
5295 xr += screenwidth2/2;
5296 scissorxl += screenwidth2/2;
5297 scissorxr += screenwidth2/2;
5301 if(viewer->iside ==1)
5306 if(viewer->iside ==1)
5316 screenheight = vport.H;
5318 if (viewer->iside == 0){
5319 bottom += screenheight;
5321 top -= screenheight;
5323 screenheight -= tg->Mainloop.clipPlane;
5328 printf(
"in setup_projection\n");
5331 aspect2 = (double)(xr - xl)/(double)(screenheight);
5333 screenwidth2 = xr-xl;
5337 FW_GL_MATRIX_MODE(GL_PROJECTION);
5346 FW_GL_SCISSOR(scissorxl,bottom,scissorxr-scissorxl,screenheight);
5347 glEnable(GL_SCISSOR_TEST);
5352 p->viewpointScreenX[viewer->iside] = xvp + screenwidth2/2;
5353 p->viewpointScreenY[viewer->iside] = top;
5354 if (viewer->updown){
5355 FW_GL_VIEWPORT(xvp - screenwidth2 / 2, bottom, screenwidth2 * 2, screenheight);
5358 FW_GL_VIEWPORT(xvp, bottom, screenwidth2, screenheight);
5361 FW_GL_LOAD_IDENTITY();
5364 if (viewer->ortho) {
5365 double minX, maxX, minY, maxY;
5368 minX = viewer->orthoField[0];
5369 minY = viewer->orthoField[1];
5370 maxX = viewer->orthoField[2];
5371 maxY = viewer->orthoField[3];
5373 if (screenheight != 0) {
5375 numerator = (maxY - minY) * ((
float) screenwidth2) / ((
float) screenheight);
5376 maxX = numerator/2.0f;
5377 minX = -(numerator/2.0f);
5380 FW_GL_ORTHO (minX, maxX, minY, maxY,
5381 viewer->nearPlane,viewer->farPlane);
5385 if ((fieldofview2 <= 0.0) || (fieldofview2 > 180.0))
5389 if(0) FW_GLU_PERSPECTIVE(fieldofview2, aspect2, viewer->nearPlane,viewer->farPlane);
5390 if(1) fw_gluPerspective_2(viewer->xcenter,fieldofview2, aspect2, viewer->nearPlane,viewer->farPlane);
5391 tg->Mainloop.fieldOfView = (float)fieldofview2;
5393 FW_GL_MATRIX_MODE(GL_MODELVIEW);
5394 PRINT_GL_ERROR_IF_ANY(
"XEvents::setup_projection");
5398 void getPickrayXY(
int *x,
int *y){
5400 *x = tg->Mainloop.pickray_x;
5401 *y = tg->Mainloop.pickray_y;
5404 void setPickrayXY(
int x,
int y){
5406 tg->Mainloop.pickray_x = x;
5407 tg->Mainloop.pickray_y = y;
5410 void setup_pickray0()
5433 double mvident[16], pickMatrix[16], pmi[16], proj[16], R1[16], R2[16], R3[16], T[16];
5434 int viewport[4], x, y;
5435 double A[3], B[3], C[3], a[3], b[3];
5436 double yaw, pitch, yy,xx;
5439 getPickrayXY(&x,&y);
5440 loadIdentityMatrix(mvident);
5441 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
5442 FW_GL_GETINTEGERV(GL_VIEWPORT,viewport);
5452 a[0] = xx; a[1] = yy; a[2] = 0.0;
5453 FW_GLU_UNPROJECT(a[0], a[1], a[2], mvident, proj, viewport,
5455 mattranslate(T,A[0],A[1],A[2]);
5457 b[0] = xx; b[1] = yy; b[2] = 1.0;
5458 FW_GLU_UNPROJECT(b[0], b[1], b[2], mvident, proj, viewport,
5462 if(0) printf(
"Cdif %f %f %f\n",C[0],C[1],C[2]);
5470 yaw = atan2(C[0],-C[2]);
5471 matrixFromAxisAngle4d(R1, -yaw, 0.0, 1.0, 0.0);
5473 transformAFFINEd(C,C,R1);
5474 if(0) printf(
"Yawed Cdif %f %f %f\n",C[0],C[1],C[2]);
5475 pitch = atan2(C[1],-C[2]);
5477 double hypotenuse = sqrt(C[0]*C[0] + C[2]*C[2]);
5478 pitch = atan2(C[1],hypotenuse);
5480 if(0) printf(
"atan2 yaw=%f pitch=%f\n",yaw,pitch);
5483 if(0) printf(
"[yaw=%f pitch=%f\n",yaw,pitch);
5485 matrotate(R1, -pitch, 1.0, 0.0, 0.0);
5486 matrotate(R2, -yaw, 0.0, 1.0, 0.0);
5488 matrixFromAxisAngle4d(R1, pitch, 1.0, 0.0, 0.0);
5489 if(0) printmatrix2(R1,
"pure R1");
5490 matrixFromAxisAngle4d(R2, yaw, 0.0, 1.0, 0.0);
5491 if(0) printmatrix2(R2,
"pure R2");
5493 matmultiplyAFFINE(R3,R1,R2);
5494 if(0) printmatrix2(R3,
"R3=R1*R2");
5496 matmultiplyAFFINE(pickMatrix,R3, T);
5497 matinverseAFFINE(pmi,pickMatrix);
5504 matcopy(pickMatrix,R3);
5505 matinverseAFFINE(pmi,pickMatrix);
5506 if(0)printmatrix2(R3,
"R3[12]=A");
5508 if(0) printmatrix2(pmi,
"inverted");
5509 setPickrayMatrix(0,pickMatrix);
5510 setPickrayMatrix(1,pmi);
5513 double rA[3], rB[3];
5514 transformAFFINEd(rA,A,pmi);
5515 transformAFFINEd(rB,B,pmi);
5516 printf(
" A %f %f %f B %f %f %f \n",A[0],A[1],A[2],B[0],B[1],B[2]);
5517 printf(
"rA %f %f %f rB %f %f %f \n",rA[0],rA[1],rA[2],rB[0],rB[1],rB[2]);
5522 void setup_pickray(
int x,
int y){
5526 void generate_GeneratedCubeMapTextures();
5528 static void render()
5531 static double shuttertime;
5532 static int shutterside;
5538 generate_GeneratedCubeMapTextures();
5541 update_navigation();
5547 for (count = 0; count < p->maxbuffers; count++) {
5549 viewer->buffer = (unsigned)p->bufferarray[count];
5550 viewer->iside = count;
5553 if(viewer->isStereo)
5556 if(viewer->shutterGlasses == 2)
5558 if(TickTime() - shuttertime > 2.0)
5560 shuttertime = TickTime();
5561 if(shutterside > 0) shutterside = 0;
5562 else shutterside = 1;
5564 if(count != shutterside)
continue;
5566 if(viewer->anaglyph)
5570 Viewer_anaglyph_clearSides();
5572 Viewer_anaglyph_setSide(count);
5575 BackEndClearBuffer(2);
5576 if(Viewer()->anaglyph)
5577 Viewer_anaglyph_setSide(count);
5582 BackEndClearBuffer(2);
5588 if (!fwl_get_headlight()) {
5589 setLightState(HEADLIGHT_LIGHT,FALSE);
5590 setLightType(HEADLIGHT_LIGHT,2);
5594 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, before render_hier");
5596 render_hier(rootNode(), VF_globalLight );
5597 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_globalLight)");
5598 render_hier(rootNode(), VF_Other );
5602 profile_start(
"hier_geom");
5603 render_hier(rootNode(), VF_Geom);
5604 profile_end(
"hier_geom");
5605 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_Geom)");
5608 if (tg->RenderFuncs.have_transparency) {
5610 render_hier(rootNode(), VF_Geom | VF_Blend);
5611 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_Geom)");
5614 if (viewer->isStereo) {
5616 if (viewer->sidebyside){
5619 fiducialDrawB(CURSOR_FIDUCIALS,p->viewpointScreenX[count],p->viewpointScreenY[count]);
5622 if (viewer->anaglyph)
5623 glColorMask(1,1,1,1);
5630 struct Touch *touch;
5631 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5632 touch = &p->touchlist[ktouch];
5635 if(touch->stageId == current_stageId()){
5639 cstyle = CURSOR_DOWN;
5640 if(touch->buttonState == 0) cstyle = CURSOR_HOVER;
5641 if(touch->lastOverButtonPressed || touch->CursorOverSensitive)
5642 cstyle = CURSOR_OVER;
5643 fiducialDrawB(cstyle,touch->x,touch->y);
5653 static int currentViewerLandPort = 0;
5654 static int rotatingCCW = FALSE;
5655 static double currentViewerAngle = 0.0;
5656 static double requestedViewerAngle = 0.0;
5659 void setup_viewpoint_part1() {
5681 bstack = getActiveBindableStacks(tg);
5683 FW_GL_MATRIX_MODE(GL_MODELVIEW);
5684 FW_GL_LOAD_IDENTITY();
5687 if (viewer->screenOrientation != currentViewerLandPort) {
5690 rotatingCCW = FALSE;
5691 switch (currentViewerLandPort) {
5693 rotatingCCW= (Viewer()->screenOrientation == 270);
5697 rotatingCCW = (Viewer()->screenOrientation == 0);
5701 rotatingCCW = (Viewer()->screenOrientation != 270);
5705 rotatingCCW = (Viewer()->screenOrientation != 0);
5709 currentViewerLandPort = viewer->screenOrientation;
5710 requestedViewerAngle = (double)viewer->screenOrientation;
5713 if (!(APPROX(currentViewerAngle,requestedViewerAngle))) {
5716 currentViewerAngle -= 10.0;
5717 if (currentViewerAngle < -5.0) currentViewerAngle = 360.0;
5720 currentViewerAngle +=10.0;
5721 if (currentViewerAngle > 365.0) currentViewerAngle = 0.0;
5724 FW_GL_ROTATE_D (currentViewerAngle,0.0,0.0,1.0);
5725 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->screenorientationmatrix);
5730 bstack->isStereo = viewer->isStereo;
5731 bstack->iside = viewer->iside;
5733 viewer->isStereo = 1;
5735 FW_GL_LOAD_IDENTITY();
5736 set_stereo_offset0();
5737 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->stereooffsetmatrix[0]);
5740 FW_GL_LOAD_IDENTITY();
5741 set_stereo_offset0();
5742 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->stereooffsetmatrix[1]);
5743 viewer->isStereo = 0;
5744 FW_GL_LOAD_IDENTITY();
5747 viewer_togl(viewer->fieldofview);
5748 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->posorimatrix);
5750 FW_GL_LOAD_IDENTITY();
5752 struct X3D_Node *getActiveLayerBoundViewpoint(){
5756 bstack = getActiveBindableStacks(tg);
5759 if(bstack->viewpoint){
5760 if( vectorSize(bstack->viewpoint) > 0){
5761 boundvp = vector_back(
struct X3D_Node*,bstack->viewpoint);
5767 int render_foundLayerViewpoint(){
5777 boundvp = (
struct X3D_Viewpoint*)getActiveLayerBoundViewpoint();
5784 iret = boundvp->_donethispass;
5787 void setup_viewpoint_part2() {
5810 profile_start(
"vp_hier");
5815 boundvp = (
struct X3D_Viewpoint*)getActiveLayerBoundViewpoint();
5817 boundvp->_donethispass = 0;
5818 render_hier(rootNode(), VF_Viewpoint);
5820 boundvp->_donethispass = 0;
5823 profile_end(
"vp_hier");
5827 void setup_viewpoint_part3() {
5843 double viewmatrix[16];
5850 bstack = getActiveBindableStacks(tg);
5852 PRINT_GL_ERROR_IF_ANY(
"XEvents::setup_viewpoint");
5853 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->viewtransformmatrix);
5866 matcopy(viewmatrix,bstack->screenorientationmatrix);
5869 matmultiplyAFFINE(viewmatrix,bstack->posorimatrix,viewmatrix);
5870 matmultiplyAFFINE(viewmatrix,bstack->viewtransformmatrix,viewmatrix);
5871 fw_glSetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
5873 if(slerp_viewpoint(2))
5874 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->viewtransformmatrix);
5877 void setup_viewpoint(){
5879 setup_viewpoint_part1();
5880 setup_viewpoint_part2();
5881 setup_viewpoint_part3();
5886 void set_viewmatrix0(
int iplace) {
5890 double viewmatrix[16];
5897 bstack = getActiveBindableStacks(tg);
5899 FW_GL_MATRIX_MODE(GL_MODELVIEW);
5900 matcopy(viewmatrix,bstack->screenorientationmatrix);
5901 if(viewer->isStereoB){
5902 int iside = Viewer()->isideB;
5903 matmultiplyAFFINE(viewmatrix,bstack->stereooffsetmatrix[iside],viewmatrix);
5905 if(viewer->isStereo){
5906 int iside = Viewer()->iside;
5907 matmultiplyAFFINE(viewmatrix,bstack->stereooffsetmatrix[iside],viewmatrix);
5909 matmultiplyAFFINE(viewmatrix,bstack->posorimatrix,viewmatrix);
5910 matmultiplyAFFINE(viewmatrix,bstack->viewtransformmatrix,viewmatrix);
5911 fw_glSetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
5913 void set_viewmatrix() {
5918 char *nameLogFileFolderNORMAL(
char *logfilename,
int size){
5919 strcat(logfilename,
"freewrl_tmp");
5920 fw_mkdir(logfilename);
5921 strcat(logfilename,
"/");
5922 strcat(logfilename,
"logfile");
5925 char * (*nameLogFileFolderPTR)(
char *logfilename,
int size) = nameLogFileFolderNORMAL;
5927 void toggleLogfile()
5937 freopen(
"CON",
"w",stdout);
5943 printf(
"logging off\n");
5946 if(p->logfname == NULL){
5947 char logfilename[1000];
5949 logfilename[0] =
'\0';
5950 nameLogFileFolderPTR(logfilename, 1000);
5951 strcat(logfilename,
".log");
5952 p->logfname = STRDUP(logfilename);
5954 printf(
"logging to %s\n",p->logfname);
5955 p->logfile = freopen(p->logfname, mode, stdout );
5960 #if defined(_MSC_VER)
5961 #define strncasecmp _strnicmp
5963 void fwl_set_logfile(
char *lname){
5967 if (strncasecmp(lname,
"-", 1) == 0) {
5968 printf(
"FreeWRL: output to stdout/stderr\n");
5970 p->logfname = STRDUP(lname);
5975 int unload_broto(
struct X3D_Proto* node);
5977 void fwl_clearWorld(){
5984 unload_broto(X3D_PROTO(rn));
5985 printf(
"unloaded scene as broto\n");
5990 tg->Mainloop.replaceWorldRequest = NULL;
5991 tg->threads.flushing =
true;
5996 void sendKeyToKeySensor(
const char key,
int upDown);
6010 char lookup_fly_key(
int key);
6012 void dump_scenegraph(
int method);
6013 void fwl_do_keyPress0(
int key,
int type) {
6021 if(key == 27 && type == 1)
6024 p->keySensorMode = 1 - p->keySensorMode;
6026 if (p->keySensorMode && KeySensorNodePresent()) {
6027 sendKeyToKeySensor(key,type);
6029 int handled = isAqua;
6032 if(type == KEYPRESS){
6042 int len = strlen(p->keywaitstring);
6046 fwl_commandline(p->keywaitstring);
6048 p->keywaitstring[0] =
'\0';
6049 ConsoleMessage(
"%c",
'\n');
6051 ConsoleMessage(
"%c",lkp);
6052 if(lkp ==
'\b' && len){
6053 p->keywaitstring[len-1] =
'\0';
6055 p->keywaitstring[len] = lkp;
6056 p->keywaitstring[len+1] =
'\0';
6064 if(type == KEYPRESS)
6070 case 'n': { fwl_clearWorld();
break; }
6071 case 'e': { fwl_set_viewer_type (VIEWER_EXAMINE);
break; }
6072 case 'w': { fwl_set_viewer_type (VIEWER_WALK);
break; }
6073 case 'd': { fwl_set_viewer_type (VIEWER_FLY);
break; }
6074 case 'f': { fwl_set_viewer_type (VIEWER_EXFLY);
break; }
6075 case 'y': { fwl_set_viewer_type (VIEWER_SPHERICAL);
break; }
6076 case 't': { fwl_set_viewer_type(VIEWER_TURNTABLE);
break; }
6077 case 'm': { fwl_set_viewer_type(VIEWER_LOOKAT);
break; }
6078 case 'g': { fwl_set_viewer_type(VIEWER_EXPLORE);
break; }
6079 case 'h': { fwl_toggle_headlight();
break; }
6080 case '/': { print_viewer();
break; }
6082 case '\\': { dump_scenegraph(1);
break; }
6083 case '|': { dump_scenegraph(2);
break; }
6084 case '=': { dump_scenegraph(3);
break; }
6085 case '+': { dump_scenegraph(4);
break; }
6086 case '-': { dump_scenegraph(5);
break; }
6087 case '`': { toggleLogfile();
break; }
6088 case '$': resource_tree_dump(0, (
resource_item_t*)tg->resources.root_res);
break;
6089 case '*': resource_tree_list_files(0, (
resource_item_t*)tg->resources.root_res);
break;
6090 case 'q': {
if (!RUNNINGASPLUGIN) {
6091 fwl_doQuit(__FILE__,__LINE__);
6095 case 'c': { toggle_collision();
break;}
6096 case 'v': {fwl_Next_ViewPoint();
break;}
6097 case 'b': {fwl_Prev_ViewPoint();
break;}
6098 case '.': {profile_print_all();
break;}
6099 case ' ': p->keywait = TRUE; ConsoleMessage(
"\n%c",
':'); p->keywaitstring[0] =
'\0';
break;
6100 case ',': toggle_debugging_trigger();
break;
6101 #if !defined(FRONTEND_DOES_SNAPSHOTS)
6102 case 's': {fwl_toggleSnapshot();
break;}
6103 case 'x': {Snapshot();
break;}
6104 #endif //FRONTEND_DOES_SNAPSHOTS
6107 printf(
"didn't handle key=[%c][%d] type=%d\n",lkp,(
int)lkp,type);
6117 kp = lookup_fly_key(key);
6120 int keystate = type % 10 == KEYDOWN ? 1 : 0;
6123 tg->Mainloop.CTRL = keystate;
break;
6125 tg->Mainloop.SHIFT = keystate;
break;
6127 case HOME_KEY:
if(keystate) fwl_First_ViewPoint();
break;
6128 case END_KEY:
if(keystate) fwl_Last_ViewPoint();
break;
6129 case PGUP_KEY:
if(keystate) fwl_Prev_ViewPoint();
break;
6130 case PGDN_KEY:
if(keystate) fwl_Next_ViewPoint();
break;
6138 if(tg->Mainloop.SHIFT){
6139 if(type%10 == KEYDOWN && (key == LEFT_KEY || key == RIGHT_KEY)){
6142 ichord = viewer_getKeyChord();
6143 if(key == LEFT_KEY) ichord--;
6144 if(key == RIGHT_KEY) ichord++;
6145 viewer_setKeyChord(ichord);
6148 double keytime = Time1970sec();
6149 if(type%10 == KEYDOWN)
6150 handle_key(kp,keytime);
6151 if(type%10 == KEYUP)
6152 handle_keyrelease(kp,keytime);
6160 return tg->Mainloop.SHIFT;
6162 void fwl_setShift(
int ishift){
6164 tg->Mainloop.SHIFT = ishift;
6169 return tg->Mainloop.CTRL;
6173 int platform2web3dActionKey(
int platformKey);
6175 void (*fwl_do_rawKeyPressPTR)(
int key,
int type) = fwl_do_keyPress0;
6176 void fwl_do_rawKeyPress(
int key,
int type) {
6177 fwl_do_rawKeyPressPTR(key,type);
6180 void fwl_do_keyPress(
char kp,
int type) {
6187 ConsoleMessage(
"key pressed decimal = %d\n",key);
6188 if (type != KEYPRESS)
6189 actionKey = platform2web3dActionKey(key);
6191 fwl_do_rawKeyPress(actionKey,type+10);
6193 fwl_do_rawKeyPress(key,type);
6198 void fwl_gotoViewpoint (
char *findThisOne) {
6201 struct tProdCon *t = &gglobal()->ProdCon;
6204 if (findThisOne != NULL) {
6205 for (i=0; i<vectorSize(t->viewpointNodes); i++) {
6206 switch ((vector_get(
struct X3D_Node*, t->viewpointNodes,i)->_nodeType)) {
6207 case NODE_Viewpoint:
6208 if (strcmp(findThisOne,
6209 X3D_VIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6215 case NODE_GeoViewpoint:
6216 if (strcmp(findThisOne,
6217 X3D_GEOVIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6222 case NODE_OrthoViewpoint:
6223 if (strcmp(findThisOne,
6224 X3D_ORTHOVIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6235 if (whichnode != -1) {
6237 t->setViewpointBindInRender = vector_get(
struct X3D_Node *,t->viewpointNodes,whichnode);
6242 void setup_viewpoint_slerp(
double *center,
double pivot_radius,
double vp_radius);
6244 int getRayHitAndSetLookatTarget() {
6251 double pivot_radius, vp_radius;
6257 if(tg->RenderFuncs.hitPointDist >= 0) {
6262 if (rh->hitNode == NULL) {
6263 Viewer()->LookatMode = 0;
6266 double center[3], radius;
6268 if(Viewer()->type == VIEWER_LOOKAT){
6270 GLDOUBLE smin[3], smax[3], shapeMBBmin[3], shapeMBBmax[3];
6276 shapeMBBmin[i] = node->_extent[i*2 + 1];
6277 shapeMBBmax[i] = node->_extent[i*2];
6279 transformMBB(smin,smax,rh->modelMatrix,shapeMBBmin,shapeMBBmax);
6282 center[i] = (smax[i] + smin[i])*.5;
6283 radius = max(radius,(max(fabs(smax[i]-center[i]),fabs(smin[i]-center[i]))));
6285 viewerdist = Viewer()->Dist;
6286 vp_radius = max(viewerdist, radius + 5.0);
6293 }
else if(Viewer()->type == VIEWER_EXPLORE){
6296 pointxyz2double(center,tg->RenderFuncs.hp);
6297 transformAFFINEd(center,center,getPickrayMatrix(0));
6299 vp_radius = .8 * veclengthd(center);
6301 Viewer()->LookatMode = 3;
6302 setup_viewpoint_slerp(center,pivot_radius,vp_radius);
6305 return Viewer()->LookatMode;
6307 void prepare_model_view_pickmatrix_inverse(GLDOUBLE *mvpi);
6330 if(tg->RenderFuncs.hitPointDist >= 0) {
6335 if (rh->hitNode == NULL){
6352 if (rh->hitNode != NULL)
6359 for (i=0; i<p->num_SensorEvents; i++) {
6360 if (p->SensorEvents[i].fromnode == rh->hitNode) {
6362 retnode = ((
struct X3D_Node*) rh->hitNode);
6369 if(retnode != NULL){
6372 GLDOUBLE viewmatrix[16], viewinverse[16];
6374 rh = (
struct currayhit *)tg->RenderFuncs.rayHit;
6376 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6377 fw_glGetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6378 matinverseAFFINE(viewinverse,viewmatrix);
6379 matmultiplyAFFINE(rh->justModel,rh->modelMatrix,viewinverse);
6395 void setSensitive(
struct X3D_Node *parentNode,
struct X3D_Node *datanode) {
6396 void (*myp)(
unsigned *);
6400 switch (datanode->_nodeType) {
6402 case NODE_TouchSensor: myp = (
void *)do_TouchSensor;
break;
6403 case NODE_GeoTouchSensor: myp = (
void *)do_GeoTouchSensor;
break;
6404 case NODE_LineSensor: myp = (
void *)do_LineSensor;
break;
6405 case NODE_PlaneSensor: myp = (
void *)do_PlaneSensor;
break;
6406 case NODE_CylinderSensor: myp = (
void *)do_CylinderSensor;
break;
6407 case NODE_SphereSensor: myp = (
void *)do_SphereSensor;
break;
6408 case NODE_ProximitySensor:
return;
break;
6409 case NODE_GeoProximitySensor:
return;
break;
6412 case NODE_Anchor: myp = (
void *)do_Anchor; parentNode = datanode;
break;
6421 for (i=0; i<p->num_SensorEvents; i++) {
6422 if ((p->SensorEvents[i].fromnode == parentNode) &&
6423 (p->SensorEvents[i].datanode == datanode) &&
6424 (p->SensorEvents[i].interpptr == (
void *)myp)) {
6430 if (datanode == 0) {
6431 printf (
"setSensitive: datastructure is zero for type %s\n",stringNodeType(datanode->_nodeType));
6436 p->SensorEvents = REALLOC(p->SensorEvents,sizeof (
struct SensStruct) * (p->num_SensorEvents+1));
6439 p->SensorEvents[p->num_SensorEvents].fromnode = parentNode;
6440 p->SensorEvents[p->num_SensorEvents].datanode = datanode;
6441 p->SensorEvents[p->num_SensorEvents].interpptr = (
void *)myp;
6444 p->num_SensorEvents++;
6449 static void sendSensorEvents(
struct X3D_Node* COS,
int ev,
int butStatus,
int status) {
6459 if (COS==NULL)
return;
6461 for (count = 0; count < p->num_SensorEvents; count++) {
6462 if (p->SensorEvents[count].fromnode == COS) {
6463 butStatus2 = butStatus;
6465 if (ev==ButtonPress) {
6466 tg->RenderFuncs.hypersensitive = p->SensorEvents[count].fromnode;
6467 tg->RenderFuncs.hyperhit = 1;
6469 }
else if (ev==ButtonRelease) {
6470 tg->RenderFuncs.hypersensitive = 0;
6471 tg->RenderFuncs.hyperhit = 0;
6473 }
else if (ev==MotionNotify) {
6478 p->SensorEvents[count].interpptr(p->SensorEvents[count].datanode, ev,butStatus2, status);
6485 void prepare_model_view_pickmatrix_inverse0(GLDOUBLE *modelMatrix, GLDOUBLE *mvpi);
6486 void prepare_model_view_pickmatrix_inverse(GLDOUBLE *mvpi){
6495 GLDOUBLE viewmatrix[16], mv[16];
6498 rh = (
struct currayhit *)tg->RenderFuncs.rayHit;
6501 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6502 fw_glGetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6504 matmultiplyAFFINE(mv,rh->justModel,viewmatrix);
6508 prepare_model_view_pickmatrix_inverse0(mv, mvpi);
6522 void get_hyperhit() {
6543 double x1,y1,z1,x2,y2,z2,x3,y3,z3;
6556 prepare_model_view_pickmatrix_inverse(mvpi);
6558 transform(&tp,&r11,mvpi);
6559 x1 = tp.x; y1 = tp.y; z1 = tp.z;
6560 transform(&tp,&r2,mvpi);
6561 x2 = tp.x; y2 = tp.y; z2 = tp.z;
6563 transform(&tp,tg->RenderFuncs.hp,mvpi);
6564 x3 = tp.x; y3 = tp.y; z3 = tp.z;
6566 printf(
"get_hyperhit\n");
6574 tg->RenderFuncs.hyp_save_posn[0] = (float) x1; tg->RenderFuncs.hyp_save_posn[1] = (float) y1; tg->RenderFuncs.hyp_save_posn[2] = (float) z1;
6575 tg->RenderFuncs.hyp_save_norm[0] = (float) x2; tg->RenderFuncs.hyp_save_norm[1] = (float) y2; tg->RenderFuncs.hyp_save_norm[2] = (float) z2;
6577 tg->RenderFuncs.ray_save_posn[0] = (float) x3; tg->RenderFuncs.ray_save_posn[1] = (float) y3; tg->RenderFuncs.ray_save_posn[2] = (float) z3;
6583 void setStereoBufferStyle(
int itype)
6589 p->bufferarray[0]=GL_BACK_LEFT;
6590 p->bufferarray[1]=GL_BACK_RIGHT;
6596 p->bufferarray[0]=FW_GL_BACK;
6597 p->bufferarray[1]=FW_GL_BACK;
6600 printf(
"maxbuffers=%d\n",p->maxbuffers);
6602 void setStereoBufferStyleB(
int itype,
int iside,
int ibuffer)
6609 p->bufferarray[ibuffer]=GL_BACK_LEFT;
6611 p->bufferarray[ibuffer]=GL_BACK_RIGHT;
6616 p->bufferarray[ibuffer]=FW_GL_BACK;
6625 if (vp_parent->_nodeType != NODE_ViewpointGroup)
return TRUE;
6627 if (vp_parent->__proxNode != NULL) {
6629 if ((APPROX(0.0,vp_parent->size.c[0])) && (APPROX(0.0,vp_parent->size.c[1])) && (APPROX(0.0,vp_parent->size.c[2]))) {
6630 printf (
"size is zero\n");
6634 return X3D_PROXIMITYSENSOR(vp_parent->__proxNode)->isActive;
6640 static int moreThanOneValidViewpoint(
void) {
6642 struct tProdCon *t = &gglobal()->ProdCon;
6644 if (vectorSize(t->viewpointNodes)<=1)
return FALSE;
6646 for (count=0; count < vectorSize(t->viewpointNodes); count++) {
6647 if (count != t->currboundvpno) {
6648 struct Vector *me = vector_get(
struct X3D_Node*, t->viewpointNodes,count)->_parentVector;
6653 if (vectorSize(me) > 0) {
6657 vector_get(
struct X3D_Node *,t->viewpointNodes,count)->_parentVector, 0),
6673 void fwl_Last_ViewPoint() {
6674 if (moreThanOneValidViewpoint()) {
6678 struct tProdCon *t = &gglobal()->ProdCon;
6683 vp_to_go_to = vectorSize(t->viewpointNodes);
6684 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind--) {
6688 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
6689 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
6697 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),0);
6698 t->currboundvpno = vp_to_go_to;
6699 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6700 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),1);
6706 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,
6707 t->viewpointNodes,vp_to_go_to);
6708 t->currboundvpno = vp_to_go_to;
6709 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6720 void fwl_First_ViewPoint() {
6721 if (moreThanOneValidViewpoint()) {
6725 struct tProdCon *t = &gglobal()->ProdCon;
6731 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind++) {
6735 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
6736 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
6737 struct X3D_Node* , t->viewpointNodes,vp_to_go_to),cn);
6745 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),0);
6746 t->currboundvpno = vp_to_go_to;
6747 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6748 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),1);
6753 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,t->viewpointNodes,vp_to_go_to);
6754 t->currboundvpno = vp_to_go_to;
6755 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6765 void fwl_Prev_ViewPoint() {
6766 if (moreThanOneValidViewpoint()) {
6770 struct tProdCon *t = &gglobal()->ProdCon;
6775 vp_to_go_to = t->currboundvpno;
6776 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind--) {
6780 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
6781 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
6790 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),0);
6791 t->currboundvpno = vp_to_go_to;
6792 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6793 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),1);
6798 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,
6799 t->viewpointNodes,vp_to_go_to);
6800 t->currboundvpno = vp_to_go_to;
6801 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6812 void fwl_Next_ViewPoint() {
6813 if (moreThanOneValidViewpoint()) {
6817 struct tProdCon *t = &gglobal()->ProdCon;
6822 vp_to_go_to = t->currboundvpno;
6823 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind++) {
6827 if (vp_to_go_to>=vectorSize(t->viewpointNodes)) vp_to_go_to=0;
6828 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
6829 struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
6839 t->setViewpointBindInRender = vector_get(
6840 struct X3D_Node*,t->viewpointNodes,vp_to_go_to);
6841 t->currboundvpno = vp_to_go_to;
6842 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6851 void fwl_initializeRenderSceneUpdateScene() {
6867 viewer_postGLinit_init();
6870 if( ((
freewrl_params_t*)(tg->display.params))->fullscreen && newResetGeometry != NULL) newResetGeometry();
6885 static int workers_waiting(){
6888 waiting = tg->threads.ResourceThreadWaiting && tg->threads.TextureThreadWaiting;
6892 static void workers_stop()
6894 resitem_queue_exit();
6895 texitem_queue_exit();
6897 static int workers_running(){
6900 more = tg->threads.ResourceThreadRunning || tg->threads.TextureThreadRunning;
6927 ret = (!fwl_isinputThreadParsing()) && (!fwl_isTextureParsing()) && fwl_isInputThreadInitialized();
6928 ret = ret && workers_waiting();
6930 dtime = tg->Mainloop.TickTime - p->BrowserInitTime;
6931 ret = ret && (dtime > 10.0);
6935 void end_of_run_tests(){
6939 int i, notfreed, notfreedt;
6943 for(i=0;i<100000;i++){
6944 if(glIsBuffer(i)) {notfreed++; printf(
"b%d ",i);}
6945 if(glIsTexture(i)) {notfreedt++; printf(
"t%d ",i);}
6947 printf(
"\ngl buffers not freed = %d\n",notfreed);
6948 printf(
"gl textures not freed = %d\n",notfreedt);
6953 static void finalizeRenderSceneUpdateScene() {
6957 printf (
"finalizeRenderSceneUpdateScene\n");
6960 if (newResetGeometry != NULL) newResetGeometry();
6962 killErrantChildren();
6966 deleteVector(
struct X3D_Node*,rn->_parentVector);
6967 freeMallocedNodeFields(rn);
6973 iglobal_destructor(tg);
6975 void scanMallocTableOnQuit(
void);
6976 scanMallocTableOnQuit();
6982 int checkReplaceWorldRequest(){
6984 if (tg->Mainloop.replaceWorldRequest || tg->Mainloop.replaceWorldRequestMulti){
6985 tg->threads.flushing =
true;
6987 return tg->threads.flushing;
6989 static int exitRequest = 0;
6990 int checkExitRequest(){
6994 static int checkQuitRequest(){
6996 if ((tg->threads.MainLoopQuit) == 1){
6998 tg->threads.flushing =
true;
7000 return tg->threads.MainLoopQuit;
7002 void doReplaceWorldRequest()
7009 req = tg->Mainloop.replaceWorldRequest;
7010 tg->Mainloop.replaceWorldRequest = NULL;
7013 res = resource_create_single(req);
7015 resitem_enqueue(ml_new(res));
7020 tg->Mainloop.replaceWorldRequestMulti = NULL;
7022 resm->new_root =
true;
7023 gglobal()->resources.root_res = (
void*)resm;
7025 resitem_enqueue(ml_new(resm));
7027 tg->threads.flushing =
false;
7029 static int(*view_initialize)() = NULL;
7033 #if defined(_ANDROID) || defined(ANDROIDNDK) || defined(WINRT)
7034 int view_initialize0(
void){
7036 if (!fv_display_initialize()) {
7037 ERROR_MSG(
"initFreeWRL: error in display initialization.\n");
7043 int view_initialize0(
void){
7045 if (!fv_display_initialize_desktop()) {
7046 ERROR_MSG(
"initFreeWRL: error in display initialization.\n");
7062 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
7066 if (!p->draw_initialized){
7068 view_initialize = view_initialize0;
7069 if (view_initialize)
7070 more = view_initialize();
7073 fwl_initializeRenderSceneUpdateScene();
7075 p->draw_initialized = TRUE;
7078 switch (tg->threads.MainLoopQuit){
7083 if (tg->threads.flushing ==
false)
7086 profile_end(
"frontend");
7087 profile_start(
"mainloop");
7089 fwl_RenderSceneUpdateScene();
7090 profile_end(
"mainloop");
7091 profile_start(
"frontend");
7093 PRINT_GL_ERROR_IF_ANY(
"XEvents::render");
7094 checkReplaceWorldRequest();
7099 if (workers_waiting())
7104 tg->threads.flushing =
false;
7105 if (tg->threads.MainLoopQuit)
7106 tg->threads.MainLoopQuit++;
7108 doReplaceWorldRequest();
7111 tg->threads.MainLoopQuit++;
7122 tg->threads.MainLoopQuit++;
7126 more = workers_running();
7129 finalizeRenderSceneUpdateScene();
7140 void fwl_initialize_parser()
7143 if (rootNode() == NULL) {
7144 setRootNode( createNewX3DNode (NODE_Proto) );
7146 doNotRegisterThisNodeForDestroy(X3D_NODE(rootNode()));
7150 void fwl_init_SnapSeq() {
7151 #ifdef DOSNAPSEQUENCE
7153 set_snapsequence(TRUE);
7158 void fwl_set_LineWidth(
float lwidth) {
7159 gglobal()->Mainloop.gl_linewidth = lwidth;
7162 void fwl_set_KeyString(
const char* kstring)
7165 p->keypress_string = STRDUP(kstring);
7173 void outOfMemory(
const char *msg) {
7174 ConsoleMessage (
"FreeWRL has encountered a memory allocation problem\n"\
7175 "and is exiting. -- %s--",msg);
7180 void _disposeThread(
void *globalcontext);
7183 void fwl_doQuitInstance(
void *tg_remote)
7186 printf (
"fwl_doQuitInstance called\n");
7188 if (tg_remote == tg)
7190 fwl_doQuit(__FILE__,__LINE__);
7193 fwl_clearCurrentHandle();
7195 pthread_create(&tg->threads.disposeThread, NULL, (
void *(*)(
void *))&_disposeThread, tg);
7200 void __iglobal_destructor(
ttglobal tg);
7202 void _disposeThread(
void *globalcontext)
7206 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
7208 while((more = workers_running()) && more > 0)
7214 markForDispose(rootNode(), TRUE);
7218 finalizeRenderSceneUpdateScene();
7220 #if defined(WRAP_MALLOC) || defined(DEBUG_MALLOC)
7221 freewrlFreeAllRegisteredAllocations();
7222 freewrlDisposeMemTable();
7224 __iglobal_destructor(tg);
7229 void fwl_doQuit(
char *fl,
int ln)
7232 tg->threads.MainLoopQuit = max(1,tg->threads.MainLoopQuit);
7237 void fwl_doQuitAndWait(){
7238 pthread_t displaythread;
7240 displaythread = tg->threads.DispThrd;
7241 fwl_doQuit(__FILE__,__LINE__);
7242 pthread_join(displaythread,NULL);
7248 void fwl_tmpFileLocation(
char *tmpFileLocation) {
7250 if (tmpFileLocation == NULL)
return;
7252 FREE_IF_NZ(tg->Mainloop.tmpFileLocation);
7253 tg->Mainloop.tmpFileLocation = MALLOC(
char *,strlen(tmpFileLocation)+1);
7254 strcpy(tg->Mainloop.tmpFileLocation,tmpFileLocation);
7257 void close_internetHandles();
7258 void freewrlDie (
const char *format) {
7259 ConsoleMessage (
"Catastrophic error: %s\n",format);
7260 fwl_doQuit(__FILE__,__LINE__);
7266 struct Touch * AllocTouch(
unsigned int ID){
7272 for(i=0;i<p->ntouch;i++)
7273 if(p->touchlist[i].ID == ID && p->touchlist[i].inUse){
7275 p->touchlist[i].inUse = 2;
7276 return &p->touchlist[i];
7278 for(i=0;i<p->ntouch;i++)
7279 if(!p->touchlist[i].inUse){
7280 memset(&p->touchlist[i],0,
sizeof(
struct Touch));
7281 p->touchlist[i].inUse = 2;
7282 p->touchlist[i].ID = ID;
7283 return &p->touchlist[i];
7287 struct Touch * GetTouch(
unsigned int ID){
7293 for(i=0;i<p->ntouch;i++)
7294 if(p->touchlist[i].ID == ID && (p->touchlist[i].inUse || ID == 0) ){
7295 return &p->touchlist[i];
7299 void ReleaseTouch(
unsigned int ID){
7306 for(i=0;i<p->ntouch;i++)
7307 if(p->touchlist[i].ID == ID ){
7308 p->touchlist[i].inUse = 0;
7329 void setCurrentTouchID(
unsigned int ID){
7333 p->currentTouch = ID;
7335 struct Touch *currentTouch(){
7341 return GetTouch(p->currentTouch);
7344 void handle_pedal(
int mev,
int x,
int y,
ivec4 vport){
7349 pstate = &p->pedalstate;
7350 if(mev == ButtonPress) {
7351 if(!pstate->initialized){
7354 pstate->initialized = TRUE;
7358 pstate->isDown = TRUE;
7359 }
else if (mev == MotionNotify) {
7361 pstate->x += x - pstate->rx;
7362 pstate->y += y - pstate->ry;
7366 }
else if(mev == ButtonRelease) {
7368 pstate->x += x - pstate->rx;
7369 pstate->y += y - pstate->ry;
7371 pstate->isDown = FALSE;
7375 void viewer_setNextDragChord();
7376 void fwl_handle_aqua_multiNORMAL(
const int mev,
const unsigned int button,
int x,
int y,
unsigned int ID,
int windex) {
7377 int ibutton, passed, claimant;
7379 struct Touch *touch;
7395 if(mev == ButtonPress){
7396 viewer_setNextDragChord();
7401 if(fwl_getHover()) ibutton = 0;
7406 vportstack = (
Stack*)tg->Mainloop._vportstack;
7407 vport = stack_top(
ivec4,vportstack);
7409 printf(
"multiNORMAL x %d y %d fx %f fy %f vp %d %d %d %d\n",x,y,fx,fy,vport.X,vport.W,vport.Y,vport.H);
7412 ConsoleMessage(
"fwl_handle_aqua in MainLoop; mev %d but %d x %d y %d ID %d ",
7413 mev, ibutton, x, y, ID);
7414 ConsoleMessage(
"wndx %d swi %d shi %d ", windex, vport.W, vport.H);
7415 if (mev == ButtonPress) ConsoleMessage(
"ButtonPress\n");
7416 else if (mev == ButtonRelease) ConsoleMessage(
"ButtonRelease\n");
7417 else if (mev == MotionNotify) ConsoleMessage(
"MotionNotify\n");
7418 else ConsoleMessage(
"event %d\n", mev);
7424 passed = TOUCHCLAIMANT_PEDAL;
7425 claimant = TOUCHCLAIMANT_UNCLAIMED;
7426 if (fwl_getPedal()) {
7427 handle_pedal(mev, x, y, vport);
7431 claimant = TOUCHCLAIMANT_PEDAL;
7436 if(mev == ButtonPress){
7441 touch = GetTouch(ID);
7444 touch = AllocTouch(ID);
7445 if(currentTouch()->ID == 0) {
7448 setCurrentTouchID(ID);
7450 touch->windex = windex;
7451 touch->stageId = current_stageId();
7452 touch->buttonState = ibutton ? 1 : 0;
7453 touch->claimant = claimant;
7454 touch->passed = passed;
7455 touch->dragStart = TRUE;
7458 touch = GetTouch(ID);
7468 touch->x = p->pedalstate.x;
7469 touch->y = p->pedalstate.y;
7476 fx = (float)(touch->x - vport.X) / (float)vport.W;
7477 fy = (
float)(touch->y - vport.Y) / (
float)vport.H;
7481 touch->angle = 0.0f;
7483 if(mev == ButtonRelease){
7485 p->currentTouch = 0;
7486 touch->dragEnd = TRUE;
7487 if(touch->claimant == TOUCHCLAIMANT_PEDAL) touch->inUse = FALSE;
7491 void update_navigation(){
7497 struct Touch *curTouch;
7502 for(i=0;i<p->ntouch;i++){
7503 curTouch = &p->touchlist[i];
7504 if(curTouch->inUse){
7507 int priorclaimants = TOUCHCLAIMANT_PEDAL | TOUCHCLAIMANT_SENSOR;
7508 if(curTouch->claimant == TOUCHCLAIMANT_UNCLAIMED && curTouch->passed == priorclaimants ){
7511 curTouch->claimant = TOUCHCLAIMANT_NAVIGATION;
7513 curTouch->passed |= TOUCHCLAIMANT_NAVIGATION;
7515 if(curTouch->claimant == TOUCHCLAIMANT_NAVIGATION){
7517 ibut = curTouch->buttonState;
7518 if (curTouch->dragStart || (curTouch->dragEnd)) {
7519 if(curTouch->dragStart) imev = ButtonPress;
7520 if(curTouch->dragEnd) imev = ButtonRelease;
7521 handle(imev, ibut, curTouch->fx,curTouch->fy);
7522 curTouch->dragStart = FALSE;
7523 if(curTouch->dragEnd) curTouch->inUse = FALSE;
7524 curTouch->dragEnd = FALSE;
7526 imev = MotionNotify;
7527 handle (imev, ibut, curTouch->fx, curTouch->fy);
7538 void fwl_setOrientation (
int orient) {
7546 Viewer()->screenOrientation = orient;
7550 ConsoleMessage (
"invalid orientation %d\n",orient);
7551 Viewer()->screenOrientation = 0;
7555 int fwl_getOrientation(){
7556 return Viewer()->screenOrientation;
7559 void fwl_setOrientation2 (
int orient) {
7567 gglobal()->Mainloop.screenOrientation2 = orient;
7572 ConsoleMessage (
"invalid orientation2 %d\n",orient);
7573 gglobal()->Mainloop.screenOrientation2 = 0;
7577 int fwl_getOrientation2(){
7579 return gglobal()->Mainloop.screenOrientation2;
7582 void setIsPlugin() {
7584 RUNNINGASPLUGIN = TRUE;
7620 void setDisplayed (
int state) {
7624 if (state) printf (
"WE ARE DISPLAYED\n");
7625 else printf (
"we are now iconic\n");
7627 p->onScreen = state;
7630 void fwl_init_EaiVerbose() {
7632 #if !defined(EXCLUDE_EAI)
7633 gglobal()->EAI_C_CommonFunctions.eaiverbose = TRUE;
7634 fwlio_RxTx_control(CHANNEL_EAI, RxTx_MOREVERBOSE);
7640 #if defined (_ANDROID)
7642 void fwl_Android_replaceWorldNeeded() {
7650 resetSensorEvents();
7653 gglobal()->resources.root_res = NULL;
7654 Android_reset_viewer_to_defaults();
7656 struct tProdCon *t = &gglobal()->ProdCon;
7659 if (vectorSize(t->viewpointNodes) > t->currboundvpno) {
7660 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),0);
7663 if (rootNode() != NULL) {
7666 for (i=0; i<proto->__children.n; i++) {
7667 markForDispose(proto->__children.p[i], TRUE);
7672 proto->__children.n = 0;
7677 closeConsoleMessage();
7690 killKeySensorNodeList();
7697 setMenuStatus(NULL);
7700 kill_userDefinedShaders();
7707 #if !defined(EXCLUDE_EAI)
7711 fwlio_RxTx_control(CHANNEL_EAI, RxTx_STOP) ;
7713 #endif //EXCLUDE_EAI
7716 sprintf (mystring,
"QUIT");
7717 Sound_toserver(mystring);
7721 if (globalParser != NULL) {
7722 parser_destroyData(globalParser);
7724 gglobal()->CParse.globalParser = NULL;
7731 setMenuStatus(
"NONE");
7737 #if !defined(_ANDROID) || defined(ANDROIDNDK)
7742 char *strBackslash2fore(
char *);
7743 void fwl_replaceWorldNeeded(
char* str)
7745 ConsoleMessage(
"file to load: %s\n",str);
7746 FREE_IF_NZ(gglobal()->Mainloop.replaceWorldRequest);
7747 gglobal()->Mainloop.replaceWorldRequest = strBackslash2fore(STRDUP(str));
7750 gglobal()->Mainloop.replaceWorldRequestMulti = (
void*)(multiResWithParent);
7756 ConsoleMessage(
"fwl_reload called");
7759 #endif //NOT _ANDROID
7763 void sendDescriptionToStatusBar(
struct X3D_Node *CursorOverSensitive) {
7768 if (CursorOverSensitive == NULL) update_status(NULL);
7772 for (tmp=0; tmp<p->num_SensorEvents; tmp++) {
7773 if (p->SensorEvents[tmp].fromnode == CursorOverSensitive) {
7774 switch (p->SensorEvents[tmp].datanode->_nodeType) {
7775 case NODE_Anchor: ns = ((
struct X3D_Anchor *)p->SensorEvents[tmp].datanode)->description->strptr;
break;
7776 case NODE_LineSensor: ns = ((
struct X3D_LineSensor *)p->SensorEvents[tmp].datanode)->description->strptr;
break;
7777 case NODE_PlaneSensor: ns = ((
struct X3D_PlaneSensor *)p->SensorEvents[tmp].datanode)->description->strptr;
break;
7778 case NODE_SphereSensor: ns = ((
struct X3D_SphereSensor *)p->SensorEvents[tmp].datanode)->description->strptr;
break;
7779 case NODE_TouchSensor: ns = ((
struct X3D_TouchSensor *)p->SensorEvents[tmp].datanode)->description->strptr;
break;
7780 case NODE_GeoTouchSensor: ns = ((
struct X3D_GeoTouchSensor *)p->SensorEvents[tmp].datanode)->description->strptr;
break;
7781 case NODE_CylinderSensor: ns = ((
struct X3D_CylinderSensor *)p->SensorEvents[tmp].datanode)->description->strptr;
break;
7782 default: {printf (
"sendDesc; unknown node type %d\n",p->SensorEvents[tmp].datanode->_nodeType);}
7785 if (ns == NULL) {ns =
"(over sensitive)";}
7786 else if (ns[0] ==
'\0') ns = (
char *)stringNodeType(p->SensorEvents[tmp].datanode->_nodeType);
7797 void resetSensorEvents(
void) {
7801 for(ktouch=0;ktouch<20;ktouch++){
7802 struct Touch *touch;
7803 touch = &p->touchlist[ktouch];
7805 if (touch->oldCOS != NULL)
7806 sendSensorEvents(touch->oldCOS,MapNotify,touch->buttonState, FALSE);
7810 sendDescriptionToStatusBar(NULL);
7811 memset(touch,0,
sizeof(
struct Touch));
7812 FREE_IF_NZ(p->SensorEvents);
7814 p->num_SensorEvents = 0;
7815 gglobal()->RenderFuncs.hypersensitive = NULL;
7816 gglobal()->RenderFuncs.hyperhit = 0;