30#include <system_threads.h>
34#include <libFreeWRL.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"
78ivec2 ivec2_init(
int x,
int y);
79ivec4 ivec4_init(
int x,
int y,
int w,
int h);
81int getRayHitAndSetLookatTarget();
82void transformMBB(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax);
89void (*newResetGeometry) (void) = NULL;
98OLDCODE #
if defined(_ANDROID )
99OLDCODE
void setAquaCursor(
int ctype) { };
106static int debugging_trigger_state;
107void toggle_debugging_trigger(){
109 debugging_trigger_state = 1 - debugging_trigger_state;
111int get_debugging_trigger_once(){
112 int iret = debugging_trigger_state;
113 if(iret) debugging_trigger_state = 0;
116int 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);
194void 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;
218int 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);
228int pointinsidecurrentviewport(
Stack *vpstack,
ivec2 pt){
230 return pointinsideviewport(vp,pt);
232void intersectandpushviewport(
Stack *vpstack,
ivec4 childvp){
234 ivec4 olap = intersectviewports(childvp,currentvp);
235 pushviewport(vpstack, olap);
238 return stack_top(
ivec4,vpstack);
240int currentviewportvisible(
Stack *vpstack){
242 return visibleviewport(currentvp);
244void setcurrentviewport(
Stack *_vpstack){
246 glViewport(vp.X,vp.Y,vp.W,vp.H);
248ivec4 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,
330int haveFrameBufferObject()
333#if defined(GLEW) || defined(GLEW_MX)
334 iret = GLEW_ARB_framebuffer_object != 0;
339void 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);
353void 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);
368void 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);
378void popnset_viewport(){
381 vportstack = (
Stack *)gglobal()->Mainloop._vportstack;
382 popviewport(vportstack);
383 setcurrentviewport(vportstack);
385int 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);
412ivec4 get_current_viewport(){
414 vportstack = (
Stack *)gglobal()->Mainloop._vportstack;
415 return stack_top(
ivec4,vportstack);
417float defaultClipBoundary [] = {0.0f, 1.0f, 0.0f, 1.0f};
445void register_contenttype(
void *ct);
446void free_contenttypes();
455 void (*render)(
void *self);
456 int (*pick)(
void *self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex);
461void content_render(
void *_self){
466 pushnset_viewport(self->t1.viewport);
467 c = self->t1.contents;
475int content_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
482 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
483 c = self->t1.contents;
485 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
494 self->itype = CONTENT_GENERIC;
495 self->contents = NULL;
496 self->render = content_render;
497 self->pick = content_pick;
498 memcpy(self->viewport,defaultClipBoundary,4*
sizeof(
float));
511int setup_pickside0(
int x,
int y,
int *iside,
ivec4 *vportleft,
ivec4 *vportright);
512void scene_render(
void *self){
516void fwl_handle_aqua_multiNORMAL(
const int mev,
const unsigned int button,
int x,
int y,
unsigned int ID,
int windex);
517int scene_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
523 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
527 inside = setup_pickside0(mouseX,mouseY,&iside,&vport[0],&vport[1]);
529 Stack *vpstack = (
Stack*)gglobal()->Mainloop._vportstack;
530 pushviewport(vpstack,vport[iside]);
531 fwl_handle_aqua_multiNORMAL(mev,butnum,mouseX,mouseY,ID,windex);
533 popviewport(vpstack);
541 register_contenttype(self);
542 init_tcontenttype(&self->t1);
543 self->t1.itype = CONTENT_SCENE;
544 self->t1.render = scene_render;
545 self->t1.pick = scene_pick;
548int statusbar_getClipPlane();
553void render_statusbar0();
554void statusbar_render(
void *_self){
562 pushnset_viewport(self->t1.viewport);
563 self->clipplane = statusbar_getClipPlane();
567 if(self->clipplane != 0){
572 vportstack = (
Stack*)tg->Mainloop._vportstack;
573 ivport = stack_top(
ivec4,vportstack);
574 ivport.H -= self->clipplane;
575 ivport.Y += self->clipplane;
576 stack_push(
ivec4,vportstack,ivport);
579 c = self->t1.contents;
586 stack_pop(
ivec4,vportstack);
591int statusbar_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
600 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
601 iret = statusbar_handle_mouse1(mev,butnum,mouseX,mouseY,windex);
607 if(self->clipplane != 0){
612 vportstack = (
Stack*)tg->Mainloop._vportstack;
613 ivport = stack_top(
ivec4,vportstack);
614 ivport.H -= self->clipplane;
615 ivport.Y += self->clipplane;
616 stack_push(
ivec4,vportstack,ivport);
620 c = self->t1.contents;
622 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
627 stack_pop(
ivec4,vportstack);
636 register_contenttype(self);
637 init_tcontenttype(&self->t1);
638 self->t1.itype = CONTENT_STATUSBAR;
639 self->t1.render = statusbar_render;
640 self->t1.pick = statusbar_pick;
652void render_switch0();
653void switch_render(
void *_self){
660 pushnset_viewport(self->t1.viewport);
661 c = self->t1.contents;
664 iwhich = *(self->whichPtr);
673int switch_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
682 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
684 c = self->t1.contents;
686 if(i == *(self->whichPtr)){
687 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
699 register_contenttype(self);
700 init_tcontenttype(&self->t1);
701 self->t1.itype = CONTENT_SWITCH;
702 self->t1.render = switch_render;
703 self->t1.pick = switch_pick;
704 self->whichCase = -1;
705 self->whichPtr = &self->whichCase;
708void contenttype_switch_set_which(
contenttype *_self,
int which){
710 self->whichCase = which;
711 self->whichPtr = &self->whichCase;
713void contenttype_switch_set_which_ptr(
contenttype *_self,
int *whichPtr){
715 self->whichPtr = whichPtr;
724typedef struct AtlasFont AtlasFont;
726AtlasFont *searchAtlasTableOrLoad(
char *facename,
int EMpixels);
727AtlasEntrySet* searchAtlasFontForSizeOrMake(AtlasFont *font,
int EMpixels);
728typedef struct vec4 {
float X;
float Y;
float Z;
float W;}
vec4;
729vec4 vec4_init(
float x,
float y,
float z,
float w);
730int render_captiontext(AtlasFont *font,
int *utf32,
int len32,
vec4 color);
748void captiontext_render(
void *_self){
752 pushnset_viewport(self->t1.viewport);
754 render_captiontext(self->font, self->utf32, self->len32, self->color);
757int captiontext_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
761contenttype *new_contenttype_captiontext(
char *fontname,
int EMpixels,
vec4 color){
763 register_contenttype(self);
764 init_tcontenttype(&self->t1);
765 self->t1.itype = CONTENT_CAPTIONTEXT;
766 self->t1.render = captiontext_render;
767 self->t1.pick = captiontext_pick;
769 self->EMpixels = EMpixels;
772 self->fontname = fontname;
773 self->caption = NULL;
778 self->font = (AtlasFont*)searchAtlasTableOrLoad(fontname,EMpixels);
780 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
787unsigned int *utf8_to_utf32(
unsigned char *utf8string,
unsigned int *str32,
unsigned int *len32);
788void captiontext_setString(
void *_self,
char *utf8string){
791 lenstr = strlen(utf8string);
792 if(self->nalloc < lenstr){
793 self->caption = realloc(self->caption,lenstr+1);
795 self->utf32 = realloc(self->utf32,(lenstr+1)*
sizeof(
int));
796 self->nalloc = lenstr;
798 strcpy(self->caption,utf8string);
800 self->utf32 = (
int *)utf8_to_utf32((
unsigned char *)self->caption,(
unsigned int *)self->utf32,(
unsigned int *)&self->len32);
837 unsigned char *Ablob;
839 unsigned char *S, *E;
848void textpanel_render(
void *self);
849contenttype *new_contenttype_textpanel(
char* fontname,
int EMpixels,
int maxlines,
int maxlen,
int wrap){
852 register_contenttype(self);
853 init_tcontenttype(&self->t1);
854 self->t1.itype = CONTENT_TEXTPANEL;
855 self->t1.render = textpanel_render;
858 self->color = vec4_init(1.0f,1.0f,1.0f,0.0f);
860 self->maxlines = maxlines;
861 self->maxlen = maxlen;
866 self->blobsize = self->maxlines * self->maxlen;
867 self->Ablob = (
unsigned char*)MALLOCV(self->blobsize+1);
868 register_contenttype(self->Ablob);
869 memset(self->Ablob,0,self->blobsize+1);
870 self->Z = self->z = self->Ablob;
871 self->S = self->Ablob;
872 self->E = self->Ablob + self->blobsize;
873 self->Blist = MALLOCV(
sizeof(
BUTitem)*self->maxlines);
874 register_contenttype(self->Blist);
875 self->rowsize = self->maxlen;
876 self->row = MALLOCV(self->rowsize +1);
877 register_contenttype(self->row);
879 for(i=0;i<self->maxlines;i++){
883 if(prev < 0) prev = self->maxlines -1;
884 if(next > self->maxlines -1) next = 0;
885 self->Blist[i].next = &self->Blist[next];
886 self->Blist[i].prev = &self->Blist[prev];
887 self->Blist[i].B = self->Z;
889 self->bhead = &self->Blist[0];
892 self->fontname = fontname;
893 iem = (int)(EMpixels * fwl_getDensityFactor());
894 self->fontSize = iem;
895 self->maxadvancepx = iem/2;
896 self->initialized = FALSE;
898 self->fontname = fontname;
899 self->font = (AtlasFont*)searchAtlasTableOrLoad(fontname,iem);
901 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
992 unsigned char *T, *U, *B;
993 int lenT, lenU, haveTU;
996 T = min(self->Z + len, self->E);
997 U = T == self->E ? self->S : T;
1001 memcpy(self->Z,line,lenT);
1003 memcpy(U,&line[lenT],lenU);
1005 BUTI = endline? self->bhead->next : self->bhead;
1009 self->added = min(self->added + len, self->blobsize + 1);
1010 if(self->added > self->blobsize){
1012 self->z = self->z + 1;
1013 if(self->z > self->E) self->z = self->S;
1016void TextPanel_AddString(
void *_self,
char *
string){
1020 int endline, endstring;
1022 if(s == NULL)
return;
1023 endstring = (*s) ==
'\0';
1026 while( (*ln) !=
'\0' && (*ln) !=
'\n') ln++;
1027 endline = (*ln) ==
'\n';
1028 endstring = (*ln) ==
'\0';
1029 TextPanel_AddLine_blobMethodB(self,s,ln-s,endline);
1034void fwg_register_consolemessage_callbackB(
void *data,
void(*callback)(
void*,
char *));
1035void textpanel_register_as_console(
void *_self){
1036 fwg_register_consolemessage_callbackB(_self,TextPanel_AddString);
1038ivec2 pixel2text(
int x,
int y,
int rowheight,
int maxadvancepx){
1040 int w = maxadvancepx;
1041 ivec2 ret = ivec2_init(x/w,y/h);
1044ivec2 text2pixel(
int x,
int y,
int rowheight,
int maxadvancepx){
1046 int w = maxadvancepx;
1047 ivec2 ret = ivec2_init(x*w, y*h);
1051void atlasfont_get_rowheight_charwidth_px(AtlasFont *font,
int *rowheight,
int *maxadvancepx);
1052static int show_ringtext = 0;
1053int before_textpanel_render_rows(AtlasFont *font,
vec4 color);
1054int textpanel_render_row(AtlasFont *font,
char * cText,
int len,
int *pen_x,
int *pen_y);
1055void after_textpanel_render_rows();
1071 int jline, jrow, nrows, isFull, moredata, rowheight, maxadvancepx, atlasOK;
1073 ivec2 panelsizechars;
1079 if(self->t1.itype != CONTENT_TEXTPANEL)
return;
1080 if(!self->font )
return;
1082 atlasfont_get_rowheight_charwidth_px(self->font,&rowheight,&maxadvancepx);
1083 panelsizechars = ivec2_init(ivport.W / maxadvancepx, ivport.H / rowheight);
1084 panelsizechars.X = min(panelsizechars.X,self->maxlen);
1085 panelsizechars.Y = min(panelsizechars.Y,self->maxlines);
1100 isFull = self->added > self->blobsize;
1101 moredata = min(self->added,self->blobsize);
1103 int i, nchars, bchars, achars, hasTU, Trow;
1104 unsigned char *B, *A, *U, *T, *P;
1117 nchars = (B - U + T - A);
1119 bchars = nchars - achars;
1121 nrows = (int)ceil((
float)nchars/(float)panelsizechars.X);
1122 Trow = nrows -1 - (T - A)/panelsizechars.X;
1137 atlasOK = before_textpanel_render_rows(self->font, self->color);
1141 for(i=0;i<nrows;i++){
1143 int l0, l1, i0, lenrow, pen_x, pen_y;
1146 i0 = (nrows-i-1)*panelsizechars.X;
1147 lenrow = min(nchars - i0,panelsizechars.X);
1152 if(jrow > panelsizechars.Y)
1154 row = (
char *)&P[-nchars + i0];
1155 if(hasTU && Trow == i){
1158 row = (
char *)self->row;
1159 memcpy(&row[l0],U,l1);
1160 memcpy(row,&A[i0],l0);
1161 P = &self->E[bchars];
1188 xy = text2pixel(0,jrow,rowheight,maxadvancepx);
1203 textpanel_render_row(self->font, row, lenrow,&pen_x, &pen_y);
1206 memcpy(self->row,row,lenrow);
1207 self->row[lenrow] =
'\n';
1208 self->row[lenrow+1] =
'\0';
1209 printf(
"%s",self->row);
1215 }
while(jrow < panelsizechars.Y && moredata > 0);
1216 after_textpanel_render_rows();
1217 if(0) printf(
"======================\n");
1236void textpanel_render(
void *_self){
1245 pushnset_viewport(self->t1.viewport);
1246 c = self->t1.contents;
1252 if(getShowConsoleText()){
1254 vportstack = (
Stack*)tg->Mainloop._vportstack;
1255 ivport = stack_top(
ivec4,vportstack);
1256 textpanel_render_blobmethod(self,ivport);
1282void layer_render(
void *_self){
1286 pushnset_viewport(self->t1.viewport);
1287 c = self->t1.contents;
1294int layer_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1299 c = self->t1.contents;
1308 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1312 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID,windex);
1322 register_contenttype(self);
1323 init_tcontenttype(&self->t1);
1324 self->t1.itype = CONTENT_LAYER;
1325 self->t1.render = layer_render;
1326 self->t1.pick = layer_pick;
1330int emulate_multitouch2(
struct Touch *touchlist,
int ntouch,
int *IDD,
int *lastbut,
int *mev,
unsigned int *button,
int x,
int y,
int *ID,
int windex);
1331void record_multitouch(
struct Touch *touchlist,
int mev,
int butnum,
int mouseX,
int mouseY,
int ID,
int windex,
int ihandle);
1332int fwl_get_emulate_multitouch();
1334void render_multitouch2(
struct Touch* touchlist,
int ntouch);
1341 struct Touch touchlist[20];
1346void multitouch_render(
void *_self){
1351 pushnset_viewport(self->t1.viewport);
1352 c = self->t1.contents;
1361int multitouch_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1369 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1373 if(fwl_get_emulate_multitouch()){
1374 ihandle = emulate_multitouch2(self->touchlist,self->ntouch,&self->IDD,&self->lastbut,&mev,(
unsigned int *)&butnum,mouseX,mouseY,(
int *)&ID,windex);
1375 iret = ihandle < 0 ? 0 : 1;
1379 c = self->t1.contents;
1382 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID,windex);
1387 record_multitouch(self->touchlist,mev,butnum,mouseX,mouseY,ID,windex,ihandle);
1396 register_contenttype(self);
1397 init_tcontenttype(&self->t1);
1398 self->t1.itype = CONTENT_MULTITOUCH;
1399 self->t1.render = multitouch_render;
1400 self->t1.pick = multitouch_pick;
1403 memset(self->touchlist,0,20*
sizeof(
struct Touch));
1418void e3dmouse_render(
void *_self){
1421 content_render(_self);
1429 vportstack = (
Stack*)tg->Mainloop._vportstack;
1430 ivport = stack_top(
ivec4,vportstack);
1431 x = ivport.W/2 + ivport.X;
1432 y = ivport.H/2 + ivport.Y;
1434 fiducialDrawB(CURSOR_DOWN,x,y);
1438int e3dmouse_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1449 int iret, but2, x,y;
1450 unsigned int ID0, ID1;
1456 vportstack = (
Stack*)tg->Mainloop._vportstack;
1458 ivport = stack_top(
ivec4,vportstack);
1459 x = ivport.W/2 + ivport.X;
1460 y = ivport.H/2 + ivport.Y;
1466 ivport = stack_top(
ivec4,vportstack);
1468 if(mev == ButtonRelease){
1469 self->sphericalmode = 1 - self->sphericalmode;
1470 if(self->sphericalmode){
1471 printf(
"turning on spherical mode\n");
1472 self->navigationMode = fwl_getNavMode();
1473 fwl_setNavMode(
"SPHERICAL");
1476 iret = content_pick(_self,ButtonPress,but2,mouseX,mouseY,ID0,windex);
1478 printf(
"turning off spherical mode\n");
1479 fwl_set_viewer_type(self->navigationMode);
1482 iret = content_pick(_self,ButtonRelease,but2,mouseX,mouseY,ID0,windex);
1484 self->waste = FALSE;
1485 }
else if(mev == ButtonPress){
1490 if(self->waste)
return 1;
1491 if(self->sphericalmode){
1492 iret = content_pick(_self,mev,butnum,x,y,ID1,windex);
1495 iret = content_pick(_self,MotionNotify,0,mouseX,mouseY,ID0,windex);
1499 iret = content_pick(_self,mev,butnum,mouseX,mouseY,ID0,windex);
1508 register_contenttype(self);
1509 init_tcontenttype(&self->t1);
1510 self->t1.itype = CONTENT_E3DMOUSE;
1511 self->t1.render = e3dmouse_render;
1512 self->t1.pick = e3dmouse_pick;
1513 self->sphericalmode = 0;
1521 float offset_fraction[2];
1523void loadIdentityMatrix (
double *mat);
1524void get_view_matrix(
double *savePosOri,
double *saveView);
1525static void set_view_matrix(
double *savePosOri,
double *saveView);
1527static void set_quadrant_viewmatrix(
double *savePosOri,
double *saveView,
int iq) {
1531 double viewmatrix[16], tmat[16], pomat[16], vmat[16], bothinverse[16];
1532 double xyz[3], zero[3];
1534 get_view_matrix(savePosOri,saveView);
1536 zero[0] = zero[1] = zero[2] = 0.0;
1537 matmultiplyAFFINE(viewmatrix,saveView,savePosOri);
1538 matinverseAFFINE(bothinverse,viewmatrix);
1540 transformAFFINEd(xyz, zero, bothinverse);
1542 loadIdentityMatrix (pomat);
1543 loadIdentityMatrix (vmat);
1544 if(0) mattranslate(vmat, -Viewer()->Dist,0.0,0.0);
1546 mattranslate(tmat,-xyz[0],-xyz[1],-xyz[2]);
1547 matmultiplyAFFINE(vmat,tmat,vmat);
1551 case 1: matrotate(tmat, 0.0, 0.0,0.0,1.0);
1553 case 2: matrotate(tmat, PI * .5, 1.0,0.0,0.0);
1555 case 3: matrotate(tmat, PI * .5, 0.0,1.0,0.0);
1560 matmultiplyAFFINE(vmat,vmat,tmat);
1561 set_view_matrix(pomat,vmat);
1563void quadrant_render(
void *_self){
1570 pushnset_viewport(self->t1.viewport);
1571 c = self->t1.contents;
1574 double savePosOri[16], saveView[16];
1576 memcpy(viewport,defaultClipBoundary,4*
sizeof(
float));
1578 viewport[0] = i==0 || i==2 ? 0.0f : self->offset_fraction[0];
1579 viewport[1] = i==0 || i==2 ? self->offset_fraction[0] : 1.0f;
1580 viewport[2] = i==0 || i==1 ? 0.0f : self->offset_fraction[1];
1581 viewport[3] = i==0 || i==1 ? self->offset_fraction[1] : 1.0f;
1582 pushnset_viewport(viewport);
1585 set_quadrant_viewmatrix(savePosOri, saveView, i);
1588 set_view_matrix(savePosOri,saveView);
1596int quadrant_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1605 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1606 c = self->t1.contents;
1611 memcpy(viewport,defaultClipBoundary,4*
sizeof(
float));
1613 viewport[0] = i==0 || i==2 ? 0.0f : self->offset_fraction[0];
1614 viewport[1] = i==0 || i==2 ? self->offset_fraction[0] : 1.0f;
1615 viewport[2] = i==0 || i==1 ? 0.0f : self->offset_fraction[1];
1616 viewport[3] = i==0 || i==1 ? self->offset_fraction[1] : 1.0f;
1617 if(checknpush_viewport(viewport,mouseX,mouseY)){
1619 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1634 register_contenttype(self);
1635 init_tcontenttype(&self->t1);
1636 self->t1.itype = CONTENT_QUADRANT;
1637 self->t1.render = quadrant_render;
1638 self->t1.pick = quadrant_pick;
1639 self->offset_fraction[0] = .5f;
1640 self->offset_fraction[1] = .5f;
1653void loadIdentityMatrix (
double *mat);
1654void get_view_matrix(
double *savePosOri,
double *saveView);
1655static void set_view_matrix(
double *savePosOri,
double *saveView);
1656void compute_sidebyside_viewport_and_fiducial(
int iside,
ivec4 *ivport,
ivec2 *fidcenter){
1667 vportstack = (
Stack*)tg->Mainloop._vportstack;
1668 vport = stack_top(
ivec4,vportstack);
1670 screenwidth2 = vport.W/2;
1671 ivport->W = screenwidth2;
1672 ivport->H = vport.H;
1673 ivport->Y = vport.Y;
1675 ivport->X = vport.X;
1677 ivport->X = vport.X + screenwidth2;
1679 fidcenter->Y = vport.Y + vport.H;
1683 expansion =
viewer->screendist - .5;
1684 iexpand = (GLint)(expansion * ivport->W);
1686 fidcenter->X = ivport->X + screenwidth2/2;
1688 fidcenter->X -= iexpand;
1690 fidcenter->X += iexpand;
1693void stereo_sidebyside_render(
void *_self){
1705 pushnset_viewport(self->t1.viewport);
1706 c = self->t1.contents;
1718 vportstack = (
Stack*)tg->Mainloop._vportstack;
1721 compute_sidebyside_viewport_and_fiducial(
viewer->isideB,&ivport2,&fidcenter);
1725 halfW = ivport2.W / 2;
1726 vpc = halfW + ivport2.X;
1727 viewer->xcenter = (double)(fidcenter.X - vpc)/(double)halfW;
1728 pushviewport(vportstack,ivport2);
1730 setcurrentviewport(vportstack);
1734 fiducialDrawB(CURSOR_FIDUCIALS,fidcenter.X,fidcenter.Y);
1744int stereo_sidebyside_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1757 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1758 c = self->t1.contents;
1764 ivec2 fidcenter, pt;
1767 compute_sidebyside_viewport_and_fiducial(
viewer->isideB,&ivport2,&fidcenter);
1772 iret = pointinsideviewport(ivport2,pt);
1774 pushviewport(gglobal()->Mainloop._vportstack,ivport2);
1775 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1789 register_contenttype(self);
1790 init_tcontenttype(&self->t1);
1791 self->t1.itype = CONTENT_STEREO_SIDEBYSIDE;
1792 self->t1.render = stereo_sidebyside_render;
1793 self->t1.pick = stereo_sidebyside_pick;
1805void loadIdentityMatrix (
double *mat);
1806void clear_shader_table();
1807void setStereoBufferStyle(
int);
1808void stereo_anaglyph_render(
void *_self){
1823 clear_shader_table();
1826 pushnset_viewport(self->t1.viewport);
1827 c = self->t1.contents;
1830 Viewer_anaglyph_clearSides();
1832 glClearColor(0.0f,0.0f,0.0f,1.0f);
1833 BackEndClearBuffer(2);
1837 Viewer_anaglyph_setSide(i);
1845 Viewer_anaglyph_clearSides();
1847 clear_shader_table();
1853int stereo_anaglyph_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1866 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1867 c = self->t1.contents;
1872 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1884 register_contenttype(self);
1885 init_tcontenttype(&self->t1);
1886 self->t1.itype = CONTENT_STEREO_ANAGLYPH;
1887 self->t1.render = stereo_anaglyph_render;
1888 self->t1.pick = stereo_anaglyph_pick;
1899void stereo_updown_render(
void *_self){
1913 vportstack = (
Stack*)tg->Mainloop._vportstack;
1916 pushnset_viewport(self->t1.viewport);
1917 c = self->t1.contents;
1921 ivport = stack_top(
ivec4,vportstack);
1923 ivport.Y += (1-i)*ivport.H;
1924 pushviewport(vportstack,ivport);
1925 setcurrentviewport(vportstack);
1942int stereo_updown_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1955 vportstack = (
Stack*)tg->Mainloop._vportstack;
1958 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1959 c = self->t1.contents;
1967 ivport = stack_top(
ivec4,vportstack);
1969 ivport.Y += (1-i)*ivport.H;
1972 iret = pointinsideviewport(ivport,pt);
1975 pushviewport(vportstack,ivport);
1976 setcurrentviewport(vportstack);
1978 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1992 register_contenttype(self);
1993 init_tcontenttype(&self->t1);
1994 self->t1.itype = CONTENT_STEREO_UPDOWN;
1995 self->t1.render = stereo_updown_render;
1996 self->t1.pick = stereo_updown_pick;
2006void setStereoBufferStyleB(
int itype,
int iside,
int ibuffer);
2007void stereo_shutter_render(
void *_self){
2009 int i, shutterGlasses;
2014 static double shuttertime;
2015 static int shutterside;
2024 if(
viewer->haveQuadbuffer)
2027 pushnset_viewport(self->t1.viewport);
2028 c = self->t1.contents;
2034 if(shutterGlasses == 2)
2036 if(TickTime() - shuttertime > 2.0)
2038 shuttertime = TickTime();
2039 shutterside = 1 - shutterside;
2041 setStereoBufferStyleB(1,i,0);
2044 setStereoBufferStyleB(0,i,0);
2055 setStereoBufferStyleB(1,0,0);
2059int stereo_shutter_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2075 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2076 c = self->t1.contents;
2080 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
2093 register_contenttype(self);
2094 init_tcontenttype(&self->t1);
2095 self->t1.itype = CONTENT_STEREO_SHUTTER;
2096 self->t1.render = stereo_shutter_render;
2097 self->t1.pick = stereo_shutter_pick;
2114 float offset_fraction;
2120 register_contenttype(self);
2121 init_tcontenttype(&self->t1);
2122 self->t1.itype = CONTENT_SPLITTER;
2135 unsigned int ibuffer;
2136 unsigned int itexturebuffer;
2137 unsigned int idepthbuffer;
2157void push_stageId(
void *stageId){
2158 Stack *stagestack = (
Stack*)gglobal()->Mainloop._stagestack;
2159 stack_push(
void*,stagestack,stageId);
2161void *current_stageId(){
2162 Stack *stagestack = (
Stack*)gglobal()->Mainloop._stagestack;
2163 return stack_top(
void*,stagestack);
2166 Stack *stagestack = (
Stack*)gglobal()->Mainloop._stagestack;
2167 stack_pop(
void*,stagestack);
2170void stage_render(
void *_self){
2175 pushnset_framebuffer(self->ibuffer);
2176 vportstack = (
Stack*)gglobal()->Mainloop._vportstack;
2177 pushviewport(vportstack,self->ivport);
2179 setcurrentviewport(vportstack);
2182 if(self->ibuffer != FW_GL_BACK)
2183 glClearColor(.3f,.4f,.5f,1.0f);
2185 glClearColor(1.0f,0.0f,0.0f,1.0f);
2186 BackEndClearBuffer(2);
2187 content_render(_self);
2190 popnset_framebuffer();
2192int stage_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2194 ivec4 ivport_parent;
2199 ivport_parent = get_current_viewport();
2200 x = mouseX - ivport_parent.X;
2201 y = mouseY - ivport_parent.Y;
2203 x = x + self->ivport.X;
2204 y = y + self->ivport.Y;
2205 vportstack = (
Stack*)gglobal()->Mainloop._vportstack;
2206 pushviewport(vportstack,self->ivport);
2208 iret = content_pick(_self,mev,butnum,x,y,ID,windex);
2216 register_contenttype(self);
2217 init_tcontenttype(&self->t1);
2218 self->t1.itype = CONTENT_STAGE;
2219 self->t1.render = stage_render;
2220 self->t1.pick = stage_pick;
2221 self->type = STAGETYPE_BACKBUF;
2222 self->ibuffer = FW_GL_BACK;
2223 self->clear_zbuffer = TRUE;
2224 self->ivport = ivec4_init(0,0,100,100);
2228#ifdef GL_DEPTH_COMPONENT32
2229#define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT32
2231#define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT16
2233contenttype *new_contenttype_stagefbo(
int width,
int height){
2238 _self = new_contenttype_stage();
2239 self = (
stage*)_self;
2240 self->type = STAGETYPE_FBO;
2241 self->ivport.W = width;
2242 self->ivport.H = height;
2246 if ( !haveFrameBufferObject() )
2249 glGenTextures(1, &self->itexturebuffer);
2251 glBindTexture(GL_TEXTURE_2D, self->itexturebuffer);
2252 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2255 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2256 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
2258 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2260 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2261 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2262 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->ivport.W, self->ivport.H, 0, GL_RGBA , GL_UNSIGNED_BYTE, 0);
2265 glBindTexture(GL_TEXTURE_2D, 0);
2267 glGenFramebuffers(1, &self->ibuffer);
2268 glBindFramebuffer(GL_FRAMEBUFFER, self->ibuffer);
2276 glGenRenderbuffers(1, &self->idepthbuffer);
2278 glBindRenderbuffer(GL_RENDERBUFFER, self->idepthbuffer);
2279 glRenderbufferStorage(GL_RENDERBUFFER, FW_GL_DEPTH_COMPONENT, self->ivport.W, self->ivport.H);
2281 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2284 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->itexturebuffer, 0);
2287 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self->idepthbuffer);
2289 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2293void stage_resize(
void *_self,
int width,
int height){
2295 self = (
stage*)_self;
2296 if(self->type == STAGETYPE_FBO){
2297 if(width != self->ivport.W || height != self->ivport.H){
2298 self->ivport.W = width;
2299 self->ivport.H = height;
2300 glBindTexture(GL_TEXTURE_2D, self->itexturebuffer);
2301 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->ivport.W, self->ivport.H, 0, GL_RGBA , GL_UNSIGNED_BYTE, NULL);
2303 glBindTexture(GL_TEXTURE_2D, 0);
2305 glBindRenderbuffer(GL_RENDERBUFFER, self->idepthbuffer);
2306 glRenderbufferStorage(GL_RENDERBUFFER, FW_GL_DEPTH_COMPONENT, self->ivport.W, self->ivport.H);
2309 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2312 glBindFramebuffer(GL_FRAMEBUFFER, self->ibuffer);
2314 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->itexturebuffer, 0);
2317 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self->idepthbuffer);
2319 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2326 self->ivport.W = width;
2327 self->ivport.H = height;
2335 int nx, ny, nelements, nvert;
2337 GLfloat *vert, *vert2, *tex, *norm, dx, tx;
2339 int usingDistortions;
2343void render_texturegrid(
void *_self);
2344void texturegrid_render(
void *_self){
2347 pushnset_viewport(self->t1.viewport);
2348 c = self->t1.contents;
2351 if(c->t1.itype == CONTENT_STAGE){
2357 vpstack = (
Stack*)gglobal()->Mainloop._vportstack;
2358 ivport = stack_top(
ivec4,vpstack);
2359 if(s->ivport.W != ivport.W || s->ivport.H != ivport.H)
2360 stage_resize(c,ivport.W,ivport.H);
2365 render_texturegrid(_self);
2368static GLfloat matrixIdentity[] = {
2369 1.0f, 0.0f, 0.0f, 0.0f,
2370 0.0f, 1.0f, 0.0f, 0.0f,
2371 0.0f, 0.0f, 1.0f, 0.0f,
2372 0.0f, 0.0f, 0.0f, 1.0f
2374int texturegrid_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex);
2375contenttype *new_contenttype_texturegrid(
int nx,
int ny){
2377 register_contenttype(self);
2378 init_tcontenttype(&self->t1);
2379 self->t1.itype = CONTENT_TEXTUREGRID;
2380 self->t1.render = texturegrid_render;
2381 self->t1.pick = texturegrid_pick;
2390 GLfloat *vert, *vert2, *tex, *norm;
2391 GLfloat dx,dy, tx,ty;
2393 index = (GLushort*)MALLOCV((nx-1)*(ny-1)*2*3 *
sizeof(GLushort));
2394 vert = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2395 vert2 = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2396 tex = (GLfloat*)MALLOCV(nx*ny*2*
sizeof(GLfloat));
2397 norm = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2398 register_contenttype(index);
2399 register_contenttype(vert);
2400 register_contenttype(vert2);
2401 register_contenttype(tex);
2402 register_contenttype(norm);
2405 dx = 2.0f / (float)(nx-1);
2406 dy = 2.0f / (float)(ny-1);
2407 tx = 1.0f / (float)(nx-1);
2408 ty = 1.0f / (float)(ny-1);
2411 vert[(i*nx + j)*3 + 0] = -1.0f + j*dy;
2412 vert[(i*nx + j)*3 + 1] = -1.0f + i*dx;
2413 vert[(i*nx + j)*3 + 2] = 0.0f;
2414 tex[(i*nx + j)*2 + 0] = 0.0f + j*ty;
2415 tex[(i*nx + j)*2 + 1] = 0.0f + i*tx;
2416 norm[(i*nx + j)*3 + 0] = 0.0f;
2417 norm[(i*nx + j)*3 + 1] = 0.0f;
2418 norm[(i*nx + j)*3 + 2] = 1.0f;
2425 for(j=0;j<ny-1;j++){
2427 index[k++] = i*nx + j;
2428 index[k++] = i*nx + j + 1;
2429 index[k++] = (i+1)*nx + j + 1;
2431 index[k++] = i*nx + j;
2432 index[k++] = (i+1)*nx + j + 1;
2433 index[k++] = (i+1)*nx + j;
2435 self->index = index;
2439 self->vert2 = vert2;
2440 self->nelements = k;
2441 self->nvert = nx*ny;
2443 for(i=0;i<self->nvert;i++){
2444 self->vert2[i*3 +0] = self->vert[i*3 +0];
2445 self->vert2[i*3 +1] = self->vert[i*3 +1];
2446 self->vert2[i*3 +2] = self->vert[i*3 +2];
2451void texturegrid_barrel_distort(
void *_self,
float k1){
2458 for(i=0;i<self->nvert;i++){
2459 float radius2, x, y;
2460 x = self->vert[i*3 +0];
2461 y = self->vert[i*3 +1];
2462 radius2 = x*x + y*y;
2463 self->vert2[i*3 +0] = x*(1.0f - k1*radius2);
2464 self->vert2[i*3 +1] = y*(1.0f - k1*radius2);
2472 float aspect, scale, xshift, yshift;
2479 for(i=0;i<self->nvert;i++){
2480 self->vert2[i*3 +0] += xshift;
2481 self->vert2[i*3 +1] += yshift;
2482 self->vert2[i*3 +0] *= 1.0;
2483 self->vert2[i*3 +1] *= aspect;
2484 self->vert2[i*3 +0] *= scale;
2485 self->vert2[i*3 +1] *= scale;
2486 self->vert2[i*3 +2] = self->vert[i*3 +2];
2492void texturegrid_barrel_distort2(
void *_self,
float xc,
float k1){
2502 float xc2 = xc * 2.0f - 1.0f;
2503 for(i=0;i<self->nvert;i++){
2504 float radius2, x, y;;
2505 x = self->vert[i*3 +0];
2506 y = self->vert[i*3 +1];
2507 radius2 = (x-xc2)*(x-xc2) + y*y;
2508 self->vert2[i*3 +0] = x*(1.0f - k1*radius2);
2509 self->vert2[i*3 +1] = y*(1.0f - k1*radius2);
2513 self->usingDistortions = TRUE;
2516void texturegrid_barrel_undistort2(
void *_self,
ivec4 vport,
ivec2 *xy){
2527 x = (float)(xy->X - vport.X) / (float)vport.W;
2528 y = (float)(xy->Y - vport.Y) / (float)vport.H;
2534 float xb, yb, xa,ya, deltax, deltay, xc2, k1, tolerance;
2541 radius2 = (xb-xc2)*(xb-xc2) + yb*yb;
2542 xa = xb*(1.0f - k1*radius2);
2543 ya = yb*(1.0f - k1*radius2);
2548 if(fabs(deltax) + fabs(deltay) < tolerance )
break;
2555 xy->X = (int)(x*vport.W) + vport.X;
2556 xy->Y = (int)(y*vport.H) + vport.Y;
2558int texturegrid_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2566 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2572 ivport = get_current_viewport();
2580 if(self->usingDistortions) texturegrid_barrel_undistort2(self, ivport, &xy );
2583 c = self->t1.contents;
2585 iret = c->t1.pick(c,mev,butnum,x,y,ID, windex);
2593#include "../scenegraph/Component_Shape.h"
2594void render_texturegrid(
void *_self){
2596 int useMip,haveTexture;
2598 GLint positionLoc, texCoordLoc, textureLoc;
2599 GLint textureMatrix0;
2604 haveTexture = FALSE;
2605 if(self->t1.contents && self->t1.contents->t1.itype == CONTENT_STAGE){
2607 if(s->type == STAGETYPE_FBO){
2608 textureID = s->itexturebuffer;
2612 if(!haveTexture)
return;
2615 FW_GL_DEPTHMASK(GL_FALSE);
2616 glDisable(GL_DEPTH_TEST);
2656 scap = getMyShader(ONE_TEX_APPEARANCE_SHADER);
2657 enableGlobalShader(scap);
2658 positionLoc = scap->Vertices;
2659 glVertexAttribPointer (positionLoc, 3, GL_FLOAT,
2660 GL_FALSE, 0, self->vert2 );
2662 texCoordLoc = scap->TexCoords[0];
2663 glVertexAttribPointer ( texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex );
2664 glEnableVertexAttribArray (positionLoc );
2665 glEnableVertexAttribArray ( texCoordLoc);
2668 glActiveTexture ( GL_TEXTURE0 );
2669 glBindTexture ( GL_TEXTURE_2D, textureID );
2672 glGenerateMipmap(GL_TEXTURE_2D);
2676 textureLoc = scap->TextureUnit[0];
2677 textureMatrix0 = scap->TextureMatrix[0];
2678 glUniformMatrix4fv(textureMatrix0, 1, GL_FALSE, matrixIdentity);
2680 glUniform1i ( textureLoc, 0 );
2685 glUniformMatrix4fv(scap->ProjectionMatrix, 1, GL_FALSE, matrixIdentity);
2687 glUniformMatrix4fv(scap->ModelViewMatrix, 1, GL_FALSE, matrixIdentity);
2690 glDrawArrays(GL_TRIANGLES,0,self->nelements);
2692 glDrawElements(GL_TRIANGLES,self->nelements,GL_UNSIGNED_SHORT,self->index);
2695 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
2696 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
2698 restoreGlobalShader();
2699 FW_GL_DEPTHMASK(GL_TRUE);
2700 glEnable(GL_DEPTH_TEST);
2708 int nx, ny, nelements, nvert;
2710 GLfloat *vert, *vert2, *tex, *norm, dx, tx;
2714void render_orientation(
void *_self);
2715void orientation_render(
void *_self){
2718 pushnset_viewport(self->t1.viewport);
2719 c = self->t1.contents;
2722 if(c->t1.itype == CONTENT_STAGE){
2724 int fbowidth,fboheight;
2730 vpstack = (
Stack*)tg->Mainloop._vportstack;
2731 ivport = stack_top(
ivec4,vpstack);
2732 switch(tg->Mainloop.screenOrientation2){
2736 fbowidth = ivport.H;
2737 fboheight = ivport.W;
2743 fbowidth = ivport.W;
2744 fboheight = ivport.H;
2748 if(s->ivport.W != fbowidth || s->ivport.H != fboheight)
2749 stage_resize(c,fbowidth,fboheight);
2754 render_orientation(_self);
2759int orientation_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2766 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2770 ivport = stack_top(
ivec4,(
Stack*)tg->Mainloop._vportstack);
2771 switch(tg->Mainloop.screenOrientation2){
2773 x = ivport.H - mouseY;
2777 x = ivport.W - mouseX;
2778 y = ivport.H - mouseY;
2782 y = ivport.W - mouseX;
2792 c = self->t1.contents;
2794 iret = c->t1.pick(c,mev,butnum,x,y,ID, windex);
2802void render_orientation(
void *_self);
2807GLfloat quad1Vert[] = {
2813GLfloat quad1Tex[] = {
2819GLushort quad1TriangleInd[] = {
2825 register_contenttype(self);
2826 init_tcontenttype(&self->t1);
2827 self->t1.itype = CONTENT_ORIENTATION;
2828 self->t1.render = orientation_render;
2829 self->t1.pick = orientation_pick;
2834 self->vert = quad1Vert;
2835 self->tex = quad1Tex;
2836 self->index = quad1TriangleInd;
2837 self->nelements = 6;
2843static GLfloat matrix180[] = {
2844 -1.f, 0.0f, 0.0f, 0.0f,
2845 0.0f,-1.0f, 0.0f, 0.0f,
2846 0.0f, 0.0f, 1.0f, 0.0f,
2847 0.0f, 0.0f, 0.0f, 1.0f
2849static GLfloat matrix270[] = {
2850 0.0f, 1.0f, 0.0f, 0.0f,
2851 -1.f, 0.0f, 0.0f, 0.0f,
2852 0.0f, 0.0f, 1.0f, 0.0f,
2853 0.0f, 0.0f, 0.0f, 1.0f
2855static GLfloat matrix90[] = {
2856 0.0f, -1.0f, 0.0f, 0.0f,
2857 1.0f, 0.0f, 0.0f, 0.0f,
2858 0.0f, 0.0f, 1.0f, 0.0f,
2859 0.0f, 0.0f, 0.0f, 1.0f
2863unsigned int getCircleCursorTextureID();
2864void render_orientation(
void *_self){
2867 GLint positionLoc, texCoordLoc, textureLoc;
2868 GLint textureMatrix0;
2870 float *orientationMatrix;
2874 haveTexture = FALSE;
2875 if(self->t1.contents && self->t1.contents->t1.itype == CONTENT_STAGE){
2877 if(s->type == STAGETYPE_FBO){
2879 textureID = s->itexturebuffer;
2889 switch(gglobal()->Mainloop.screenOrientation2){
2891 orientationMatrix = matrix180;
2894 orientationMatrix = matrix270;
2897 orientationMatrix = matrix90;
2903 orientationMatrix = matrixIdentity;
2907 FW_GL_DEPTHMASK(GL_FALSE);
2908 glDisable(GL_DEPTH_TEST);
2914 scap = getMyShader(ONE_TEX_APPEARANCE_SHADER);
2915 enableGlobalShader(scap);
2916 positionLoc = scap->Vertices;
2917 glVertexAttribPointer (positionLoc, 3, GL_FLOAT,
2918 GL_FALSE, 0, self->vert );
2920 texCoordLoc = scap->TexCoords[0];
2921 glVertexAttribPointer ( texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex );
2922 glEnableVertexAttribArray (positionLoc );
2923 glEnableVertexAttribArray ( texCoordLoc);
2926 glActiveTexture ( GL_TEXTURE0 );
2927 glBindTexture ( GL_TEXTURE_2D, textureID );
2930 textureLoc = scap->TextureUnit[0];
2931 textureMatrix0 = scap->TextureMatrix[0];
2932 glUniformMatrix4fv(textureMatrix0, 1, GL_FALSE, matrixIdentity);
2934 glUniform1i ( textureLoc, 0 );
2939 glUniformMatrix4fv(scap->ProjectionMatrix, 1, GL_FALSE, matrixIdentity);
2940 glUniformMatrix4fv(scap->ModelViewMatrix, 1, GL_FALSE, orientationMatrix);
2943 glDrawElements(GL_TRIANGLES, self->nelements, GL_UNSIGNED_SHORT, self->index);
2946 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
2947 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
2949 restoreGlobalShader();
2950 FW_GL_DEPTHMASK(GL_TRUE);
2951 glEnable(GL_DEPTH_TEST);
2959int frame_increment_even_odd_frame_count(
int ieo){
2961 ieo = ieo > 1 ? 0 : 1;
2975void init_targetwindow(
void *_self){
2979 self->swapbuf = TRUE;
3009 char* PluginFullPath;
3014 struct Vector *SensorEvents;
3017 GLint viewPort2[10];
3018 GLint viewpointScreenX[2], viewpointScreenY[2];
3024 double BrowserStartTime;
3025 double BrowserInitTime;
3028 int keypress_wait_for_settle;
3029 char * keypress_string;
3031 unsigned int loop_count;
3033 unsigned int slowloop_count;
3034 unsigned int total_loop_count;
3043 unsigned int currentTouch;
3044 struct Touch touchlist[20];
3045 int EMULATE_MULTITOUCH;
3052 int draw_initialized;
3054 char keywaitstring[25];
3055 int fps_sleep_remainder;
3056 double screenorientationmatrix[16];
3057 double viewtransformmatrix[16];
3058 double posorimatrix[16];
3059 double stereooffsetmatrix[2][16];
3060 int targets_initialized;
3062 void *hyper_switch[4];
3068 Stack *_framebufferstack;
3069 struct Vector *contenttype_registry;
3074void *Mainloop_constructor(){
3075 void *v = MALLOCV(
sizeof(
struct pMainloop));
3079void Mainloop_init(
struct tMainloop *t){
3082 t->gl_linewidth= 1.0f;
3085 t->BrowserFPS = 100.0;
3086 t->BrowserSpeed = 0.0;
3087 t->BrowserDescription =
"libfreewrl opensource virtual reality player library";
3088 t->trisThisLoop = 0;
3091 t->currentFileVersion = 0;
3093 t->HaveSensitive = FALSE;
3098 t->tmpFileLocation = MALLOC(
char *, 5);
3099 strcpy(t->tmpFileLocation,
"/tmp");
3100 t->replaceWorldRequest = NULL;
3101 t->replaceWorldRequestMulti = NULL;
3103 t->prv = Mainloop_constructor();
3112 p->doEvents = FALSE;
3119 p->SensorEvents = newVector(
struct SensStruct *,0);
3121 p->bufferarray[0] = FW_GL_BACK;
3122 p->bufferarray[1] = 0;
3125 p->BrowserInitTime = 0.0;
3128 p->keypress_wait_for_settle = 100;
3129 p->keypress_string=NULL;
3133 p->slowloop_count = 0;
3144 p->currentTouch = 0;
3146 p->EMULATE_MULTITOUCH = 0;
3147 memset(p->touchlist,0,20*
sizeof(
struct Touch));
3154 p->keySensorMode = 1;
3155 p->draw_initialized = FALSE;
3157 p->keywaitstring[0] = (char)0;
3158 p->fps_sleep_remainder = 0;
3161 p->targets_initialized = 0;
3162 for(i=0;i<4;i++) init_targetwindow(&p->cwindows[i]);
3164 p->_vportstack = newStack(
ivec4);
3165 t->_vportstack = (
void *)p->_vportstack;
3166 p->_stagestack = newStack(
void*);
3167 t->_stagestack = (
void *)p->_stagestack;
3168 p->_framebufferstack = newStack(
int);
3169 t->_framebufferstack = (
void*)p->_framebufferstack;
3170 stack_push(
int,p->_framebufferstack,FW_GL_BACK);
3171 p->contenttype_registry = NULL;
3174 memset(&p->pedalstate,0,
sizeof(
struct pedal_state));
3177void Mainloop_clear(
struct tMainloop *t){
3178 FREE_IF_NZ(t->scene_name);
3179 FREE_IF_NZ(t->scene_suff);
3180 FREE_IF_NZ(t->replaceWorldRequest);
3181 FREE_IF_NZ(t->tmpFileLocation);
3185 for(k=0;k<vectorSize(p->SensorEvents);k++){
3189 deleteVector(
struct SensStruct*,p->SensorEvents);
3190 deleteVector(
ivec4,p->_vportstack);
3191 deleteVector(
void*,p->_stagestack);
3192 deleteVector(
int,p->_framebufferstack);
3193 free_contenttypes();
3194 deleteVector(
contenttype*,p->contenttype_registry);
3206int fwl_hwnd_to_windex(
void *hWnd){
3216 if(!targets[i].hwnd){
3218 targets[i].hwnd = hWnd;
3219 targets[i].swapbuf = TRUE;
3221 if(targets[i].hwnd == hWnd)
return i;
3226void get_view_matrix(
double *savePosOri,
double *saveView) {
3235 bstack = getActiveBindableStacks(tg);
3236 matcopy(saveView,bstack->viewtransformmatrix);
3237 matcopy(savePosOri,bstack->posorimatrix);
3240static void set_view_matrix(
double *savePosOri,
double *saveView){
3246 matcopy(p->viewtransformmatrix,saveView);
3247 matcopy(p->posorimatrix,savePosOri);
3250 bstack = getActiveBindableStacks(tg);
3251 matcopy(bstack->viewtransformmatrix,saveView);
3252 matcopy(bstack->posorimatrix,savePosOri);
3257void fwl_getWindowSize(
int *width,
int *height){
3262 *width = tg->display.screenWidth;
3263 *height = tg->display.screenHeight;
3266void fwl_getWindowSize1(
int windex,
int *width,
int *height){
3274 ivport = p->cwindows[windex].ivport;
3281int isBrowserPlugin = FALSE;
3282void fwl_set_emulate_multitouch(
int ion){
3284 p->EMULATE_MULTITOUCH = ion;
3290int fwl_get_emulate_multitouch(){
3292 return p->EMULATE_MULTITOUCH;
3310#define SEND_BIND_IF_REQUIRED(node) \
3311 if (node != NULL) { send_bind_to(X3D_NODE(node),1); node = NULL; }
3315void setup_viewpoint();
3316void set_viewmatrix();
3319static void sendDescriptionToStatusBar(
struct X3D_Node *CursorOverSensitive);
3321void render_collisions(
int Viewer_type);
3322int slerp_viewpoint2();
3323int slerp_viewpoint3();
3324static void render_pre(
void);
3326static int setup_pickside(
int x,
int y);
3327void setup_projection();
3328void setup_pickray(
int x,
int y);
3330void get_hyperhit(
void);
3331static void sendSensorEvents(
struct X3D_Node *COS,
int ev,
int butStatus,
int status);
3333void activate_OSCsensors();
3345#if !defined(_MSC_VER)
3348double Time1970sec(
void) {
3349 struct timeval mytime;
3350 gettimeofday(&mytime, NULL);
3351 return (
double) mytime.tv_sec + (double)mytime.tv_usec/1000000.0;
3358#define DJ_KEEP_COMPILER_WARNING 0
3359#if DJ_KEEP_COMPILER_WARNING
3360#define TI(_tv) gettimeofdat(&_tv)
3361#define TID(_tv) ((double)_tv.tv_sec + (double)_tv.tv_usec/1000000.0)
3366void fwl_do_keyPress0(
int key,
int type);
3367void handle0(
const int mev,
const unsigned int button,
const float x,
const float y);
3368void fwl_handle_aqua_multi(
const int mev,
const unsigned int button,
int x,
int y,
int ID,
int windex);
3370void fwl_RenderSceneUpdateScene0(
double dtime);
3371void splitpath_local_suffix(
const char *url,
char **local_name,
char **suff);
3373void fwl_gotoCurrentViewPoint()
3375 struct tProdCon *t = &gglobal()->ProdCon;
3378 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes, t->currboundvpno),cn);
3384 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,t->viewpointNodes, t->currboundvpno);
3391 printf(
"exiting with value=%d hit Enter:",val);
3396void render_statusbar0(
void){
3397 #if defined(STATUSBAR_HUD)
3399 finishedWithGlobalShader();
3401 restoreGlobalShader();
3439void fwl_RenderSceneUpdateSceneNORMAL() {
3444 dtime = Time1970sec();
3445 fwl_RenderSceneUpdateScene0(dtime);
3454ivec4 childViewport(
ivec4 parentViewport,
float *clipBoundary);
3503 twindows = p->cwindows;
3504 twindows[itargetwindow].params = *params;
3505 if(itargetwindow > 0){
3506 twindows[itargetwindow -1].next = &twindows[itargetwindow];
3508 p->nwindow = max(p->nwindow,itargetwindow+1);
3512 printf(
"windex=%d t->next = %p\n",itargetwindow,t->next);
3515 printf(
"hows that?\n");
3523 twindows = p->cwindows;
3524 return &twindows[itargetwindow].params;
3527void fwl_setScreenDim1(
int wi,
int he,
int itargetwindow){
3538 twindows = p->cwindows;
3539 twindows[itargetwindow].ivport = window_rect;
3546void register_contenttype(
void *ct){
3549 if(!p->contenttype_registry)
3550 p->contenttype_registry = newVector(
void *,4);
3556 vector_pushBack(
void*,p->contenttype_registry,ct);
3559void free_contenttypes(){
3562 if(p->contenttype_registry){
3564 for(i=0;i<p->contenttype_registry->n;i++){
3566 ct = vector_get(
void*,p->contenttype_registry,i);
3575void setup_stagesNORMAL(){
3585 for(i=0;i<p->nwindow;i++){
3593 if(t->params.context != dp->context){
3594 tg->display.params = (
void*)&t->params;
3599 cstage = new_contenttype_stage();
3600 cswitch = new_contenttype_switch();
3601 p->hyper_switch[i] = cswitch;
3602 cstage->t1.contents = cswitch;
3603 last = &cswitch->t1.contents;
3605 p->hyper_case[i] = 8;
3607 p->EMULATE_MULTITOUCH = FALSE;
3614 csbh = new_contenttype_statusbar();
3615 cscene = new_contenttype_scene();
3617 csbh->t1.contents = cscene;
3620 last = &csbh->t1.next;
3628 cmultitouch = new_contenttype_multitouch();
3629 cscene = new_contenttype_scene();
3630 csbh = new_contenttype_statusbar();
3632 cmultitouch->t1.contents = csbh;
3633 csbh->t1.contents = cscene;
3635 *last = cmultitouch;
3636 last = &cmultitouch->t1.next;
3637 p->EMULATE_MULTITOUCH = TRUE;
3646 csbh = new_contenttype_statusbar();
3647 cscene = new_contenttype_scene();
3648 ctextpanel = new_contenttype_textpanel(
"VeraMono",8,60,120,TRUE);
3649 ccolor = vec4_init(1.0f,.6f,0.0f,1.0f);
3650 ctext = new_contenttype_captiontext(
"VeraMono",12,ccolor);
3654 captiontext_setString(ctext,
"ABCDEDFGHIJKLMNOPQRSTUVWXYZabcd");
3655 ctext->t1.viewport[0] = .1f;
3656 ctext->t1.viewport[1] = .6f;
3657 ctext->t1.viewport[2] = 1.0f;
3658 ctext->t1.viewport[3] = .5f;
3661 textpanel_register_as_console(ctextpanel);
3664 csbh->t1.contents = ctextpanel;
3665 ctextpanel->t1.contents = cscene;
3666 ctextpanel->t1.next = ctext;
3669 last = &csbh->t1.next;
3677 csbh = new_contenttype_statusbar();
3678 ccolor = vec4_init(1.0f,.6f,0.0f,1.0f);
3680 ctext = new_contenttype_captiontext(
"freewrl_wingding",10,ccolor);
3682 cscene = new_contenttype_scene();
3691 captiontext_setString(ctext,
"abcdABCDEDFGHIJKLMNOPQRSTUVWXYZ");
3693 ctext->t1.viewport[0] = .1f;
3694 ctext->t1.viewport[1] = .6f;
3695 ctext->t1.viewport[2] = .4f;
3696 ctext->t1.viewport[3] = .5f;
3698 csbh->t1.contents = cscene;
3699 cscene->t1.next = ctext;
3702 last = &csbh->t1.next;
3709 csbh = new_contenttype_statusbar();
3710 ce3dmouse = new_contenttype_e3dmouse();
3712 cscene = new_contenttype_scene();
3714 csbh->t1.contents = ce3dmouse;
3715 ce3dmouse->t1.contents = cscene;
3716 cscene->t1.next = NULL;
3718 last = &csbh->t1.next;
3724 contenttype *csbh, *cscene, *cstagefbo, *ctexturegrid, *cmultitouch;
3726 cmultitouch = new_contenttype_multitouch();
3727 ctexturegrid = new_contenttype_texturegrid(2,2);
3728 cstagefbo = new_contenttype_stagefbo(512,512);
3729 csbh = new_contenttype_statusbar();
3730 cscene = new_contenttype_scene();
3732 cmultitouch->t1.contents = ctexturegrid;
3733 ctexturegrid->t1.contents = cstagefbo;
3734 cstagefbo->t1.contents = csbh;
3735 csbh->t1.contents = cscene;
3737 *last = cmultitouch;
3738 last = &cmultitouch->t1.next;
3743 contenttype *csbh, *cscene, *corientation, *cmultitouch, *cstagefbo;
3745 cmultitouch = new_contenttype_multitouch();
3746 corientation = new_contenttype_orientation();
3747 cstagefbo = new_contenttype_stagefbo(512,512);
3748 csbh = new_contenttype_statusbar();
3749 cscene = new_contenttype_scene();
3751 cmultitouch->t1.contents = corientation;
3752 corientation->t1.contents = cstagefbo;
3753 cstagefbo->t1.contents = csbh;
3754 csbh->t1.contents = cscene;
3756 *last = cmultitouch;
3757 last = &cmultitouch->t1.next;
3763 contenttype *csbh, *cscene, *corientation, *cmultitouch, *cstagefbo;
3765 cmultitouch = new_contenttype_multitouch();
3766 csbh = new_contenttype_statusbar();
3767 corientation = new_contenttype_orientation();
3768 cstagefbo = new_contenttype_stagefbo(512,512);
3769 cscene = new_contenttype_scene();
3771 cmultitouch->t1.contents = csbh;
3772 csbh->t1.contents = corientation;
3773 corientation->t1.contents = cstagefbo;
3774 cstagefbo->t1.contents = cscene;
3776 *last = cmultitouch;
3777 last = &cmultitouch->t1.next;
3783 contenttype *cstereo1, *cstereo2, *cstereo3, *cstereo4, *cswitch0;
3786 csbh = new_contenttype_statusbar();
3787 ctextpanel = new_contenttype_textpanel(
"VeraMono",8,60,120,TRUE);
3788 cswitch0 = new_contenttype_switch();
3789 cstereo1 = new_contenttype_stereo_shutter();
3790 cstereo2 = new_contenttype_stereo_sidebyside();
3791 cstereo3 = new_contenttype_stereo_anaglyph();
3792 cstereo4 = new_contenttype_stereo_updown();
3794 contenttype_switch_set_which_ptr(cswitch0,&tg->Viewer.stereotype);
3798 cscene0 = new_contenttype_scene();
3799 cscene1 = new_contenttype_scene();
3800 cscene0->t1.next = cscene1;
3802 cscene2 = new_contenttype_scene();
3806 textpanel_register_as_console(ctextpanel);
3809 csbh->t1.contents = ctextpanel;
3810 ctextpanel->t1.contents = cswitch0;
3811 cswitch0->t1.contents = cscene2;
3812 cscene2->t1.next = cstereo1;
3813 cstereo1->t1.contents = cscene0;
3814 cstereo2->t1.contents = cscene0;
3815 cstereo3->t1.contents = cscene0;
3816 cstereo4->t1.contents = cscene0;
3817 cstereo1->t1.next = cstereo2;
3818 cstereo2->t1.next = cstereo3;
3819 cstereo3->t1.next = cstereo4;
3822 last = &csbh->t1.next;
3833 csbh = new_contenttype_statusbar();
3834 cstereo = new_contenttype_stereo_sidebyside();
3836 cstagefbo0 = new_contenttype_stagefbo(512,512);
3837 ctexturegrid0 = new_contenttype_texturegrid(5,5);
3839 cstagefbo1 = new_contenttype_stagefbo(512,512);
3840 ctexturegrid1 = new_contenttype_texturegrid(5,5);
3841 cscene0 = new_contenttype_scene();
3842 cscene1 = new_contenttype_scene();
3850 xc = 1.0f - (float)
viewer->screendist;
3851 texturegrid_barrel_distort2(ctexturegrid0, xc,.1f);
3852 xc = (float)
viewer->screendist;
3853 texturegrid_barrel_distort2(ctexturegrid1, xc,.1f);
3857 csbh->t1.contents = cstereo;
3858 cstereo->t1.contents = ctexturegrid0;
3859 ctexturegrid0->t1.next = ctexturegrid1;
3860 ctexturegrid0->t1.contents = cstagefbo0;
3861 ctexturegrid1->t1.contents = cstagefbo1;
3862 cstagefbo0->t1.contents = cscene0;
3863 cstagefbo1->t1.contents = cscene1;
3866 last = &csbh->t1.next;
3871 contenttype *cscene0, *cscene1, *cscene2, *cscene3;
3874 csbh = new_contenttype_statusbar();
3875 cquadrant = new_contenttype_quadrant();
3877 cscene0 = new_contenttype_scene();
3878 cscene1 = new_contenttype_scene();
3879 cscene2 = new_contenttype_scene();
3880 cscene3 = new_contenttype_scene();
3882 csbh->t1.contents = cquadrant;
3883 cquadrant->t1.contents = cscene0;
3884 cscene0->t1.next = cscene1;
3885 cscene1->t1.next = cscene2;
3886 cscene2->t1.next = cscene3;
3889 last = &csbh->t1.next;
3897int fwl_hyper_option(
char *val){
3906 if(iopt >= 0 && iopt <=10)
3907 for(i=0;i<p->nwindow;i++){
3908 p->hyper_case[i] = iopt;
3912void initialize_targets_simple(){
3920 setup_stagesNORMAL();
3924 p->targets_initialized = 1;
3927void update_navigation();
3928void fwl_lockTestMutex();
3929void fwl_unlockTestMutex();
3932void fwl_RenderSceneUpdateSceneTARGETWINDOWS() {
3943 if(!p->targets_initialized)
3944 initialize_targets_simple();
3946 dtime = Time1970sec();
3948 vportstack = (
Stack *)tg->Mainloop._vportstack;
3949 defaultvport = ivec4_init(0,0,100,100);
3950 pushviewport(vportstack,defaultvport);
3952 fwl_RenderSceneUpdateScene0(dtime);
3953 popviewport(vportstack);
3961 static double starttime = 0.0;
3962 if(starttime == 0.0) starttime = dtime;
3963 if(dtime - starttime < 2.0)
return;
3966 for(i=0;i<p->nwindow;i++){
3973 hyper_switch = p->hyper_switch[i];
3974 hyper_case = p->hyper_case[i];
3975 contenttype_switch_set_which(hyper_switch,hyper_case);
3980 s = (
stage*)(t->stage);
3981 if(s->type == STAGETYPE_BACKBUF){
3982 s->ivport = t->ivport;
3987 fwl_setScreenDim0(s->ivport.W, s->ivport.H);
3989 if(t->params.context != dp->context){
3990 tg->display.params = (
void*)&t->params;
3995 vportstack = (
Stack *)tg->Mainloop._vportstack;
3996 pushviewport(vportstack,t->ivport);
3999 popviewport(vportstack);
4001 if(t->swapbuf) { FW_GL_SWAPBUFFERS }
4009int fwl_handle_mouse_multi_yup(
int mev,
int butnum,
int mouseX,
int yup,
unsigned int ID,
int windex){
4018 if (mev == MotionNotify) butnum = 0;
4020 t = &p->cwindows[windex];
4021 s = (
stage*)t->stage;
4023 if(s->type == STAGETYPE_BACKBUF)
4024 s->ivport = t->ivport;
4025 vportstack = (
Stack *)tg->Mainloop._vportstack;
4026 pushviewport(vportstack,s->ivport);
4027 ihit = s->t1.pick(s,mev,butnum,mouseX,yup,ID,windex);
4028 popviewport(vportstack);
4032void emulate_multitouch(
int mev,
unsigned int button,
int x,
int ydown,
int windex)
4039 struct Touch *touch;
4040 static int buttons[4] = {0,0,0,0};
4041 static int idone = 0;
4047 t = &p->cwindows[windex];
4050 y = t->ivport.H - ydown;
4053 printf(
"Use RMB (right mouse button) to create and delete touches\n");
4054 printf(
"Use LMB to drag touches (+- 5 pixel selection window)\n");
4057 buttons[button] = mev == ButtonPress;
4062 for(i=0;i<p->ntouch;i++){
4063 touch = &p->touchlist[i];
4065 if(touch->windex == windex && touch->stageId == current_stageId())
4066 if((abs(x - touch->rx) < 10) && (abs(y - touch->ry) < 10)){
4074 if( mev == ButtonPress && button == RMB )
4077 if(ifound && touch){
4078 fwl_handle_mouse_multi_yup(ButtonRelease,LMB,x,y,ID,windex);
4081 printf(
"delete ID=%d windex=%d\n",ID,windex);
4086 for(i=0;i<p->ntouch;i++){
4087 touch = &p->touchlist[i];
4089 fwl_handle_mouse_multi_yup(mev, LMB, x, y, i,windex);
4092 printf(
"create ID=%d windex=%d\n",i,windex);
4097 }
else if( mev == MotionNotify && buttons[LMB]) {
4100 fwl_handle_mouse_multi_yup(MotionNotify,0,x,y,ID,windex);
4101 touch = &p->touchlist[ID];
4126void render_multitouch2(
struct Touch *touchlist,
int ntouch){
4131 if(p->EMULATE_MULTITOUCH) {
4133 for(i=0;i<ntouch;i++){
4134 if(touchlist[i].ID > -1)
4135 if(touchlist[i].windex == p->windex )
4137 struct Touch *touch;
4138 touch = &touchlist[i];
4139 cursorDraw(touch->ID,touch->rx,touch->ry,touch->angle);
4144void record_multitouch(
struct Touch *touchlist,
int mev,
int butnum,
int mouseX,
int mouseY,
int ID,
int windex,
int ihandle){
4145 struct Touch *touch;
4150 touch = &touchlist[ID];
4156 touch->windex = windex;
4157 touch->stageId = current_stageId();
4158 touch->buttonState = mev == ButtonPress;
4161 touch->angle = 0.0f;
4167int emulate_multitouch2(
struct Touch *touchlist,
int ntouch,
int *IDD,
int *lastbut,
int *mev,
unsigned int *button,
int x,
int y,
int *ID,
int windex)
4174 struct Touch *touch;
4175 static int idone = 0;
4181 printf(
"Use RMB (right mouse button) to create and delete touches\n");
4182 printf(
"Use LMB to drag touches (+- 5 pixel selection window)\n");
4188 if(*mev == ButtonPress && (*button == LMB || *button == RMB)){
4192 for(i=0;i<ntouch;i++){
4193 touch = &touchlist[i];
4195 if(touch->windex == windex )
4196 if((abs(x - touch->rx) < 10) && (abs(y - touch->ry) < 10)){
4198 printf(
"drag found ID %d\n",*IDD);
4205 if(*lastbut == LMB){
4206 if( *mev == MotionNotify ) {
4210 *mev = MotionNotify;
4214 touch = &touchlist[*IDD];
4217 printf(
"drag ID=%d \n",*IDD);
4219 }
else if(*mev == ButtonRelease){
4222 }
else if(*lastbut == RMB){
4223 if( *mev == ButtonPress )
4226 if(*IDD > -1 && touch){
4228 *mev = ButtonRelease;
4234 printf(
"delete ID=%d windex=%d ihandle=%d\n",*IDD,windex,ihandle);
4239 for(i=1;i<p->ntouch;i++){
4240 touch = &touchlist[i];
4241 if(touch->inUse == FALSE) {
4249 touch->inUse = TRUE;
4250 printf(
"create ID=%d windex=%d\n",i,windex);
4262int fwl_handle_mouse_multi(
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
4269 t = &p->cwindows[windex];
4272 yup = t->ivport.H - mouseY;
4273 fwl_handle_mouse_multi_yup(mev,butnum,mouseX,yup,ID,windex);
4274 return getCursorStyle();
4282void fwl_handle_mouse_window_leave() {
4294 if (targets[i].hwnd != NULL) {
4295 fwl_handle_mouse(ButtonRelease,1,0,0,i);
4296 fwl_handle_mouse(ButtonRelease,2,0,0,i);
4297 fwl_handle_mouse(ButtonRelease,3,0,0,i);
4303int fwl_handle_mouse0(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex){
4304 int cstyle, tactic_up_drag;
4305 static unsigned int ID = 1;
4321 if(!p->mouseDown && !p->mouseOver){
4323 p->mouseOver = TRUE;
4336 fwl_handle_mouse_multi(ButtonRelease, 0, mouseX, mouseY, 2, windex);
4337 p->mouseOver = FALSE;
4339 p->mouseDown = TRUE;
4344 cstyle = fwl_handle_mouse_multi(mev,butnum,mouseX,mouseY,ID,windex);
4345 if(mev == ButtonRelease){
4346 p->mouseDown = FALSE;
4350 cstyle = fwl_handle_mouse_multi(mev,butnum,mouseX,mouseY,ID,windex);
4354int(*fwl_handle_mousePTR)(
int mev,
int button,
int x,
int y,
int windex) = fwl_handle_mouse0;
4355int fwl_handle_mouse(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex) {
4356 return fwl_handle_mousePTR(mev, butnum, mouseX, mouseY, windex);
4358int fwl_handle_touch(
int mev,
unsigned int ID,
int mouseX,
int mouseY,
int windex) {
4368 cstyle = fwl_handle_mouse_multi(mev, ibut, mouseX, mouseY, ID, windex);
4374void viewer_getpose(
double *quat4,
double *vec3);
4375void viewer_setpose(
double *quat4,
double *vec3);
4376static int using_sensors_for_navigation = 1;
4377static int using_magnetic = 0;
4378static int using_gyro = 1;
4381void fwl_handle_gyro(
float rx,
float ry,
float rz) {
4382 if(using_sensors_for_navigation && using_gyro){
4383 double axyz[3], dd[3], quat4[4], vec3[3];
4384 static double dt, lasttime, curtime;
4386 static int initialized = 0;
4389 lasttime = Time1970sec();
4393 curtime = Time1970sec();
4394 dt = curtime - lasttime;
4397 viewer_getpose(quat4, vec3);
4398 double2quat(&qq0, quat4);
4399 quaternion_normalize(&qq0);
4401 axyz[0] = (double)rx;
4402 axyz[2] = -(double)ry;
4403 axyz[1] = -(double)rz;
4406 if (fabs(axyz[0]) < .01) axyz[0] = 0.0;
4407 if (fabs(axyz[1]) < .01) axyz[1] = 0.0;
4408 if (fabs(axyz[2]) < .01) axyz[2] = 0.0;
4409 vecscaled(dd, axyz, dt);
4413 euler2quat(&qq2, dd[0], dd[1], dd[2]);
4414 quaternion_multiply(&qq, &qq2, &qq0);
4415 quaternion_normalize(&qq);
4417 quat2double(quat4, &qq);
4418 viewer_setpose(quat4, vec3);
4422void fwl_handle_accelerometer(
float ax,
float ay,
float az){
4426void fwl_handle_magnetic(
float azimuth,
float pitch,
float roll) {
4427 if (using_sensors_for_navigation && using_magnetic) {
4431 double rxyz[3], dd[3], Rxyz[3], quat4[4], vec3[3];
4432 static double ddlast[3];
4434 static int initialized = 0;
4438 Rxyz[0] = (double)azimuth;
4439 Rxyz[2] = -(double)roll;
4440 Rxyz[1] = -(double)pitch;
4441 vecscaled(ddlast,ddlast,0.0);
4445 viewer_getpose(quat4, vec3);
4446 double2quat(&qq0, quat4);
4447 quaternion_normalize(&qq0);
4449 rxyz[0] = (double)azimuth;
4450 rxyz[2] = -(double)roll;
4451 rxyz[1] = -(double)pitch;
4453 vecdifd(dd,rxyz,Rxyz);
4454 vecscaled(dd, dd, .05);
4456 euler2quat(&qqlast,ddlast[0],ddlast[1],ddlast[2]);
4457 quaternion_normalize(&qqlast);
4458 quaternion_inverse(&qqlast,&qqlast);
4459 quaternion_normalize(&qqlast);
4460 quaternion_multiply(&qq0,&qqlast,&qq0);
4461 quaternion_normalize(&qq0);
4464 euler2quat(&qq2, dd[0], dd[1], dd[2]);
4465 quaternion_multiply(&qq, &qq2, &qq0);
4466 quaternion_normalize(&qq);
4468 quat2double(quat4, &qq);
4469 viewer_setpose(quat4, vec3);
4470 veccopyd(ddlast,dd);
4475OLDCODE
void fwl_handle_magnetic_old(
float azimuth,
float pitch,
float roll) {
4476OLDCODE ConsoleMessage(
"hi from handle_magnetic %f %f %f\n", azimuth, pitch, roll);
4477OLDCODE
if(using_sensors_for_navigation && using_magnetic){
4478OLDCODE
static int initialized = 0;
4479OLDCODE
static float home_azimuth = 0.0f, home_pitch = 0.0f, home_roll = 0.0f;
4480OLDCODE
static double lasttime, curtime, dt;
4483OLDCODE
float dazimuth,ddazimuth, dpitch, droll;
4484OLDCODE
double quat4[4], vec3[3], rxyz[3];
4485OLDCODE
static double ypr[3];
4486OLDCODE
static float lazimuth, lpitch, lroll;
4492OLDCODE
if(!initialized){
4493OLDCODE home_azimuth = azimuth;
4494OLDCODE home_pitch = pitch;
4495OLDCODE home_roll = roll;
4496OLDCODE lazimuth = azimuth;
4497OLDCODE lpitch = pitch;
4498OLDCODE lroll = roll;
4499OLDCODE lasttime = Time1970sec();
4500OLDCODE initialized = 1;
4502OLDCODE viewer_getpose(quat4, vec3);
4503OLDCODE double2quat(&qq0, quat4);
4504OLDCODE quaternion_normalize(&qq0);
4506OLDCODE quat2euler(ypr,0,&qq0);
4520OLDCODE curtime = Time1970sec();
4521OLDCODE dt = curtime - lasttime;
4522OLDCODE lasttime = curtime;
4525OLDCODE viewer_getpose(quat4, vec3);
4526OLDCODE double2quat(&qq0,quat4);
4527OLDCODE quaternion_normalize(&qq0);
4529OLDCODE quat2euler(ypr,0,&qq0);
4532OLDCODE dazimuth = (azimuth - home_azimuth);
4533OLDCODE ddazimuth = dazimuth - lazimuth;
4534OLDCODE lazimuth = dazimuth;
4535OLDCODE
if (fabs(ddazimuth) < .7f)
4536OLDCODE dazimuth = 0.0;
4537OLDCODE
if(fabs(ddazimuth) < 2.0f)
4538OLDCODE dazimuth = .01f * dazimuth;
4539OLDCODE
if(fabs(ddazimuth) < 10.0f)
4540OLDCODE dazimuth = .1f * dazimuth;
4542OLDCODE dpitch = (pitch - home_pitch);
4543OLDCODE droll = (roll - home_roll);
4547OLDCODE rxyz[2] = dazimuth*PI/180.0;
4548OLDCODE rxyz[1] = (50.0 - droll )*PI/50.0*dt;
4550OLDCODE rxyz[0] = 0.0;
4551OLDCODE rxyz[1] = 0.0;
4556OLDCODE euler2quat(&qq2,rxyz[0],rxyz[1],-rxyz[2]);
4557OLDCODE quaternion_multiply(&qq,&qq2,&qq0);
4558OLDCODE quaternion_normalize(&qq);
4560OLDCODE quat2double(quat4,&qq);
4561OLDCODE viewer_setpose(quat4,vec3);
4563OLDCODE home_pitch = pitch;
4570void (*fwl_RenderSceneUpdateScenePTR)() = fwl_RenderSceneUpdateSceneTARGETWINDOWS;
4579void fwl_RenderSceneUpdateScene(
void){
4581 fwl_RenderSceneUpdateScenePTR();
4583void setup_picking();
4584void setup_projection();
4585void rbp_run_physics();
4586void fwl_sendreceive_DIS();
4587void fps_histo_collect();
4588void fwl_RenderSceneUpdateScene0(
double dtime) {
4604 PRINT_GL_ERROR_IF_ANY(
"start of renderSceneUpdateScene");
4606 DEBUG_RENDER(
"start of MainLoop (parsing=%s) (url loaded=%s)\n",
4607 BOOL_STR(fwl_isinputThreadParsing()), BOOL_STR(resource_is_root_loaded()));
4610 p->doEvents = (!fwl_isinputThreadParsing()) && (!fwl_isTextureParsing()) && fwl_isInputThreadInitialized();
4614 p->BrowserStartTime = dtime;
4615 tg->Mainloop.TickTime = p->BrowserStartTime;
4616 tg->Mainloop.lastTime = tg->Mainloop.TickTime - 0.01;
4617 if(p->BrowserInitTime == 0.0)
4618 p->BrowserInitTime = dtime;
4624 static int debugg_time = FALSE;
4629 static int frame_count = 0;
4631 dtime = .02 * (double)frame_count;
4634 fps_histo_collect();
4638 if(!((
freewrl_params_t*)(tg->display.params))->frontend_handles_display_thread){
4653 double elapsed_time_per_frame, suggested_wait_time, target_time_per_frame, kludgefactor;
4654 int wait_time_micro_sec, target_frames_per_second;
4655 static int emulating_fps_stutter = 0;
4657 target_frames_per_second = fwl_get_target_fps();
4659 if(target_frames_per_second > 0){
4661 elapsed_time_per_frame = TickTime() - lastTime();
4662 if(target_frames_per_second > 0)
4663 target_time_per_frame = 1.0/(double)target_frames_per_second;
4665 target_time_per_frame = 1.0/30.0;
4666 suggested_wait_time = target_time_per_frame - elapsed_time_per_frame;
4667 suggested_wait_time *= kludgefactor;
4668 if(emulating_fps_stutter){
4669 p->total_loop_count++;
4671 if(((p->total_loop_count / 5) % 10) == 0){
4673 suggested_wait_time += .5;
4676 wait_time_micro_sec = (int)(suggested_wait_time * 1000000.0);
4677 if(wait_time_micro_sec > 1)
4678 usleep(wait_time_micro_sec);
4688 if(emulating_fps_stutter){
4689 p->total_loop_count++;
4691 if(((p->total_loop_count / 5) % 10) == 0){
4703 tg->Mainloop.lastTime = tg->Mainloop.TickTime;
4704 tg->Mainloop.TickTime = dtime;
4706 #if !defined(FRONTEND_DOES_SNAPSHOTS)
4708 if (tg->Snapshot.doSnapshot) {
4713 fwl_sendreceive_DIS();
4722 initializeAnyScripts();
4728 if (tg->RenderFuncs.BrowserAction) {
4729 tg->RenderFuncs.BrowserAction = doBrowserAction ();
4735 OcclusionStartofRenderSceneUpdateScene();
4737 startOfLoopNodeUpdates();
4739 if (p->loop_count == 25) {
4740 tg->Mainloop.BrowserFPS = 25.0 / (TickTime()-p->BrowserStartTime);
4741 setMenuFps((
float)tg->Mainloop.BrowserFPS);
4745 p->BrowserStartTime = TickTime();
4751 tg->Mainloop.trisThisLoop = 0;
4753 if(p->slowloop_count == 1009) p->slowloop_count = 0 ;
4755 if ((p->slowloop_count % 256) == 0) {
4761 activate_OSCsensors() ;
4767 p->slowloop_count++ ;
4770 if (p->keypress_string && p->doEvents) {
4771 if (p->keypress_wait_for_settle > 0) {
4772 p->keypress_wait_for_settle--;
4775 if (*p->keypress_string) {
4777#if !defined( _MSC_VER )
4778 DEBUG_XEV(
"CMD LINE GEN EVENT: %c\n", *p->keypress_string);
4779 fwl_do_keyPress(*p->keypress_string,KeyPress);
4781 p->keypress_string++;
4783 p->keypress_string=NULL;
4794#if defined(TARGET_X11)
4798 for(kw=0;kw<p->nwindow;kw++)
4800 void * xdpy = p->cwindows[kw].params.display;
4802 while(XPending(xdpy)) {
4803 XNextEvent(xdpy, &event);
4804 DEBUG_XEV(
"EVENT through XNextEvent\n");
4805 handle_Xevents(event);
4812 PRINT_GL_ERROR_IF_ANY(
"before xtdispatch");
4813#if defined(TARGET_MOTIF)
4816 frontendUpdateButtons();
4819 while (XtAppPending(Xtcx)!= 0) {
4820 XtAppNextEvent(Xtcx, &event);
4821#ifdef XEVENT_VERBOSE
4824 switch (event.type) {
4826 mev = &
event.xmotion;
4827 TRACE_MSG(
"mouse motion event: win=%u, state=%d\n",mev->window, mev->state);
4831 bev = &
event.xbutton;
4832 TRACE_MSG(
"mouse button event: win=%u, state=%d\n",bev->window, bev->state);
4837 DEBUG_XEV(
"EVENT through XtDispatchEvent\n");
4838 XtDispatchEvent (&event);
4848 PRINT_GL_ERROR_IF_ANY(
"after handle_tick")
4859 SEND_BIND_IF_REQUIRED(tg->ProdCon.setViewpointBindInRender)
4860 SEND_BIND_IF_REQUIRED(tg->ProdCon.setFogBindInRender)
4861 SEND_BIND_IF_REQUIRED(tg->ProdCon.setBackgroundBindInRender)
4862 SEND_BIND_IF_REQUIRED(tg->ProdCon.setNavigationBindInRender)
4868 process_eventsProcessed();
4870 #if !defined(EXCLUDE_EAI)
4881 int socketVerbose = fwlio_RxTx_control(CHANNEL_EAI, RxTx_GET_VERBOSITY) ;
4883 if ( socketVerbose <= 1 || (socketVerbose > 1 && ((p->slowloop_count % 256) == 0)) ) {
4884 if(fwlio_RxTx_control(CHANNEL_EAI, RxTx_REFRESH) == 0) {
4886 if ( socketVerbose > 1 ) {
4887 printf(
"%s:%d Nothing to be done\n",__FILE__,__LINE__) ;
4890 if ( socketVerbose > 1 ) {
4891 printf(
"%s:%d Test RxTx_PENDING\n",__FILE__,__LINE__) ;
4893 if(fwlio_RxTx_control(CHANNEL_EAI, RxTx_PENDING) > 0) {
4895 if ( socketVerbose != 0 ) {
4896 printf(
"%s:%d Something pending\n",__FILE__,__LINE__) ;
4898 tempEAIdata = fwlio_RxTx_getbuffer(CHANNEL_EAI) ;
4899 if(tempEAIdata != (
char *)NULL) {
4902 if ( socketVerbose != 0 ) {
4903 printf(
"%s:%d Something for EAI to do with buffer addr %p\n",__FILE__,__LINE__,tempEAIdata ) ;
4907 replyData = fwl_EAI_handleBuffer(tempEAIdata);
4911 if(replyData != NULL && strlen(replyData) != 0) {
4912 fwlio_RxTx_sendbuffer(__FILE__,__LINE__,CHANNEL_EAI, replyData) ;
4918 EAI_StillToDo = fwl_EAI_allDone();
4920 if ( socketVerbose != 0 ) {
4921 printf(
"%s:%d Something still in EAI buffer? %d\n",__FILE__,__LINE__,EAI_StillToDo ) ;
4923 replyData = fwl_EAI_handleRest();
4925 }
while(EAI_StillToDo) ;
4935 printf(
"RENDER STEP----------\n");
4945void set_viewmatrix0(
int iplace);
4946struct Touch *currentTouch();
4947void setup_picking(){
4960 if (tg->Mainloop.HaveSensitive && !Viewer()->LookatMode && !tg->Mainloop.SHIFT) {
4962 int x,yup,ktouch,priorclaimants;
4963 struct Touch *touch;
4965 priorclaimants = TOUCHCLAIMANT_PEDAL;
4966 for(ktouch=0;ktouch<p->ntouch;ktouch++){
4967 touch = &p->touchlist[ktouch];
4968 if(!touch->inUse)
continue;
4970 if(touch->windex != windex)
continue;
4971 if(touch->stageId != current_stageId())
continue;
4975 if(touch->claimant == TOUCHCLAIMANT_SENSOR || (touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants)) {
4977 if(setup_pickside(x,yup)){
4985 setup_pickray(x,yup);
4988 tg->RenderFuncs.hypersensitive = touch->hypersensitive;
4989 tg->RenderFuncs.hyperhit = touch->hyperhit;
4991 if(!touch->hyperhit){
4993 render_hier(rootNode(),VF_Sensitive | VF_Geom);
4994 touch->CursorOverSensitive = getRayHit();
4995 memcpy( touch->justModel, ((
struct currayhit *)(tg->RenderFuncs.rayHit))->justModel, 16 *
sizeof(
double));
4996 memcpy( &touch->hp, tg->RenderFuncs.hp,
sizeof(
struct point_XYZ));
4999 touch->CursorOverSensitive = NULL;
5000 memcpy(((
struct currayhit *)(tg->RenderFuncs.rayHit))->justModel, touch->justModel, 16 *
sizeof(
double));
5001 memcpy( tg->RenderFuncs.hp, &touch->hp,
sizeof(
struct point_XYZ));
5005 if(touch->dragStart){
5006 if(touch->CursorOverSensitive || fwl_getHover()){
5007 touch->claimant = TOUCHCLAIMANT_SENSOR;
5009 touch->passed |= TOUCHCLAIMANT_SENSOR;
5016 if (touch->lastOver != touch->CursorOverSensitive) {
5018 printf (
"%lf over changed, p->lastOver %u p->cursorOverSensitive %u, p->butDown1 %d\n",
5019 TickTime(), (
unsigned int) touch->lastOver, (
unsigned int) touch->CursorOverSensitive,
5020 touch->ButDown[p->currentCursor][1]);
5024 if (touch->buttonState == 0) {
5029 if (!touch->lastOverButtonPressed) {
5030 sendSensorEvents(touch->lastOver, overMark, 0, FALSE);
5031 sendSensorEvents(touch->CursorOverSensitive, overMark, 0, TRUE);
5032 touch->lastOver = touch->CursorOverSensitive;
5034 touch->lastOverButtonPressed = FALSE;
5036 touch->lastOverButtonPressed = TRUE;
5040 if (p->CursorOverSensitive != NULL)
5041 printf(
"COS %d (%s)\n", (
unsigned int) p->CursorOverSensitive, stringNodeType(p->CursorOverSensitive->_nodeType));
5044 if(touch->claimant != TOUCHCLAIMANT_SENSOR)
continue;
5049 if (touch->dragStart && touch->buttonState && (touch->lastPressedOver==NULL)) {
5052 touch->lastPressedOver = touch->CursorOverSensitive;
5053 sendSensorEvents(touch->lastPressedOver, ButtonPress, touch->dragStart, TRUE);
5057 if(touch->dragEnd && touch->lastPressedOver!=NULL) {
5062 sendSensorEvents(touch->lastPressedOver, ButtonRelease, touch->buttonState, TRUE);
5063 touch->lastPressedOver = NULL;
5074 sendSensorEvents(touch->CursorOverSensitive,MotionNotify, touch->buttonState, TRUE);
5077 sendSensorEvents(touch->lastPressedOver,MotionNotify, touch->buttonState, TRUE);
5083 sensornode = touch->lastPressedOver ? touch->lastPressedOver : touch->CursorOverSensitive;
5084 sendDescriptionToStatusBar(sensornode);
5085 if (touch->CursorOverSensitive!= NULL) {
5090 if ((touch->lastPressedOver==NULL) && (touch->CursorOverSensitive != touch->oldCOS)) {
5092 sendSensorEvents(touch->oldCOS,MapNotify,touch->buttonState, FALSE);
5094 sendSensorEvents(touch->CursorOverSensitive,MapNotify,touch->buttonState, TRUE);
5095 touch->oldCOS = touch->CursorOverSensitive;
5109 if ((touch->oldCOS != NULL) && touch->buttonState == 0) {
5110 sendSensorEvents(touch->oldCOS, MapNotify, touch->buttonState, FALSE);
5113 touch->oldCOS = NULL;
5117 touch->hypersensitive = tg->RenderFuncs.hypersensitive;
5118 touch->hyperhit = tg->RenderFuncs.hyperhit;
5120 if(touch->dragStart){
5121 touch->dragStart = FALSE;
5124 touch->dragEnd = FALSE;
5125 touch->inUse = FALSE;
5131 else if(Viewer()->LookatMode){
5133 int ktouch, kcount, priorclaimants;
5135 struct Touch *touch;
5136 priorclaimants = TOUCHCLAIMANT_PEDAL;
5143 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5144 touch = &p->touchlist[ktouch];
5145 if(!touch->inUse)
continue;
5146 if(touch->windex != windex)
continue;
5147 if(touch->stageId != current_stageId())
continue;
5149 if(touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants)
5150 touch->passed |= TOUCHCLAIMANT_SENSOR;
5152 if(Viewer()->LookatMode == 2 ){
5156 if(setup_pickside(x,yup)){
5158 setup_pickray(x,yup);
5161 render_hier(rootNode(),VF_Sensitive | VF_Geom);
5162 getRayHitAndSetLookatTarget();
5169 int ktouch, priorclaimants;
5170 struct Touch *touch;
5171 priorclaimants = TOUCHCLAIMANT_PEDAL;
5172 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5173 touch = &p->touchlist[ktouch];
5174 if(!touch->inUse)
continue;
5175 if(touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants)
5176 touch->passed |= TOUCHCLAIMANT_SENSOR;
5184void (*handlePTR)(
const int mev,
const unsigned int button,
const float x,
const float y) = handle0;
5185void handle(
const int mev,
const unsigned int button,
const float x,
const float y)
5187 handlePTR(mev, button, x, y);
5192void SSR_test_cumulative_pose();
5193static void render_pre() {
5204 if (fwl_get_headlight()) {
5205 setLightState(HEADLIGHT_LIGHT,TRUE);
5206 setLightType(HEADLIGHT_LIGHT,2);
5218 static double toggleTime = 0.0;
5219 static int runTest = 0;
5222 if(dtime - toggleTime > 5.0){
5224 runTest = 1 - runTest;
5227 if(runTest) SSR_test_cumulative_pose();
5233 if (fwl_getCollision() == 1) {
5234 profile_start(
"collision");
5235 render_collisions(Viewer()->type);
5236 profile_end(
"collision");
5248 profile_start(
"hier_prox");
5249 render_hier(rootNode(), VF_Proximity);
5250 profile_end(
"hier_prox");
5254 PRINT_GL_ERROR_IF_ANY(
"GLBackend::render_pre");
5257int setup_pickside0(
int x,
int y,
int *iside,
ivec4 *vportleft,
ivec4 *vportright){
5264 int sideleft, sideright, userPreferredPickSide, ieither;
5265 ivec4 vport, vportscene;
5272 userPreferredPickSide =
viewer->dominantEye;
5273 ieither =
viewer->eitherDominantEye;
5276 pt = ivec2_init(x,y);
5277 vportstack = (
Stack*)tg->Mainloop._vportstack;
5278 vport = stack_top(
ivec4,vportstack);
5280 vportscene.Y = vport.Y + tg->Mainloop.clipPlane;
5281 vportscene.H = vport.H - tg->Mainloop.clipPlane;
5283 *vportleft = vportscene;
5284 *vportright = vportscene;
5290 vportright->X = vportleft->X + vportleft->W;
5295 *vportright = vportscene;
5296 vportright->Y += tg->Mainloop.clipPlane;
5297 vportright->H -= tg->Mainloop.clipPlane;
5298 *vportleft = *vportright;
5300 vportleft->Y += vportscene.H;
5304 sideleft = sideright=0;
5305 sideleft = pointinsideviewport(*vportleft,pt);
5306 sideright = pointinsideviewport(*vportright,pt);;
5307 if(sideleft && sideright)
5308 *iside = userPreferredPickSide;
5310 *iside = sideleft? 0 : sideright ? 1 : 0;
5311 if(!ieither) *iside = userPreferredPickSide;
5312 return sideleft || sideright;
5314static int setup_pickside(
int x,
int y){
5315 ivec4 vpleft, vpright;
5318 inside = setup_pickside0(x,y,&iside,&vpleft,&vpright);
5322void fw_gluPerspective_2(GLDOUBLE xcenter, GLDOUBLE fovy, GLDOUBLE aspect, GLDOUBLE zNear, GLDOUBLE zFar);
5323void setup_projection()
5332 GLDOUBLE fieldofview2;
5334 GLint scissorxl,scissorxr;
5340 GLsizei screenwidth2;
5341 GLsizei screenheight, bottom, top;
5342 static int counter = 0;
5346 vportstack = (
Stack*)tg->Mainloop._vportstack;
5347 vport = stack_top(
ivec4,vportstack);
5349 screenwidth2 = vport.W;
5351 top = vport.Y + vport.H;
5352 bottom = vport.Y + tg->Mainloop.clipPlane;
5353 screenheight = top - bottom;
5355 PRINT_GL_ERROR_IF_ANY(
"XEvents::start of setup_projection");
5358 scissorxr = xvp + screenwidth2;
5359 fieldofview2 =
viewer->fieldofview;
5361 aspect2 = (double)(scissorxr - scissorxl)/(double)(screenheight);
5363 if(
viewer->type==VIEWER_SPHERICAL)
5364 fieldofview2*=
viewer->fovZoom;
5369 xr = xvp + screenwidth2;
5390 expand =
viewer->screendist > .5f;
5391 expansion =
viewer->screendist - .5;
5392 expansion = fabs(expansion);
5393 iexpand = (GLint)(expansion * screenwidth2);
5395 xr -= screenwidth2/4;
5396 xl -= screenwidth2/4;
5397 scissorxr = xvp + screenwidth2/2;
5400 xl += screenwidth2/2;
5401 xr += screenwidth2/2;
5402 scissorxl += screenwidth2/2;
5403 scissorxr += screenwidth2/2;
5422 screenheight = vport.H;
5425 bottom += screenheight;
5427 top -= screenheight;
5429 screenheight -= tg->Mainloop.clipPlane;
5434 printf(
"in setup_projection\n");
5437 aspect2 = (double)(xr - xl)/(double)(screenheight);
5439 screenwidth2 = xr-xl;
5443 FW_GL_MATRIX_MODE(GL_PROJECTION);
5452 FW_GL_SCISSOR(scissorxl,bottom,scissorxr-scissorxl,screenheight);
5453 glEnable(GL_SCISSOR_TEST);
5458 p->viewpointScreenX[
viewer->iside] = xvp + screenwidth2/2;
5459 p->viewpointScreenY[
viewer->iside] = top;
5461 FW_GL_VIEWPORT(xvp - screenwidth2 / 2, bottom, screenwidth2 * 2, screenheight);
5464 FW_GL_VIEWPORT(xvp, bottom, screenwidth2, screenheight);
5467 FW_GL_LOAD_IDENTITY();
5471 double minX, maxX, minY, maxY;
5474 minX =
viewer->orthoField[0];
5475 minY =
viewer->orthoField[1];
5476 maxX =
viewer->orthoField[2];
5477 maxY =
viewer->orthoField[3];
5479 if (screenheight != 0) {
5481 numerator = (maxY - minY) * ((
float) screenwidth2) / ((
float) screenheight);
5482 maxX = numerator/2.0f;
5483 minX = -(numerator/2.0f);
5486 FW_GL_ORTHO (minX, maxX, minY, maxY,
5491 if ((fieldofview2 <= 0.0) || (fieldofview2 > 180.0))
5495 if(0) FW_GLU_PERSPECTIVE(fieldofview2, aspect2,
viewer->nearPlane,
viewer->farPlane);
5496 if(1) fw_gluPerspective_2(
viewer->xcenter,fieldofview2, aspect2,
viewer->nearPlane,
viewer->farPlane);
5497 tg->Mainloop.fieldOfView = (float)fieldofview2;
5499 FW_GL_MATRIX_MODE(GL_MODELVIEW);
5500 PRINT_GL_ERROR_IF_ANY(
"XEvents::setup_projection");
5504void getPickrayXY(
int *x,
int *y){
5506 *x = tg->Mainloop.pickray_x;
5507 *y = tg->Mainloop.pickray_y;
5510void setPickrayXY(
int x,
int y){
5512 tg->Mainloop.pickray_x = x;
5513 tg->Mainloop.pickray_y = y;
5516void setup_pickray0()
5539 double mvident[16], pickMatrix[16], pmi[16], proj[16], R1[16], R2[16], R3[16], T[16];
5540 int viewport[4], x, y;
5541 double A[3], B[3], C[3], a[3], b[3];
5542 double yaw, pitch, yy,xx;
5545 getPickrayXY(&x,&y);
5546 loadIdentityMatrix(mvident);
5547 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
5548 FW_GL_GETINTEGERV(GL_VIEWPORT,viewport);
5558 a[0] = xx; a[1] = yy; a[2] = 0.0;
5559 FW_GLU_UNPROJECT(a[0], a[1], a[2], mvident, proj, viewport,
5561 mattranslate(T,A[0],A[1],A[2]);
5563 b[0] = xx; b[1] = yy; b[2] = 1.0;
5564 FW_GLU_UNPROJECT(b[0], b[1], b[2], mvident, proj, viewport,
5568 if(0) printf(
"Cdif %f %f %f\n",C[0],C[1],C[2]);
5576 yaw = atan2(C[0],-C[2]);
5577 matrixFromAxisAngle4d(R1, -yaw, 0.0, 1.0, 0.0);
5579 transformAFFINEd(C,C,R1);
5580 if(0) printf(
"Yawed Cdif %f %f %f\n",C[0],C[1],C[2]);
5581 pitch = atan2(C[1],-C[2]);
5583 double hypotenuse = sqrt(C[0]*C[0] + C[2]*C[2]);
5584 pitch = atan2(C[1],hypotenuse);
5586 if(0) printf(
"atan2 yaw=%f pitch=%f\n",yaw,pitch);
5589 if(0) printf(
"[yaw=%f pitch=%f\n",yaw,pitch);
5591 matrotate(R1, -pitch, 1.0, 0.0, 0.0);
5592 matrotate(R2, -yaw, 0.0, 1.0, 0.0);
5594 matrixFromAxisAngle4d(R1, pitch, 1.0, 0.0, 0.0);
5595 if(0) printmatrix2(R1,
"pure R1");
5596 matrixFromAxisAngle4d(R2, yaw, 0.0, 1.0, 0.0);
5597 if(0) printmatrix2(R2,
"pure R2");
5599 matmultiplyAFFINE(R3,R1,R2);
5600 if(0) printmatrix2(R3,
"R3=R1*R2");
5602 matmultiplyAFFINE(pickMatrix,R3, T);
5603 matinverseAFFINE(pmi,pickMatrix);
5610 matcopy(pickMatrix,R3);
5611 matinverseAFFINE(pmi,pickMatrix);
5612 if(0)printmatrix2(R3,
"R3[12]=A");
5614 if(0) printmatrix2(pmi,
"inverted");
5615 setPickrayMatrix(0,pickMatrix);
5616 setPickrayMatrix(1,pmi);
5619 double rA[3], rB[3];
5620 transformAFFINEd(rA,A,pmi);
5621 transformAFFINEd(rB,B,pmi);
5622 printf(
" A %f %f %f B %f %f %f \n",A[0],A[1],A[2],B[0],B[1],B[2]);
5623 printf(
"rA %f %f %f rB %f %f %f \n",rA[0],rA[1],rA[2],rB[0],rB[1],rB[2]);
5628void setup_pickray(
int x,
int y){
5632void generate_GeneratedCubeMapTextures();
5634int get_n_depth_slices();
5635void get_depth_slice(
int islice,
double *znear,
double *zfar);
5636void fw_depth_slice_push(
double nearplane,
double farplane);
5637void fw_depth_slice_pop();
5641 int count, nslice, islice;
5643 static double shuttertime;
5644 static int shutterside;
5650 generate_GeneratedCubeMapTextures();
5653 update_navigation();
5659 for (count = 0; count < p->maxbuffers; count++) {
5661 viewer->buffer = (unsigned)p->bufferarray[count];
5668 if(
viewer->shutterGlasses == 2)
5670 if(TickTime() - shuttertime > 2.0)
5672 shuttertime = TickTime();
5673 if(shutterside > 0) shutterside = 0;
5674 else shutterside = 1;
5676 if(count != shutterside)
continue;
5682 Viewer_anaglyph_clearSides();
5684 Viewer_anaglyph_setSide(count);
5687 BackEndClearBuffer(2);
5688 if(Viewer()->anaglyph)
5689 Viewer_anaglyph_setSide(count);
5694 BackEndClearBuffer(2);
5697 projectorTable_clear();
5699 render_bound_background();
5701 nslice = get_n_depth_slices();
5703 for(islice=0;islice<nslice;islice++){
5704 get_depth_slice(islice,&znear,&zfar);
5705 fw_depth_slice_push(znear,zfar);
5706 glClear(GL_DEPTH_BUFFER_BIT);
5708 if (!fwl_get_headlight()) {
5709 setLightState(HEADLIGHT_LIGHT,FALSE);
5710 setLightType(HEADLIGHT_LIGHT,2);
5714 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, before render_hier");
5716 render_hier(rootNode(), VF_globalLight );
5717 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_globalLight)");
5718 render_hier(rootNode(), VF_Other );
5722 profile_start(
"hier_geom");
5723 render_hier(rootNode(), VF_Geom);
5724 profile_end(
"hier_geom");
5725 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_Geom)");
5728 if (tg->RenderFuncs.have_transparency) {
5730 render_hier(rootNode(), VF_Geom | VF_Blend);
5731 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_Geom)");
5733 fw_depth_slice_pop();
5740 fiducialDrawB(CURSOR_FIDUCIALS,p->viewpointScreenX[count],p->viewpointScreenY[count]);
5744 glColorMask(1,1,1,1);
5751 struct Touch *touch;
5752 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5753 touch = &p->touchlist[ktouch];
5756 if(touch->stageId == current_stageId()){
5760 cstyle = CURSOR_DOWN;
5761 if(touch->buttonState == 0) cstyle = CURSOR_HOVER;
5762 if(touch->lastOverButtonPressed || touch->CursorOverSensitive)
5763 cstyle = CURSOR_OVER;
5764 fiducialDrawB(cstyle,touch->x,touch->y);
5774static int currentViewerLandPort = 0;
5775static int rotatingCCW = FALSE;
5776static double currentViewerAngle = 0.0;
5777static double requestedViewerAngle = 0.0;
5780void setup_viewpoint_part1() {
5802 bstack = getActiveBindableStacks(tg);
5804 FW_GL_MATRIX_MODE(GL_MODELVIEW);
5805 FW_GL_LOAD_IDENTITY();
5808 if (
viewer->screenOrientation != currentViewerLandPort) {
5811 rotatingCCW = FALSE;
5812 switch (currentViewerLandPort) {
5814 rotatingCCW= (Viewer()->screenOrientation == 270);
5818 rotatingCCW = (Viewer()->screenOrientation == 0);
5822 rotatingCCW = (Viewer()->screenOrientation != 270);
5826 rotatingCCW = (Viewer()->screenOrientation != 0);
5830 currentViewerLandPort =
viewer->screenOrientation;
5831 requestedViewerAngle = (double)
viewer->screenOrientation;
5834 if (!(APPROX(currentViewerAngle,requestedViewerAngle))) {
5837 currentViewerAngle -= 10.0;
5838 if (currentViewerAngle < -5.0) currentViewerAngle = 360.0;
5841 currentViewerAngle +=10.0;
5842 if (currentViewerAngle > 365.0) currentViewerAngle = 0.0;
5845 FW_GL_ROTATE_D (currentViewerAngle,0.0,0.0,1.0);
5846 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->screenorientationmatrix);
5851 bstack->isStereo =
viewer->isStereo;
5852 bstack->iside =
viewer->iside;
5856 FW_GL_LOAD_IDENTITY();
5857 set_stereo_offset0();
5858 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->stereooffsetmatrix[0]);
5861 FW_GL_LOAD_IDENTITY();
5862 set_stereo_offset0();
5863 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->stereooffsetmatrix[1]);
5865 FW_GL_LOAD_IDENTITY();
5868 viewer_togl(
viewer->fieldofview);
5869 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->posorimatrix);
5871 FW_GL_LOAD_IDENTITY();
5873struct X3D_Node *getActiveLayerBoundViewpoint(){
5877 bstack = getActiveBindableStacks(tg);
5880 if(bstack->viewpoint){
5881 if( vectorSize(bstack->viewpoint) > 0){
5882 boundvp = vector_back(
struct X3D_Node*,bstack->viewpoint);
5888int render_foundLayerViewpoint(){
5898 boundvp = (
struct X3D_Viewpoint*)getActiveLayerBoundViewpoint();
5905 iret = boundvp->_donethispass;
5908void setup_viewpoint_part2() {
5931 profile_start(
"vp_hier");
5936 boundvp = (
struct X3D_Viewpoint*)getActiveLayerBoundViewpoint();
5938 boundvp->_donethispass = 0;
5939 render_hier(rootNode(), VF_Viewpoint | VF_Background);
5941 boundvp->_donethispass = 0;
5944 profile_end(
"vp_hier");
5948void setup_viewpoint_part3() {
5964 double viewmatrix[16];
5971 bstack = getActiveBindableStacks(tg);
5973 PRINT_GL_ERROR_IF_ANY(
"XEvents::setup_viewpoint");
5974 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->viewtransformmatrix);
5992 matcopy(viewmatrix,bstack->screenorientationmatrix);
5995 matmultiplyAFFINE(viewmatrix,bstack->posorimatrix,viewmatrix);
5997 matmultiplyAFFINE(viewmatrix,bstack->viewtransformmatrix,viewmatrix);
5998 fw_glSetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6004void setup_viewpoint(){
6006 setup_viewpoint_part1();
6007 setup_viewpoint_part2();
6008 setup_viewpoint_part3();
6013void set_viewmatrix0(
int iplace) {
6017 double viewmatrix[16];
6024 bstack = getActiveBindableStacks(tg);
6026 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6027 matcopy(viewmatrix,bstack->screenorientationmatrix);
6029 int iside = Viewer()->isideB;
6030 matmultiplyAFFINE(viewmatrix,bstack->stereooffsetmatrix[iside],viewmatrix);
6033 int iside = Viewer()->iside;
6034 matmultiplyAFFINE(viewmatrix,bstack->stereooffsetmatrix[iside],viewmatrix);
6036 matmultiplyAFFINE(viewmatrix,bstack->posorimatrix,viewmatrix);
6037 matmultiplyAFFINE(bstack->viewmatrix,bstack->viewtransformmatrix,viewmatrix);
6038 fw_glSetDoublev(GL_MODELVIEW_MATRIX, bstack->viewmatrix);
6040void set_viewmatrix() {
6045char *nameLogFileFolderNORMAL(
char *logfilename,
int size){
6046 strcat(logfilename,
"freewrl_tmp");
6047 fw_mkdir(logfilename);
6048 strcat(logfilename,
"/");
6049 strcat(logfilename,
"logfile");
6052char * (*nameLogFileFolderPTR)(
char *logfilename,
int size) = nameLogFileFolderNORMAL;
6064 freopen(
"CON",
"w",stdout);
6070 printf(
"logging off\n");
6073 if(p->logfname == NULL){
6074 char logfilename[1000];
6076 logfilename[0] =
'\0';
6077 nameLogFileFolderPTR(logfilename, 1000);
6078 strcat(logfilename,
".log");
6079 p->logfname = STRDUP(logfilename);
6081 printf(
"logging to %s\n",p->logfname);
6082 p->logfile = freopen(p->logfname, mode, stdout );
6087#if defined(_MSC_VER)
6088#define strncasecmp _strnicmp
6090void fwl_set_logfile(
char *lname){
6094 if (strncasecmp(lname,
"-", 1) == 0) {
6095 printf(
"FreeWRL: output to stdout/stderr\n");
6097 p->logfname = STRDUP(lname);
6102int unload_broto(
struct X3D_Proto* node);
6104void fwl_clearWorld(){
6111 unload_broto(X3D_PROTO(rn));
6112 printf(
"unloaded scene as broto\n");
6117 tg->Mainloop.replaceWorldRequest = NULL;
6118 tg->threads.flushing =
true;
6123void sendKeyToKeySensor(
const char key,
int upDown);
6137char lookup_fly_key(
int key);
6139void dump_scenegraph(
int method);
6140void fps_histo_toggle();
6141void fwl_do_keyPress0(
int key,
int type) {
6149 if(
key == 27 && type == 1)
6152 p->keySensorMode = 1 - p->keySensorMode;
6154 if (p->keySensorMode && KeySensorNodePresent()) {
6155 sendKeyToKeySensor(
key,type);
6157 int handled = isAqua;
6160 if(type == KEYPRESS){
6170 int len = strlen(p->keywaitstring);
6174 fwl_commandline(p->keywaitstring);
6176 p->keywaitstring[0] =
'\0';
6177 ConsoleMessage(
"%c",
'\n');
6179 ConsoleMessage(
"%c",lkp);
6180 if(lkp ==
'\b' && len){
6181 p->keywaitstring[len-1] =
'\0';
6183 p->keywaitstring[len] = lkp;
6184 p->keywaitstring[len+1] =
'\0';
6192 if(type == KEYPRESS)
6198 case 'n': { fwl_clearWorld();
break; }
6199 case 'e': { fwl_set_viewer_type (VIEWER_EXAMINE);
break; }
6200 case 'w': { fwl_set_viewer_type (VIEWER_WALK);
break; }
6201 case 'd': { fwl_set_viewer_type (VIEWER_FLY);
break; }
6202 case 'f': { fwl_set_viewer_type (VIEWER_EXFLY);
break; }
6203 case 'y': { fwl_set_viewer_type (VIEWER_SPHERICAL);
break; }
6204 case 't': { fwl_set_viewer_type(VIEWER_TURNTABLE);
break; }
6205 case 'm': { fwl_set_viewer_type(VIEWER_LOOKAT);
break; }
6206 case 'g': { fwl_set_viewer_type(VIEWER_EXPLORE);
break; }
6207 case 'h': { fwl_toggle_headlight();
break; }
6208 case 'H': { fps_histo_toggle();
break; }
6209 case '/': { print_viewer();
break; }
6211 case '\\': { dump_scenegraph(1);
break; }
6212 case '|': { dump_scenegraph(2);
break; }
6213 case '=': { dump_scenegraph(3);
break; }
6214 case '+': { dump_scenegraph(4);
break; }
6215 case '-': { dump_scenegraph(5);
break; }
6216 case '`': { toggleLogfile();
break; }
6217 case '$': resource_tree_dump(0, (
resource_item_t*)tg->resources.root_res);
break;
6218 case '*': resource_tree_list_files(0, (
resource_item_t*)tg->resources.root_res);
break;
6219 case 'q': {
if (!RUNNINGASPLUGIN) {
6220 fwl_doQuit(__FILE__,__LINE__);
6224 case 'c': { toggle_collision();
break;}
6225 case 'v': {fwl_Next_ViewPoint();
break;}
6226 case 'b': {fwl_Prev_ViewPoint();
break;}
6227 case '.': {profile_print_all();
break;}
6228 case ' ': p->keywait = TRUE; ConsoleMessage(
"\n%c",
':'); p->keywaitstring[0] =
'\0';
break;
6229 case ',': toggle_debugging_trigger();
break;
6230#if !defined(FRONTEND_DOES_SNAPSHOTS)
6231 case 'x': {Snapshot();
break;}
6235 printf(
"didn't handle key=[%c][%d] type=%d\n",lkp,(
int)lkp,type);
6245 kp = lookup_fly_key(
key);
6248 int keystate = type % 10 == KEYDOWN ? 1 : 0;
6251 tg->Mainloop.CTRL = keystate;
break;
6253 tg->Mainloop.SHIFT = keystate;
break;
6255 case HOME_KEY:
if(keystate) fwl_First_ViewPoint();
break;
6256 case END_KEY:
if(keystate) fwl_Last_ViewPoint();
break;
6257 case PGUP_KEY:
if(keystate) fwl_Prev_ViewPoint();
break;
6258 case PGDN_KEY:
if(keystate) fwl_Next_ViewPoint();
break;
6266 if(tg->Mainloop.SHIFT){
6267 if(type%10 == KEYDOWN && (
key == LEFT_KEY ||
key == RIGHT_KEY)){
6270 ichord = viewer_getKeyChord();
6271 if(
key == LEFT_KEY) ichord--;
6272 if(
key == RIGHT_KEY) ichord++;
6273 viewer_setKeyChord(ichord);
6276 double keytime = Time1970sec();
6277 if(type%10 == KEYDOWN)
6278 handle_key(kp,keytime);
6279 if(type%10 == KEYUP)
6280 handle_keyrelease(kp,keytime);
6288 return tg->Mainloop.SHIFT;
6290void fwl_setShift(
int ishift){
6292 tg->Mainloop.SHIFT = ishift;
6297 return tg->Mainloop.CTRL;
6301int platform2web3dActionKey(
int platformKey);
6303void (*fwl_do_rawKeyPressPTR)(
int key,
int type) = fwl_do_keyPress0;
6304void fwl_do_rawKeyPress(
int key,
int type) {
6305 fwl_do_rawKeyPressPTR(
key,type);
6308void fwl_do_keyPress(
char kp,
int type) {
6315 ConsoleMessage(
"key pressed decimal = %d\n",
key);
6316 if (type != KEYPRESS)
6317 actionKey = platform2web3dActionKey(
key);
6319 fwl_do_rawKeyPress(actionKey,type+10);
6321 fwl_do_rawKeyPress(
key,type);
6326void fwl_gotoViewpoint (
char *findThisOne) {
6329 struct tProdCon *t = &gglobal()->ProdCon;
6332 if (findThisOne != NULL) {
6333 for (i=0; i<vectorSize(t->viewpointNodes); i++) {
6334 switch ((vector_get(
struct X3D_Node*, t->viewpointNodes,i)->_nodeType)) {
6335 case NODE_Viewpoint:
6336 if (strcmp(findThisOne,
6337 X3D_VIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6343 case NODE_GeoViewpoint:
6344 if (strcmp(findThisOne,
6345 X3D_GEOVIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6350 case NODE_OrthoViewpoint:
6351 if (strcmp(findThisOne,
6352 X3D_ORTHOVIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6363 if (whichnode != -1) {
6365 t->setViewpointBindInRender = vector_get(
struct X3D_Node *,t->viewpointNodes,whichnode);
6370void setup_viewpoint_slerp3(
double *center,
double pivot_radius,
double vp_radius);
6372int getRayHitAndSetLookatTarget() {
6379 double pivot_radius, vp_radius;
6385 if(tg->RenderFuncs.hitPointDist >= 0) {
6390 if (rh->hitNode == NULL) {
6391 Viewer()->LookatMode = 0;
6394 double center[3], radius;
6396 if(Viewer()->type == VIEWER_LOOKAT){
6398 GLDOUBLE smin[3], smax[3], shapeMBBmin[3], shapeMBBmax[3];
6404 shapeMBBmin[i] = node->_extent[i*2 + 1];
6405 shapeMBBmax[i] = node->_extent[i*2];
6407 transformMBB(smin,smax,rh->modelMatrix,shapeMBBmin,shapeMBBmax);
6410 center[i] = (smax[i] + smin[i])*.5;
6411 radius = max(radius,(max(fabs(smax[i]-center[i]),fabs(smin[i]-center[i]))));
6413 viewerdist = Viewer()->Dist;
6414 vp_radius = max(viewerdist, radius + 5.0);
6421 }
else if(Viewer()->type == VIEWER_EXPLORE){
6424 pointxyz2double(center,tg->RenderFuncs.hp);
6425 transformAFFINEd(center,center,getPickrayMatrix(0));
6427 vp_radius = .8 * veclengthd(center);
6429 Viewer()->LookatMode = 3;
6430 setup_viewpoint_slerp3(center,pivot_radius,vp_radius);
6433 return Viewer()->LookatMode;
6435void prepare_model_view_pickmatrix_inverse(GLDOUBLE *mvpi);
6459 if(tg->RenderFuncs.hitPointDist >= 0) {
6464 if (rh->hitNode == NULL){
6481 if (rh->hitNode != NULL)
6488 for(i=0;i<vectorSize(p->SensorEvents);i++){
6489 se = vector_get(
struct SensStruct *,p->SensorEvents,i);
6490 if (se->fromnode == rh->hitNode) {
6492 retnode = ((
struct X3D_Node*) rh->hitNode);
6499 if(retnode != NULL){
6502 GLDOUBLE viewmatrix[16], viewinverse[16];
6504 rh = (
struct currayhit *)tg->RenderFuncs.rayHit;
6506 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6507 fw_glGetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6508 matinverseAFFINE(viewinverse,viewmatrix);
6509 matmultiplyAFFINE(rh->justModel,rh->modelMatrix,viewinverse);
6526 void (*myp)(
unsigned *);
6531 switch (datanode->_nodeType) {
6533 case NODE_TouchSensor: myp = (
void *)do_TouchSensor;
break;
6534 case NODE_GeoTouchSensor: myp = (
void *)do_GeoTouchSensor;
break;
6535 case NODE_LineSensor: myp = (
void *)do_LineSensor;
break;
6536 case NODE_PointSensor: myp = (
void *)do_PointSensor;
break;
6537 case NODE_PlaneSensor: myp = (
void *)do_PlaneSensor;
break;
6538 case NODE_CylinderSensor: myp = (
void *)do_CylinderSensor;
break;
6539 case NODE_SphereSensor: myp = (
void *)do_SphereSensor;
break;
6540 case NODE_ProximitySensor:
return;
break;
6541 case NODE_GeoProximitySensor:
return;
break;
6544 case NODE_Anchor: myp = (
void *)do_Anchor; parentNode = datanode;
break;
6553 for (i=0; i<vectorSize(p->SensorEvents); i++) {
6554 se = vector_get(
struct SensStruct *,p->SensorEvents,i);
6555 if ((se->fromnode == parentNode) &&
6556 (se->datanode == datanode) &&
6557 (se->interpptr == (
void *)myp)) {
6563 if (datanode == 0) {
6564 printf (
"setSensitive: datastructure is zero for type %s\n",stringNodeType(datanode->_nodeType));
6571 se->fromnode = parentNode;
6572 se->datanode = datanode;
6573 se->interpptr = (
void *)myp;
6574 vector_pushBack(
struct SensStruct *,p->SensorEvents,se);
6579static void sendSensorEvents(
struct X3D_Node* COS,
int ev,
int butStatus,
int status) {
6590 if (COS==NULL)
return;
6592 for (count = 0; count < vectorSize(p->SensorEvents); count++) {
6593 se = vector_get(
struct SensStruct *,p->SensorEvents,count);
6594 if (se->fromnode == COS) {
6595 butStatus2 = butStatus;
6597 if (ev==ButtonPress) {
6598 tg->RenderFuncs.hypersensitive = se->fromnode;
6599 tg->RenderFuncs.hyperhit = 1;
6601 }
else if (ev==ButtonRelease) {
6602 tg->RenderFuncs.hypersensitive = 0;
6603 tg->RenderFuncs.hyperhit = 0;
6605 }
else if (ev==MotionNotify) {
6610 se->interpptr(se->datanode, ev,butStatus2, status);
6617void prepare_model_view_pickmatrix_inverse0(GLDOUBLE *modelMatrix, GLDOUBLE *mvpi);
6618void prepare_model_view_pickmatrix_inverse(GLDOUBLE *mvpi){
6627 GLDOUBLE viewmatrix[16], mv[16];
6630 rh = (
struct currayhit *)tg->RenderFuncs.rayHit;
6633 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6634 fw_glGetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6636 matmultiplyAFFINE(mv,rh->justModel,viewmatrix);
6640 prepare_model_view_pickmatrix_inverse0(mv, mvpi);
6654void get_hyperhit() {
6675 double x1,y1,z1,x2,y2,z2,x3,y3,z3;
6688 prepare_model_view_pickmatrix_inverse(mvpi);
6690 transform(&tp,&r11,mvpi);
6691 x1 = tp.x; y1 = tp.y; z1 = tp.z;
6692 transform(&tp,&r2,mvpi);
6693 x2 = tp.x; y2 = tp.y; z2 = tp.z;
6695 transform(&tp,tg->RenderFuncs.hp,mvpi);
6696 x3 = tp.x; y3 = tp.y; z3 = tp.z;
6698 printf(
"get_hyperhit\n");
6706 tg->RenderFuncs.hyp_save_posn[0] = (float) x1; tg->RenderFuncs.hyp_save_posn[1] = (float) y1; tg->RenderFuncs.hyp_save_posn[2] = (float) z1;
6707 tg->RenderFuncs.hyp_save_norm[0] = (float) x2; tg->RenderFuncs.hyp_save_norm[1] = (float) y2; tg->RenderFuncs.hyp_save_norm[2] = (float) z2;
6709 tg->RenderFuncs.ray_save_posn[0] = (float) x3; tg->RenderFuncs.ray_save_posn[1] = (float) y3; tg->RenderFuncs.ray_save_posn[2] = (float) z3;
6715void setStereoBufferStyle(
int itype)
6721 p->bufferarray[0]=GL_BACK_LEFT;
6722 p->bufferarray[1]=GL_BACK_RIGHT;
6728 p->bufferarray[0]=FW_GL_BACK;
6729 p->bufferarray[1]=FW_GL_BACK;
6732 printf(
"maxbuffers=%d\n",p->maxbuffers);
6734void setStereoBufferStyleB(
int itype,
int iside,
int ibuffer)
6741 p->bufferarray[ibuffer]=GL_BACK_LEFT;
6743 p->bufferarray[ibuffer]=GL_BACK_RIGHT;
6748 p->bufferarray[ibuffer]=FW_GL_BACK;
6757 if (vp_parent->_nodeType != NODE_ViewpointGroup)
return TRUE;
6759 if (vp_parent->__proxNode != NULL) {
6761 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]))) {
6762 printf (
"size is zero\n");
6766 return X3D_PROXIMITYSENSOR(vp_parent->__proxNode)->isActive;
6772static int moreThanOneValidViewpoint(
void) {
6774 struct tProdCon *t = &gglobal()->ProdCon;
6776 if (vectorSize(t->viewpointNodes)<=1)
return FALSE;
6778 for (count=0; count < vectorSize(t->viewpointNodes); count++) {
6779 if (count != t->currboundvpno) {
6780 struct Vector *me = vector_get(
struct X3D_Node*, t->viewpointNodes,count)->_parentVector;
6785 if (vectorSize(me) > 0) {
6789 vector_get(
struct X3D_Node *,t->viewpointNodes,count)->_parentVector, 0),
6805void fwl_Last_ViewPoint() {
6806 if (moreThanOneValidViewpoint()) {
6810 struct tProdCon *t = &gglobal()->ProdCon;
6815 vp_to_go_to = vectorSize(t->viewpointNodes);
6816 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind--) {
6820 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
6821 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
6829 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),0);
6830 t->currboundvpno = vp_to_go_to;
6831 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6832 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),1);
6838 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,
6839 t->viewpointNodes,vp_to_go_to);
6840 t->currboundvpno = vp_to_go_to;
6841 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6852void fwl_First_ViewPoint() {
6853 if (moreThanOneValidViewpoint()) {
6857 struct tProdCon *t = &gglobal()->ProdCon;
6863 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind++) {
6867 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
6868 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
6869 struct X3D_Node* , t->viewpointNodes,vp_to_go_to),cn);
6877 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),0);
6878 t->currboundvpno = vp_to_go_to;
6879 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6880 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),1);
6885 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,t->viewpointNodes,vp_to_go_to);
6886 t->currboundvpno = vp_to_go_to;
6887 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6897void fwl_Prev_ViewPoint() {
6898 if (moreThanOneValidViewpoint()) {
6902 struct tProdCon *t = &gglobal()->ProdCon;
6907 vp_to_go_to = t->currboundvpno;
6908 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind--) {
6912 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
6913 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
6922 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),0);
6923 t->currboundvpno = vp_to_go_to;
6924 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6925 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),1);
6930 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,
6931 t->viewpointNodes,vp_to_go_to);
6932 t->currboundvpno = vp_to_go_to;
6933 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6944void fwl_Next_ViewPoint() {
6945 if (moreThanOneValidViewpoint()) {
6949 struct tProdCon *t = &gglobal()->ProdCon;
6954 vp_to_go_to = t->currboundvpno;
6955 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind++) {
6959 if (vp_to_go_to>=vectorSize(t->viewpointNodes)) vp_to_go_to=0;
6960 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
6961 struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
6971 t->setViewpointBindInRender = vector_get(
6972 struct X3D_Node*,t->viewpointNodes,vp_to_go_to);
6973 t->currboundvpno = vp_to_go_to;
6974 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
6983void fwl_initializeRenderSceneUpdateScene() {
6998 new_text_tessellation();
7000 viewer_postGLinit_init();
7003 if( ((
freewrl_params_t*)(tg->display.params))->fullscreen && newResetGeometry != NULL) newResetGeometry();
7018static int workers_waiting(){
7021 waiting = tg->threads.ResourceThreadWaiting && tg->threads.TextureThreadWaiting;
7025static void workers_stop()
7027 resitem_queue_exit();
7028 texitem_queue_exit();
7030static int workers_running(){
7033 more = tg->threads.ResourceThreadRunning || tg->threads.TextureThreadRunning;
7060 ret = (!fwl_isinputThreadParsing()) && (!fwl_isTextureParsing()) && fwl_isInputThreadInitialized();
7061 ret = ret && workers_waiting();
7063 dtime = tg->Mainloop.TickTime - p->BrowserInitTime;
7064 ret = ret && (dtime > 10.0);
7068void end_of_run_tests(){
7072 int i, notfreed, notfreedt;
7076 for(i=0;i<100000;i++){
7077 if(glIsBuffer(i)) {notfreed++; printf(
"b%d ",i);}
7078 if(glIsTexture(i)) {notfreedt++; printf(
"t%d ",i);}
7080 printf(
"\ngl buffers not freed = %d\n",notfreed);
7081 printf(
"gl textures not freed = %d\n",notfreedt);
7086static void finalizeRenderSceneUpdateScene() {
7090 printf (
"finalizeRenderSceneUpdateScene\n");
7093 if (newResetGeometry != NULL) newResetGeometry();
7095 killErrantChildren();
7099 deleteVector(
struct X3D_Node*,rn->_parentVector);
7100 freeMallocedNodeFields(rn);
7106 iglobal_destructor(tg);
7108 void scanMallocTableOnQuit(
void);
7109 scanMallocTableOnQuit();
7115int checkReplaceWorldRequest(){
7117 if (tg->Mainloop.replaceWorldRequest || tg->Mainloop.replaceWorldRequestMulti){
7118 tg->threads.flushing =
true;
7120 return tg->threads.flushing;
7122static int exitRequest = 0;
7123int checkExitRequest(){
7127static int checkQuitRequest(){
7129 if ((tg->threads.MainLoopQuit) == 1){
7131 tg->threads.flushing =
true;
7133 return tg->threads.MainLoopQuit;
7135void doReplaceWorldRequest()
7142 req = tg->Mainloop.replaceWorldRequest;
7143 tg->Mainloop.replaceWorldRequest = NULL;
7146 res = resource_create_single(req);
7148 resitem_enqueue(ml_new(res));
7153 tg->Mainloop.replaceWorldRequestMulti = NULL;
7155 resm->new_root =
true;
7156 gglobal()->resources.root_res = (
void*)resm;
7158 resitem_enqueue(ml_new(resm));
7160 tg->threads.flushing =
false;
7162static int(*view_initialize)() = NULL;
7166#if defined(_ANDROID) || defined(ANDROIDNDK) || defined(WINRT)
7167int view_initialize0(
void){
7169 if (!fv_display_initialize()) {
7170 ERROR_MSG(
"initFreeWRL: error in display initialization.\n");
7176int view_initialize0(
void){
7178 if (!fv_display_initialize_desktop()) {
7179 ERROR_MSG(
"initFreeWRL: error in display initialization.\n");
7195 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
7199 if (!p->draw_initialized){
7201 view_initialize = view_initialize0;
7202 if (view_initialize)
7203 more = view_initialize();
7206 fwl_initializeRenderSceneUpdateScene();
7208 p->draw_initialized = TRUE;
7211 switch (tg->threads.MainLoopQuit){
7216 if (tg->threads.flushing ==
false)
7219 profile_end(
"frontend");
7220 profile_start(
"mainloop");
7222 fwl_RenderSceneUpdateScene();
7223 profile_end(
"mainloop");
7224 profile_start(
"frontend");
7226 PRINT_GL_ERROR_IF_ANY(
"XEvents::render");
7227 checkReplaceWorldRequest();
7232 if (workers_waiting())
7237 tg->threads.flushing =
false;
7238 if (tg->threads.MainLoopQuit)
7239 tg->threads.MainLoopQuit++;
7241 doReplaceWorldRequest();
7244 tg->threads.MainLoopQuit++;
7255 tg->threads.MainLoopQuit++;
7259 more = workers_running();
7262 finalizeRenderSceneUpdateScene();
7273void fwl_initialize_parser()
7276 if (rootNode() == NULL) {
7277 setRootNode( createNewX3DNode (NODE_Proto) );
7279 doNotRegisterThisNodeForDestroy(X3D_NODE(rootNode()));
7283void fwl_init_SnapSeq() {
7284#ifdef DOSNAPSEQUENCE
7286 set_snapsequence(TRUE);
7291void fwl_set_LineWidth(
float lwidth) {
7292 gglobal()->Mainloop.gl_linewidth = lwidth;
7295void fwl_set_KeyString(
const char* kstring)
7298 p->keypress_string = STRDUP(kstring);
7306void outOfMemory(
const char *msg) {
7307 ConsoleMessage (
"FreeWRL has encountered a memory allocation problem\n"\
7308 "and is exiting. -- %s--",msg);
7313void _disposeThread(
void *globalcontext);
7316void fwl_doQuitInstance(
void *tg_remote)
7319printf (
"fwl_doQuitInstance called\n");
7321 if (tg_remote == tg)
7323 fwl_doQuit(__FILE__,__LINE__);
7326 fwl_clearCurrentHandle();
7328 pthread_create(&tg->threads.disposeThread, NULL, (
void *(*)(
void *))&_disposeThread, tg);
7333void __iglobal_destructor(
ttglobal tg);
7335void _disposeThread(
void *globalcontext)
7339 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
7341 while((more = workers_running()) && more > 0)
7347 markForDispose(rootNode(), TRUE);
7351 finalizeRenderSceneUpdateScene();
7353#if defined(WRAP_MALLOC) || defined(DEBUG_MALLOC)
7354 freewrlFreeAllRegisteredAllocations();
7355 freewrlDisposeMemTable();
7357 __iglobal_destructor(tg);
7362void fwl_doQuit(
char *fl,
int ln)
7365 tg->threads.MainLoopQuit = max(1,tg->threads.MainLoopQuit);
7370void fwl_doQuitAndWait(){
7371 pthread_t displaythread;
7373 displaythread = tg->threads.DispThrd;
7374 fwl_doQuit(__FILE__,__LINE__);
7375 pthread_join(displaythread,NULL);
7381void fwl_tmpFileLocation(
char *tmpFileLocation) {
7383 if (tmpFileLocation == NULL)
return;
7385 FREE_IF_NZ(tg->Mainloop.tmpFileLocation);
7386 tg->Mainloop.tmpFileLocation = MALLOC(
char *,strlen(tmpFileLocation)+1);
7387 strcpy(tg->Mainloop.tmpFileLocation,tmpFileLocation);
7390void close_internetHandles();
7391void freewrlDie (
const char *format) {
7392 ConsoleMessage (
"Catastrophic error: %s\n",format);
7393 fwl_doQuit(__FILE__,__LINE__);
7399struct Touch * AllocTouch(
unsigned int ID){
7405 for(i=0;i<p->ntouch;i++)
7406 if(p->touchlist[i].ID == ID && p->touchlist[i].inUse){
7408 p->touchlist[i].inUse = 2;
7409 return &p->touchlist[i];
7411 for(i=0;i<p->ntouch;i++)
7412 if(!p->touchlist[i].inUse){
7413 memset(&p->touchlist[i],0,
sizeof(
struct Touch));
7414 p->touchlist[i].inUse = 2;
7415 p->touchlist[i].ID = ID;
7416 return &p->touchlist[i];
7420struct Touch * GetTouch(
unsigned int ID){
7426 for(i=0;i<p->ntouch;i++)
7427 if(p->touchlist[i].ID == ID && (p->touchlist[i].inUse || ID == 0) ){
7428 return &p->touchlist[i];
7432void ReleaseTouch(
unsigned int ID){
7439 for(i=0;i<p->ntouch;i++)
7440 if(p->touchlist[i].ID == ID ){
7441 p->touchlist[i].inUse = 0;
7462void setCurrentTouchID(
unsigned int ID){
7466 p->currentTouch = ID;
7468struct Touch *currentTouch(){
7474 return GetTouch(p->currentTouch);
7477void handle_pedal(
int mev,
int x,
int y,
ivec4 vport){
7482 pstate = &p->pedalstate;
7483 if(mev == ButtonPress) {
7484 if(!pstate->initialized){
7487 pstate->initialized = TRUE;
7491 pstate->isDown = TRUE;
7492 }
else if (mev == MotionNotify) {
7494 pstate->x += x - pstate->rx;
7495 pstate->y += y - pstate->ry;
7499 }
else if(mev == ButtonRelease) {
7501 pstate->x += x - pstate->rx;
7502 pstate->y += y - pstate->ry;
7504 pstate->isDown = FALSE;
7508void viewer_setNextDragChord();
7509void fwl_handle_aqua_multiNORMAL(
const int mev,
const unsigned int button,
int x,
int y,
unsigned int ID,
int windex) {
7510 int ibutton, passed, claimant;
7512 struct Touch *touch;
7528 if(mev == ButtonPress){
7529 viewer_setNextDragChord();
7534 if(fwl_getHover()) ibutton = 0;
7539 vportstack = (
Stack*)tg->Mainloop._vportstack;
7540 vport = stack_top(
ivec4,vportstack);
7542 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);
7545 ConsoleMessage(
"fwl_handle_aqua in MainLoop; mev %d but %d x %d y %d ID %d ",
7546 mev, ibutton, x, y, ID);
7547 ConsoleMessage(
"wndx %d swi %d shi %d ", windex, vport.W, vport.H);
7548 if (mev == ButtonPress) ConsoleMessage(
"ButtonPress\n");
7549 else if (mev == ButtonRelease) ConsoleMessage(
"ButtonRelease\n");
7550 else if (mev == MotionNotify) ConsoleMessage(
"MotionNotify\n");
7551 else ConsoleMessage(
"event %d\n", mev);
7557 passed = TOUCHCLAIMANT_PEDAL;
7558 claimant = TOUCHCLAIMANT_UNCLAIMED;
7559 if (fwl_getPedal()) {
7560 handle_pedal(mev, x, y, vport);
7564 claimant = TOUCHCLAIMANT_PEDAL;
7569 if(mev == ButtonPress){
7574 touch = GetTouch(ID);
7577 touch = AllocTouch(ID);
7578 if(currentTouch()->ID == 0) {
7581 setCurrentTouchID(ID);
7583 touch->windex = windex;
7584 touch->stageId = current_stageId();
7585 touch->buttonState = ibutton ? 1 : 0;
7586 touch->claimant = claimant;
7587 touch->passed = passed;
7588 touch->dragStart = TRUE;
7591 touch = GetTouch(ID);
7601 touch->x = p->pedalstate.x;
7602 touch->y = p->pedalstate.y;
7609 fx = (float)(touch->x - vport.X) / (float)vport.W;
7610 fy = (float)(touch->y - vport.Y) / (float)vport.H;
7614 touch->angle = 0.0f;
7616 if(mev == ButtonRelease){
7618 p->currentTouch = 0;
7619 touch->dragEnd = TRUE;
7620 if(touch->claimant == TOUCHCLAIMANT_PEDAL) touch->inUse = FALSE;
7624void update_navigation(){
7630 struct Touch *curTouch;
7635 for(i=0;i<p->ntouch;i++){
7636 curTouch = &p->touchlist[i];
7637 if(curTouch->inUse){
7640 int priorclaimants = TOUCHCLAIMANT_PEDAL | TOUCHCLAIMANT_SENSOR;
7641 if(curTouch->claimant == TOUCHCLAIMANT_UNCLAIMED && curTouch->passed == priorclaimants ){
7644 curTouch->claimant = TOUCHCLAIMANT_NAVIGATION;
7646 curTouch->passed |= TOUCHCLAIMANT_NAVIGATION;
7648 if(curTouch->claimant == TOUCHCLAIMANT_NAVIGATION){
7650 ibut = curTouch->buttonState;
7651 if (curTouch->dragStart || (curTouch->dragEnd)) {
7652 if(curTouch->dragStart) imev = ButtonPress;
7653 if(curTouch->dragEnd) imev = ButtonRelease;
7654 handle(imev, ibut, curTouch->fx,curTouch->fy);
7655 curTouch->dragStart = FALSE;
7656 if(curTouch->dragEnd) curTouch->inUse = FALSE;
7657 curTouch->dragEnd = FALSE;
7659 imev = MotionNotify;
7660 handle (imev, ibut, curTouch->fx, curTouch->fy);
7671void fwl_setOrientation (
int orient) {
7679 Viewer()->screenOrientation = orient;
7683 ConsoleMessage (
"invalid orientation %d\n",orient);
7684 Viewer()->screenOrientation = 0;
7688int fwl_getOrientation(){
7689 return Viewer()->screenOrientation;
7692void fwl_setOrientation2 (
int orient) {
7700 gglobal()->Mainloop.screenOrientation2 = orient;
7705 ConsoleMessage (
"invalid orientation2 %d\n",orient);
7706 gglobal()->Mainloop.screenOrientation2 = 0;
7710int fwl_getOrientation2(){
7712 return gglobal()->Mainloop.screenOrientation2;
7717 RUNNINGASPLUGIN = TRUE;
7753void setDisplayed (
int state) {
7757 if (state) printf (
"WE ARE DISPLAYED\n");
7758 else printf (
"we are now iconic\n");
7760 p->onScreen = state;
7763void fwl_init_EaiVerbose() {
7765#if !defined(EXCLUDE_EAI)
7766 gglobal()->EAI_C_CommonFunctions.eaiverbose = TRUE;
7767 fwlio_RxTx_control(CHANNEL_EAI, RxTx_MOREVERBOSE);
7773#if defined (_ANDROID)
7775void fwl_Android_replaceWorldNeeded() {
7783 resetSensorEvents();
7786 gglobal()->resources.root_res = NULL;
7787 Android_reset_viewer_to_defaults();
7789 struct tProdCon *t = &gglobal()->ProdCon;
7792 if (vectorSize(t->viewpointNodes) > t->currboundvpno) {
7793 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),0);
7796 if (rootNode() != NULL) {
7799 for (i=0; i<proto->__children.n; i++) {
7800 markForDispose(proto->__children.p[i], TRUE);
7805 proto->__children.n = 0;
7810 closeConsoleMessage();
7823 killKeySensorNodeList();
7830 setMenuStatus(NULL);
7833 kill_userDefinedShaders();
7840 #if !defined(EXCLUDE_EAI)
7844 fwlio_RxTx_control(CHANNEL_EAI, RxTx_STOP) ;
7849 sprintf (mystring,
"QUIT");
7850 Sound_toserver(mystring);
7854 if (globalParser != NULL) {
7855 parser_destroyData(globalParser);
7857 gglobal()->CParse.globalParser = NULL;
7864 setMenuStatus(
"NONE");
7870#if !defined(_ANDROID) || defined(ANDROIDNDK)
7875char *strBackslash2fore(
char *);
7876void fwl_replaceWorldNeeded(
char* str)
7878 ConsoleMessage(
"file to load: %s\n",str);
7879 FREE_IF_NZ(gglobal()->Mainloop.replaceWorldRequest);
7880 gglobal()->Mainloop.replaceWorldRequest = strBackslash2fore(STRDUP(str));
7883 gglobal()->Mainloop.replaceWorldRequestMulti = (
void*)(multiResWithParent);
7889 ConsoleMessage(
"fwl_reload called");
7896void sendDescriptionToStatusBar(
struct X3D_Node *CursorOverSensitive) {
7902 if (CursorOverSensitive == NULL) update_status(NULL);
7906 for (tmp=0; tmp<vectorSize(p->SensorEvents); tmp++) {
7907 se = vector_get(
struct SensStruct *,p->SensorEvents,tmp);
7908 if (se->fromnode == CursorOverSensitive) {
7909 switch (se->datanode->_nodeType) {
7910 case NODE_Anchor: ns = ((
struct X3D_Anchor *)se->datanode)->description->strptr;
break;
7911 case NODE_LineSensor: ns = ((
struct X3D_LineSensor *)se->datanode)->description->strptr;
break;
7912 case NODE_PointSensor: ns = ((
struct X3D_PointSensor *)se->datanode)->description->strptr;
break;
7913 case NODE_PlaneSensor: ns = ((
struct X3D_PlaneSensor *)se->datanode)->description->strptr;
break;
7914 case NODE_SphereSensor: ns = ((
struct X3D_SphereSensor *)se->datanode)->description->strptr;
break;
7915 case NODE_TouchSensor: ns = ((
struct X3D_TouchSensor *)se->datanode)->description->strptr;
break;
7916 case NODE_GeoTouchSensor: ns = ((
struct X3D_GeoTouchSensor *)se->datanode)->description->strptr;
break;
7917 case NODE_CylinderSensor: ns = ((
struct X3D_CylinderSensor *)se->datanode)->description->strptr;
break;
7918 default: {printf (
"sendDesc; unknown node type %d\n",se->datanode->_nodeType);}
7921 if (ns == NULL) {ns =
"(over sensitive)";}
7922 else if (ns[0] ==
'\0') ns = (
char *)stringNodeType(se->datanode->_nodeType);
7933void resetSensorEvents(
void) {
7937 for(ktouch=0;ktouch<20;ktouch++){
7938 struct Touch *touch;
7939 touch = &p->touchlist[ktouch];
7941 if (touch->oldCOS != NULL)
7942 sendSensorEvents(touch->oldCOS,MapNotify,touch->buttonState, FALSE);
7946 sendDescriptionToStatusBar(NULL);
7947 memset(touch,0,
sizeof(
struct Touch));
7949 for(ktouch=0;ktouch<vectorSize(p->SensorEvents);ktouch++){
7953 vector_clear(p->SensorEvents);
7954 gglobal()->RenderFuncs.hypersensitive = NULL;
7955 gglobal()->RenderFuncs.hyperhit = 0;