29#include <system_threads.h>
33#include <libFreeWRL.h>
46#include "../vrml_parser/Structs.h"
47#include "../vrml_parser/CRoutes.h"
49#include "../vrml_parser/CParseGeneral.h"
50#include "../world_script/JScript.h"
51#include "../world_script/CScripts.h"
53#include "../scenegraph/LinearAlgebra.h"
54#include "../scenegraph/Collision.h"
56#include "../scenegraph/Viewer.h"
57#include "../input/SensInterps.h"
58#include "../x3d_parser/Bindable.h"
59#include "../input/EAIHeaders.h"
61#include "../scenegraph/Component_KeyDevice.h"
62#include "../opengl/Frustum.h"
63#include "../input/InputFunctions.h"
65#include "../opengl/LoadTextures.h"
66#include "../opengl/OpenGL_Utils.h"
67#include "../ui/statusbar.h"
68#include "../ui/CursorDraw.h"
69#include "../scenegraph/RenderFuncs.h"
71#include "../ui/common.h"
72#include "../io_files.h"
75#include "../scenegraph/quaternion.h"
77ivec2 ivec2_init(
int x,
int y);
78ivec4 ivec4_init(
int x,
int y,
int w,
int h);
80int getRayHitAndSetLookatTarget();
81void transformMBB(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax);
88void (*newResetGeometry) (void) = NULL;
97OLDCODE #
if defined(_ANDROID )
98OLDCODE
void setAquaCursor(
int ctype) { };
105static int debugging_trigger_state;
106void toggle_debugging_trigger(){
108 debugging_trigger_state = 1 - debugging_trigger_state;
110int get_debugging_trigger_once(){
111 int iret = debugging_trigger_state;
112 if(iret) debugging_trigger_state = 0;
115int get_debugging_trigger(){
116 return debugging_trigger_state;
120 return gglobal()->Mainloop.TickTime;
124 return gglobal()->Mainloop.lastTime;
131 void (*interpptr)(
void *, int, int, int);
138 TOUCHTYPE_SINGLE = 0,
139 TOUCHTYPE_EMULATE_MULTITOUCH = 1,
140 TOUCHTYPE_MULTITOUCH = 2,
141 TOUCHTYPE_GESTURE = 3,
151 TOUCHCLAIMANT_UNCLAIMED = 0,
152 TOUCHCLAIMANT_PEDAL = 1,
153 TOUCHCLAIMANT_SENSOR = 2,
154 TOUCHCLAIMANT_NAVIGATION = 4,
155 TOUCHCLAIMANT_NONE = 8,
180 struct X3D_Node* CursorOverSensitive;
184 int lastOverButtonPressed;
186 void *hypersensitive;
188 double justModel[16];
202void pushviewport(Stack *vpstack,
ivec4 vp){
203 stack_push(
ivec4,vpstack,vp);
205void popviewport(Stack *vpstack){
206 stack_pop(
ivec4,vpstack);
211 inside = vp1.X >= vp2.X && (vp1.X+vp1.W) <= (vp2.X+vp2.W) ? 1 : 0;
213 inside = vp2.X >= vp1.X && (vp2.X+vp2.W) <= (vp1.X+vp1.W) ? -1 : 0;
216 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;
222 vpo.X = max(vp1.X,vp2.X);
223 vpo.W = min(vp1.X+vp1.W,vp2.X+vp2.W) - vpo.X;
224 vpo.Y = max(vp1.Y,vp2.Y);
225 vpo.H = min(vp1.Y+vp1.H,vp2.Y+vp2.H) - vpo.Y;
229int visibleviewport(
ivec4 vp){
230 int ok = vp.W > 0 && vp.H > 0;
235 inside = inside && pt.X <= (vp.X + vp.W) && (pt.X >= vp.X);
236 inside = inside && pt.Y <= (vp.Y + vp.H) && (pt.Y >= vp.Y);
239int pointinsidecurrentviewport(Stack *vpstack,
ivec2 pt){
241 return pointinsideviewport(vp,pt);
243void intersectandpushviewport(Stack *vpstack,
ivec4 childvp){
245 ivec4 olap = intersectviewports(childvp,currentvp);
246 pushviewport(vpstack, olap);
248ivec4 currentViewport(Stack *vpstack){
249 return stack_top(
ivec4,vpstack);
251int currentviewportvisible(Stack *vpstack){
253 return visibleviewport(currentvp);
255void setcurrentviewport(Stack *_vpstack){
257 glViewport(vp.X,vp.Y,vp.W,vp.H);
259ivec4 viewportFraction(
ivec4 vp,
float *fraction){
278 L = (int)(vp.X + vp.W*fraction[0]);
279 R = (int)(vp.X + vp.W*fraction[1]);
280 B = (int)(vp.Y + vp.H*fraction[2]);
281 T = (int)(vp.Y + vp.H*fraction[3]);
324 CONTENT_STEREO_SIDEBYSIDE,
325 CONTENT_STEREO_ANAGLYPH,
326 CONTENT_STEREO_UPDOWN,
327 CONTENT_STEREO_SHUTTER,
341int haveFrameBufferObject()
344#if defined(GLEW) || defined(GLEW_MX)
345 iret = GLEW_ARB_framebuffer_object != 0;
350void pushnset_framebuffer(
int ibuffer){
351 Stack *framebufferstack;
353 framebufferstack = (Stack *)gglobal()->Mainloop._framebufferstack;
355 stack_push(
int,framebufferstack,ibuffer);
358 if (haveFrameBufferObject() ){
359 glBindFramebuffer(GL_FRAMEBUFFER,0);
360 glBindFramebuffer(GL_FRAMEBUFFER, ibuffer);
364void popnset_framebuffer(){
367 Stack *framebufferstack;
368 framebufferstack = (Stack *)gglobal()->Mainloop._framebufferstack;
370 stack_pop(
int,framebufferstack);
371 ibuffer = stack_top(
int,framebufferstack);
373 if (haveFrameBufferObject()){
374 glBindFramebuffer(GL_FRAMEBUFFER,0);
375 glBindFramebuffer(GL_FRAMEBUFFER, ibuffer);
379void pushnset_viewport(
float *vpFraction){
383 vportstack = (Stack *)gglobal()->Mainloop._vportstack;
384 ivport = currentViewport(vportstack);
385 ivport = viewportFraction(ivport, vpFraction);
386 pushviewport(vportstack,ivport);
387 setcurrentviewport(vportstack);
389void popnset_viewport(){
392 vportstack = (Stack *)gglobal()->Mainloop._vportstack;
393 popviewport(vportstack);
394 setcurrentviewport(vportstack);
396int checknpush_viewport(
float *vpfraction,
int mouseX,
int mouseY){
398 ivec4 ivport, ivport1;
402 vportstack = (Stack *)gglobal()->Mainloop._vportstack;
403 ivport = currentViewport(vportstack);
404 ivport1 = viewportFraction(ivport, vpfraction);
407 iret = pointinsideviewport(ivport1,pt);
408 if(iret) pushviewport(vportstack,ivport1);
419 vportstack = (Stack *)gglobal()->Mainloop._vportstack;
420 popviewport(vportstack);
423ivec4 get_current_viewport(){
425 vportstack = (Stack *)gglobal()->Mainloop._vportstack;
426 return stack_top(
ivec4,vportstack);
428float defaultClipBoundary [] = {0.0f, 1.0f, 0.0f, 1.0f};
456void register_contenttype(
void *ct);
457void free_contenttypes();
461 contenttype *contents;
466 void (*render)(
void *self);
467 int (*pick)(
void *self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex);
472void content_render(
void *_self){
474 contenttype *c, *self;
476 self = (contenttype *)_self;
477 pushnset_viewport(self->t1.viewport);
478 c = self->t1.contents;
486int content_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
489 contenttype *c, *self;
491 self = (contenttype *)_self;
493 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
494 c = self->t1.contents;
496 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
505 self->itype = CONTENT_GENERIC;
506 self->contents = NULL;
507 self->render = content_render;
508 self->pick = content_pick;
509 memcpy(self->viewport,defaultClipBoundary,4*
sizeof(
float));
522int setup_pickside0(
int x,
int y,
int *iside,
ivec4 *vportleft,
ivec4 *vportright);
523void scene_render(
void *self){
527void fwl_handle_aqua_multiNORMAL(
const int mev,
const unsigned int button,
int x,
int y,
unsigned int ID,
int windex);
528int scene_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
532 self = (contenttype *)_self;
534 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
537 inside = setup_pickside0(mouseX,mouseY,&iside,&vport[0],&vport[1]);
539 Stack *vpstack = (Stack*)gglobal()->Mainloop._vportstack;
540 pushviewport(vpstack,vport[iside]);
541 fwl_handle_aqua_multiNORMAL(mev,butnum,mouseX,mouseY,ID,windex);
543 popviewport(vpstack);
549contenttype *new_contenttype_scene(){
551 register_contenttype(self);
552 init_tcontenttype(&self->t1);
553 self->t1.itype = CONTENT_SCENE;
554 self->t1.render = scene_render;
555 self->t1.pick = scene_pick;
556 return (contenttype*)self;
558int statusbar_getClipPlane();
563void render_statusbar0();
564void statusbar_render(
void *_self){
572 pushnset_viewport(self->t1.viewport);
573 self->clipplane = statusbar_getClipPlane();
577 if(self->clipplane != 0){
582 vportstack = (Stack*)tg->Mainloop._vportstack;
583 ivport = stack_top(
ivec4,vportstack);
584 ivport.H -= self->clipplane;
585 ivport.Y += self->clipplane;
586 stack_push(
ivec4,vportstack,ivport);
589 c = self->t1.contents;
596 stack_pop(
ivec4,vportstack);
601int statusbar_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
610 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
611 iret = statusbar_handle_mouse1(mev,butnum,mouseX,mouseY,windex);
617 if(self->clipplane != 0){
622 vportstack = (Stack*)tg->Mainloop._vportstack;
623 ivport = stack_top(
ivec4,vportstack);
624 ivport.H -= self->clipplane;
625 ivport.Y += self->clipplane;
626 stack_push(
ivec4,vportstack,ivport);
630 c = self->t1.contents;
632 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
637 stack_pop(
ivec4,vportstack);
644contenttype *new_contenttype_statusbar(){
646 register_contenttype(self);
647 init_tcontenttype(&self->t1);
648 self->t1.itype = CONTENT_STATUSBAR;
649 self->t1.render = statusbar_render;
650 self->t1.pick = statusbar_pick;
652 return (contenttype*)self;
662void render_switch0();
663void switch_render(
void *_self){
670 pushnset_viewport(self->t1.viewport);
671 c = self->t1.contents;
674 iwhich = *(self->whichPtr);
683int switch_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
692 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
694 c = self->t1.contents;
696 if(i == *(self->whichPtr)){
697 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
707contenttype *new_contenttype_switch(){
709 register_contenttype(self);
710 init_tcontenttype(&self->t1);
711 self->t1.itype = CONTENT_SWITCH;
712 self->t1.render = switch_render;
713 self->t1.pick = switch_pick;
714 self->whichCase = -1;
715 self->whichPtr = &self->whichCase;
716 return (contenttype*)self;
718void contenttype_switch_set_which(contenttype *_self,
int which){
720 self->whichCase = which;
721 self->whichPtr = &self->whichCase;
723void contenttype_switch_set_which_ptr(contenttype *_self,
int *whichPtr){
725 self->whichPtr = whichPtr;
734typedef struct AtlasFont AtlasFont;
736AtlasFont *searchAtlasTableOrLoad(
char *facename,
int EMpixels);
737AtlasEntrySet* searchAtlasFontForSizeOrMake(AtlasFont *font,
int EMpixels);
738typedef struct vec4 {
float X;
float Y;
float Z;
float W;}
vec4;
739vec4 vec4_init(
float x,
float y,
float z,
float w);
740int render_captiontext(AtlasFont *font,
int *utf32,
int len32,
vec4 color);
758void captiontext_render(
void *_self){
762 pushnset_viewport(self->t1.viewport);
764 render_captiontext(self->font, self->utf32, self->len32, self->color);
767int captiontext_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
771contenttype *new_contenttype_captiontext(
char *fontname,
int EMpixels,
vec4 color){
773 register_contenttype(self);
774 init_tcontenttype(&self->t1);
775 self->t1.itype = CONTENT_CAPTIONTEXT;
776 self->t1.render = captiontext_render;
777 self->t1.pick = captiontext_pick;
779 self->EMpixels = EMpixels;
782 self->fontname = fontname;
783 self->caption = NULL;
788 self->font = (AtlasFont*)searchAtlasTableOrLoad(fontname,EMpixels);
790 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
793 return (contenttype*)self;
797unsigned int *utf8_to_utf32(
unsigned char *utf8string,
unsigned int *str32,
unsigned int *len32);
798void captiontext_setString(
void *_self,
char *utf8string){
801 lenstr = strlen(utf8string);
802 if(self->nalloc < lenstr){
803 self->caption = realloc(self->caption,lenstr+1);
805 self->utf32 = realloc(self->utf32,(lenstr+1)*
sizeof(
int));
806 self->nalloc = lenstr;
808 strcpy(self->caption,utf8string);
810 self->utf32 = (
int *)utf8_to_utf32((
unsigned char *)self->caption,(
unsigned int *)self->utf32,(
unsigned int *)&self->len32);
847 unsigned char *Ablob;
849 unsigned char *S, *E;
858void textpanel_render(
void *self);
859contenttype *new_contenttype_textpanel(
char* fontname,
int EMpixels,
int maxlines,
int maxlen,
int wrap){
862 register_contenttype(self);
863 init_tcontenttype(&self->t1);
864 self->t1.itype = CONTENT_TEXTPANEL;
865 self->t1.render = textpanel_render;
868 self->color = vec4_init(1.0f,1.0f,1.0f,0.0f);
870 self->maxlines = maxlines;
871 self->maxlen = maxlen;
876 self->blobsize = self->maxlines * self->maxlen;
877 self->Ablob = (
unsigned char*)MALLOCV(self->blobsize+1);
878 register_contenttype(self->Ablob);
879 memset(self->Ablob,0,self->blobsize+1);
880 self->Z = self->z = self->Ablob;
881 self->S = self->Ablob;
882 self->E = self->Ablob + self->blobsize;
883 self->Blist = MALLOCV(
sizeof(BUTitem)*self->maxlines);
884 register_contenttype(self->Blist);
885 self->rowsize = self->maxlen;
886 self->row = MALLOCV(self->rowsize +1);
887 register_contenttype(self->row);
889 for(i=0;i<self->maxlines;i++){
893 if(prev < 0) prev = self->maxlines -1;
894 if(next > self->maxlines -1) next = 0;
895 self->Blist[i].next = &self->Blist[next];
896 self->Blist[i].prev = &self->Blist[prev];
897 self->Blist[i].B = self->Z;
899 self->bhead = &self->Blist[0];
902 self->fontname = fontname;
903 iem = (int)(EMpixels * fwl_getDensityFactor());
904 self->fontSize = iem;
905 self->maxadvancepx = iem/2;
906 self->initialized = FALSE;
908 self->fontname = fontname;
909 self->font = (AtlasFont*)searchAtlasTableOrLoad(fontname,iem);
911 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
927 return (contenttype*)self;
1002 unsigned char *T, *U, *B;
1003 int lenT, lenU, haveTU;
1006 T = min(self->Z + len, self->E);
1007 U = T == self->E ? self->S : T;
1011 memcpy(self->Z,line,lenT);
1013 memcpy(U,&line[lenT],lenU);
1015 BUTI = endline? self->bhead->next : self->bhead;
1019 self->added = min(self->added + len, self->blobsize + 1);
1020 if(self->added > self->blobsize){
1022 self->z = self->z + 1;
1023 if(self->z > self->E) self->z = self->S;
1026void TextPanel_AddString(
void *_self,
char *
string){
1030 int endline, endstring;
1032 if(s == NULL)
return;
1033 endstring = (*s) ==
'\0';
1036 while( (*ln) !=
'\0' && (*ln) !=
'\n') ln++;
1037 endline = (*ln) ==
'\n';
1038 endstring = (*ln) ==
'\0';
1039 TextPanel_AddLine_blobMethodB(self,s,ln-s,endline);
1044void fwg_register_consolemessage_callbackB(
void *data,
void(*callback)(
void*,
char *));
1045void textpanel_register_as_console(
void *_self){
1046 fwg_register_consolemessage_callbackB(_self,TextPanel_AddString);
1048ivec2 pixel2text(
int x,
int y,
int rowheight,
int maxadvancepx){
1050 int w = maxadvancepx;
1051 ivec2 ret = ivec2_init(x/w,y/h);
1054ivec2 text2pixel(
int x,
int y,
int rowheight,
int maxadvancepx){
1056 int w = maxadvancepx;
1057 ivec2 ret = ivec2_init(x*w, y*h);
1061void atlasfont_get_rowheight_charwidth_px(AtlasFont *font,
int *rowheight,
int *maxadvancepx);
1062static int show_ringtext = 0;
1063int before_textpanel_render_rows(AtlasFont *font,
vec4 color);
1064int textpanel_render_row(AtlasFont *font,
char * cText,
int len,
int *pen_x,
int *pen_y);
1065void after_textpanel_render_rows();
1081 int jline, jrow, nrows, isFull, moredata, rowheight, maxadvancepx, atlasOK;
1083 ivec2 panelsizechars;
1084 BUTitem *BUTI, *LBUTI;
1089 if(self->t1.itype != CONTENT_TEXTPANEL)
return;
1090 if(!self->font )
return;
1092 atlasfont_get_rowheight_charwidth_px(self->font,&rowheight,&maxadvancepx);
1093 panelsizechars = ivec2_init(ivport.W / maxadvancepx, ivport.H / rowheight);
1094 panelsizechars.X = min(panelsizechars.X,self->maxlen);
1095 panelsizechars.Y = min(panelsizechars.Y,self->maxlines);
1110 isFull = self->added > self->blobsize;
1111 moredata = min(self->added,self->blobsize);
1113 int i, nchars, bchars, achars, hasTU, Trow;
1114 unsigned char *B, *A, *U, *T, *P;
1127 nchars = (B - U + T - A);
1129 bchars = nchars - achars;
1131 nrows = (int)ceil((
float)nchars/(
float)panelsizechars.X);
1132 Trow = nrows -1 - (T - A)/panelsizechars.X;
1147 atlasOK = before_textpanel_render_rows(self->font, self->color);
1151 for(i=0;i<nrows;i++){
1153 int l0, l1, i0, lenrow, pen_x, pen_y;
1156 i0 = (nrows-i-1)*panelsizechars.X;
1157 lenrow = min(nchars - i0,panelsizechars.X);
1162 if(jrow > panelsizechars.Y)
1164 row = (
char *)&P[-nchars + i0];
1165 if(hasTU && Trow == i){
1168 row = (
char *)self->row;
1169 memcpy(&row[l0],U,l1);
1170 memcpy(row,&A[i0],l0);
1171 P = &self->E[bchars];
1198 xy = text2pixel(0,jrow,rowheight,maxadvancepx);
1213 textpanel_render_row(self->font, row, lenrow,&pen_x, &pen_y);
1216 memcpy(self->row,row,lenrow);
1217 self->row[lenrow] =
'\n';
1218 self->row[lenrow+1] =
'\0';
1219 printf(
"%s",self->row);
1225 }
while(jrow < panelsizechars.Y && moredata > 0);
1226 after_textpanel_render_rows();
1227 if(0) printf(
"======================\n");
1246void textpanel_render(
void *_self){
1255 pushnset_viewport(self->t1.viewport);
1256 c = self->t1.contents;
1262 if(getShowConsoleText()){
1264 vportstack = (Stack*)tg->Mainloop._vportstack;
1265 ivport = stack_top(
ivec4,vportstack);
1266 textpanel_render_blobmethod(self,ivport);
1292void layer_render(
void *_self){
1294 contenttype *c, *self;
1295 self = (contenttype *)_self;
1296 pushnset_viewport(self->t1.viewport);
1297 c = self->t1.contents;
1304int layer_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1307 contenttype *c, *self, *reverse[10];
1308 self = (contenttype *)_self;
1309 c = self->t1.contents;
1318 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1322 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID,windex);
1330contenttype *new_contenttype_layer(){
1332 register_contenttype(self);
1333 init_tcontenttype(&self->t1);
1334 self->t1.itype = CONTENT_LAYER;
1335 self->t1.render = layer_render;
1336 self->t1.pick = layer_pick;
1337 return (contenttype*)self;
1355int emulate_multitouch2(
struct TouchState2 *touchlist,
int ntouch,
int *IDD,
int *lastbut,
int *mev,
unsigned int *button,
int x,
int y,
int *ID,
int windex);
1356void record_multitouch(
struct TouchState2 *touchlist,
int mev,
int butnum,
int mouseX,
int mouseY,
int ID,
int windex,
int ihandle);
1357void render_multitouch2(
struct TouchState2* touchlist,
int ntouch);
1369void multitouch_render(
void *_self){
1374 pushnset_viewport(self->t1.viewport);
1375 c = self->t1.contents;
1382 render_multitouch2(self->touchlist,self->ntouch);
1385int multitouch_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1393 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1397 if(fwl_get_touchtype() == TOUCHTYPE_EMULATE_MULTITOUCH){
1398 ihandle = emulate_multitouch2(self->touchlist,self->ntouch,&self->IDD,&self->lastbut,&mev,(
unsigned int *)&butnum,mouseX,mouseY,(
int *)&ID,windex);
1399 iret = ihandle < 0 ? 0 : 1;
1403 c = self->t1.contents;
1406 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID,windex);
1411 record_multitouch(self->touchlist,mev,butnum,mouseX,mouseY,ID,windex,ihandle);
1417contenttype *new_contenttype_multitouch(){
1420 register_contenttype(self);
1421 init_tcontenttype(&self->t1);
1422 self->t1.itype = CONTENT_MULTITOUCH;
1423 self->t1.render = multitouch_render;
1424 self->t1.pick = multitouch_pick;
1427 memset(self->touchlist,0,20*
sizeof(
struct TouchState2));
1430 return (contenttype*)self;
1442void e3dmouse_render(
void *_self){
1445 content_render(_self);
1453 vportstack = (Stack*)tg->Mainloop._vportstack;
1454 ivport = stack_top(
ivec4,vportstack);
1455 x = ivport.W/2 + ivport.X;
1456 y = ivport.H/2 + ivport.Y;
1458 fiducialDrawB(CURSOR_DOWN,x,y);
1462int e3dmouse_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1473 int iret, but2, x,y;
1474 unsigned int ID0, ID1;
1480 vportstack = (Stack*)tg->Mainloop._vportstack;
1482 ivport = stack_top(
ivec4,vportstack);
1483 x = ivport.W/2 + ivport.X;
1484 y = ivport.H/2 + ivport.Y;
1490 ivport = stack_top(
ivec4,vportstack);
1492 if(mev == ButtonRelease){
1493 self->sphericalmode = 1 - self->sphericalmode;
1494 if(self->sphericalmode){
1495 printf(
"turning on spherical mode\n");
1496 self->navigationMode = fwl_getNavMode();
1497 fwl_setNavMode(
"SPHERICAL");
1500 iret = content_pick(_self,ButtonPress,but2,mouseX,mouseY,ID0,windex);
1502 printf(
"turning off spherical mode\n");
1503 fwl_set_viewer_type(self->navigationMode);
1506 iret = content_pick(_self,ButtonRelease,but2,mouseX,mouseY,ID0,windex);
1508 self->waste = FALSE;
1509 }
else if(mev == ButtonPress){
1514 if(self->waste)
return 1;
1515 if(self->sphericalmode){
1516 iret = content_pick(_self,mev,butnum,x,y,ID1,windex);
1519 iret = content_pick(_self,MotionNotify,0,mouseX,mouseY,ID0,windex);
1523 iret = content_pick(_self,mev,butnum,mouseX,mouseY,ID0,windex);
1530contenttype *new_contenttype_e3dmouse(){
1532 register_contenttype(self);
1533 init_tcontenttype(&self->t1);
1534 self->t1.itype = CONTENT_E3DMOUSE;
1535 self->t1.render = e3dmouse_render;
1536 self->t1.pick = e3dmouse_pick;
1537 self->sphericalmode = 0;
1540 return (contenttype*)self;
1545 float offset_fraction[2];
1547void loadIdentityMatrix (
double *mat);
1548void get_view_matrix(
double *savePosOri,
double *saveView);
1549static void set_view_matrix(
double *savePosOri,
double *saveView);
1551static void set_quadrant_viewmatrix(
double *savePosOri,
double *saveView,
int iq) {
1555 double viewmatrix[16], tmat[16], pomat[16], vmat[16], bothinverse[16];
1556 double xyz[3], zero[3];
1558 get_view_matrix(savePosOri,saveView);
1560 zero[0] = zero[1] = zero[2] = 0.0;
1561 matmultiplyAFFINE(viewmatrix,saveView,savePosOri);
1562 matinverseAFFINE(bothinverse,viewmatrix);
1564 transformAFFINEd(xyz, zero, bothinverse);
1566 loadIdentityMatrix (pomat);
1567 loadIdentityMatrix (vmat);
1568 if(0) mattranslate(vmat, -Viewer()->Dist,0.0,0.0);
1570 mattranslate(tmat,-xyz[0],-xyz[1],-xyz[2]);
1571 matmultiplyAFFINE(vmat,tmat,vmat);
1575 case 1: matrotate(tmat, 0.0, 0.0,0.0,1.0);
1577 case 2: matrotate(tmat, PI * .5, 1.0,0.0,0.0);
1579 case 3: matrotate(tmat, PI * .5, 0.0,1.0,0.0);
1584 matmultiplyAFFINE(vmat,vmat,tmat);
1585 set_view_matrix(pomat,vmat);
1587void quadrant_render(
void *_self){
1594 pushnset_viewport(self->t1.viewport);
1595 c = self->t1.contents;
1598 double savePosOri[16], saveView[16];
1600 memcpy(viewport,defaultClipBoundary,4*
sizeof(
float));
1602 viewport[0] = i==0 || i==2 ? 0.0f : self->offset_fraction[0];
1603 viewport[1] = i==0 || i==2 ? self->offset_fraction[0] : 1.0f;
1604 viewport[2] = i==0 || i==1 ? 0.0f : self->offset_fraction[1];
1605 viewport[3] = i==0 || i==1 ? self->offset_fraction[1] : 1.0f;
1606 pushnset_viewport(viewport);
1609 set_quadrant_viewmatrix(savePosOri, saveView, i);
1612 set_view_matrix(savePosOri,saveView);
1620int quadrant_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1629 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1630 c = self->t1.contents;
1635 memcpy(viewport,defaultClipBoundary,4*
sizeof(
float));
1637 viewport[0] = i==0 || i==2 ? 0.0f : self->offset_fraction[0];
1638 viewport[1] = i==0 || i==2 ? self->offset_fraction[0] : 1.0f;
1639 viewport[2] = i==0 || i==1 ? 0.0f : self->offset_fraction[1];
1640 viewport[3] = i==0 || i==1 ? self->offset_fraction[1] : 1.0f;
1641 if(checknpush_viewport(viewport,mouseX,mouseY)){
1643 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1656contenttype *new_contenttype_quadrant(){
1658 register_contenttype(self);
1659 init_tcontenttype(&self->t1);
1660 self->t1.itype = CONTENT_QUADRANT;
1661 self->t1.render = quadrant_render;
1662 self->t1.pick = quadrant_pick;
1663 self->offset_fraction[0] = .5f;
1664 self->offset_fraction[1] = .5f;
1665 return (contenttype*)self;
1677void loadIdentityMatrix (
double *mat);
1678void get_view_matrix(
double *savePosOri,
double *saveView);
1679static void set_view_matrix(
double *savePosOri,
double *saveView);
1680void compute_sidebyside_viewport_and_fiducial(
int iside,
ivec4 *ivport,
ivec2 *fidcenter){
1686 ttglobal tg = gglobal();
1691 vportstack = (Stack*)tg->Mainloop._vportstack;
1692 vport = stack_top(
ivec4,vportstack);
1694 screenwidth2 = vport.W/2;
1695 ivport->W = screenwidth2;
1696 ivport->H = vport.H;
1697 ivport->Y = vport.Y;
1699 ivport->X = vport.X;
1701 ivport->X = vport.X + screenwidth2;
1703 fidcenter->Y = vport.Y + vport.H;
1707 expansion =
viewer->screendist - .5;
1708 iexpand = (GLint)(expansion * ivport->W);
1710 fidcenter->X = ivport->X + screenwidth2/2;
1712 fidcenter->X -= iexpand;
1714 fidcenter->X += iexpand;
1717void stereo_sidebyside_render(
void *_self){
1729 pushnset_viewport(self->t1.viewport);
1730 c = self->t1.contents;
1737 ttglobal tg = gglobal();
1742 vportstack = (Stack*)tg->Mainloop._vportstack;
1745 compute_sidebyside_viewport_and_fiducial(
viewer->isideB,&ivport2,&fidcenter);
1749 halfW = ivport2.W / 2;
1750 vpc = halfW + ivport2.X;
1751 viewer->xcenter = (double)(fidcenter.X - vpc)/(double)halfW;
1752 pushviewport(vportstack,ivport2);
1754 setcurrentviewport(vportstack);
1758 fiducialDrawB(CURSOR_FIDUCIALS,fidcenter.X,fidcenter.Y);
1768int stereo_sidebyside_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1781 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1782 c = self->t1.contents;
1788 ivec2 fidcenter, pt;
1791 compute_sidebyside_viewport_and_fiducial(
viewer->isideB,&ivport2,&fidcenter);
1796 iret = pointinsideviewport(ivport2,pt);
1798 pushviewport(gglobal()->Mainloop._vportstack,ivport2);
1799 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1811contenttype *new_contenttype_stereo_sidebyside(){
1813 register_contenttype(self);
1814 init_tcontenttype(&self->t1);
1815 self->t1.itype = CONTENT_STEREO_SIDEBYSIDE;
1816 self->t1.render = stereo_sidebyside_render;
1817 self->t1.pick = stereo_sidebyside_pick;
1818 return (contenttype*)self;
1829void loadIdentityMatrix (
double *mat);
1830void clear_shader_table();
1831void setStereoBufferStyle(
int);
1832void stereo_anaglyph_render(
void *_self){
1849 pushnset_viewport(self->t1.viewport);
1850 c = self->t1.contents;
1853 Viewer_anaglyph_clearSides();
1855 glClearColor(0.0f,0.0f,0.0f,1.0f);
1856 BackEndClearBuffer(2);
1860 Viewer_anaglyph_setSide(i);
1868 Viewer_anaglyph_clearSides();
1877int stereo_anaglyph_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1890 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1891 c = self->t1.contents;
1896 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
1906contenttype *new_contenttype_stereo_anaglyph(){
1908 register_contenttype(self);
1909 init_tcontenttype(&self->t1);
1910 self->t1.itype = CONTENT_STEREO_ANAGLYPH;
1911 self->t1.render = stereo_anaglyph_render;
1912 self->t1.pick = stereo_anaglyph_pick;
1913 return (contenttype*)self;
1923void stereo_updown_render(
void *_self){
1930 ttglobal tg = gglobal();
1937 vportstack = (Stack*)tg->Mainloop._vportstack;
1940 pushnset_viewport(self->t1.viewport);
1941 c = self->t1.contents;
1945 ivport = stack_top(
ivec4,vportstack);
1947 ivport.Y += (1-i)*ivport.H;
1948 pushviewport(vportstack,ivport);
1949 setcurrentviewport(vportstack);
1966int stereo_updown_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
1974 ttglobal tg = gglobal();
1979 vportstack = (Stack*)tg->Mainloop._vportstack;
1982 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
1983 c = self->t1.contents;
1991 ivport = stack_top(
ivec4,vportstack);
1993 ivport.Y += (1-i)*ivport.H;
1996 iret = pointinsideviewport(ivport,pt);
1999 pushviewport(vportstack,ivport);
2000 setcurrentviewport(vportstack);
2002 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
2014contenttype *new_contenttype_stereo_updown(){
2016 register_contenttype(self);
2017 init_tcontenttype(&self->t1);
2018 self->t1.itype = CONTENT_STEREO_UPDOWN;
2019 self->t1.render = stereo_updown_render;
2020 self->t1.pick = stereo_updown_pick;
2021 return (contenttype*)self;
2030void setStereoBufferStyleB(
int itype,
int iside,
int ibuffer);
2031void stereo_shutter_render(
void *_self){
2033 int i, shutterGlasses;
2038 static double shuttertime;
2039 static int shutterside;
2048 if(
viewer->haveQuadbuffer)
2051 pushnset_viewport(self->t1.viewport);
2052 c = self->t1.contents;
2058 if(shutterGlasses == 2)
2060 if(TickTime() - shuttertime > 2.0)
2062 shuttertime = TickTime();
2063 shutterside = 1 - shutterside;
2065 setStereoBufferStyleB(1,i,0);
2068 setStereoBufferStyleB(0,i,0);
2079 setStereoBufferStyleB(1,0,0);
2083int stereo_shutter_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2099 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2100 c = self->t1.contents;
2104 iret = c->t1.pick(c,mev,butnum,mouseX,mouseY,ID, windex);
2115contenttype *new_contenttype_stereo_shutter(){
2117 register_contenttype(self);
2118 init_tcontenttype(&self->t1);
2119 self->t1.itype = CONTENT_STEREO_SHUTTER;
2120 self->t1.render = stereo_shutter_render;
2121 self->t1.pick = stereo_shutter_pick;
2122 return (contenttype*)self;
2138 float offset_fraction;
2142contenttype *new_contenttype_splitter(){
2144 register_contenttype(self);
2145 init_tcontenttype(&self->t1);
2146 self->t1.itype = CONTENT_SPLITTER;
2147 return (contenttype*)self;
2159 unsigned int ibuffer;
2160 unsigned int itexturebuffer;
2161 unsigned int idepthbuffer;
2181void push_stageId(
void *stageId){
2182 Stack *stagestack = (Stack*)gglobal()->Mainloop._stagestack;
2183 stack_push(
void*,stagestack,stageId);
2185void *current_stageId(){
2186 Stack *stagestack = (Stack*)gglobal()->Mainloop._stagestack;
2187 return stack_top(
void*,stagestack);
2190 Stack *stagestack = (Stack*)gglobal()->Mainloop._stagestack;
2191 stack_pop(
void*,stagestack);
2194void stage_render(
void *_self){
2199 pushnset_framebuffer(self->ibuffer);
2200 vportstack = (Stack*)gglobal()->Mainloop._vportstack;
2201 pushviewport(vportstack,self->ivport);
2203 setcurrentviewport(vportstack);
2206 if(self->ibuffer != FW_GL_BACK)
2207 glClearColor(.3f,.4f,.5f,1.0f);
2209 glClearColor(1.0f,0.0f,0.0f,1.0f);
2210 BackEndClearBuffer(2);
2211 content_render(_self);
2214 popnset_framebuffer();
2216int stage_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2218 ivec4 ivport_parent;
2223 ivport_parent = get_current_viewport();
2224 x = mouseX - ivport_parent.X;
2225 y = mouseY - ivport_parent.Y;
2227 x = x + self->ivport.X;
2228 y = y + self->ivport.Y;
2229 vportstack = (Stack*)gglobal()->Mainloop._vportstack;
2230 pushviewport(vportstack,self->ivport);
2232 iret = content_pick(_self,mev,butnum,x,y,ID,windex);
2238contenttype *new_contenttype_stage(){
2240 register_contenttype(self);
2241 init_tcontenttype(&self->t1);
2242 self->t1.itype = CONTENT_STAGE;
2243 self->t1.render = stage_render;
2244 self->t1.pick = stage_pick;
2245 self->type = STAGETYPE_BACKBUF;
2246 self->ibuffer = FW_GL_BACK;
2247 self->clear_zbuffer = TRUE;
2248 self->ivport = ivec4_init(0,0,100,100);
2249 return (contenttype*)self;
2252#ifdef GL_DEPTH_COMPONENT32
2253#define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT32
2255#define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT16
2257contenttype *new_contenttype_stagefbo(
int width,
int height){
2262 _self = new_contenttype_stage();
2263 self = (
stage*)_self;
2264 self->type = STAGETYPE_FBO;
2265 self->ivport.W = width;
2266 self->ivport.H = height;
2270 if ( !haveFrameBufferObject() )
2273 glGenTextures(1, &self->itexturebuffer);
2275 glBindTexture(GL_TEXTURE_2D, self->itexturebuffer);
2276 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2279 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2280 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
2282 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2284 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2285 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2286 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->ivport.W, self->ivport.H, 0, GL_RGBA , GL_UNSIGNED_BYTE, 0);
2289 glBindTexture(GL_TEXTURE_2D, 0);
2291 glGenFramebuffers(1, &self->ibuffer);
2292 glBindFramebuffer(GL_FRAMEBUFFER, self->ibuffer);
2300 glGenRenderbuffers(1, &self->idepthbuffer);
2302 glBindRenderbuffer(GL_RENDERBUFFER, self->idepthbuffer);
2303 glRenderbufferStorage(GL_RENDERBUFFER, FW_GL_DEPTH_COMPONENT, self->ivport.W, self->ivport.H);
2305 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2308 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->itexturebuffer, 0);
2311 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self->idepthbuffer);
2313 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2317void stage_resize(
void *_self,
int width,
int height){
2319 self = (
stage*)_self;
2320 if(self->type == STAGETYPE_FBO){
2321 if(width != self->ivport.W || height != self->ivport.H){
2322 self->ivport.W = width;
2323 self->ivport.H = height;
2324 glBindTexture(GL_TEXTURE_2D, self->itexturebuffer);
2325 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->ivport.W, self->ivport.H, 0, GL_RGBA , GL_UNSIGNED_BYTE, NULL);
2327 glBindTexture(GL_TEXTURE_2D, 0);
2329 glBindRenderbuffer(GL_RENDERBUFFER, self->idepthbuffer);
2330 glRenderbufferStorage(GL_RENDERBUFFER, FW_GL_DEPTH_COMPONENT, self->ivport.W, self->ivport.H);
2333 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2336 glBindFramebuffer(GL_FRAMEBUFFER, self->ibuffer);
2338 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->itexturebuffer, 0);
2341 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self->idepthbuffer);
2343 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2350 self->ivport.W = width;
2351 self->ivport.H = height;
2359 int nx, ny, nelements, nvert;
2361 GLfloat *vert, *vert2, *tex, *norm, dx, tx;
2363 int usingDistortions;
2367void render_texturegrid(
void *_self);
2368void texturegrid_render(
void *_self){
2369 contenttype *c, *self;
2370 self = (contenttype *)_self;
2371 pushnset_viewport(self->t1.viewport);
2372 c = self->t1.contents;
2375 if(c->t1.itype == CONTENT_STAGE){
2381 vpstack = (Stack*)gglobal()->Mainloop._vportstack;
2382 ivport = stack_top(
ivec4,vpstack);
2383 if(s->ivport.W != ivport.W || s->ivport.H != ivport.H)
2384 stage_resize(c,ivport.W,ivport.H);
2389 render_texturegrid(_self);
2392static GLfloat matrixIdentity[] = {
2393 1.0f, 0.0f, 0.0f, 0.0f,
2394 0.0f, 1.0f, 0.0f, 0.0f,
2395 0.0f, 0.0f, 1.0f, 0.0f,
2396 0.0f, 0.0f, 0.0f, 1.0f
2398int texturegrid_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex);
2399contenttype *new_contenttype_texturegrid(
int nx,
int ny){
2401 register_contenttype(self);
2402 init_tcontenttype(&self->t1);
2403 self->t1.itype = CONTENT_TEXTUREGRID;
2404 self->t1.render = texturegrid_render;
2405 self->t1.pick = texturegrid_pick;
2414 GLfloat *vert, *vert2, *tex, *norm;
2415 GLfloat dx,dy, tx,ty;
2417 index = (GLuint*)MALLOCV((nx-1)*(ny-1)*2*3 *
sizeof(GLuint));
2418 vert = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2419 vert2 = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2420 tex = (GLfloat*)MALLOCV(nx*ny*2*
sizeof(GLfloat));
2421 norm = (GLfloat*)MALLOCV(nx*ny*3*
sizeof(GLfloat));
2422 register_contenttype(index);
2423 register_contenttype(vert);
2424 register_contenttype(vert2);
2425 register_contenttype(tex);
2426 register_contenttype(norm);
2429 dx = 2.0f / (float)(nx-1);
2430 dy = 2.0f / (float)(ny-1);
2431 tx = 1.0f / (float)(nx-1);
2432 ty = 1.0f / (float)(ny-1);
2435 vert[(i*nx + j)*3 + 0] = -1.0f + j*dy;
2436 vert[(i*nx + j)*3 + 1] = -1.0f + i*dx;
2437 vert[(i*nx + j)*3 + 2] = 0.0f;
2438 tex[(i*nx + j)*2 + 0] = 0.0f + j*ty;
2439 tex[(i*nx + j)*2 + 1] = 0.0f + i*tx;
2440 norm[(i*nx + j)*3 + 0] = 0.0f;
2441 norm[(i*nx + j)*3 + 1] = 0.0f;
2442 norm[(i*nx + j)*3 + 2] = 1.0f;
2449 for(j=0;j<ny-1;j++){
2451 index[k++] = i*nx + j;
2452 index[k++] = i*nx + j + 1;
2453 index[k++] = (i+1)*nx + j + 1;
2455 index[k++] = i*nx + j;
2456 index[k++] = (i+1)*nx + j + 1;
2457 index[k++] = (i+1)*nx + j;
2459 self->index = index;
2463 self->vert2 = vert2;
2464 self->nelements = k;
2465 self->nvert = nx*ny;
2467 for(i=0;i<self->nvert;i++){
2468 self->vert2[i*3 +0] = self->vert[i*3 +0];
2469 self->vert2[i*3 +1] = self->vert[i*3 +1];
2470 self->vert2[i*3 +2] = self->vert[i*3 +2];
2473 return (contenttype*)self;
2475void texturegrid_barrel_distort(
void *_self,
float k1){
2482 for(i=0;i<self->nvert;i++){
2483 float radius2, x, y;
2484 x = self->vert[i*3 +0];
2485 y = self->vert[i*3 +1];
2486 radius2 = x*x + y*y;
2487 self->vert2[i*3 +0] = x*(1.0f - k1*radius2);
2488 self->vert2[i*3 +1] = y*(1.0f - k1*radius2);
2496 float aspect, scale, xshift, yshift;
2503 for(i=0;i<self->nvert;i++){
2504 self->vert2[i*3 +0] += xshift;
2505 self->vert2[i*3 +1] += yshift;
2506 self->vert2[i*3 +0] *= 1.0;
2507 self->vert2[i*3 +1] *= aspect;
2508 self->vert2[i*3 +0] *= scale;
2509 self->vert2[i*3 +1] *= scale;
2510 self->vert2[i*3 +2] = self->vert[i*3 +2];
2516void texturegrid_barrel_distort2(
void *_self,
float xc,
float k1){
2526 float xc2 = xc * 2.0f - 1.0f;
2527 for(i=0;i<self->nvert;i++){
2528 float radius2, x, y;;
2529 x = self->vert[i*3 +0];
2530 y = self->vert[i*3 +1];
2531 radius2 = (x-xc2)*(x-xc2) + y*y;
2532 self->vert2[i*3 +0] = x*(1.0f - k1*radius2);
2533 self->vert2[i*3 +1] = y*(1.0f - k1*radius2);
2537 self->usingDistortions = TRUE;
2540void texturegrid_barrel_undistort2(
void *_self,
ivec4 vport,
ivec2 *xy){
2551 x = (float)(xy->X - vport.X) / (float)vport.W;
2552 y = (float)(xy->Y - vport.Y) / (float)vport.H;
2558 float xb, yb, xa,ya, deltax, deltay, xc2, k1, tolerance;
2565 radius2 = (xb-xc2)*(xb-xc2) + yb*yb;
2566 xa = xb*(1.0f - k1*radius2);
2567 ya = yb*(1.0f - k1*radius2);
2572 if(fabs(deltax) + fabs(deltay) < tolerance )
break;
2579 xy->X = (int)(x*vport.W) + vport.X;
2580 xy->Y = (int)(y*vport.H) + vport.Y;
2582int texturegrid_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2590 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2596 ivport = get_current_viewport();
2604 if(self->usingDistortions) texturegrid_barrel_undistort2(self, ivport, &xy );
2607 c = self->t1.contents;
2609 iret = c->t1.pick(c,mev,butnum,x,y,ID, windex);
2617#include "../scenegraph/Component_Shape.h"
2618void render_texturegrid(
void *_self){
2620 int useMip,haveTexture;
2622 GLint positionLoc, texCoordLoc, textureLoc;
2623 GLint textureMatrix0;
2625 s_shader_capabilities_t *scap;
2628 haveTexture = FALSE;
2629 if(self->t1.contents && self->t1.contents->t1.itype == CONTENT_STAGE){
2631 if(s->type == STAGETYPE_FBO){
2632 textureID = s->itexturebuffer;
2636 if(!haveTexture)
return;
2639 FW_GL_DEPTHMASK(GL_FALSE);
2640 glDisable(GL_DEPTH_TEST);
2682 s_shader_capabilities_t* scap;
2685 shader_requirements.debug = 1;
2686 scap = getMyShaders(shader_requirements);
2687 enableGlobalShader(scap);
2689 glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, self->vert2);
2692 glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex);
2693 glEnableVertexAttribArray(positionLoc);
2694 glEnableVertexAttribArray(texCoordLoc);
2697 int ia = glGetUniformLocation(scap->myShaderProgram,
"textureUnit");
2699 glActiveTexture(GL_TEXTURE0);
2700 glBindTexture(GL_TEXTURE_2D, textureID);
2706 scap = getMyShader(ONE_TEX_APPEARANCE_SHADER);
2707 enableGlobalShader(scap);
2708 positionLoc = scap->Vertices;
2709 glVertexAttribPointer(positionLoc, 3, GL_FLOAT,
2710 GL_FALSE, 0, self->vert2);
2712 texCoordLoc = scap->TexCoords[0];
2713 glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex);
2714 glUniform1i(scap->nTexCoordChannels, 1);
2715 glUniform1i(scap->flipuv, 0);
2716 glEnableVertexAttribArray(positionLoc);
2717 glEnableVertexAttribArray(texCoordLoc);
2720 glActiveTexture(GL_TEXTURE0);
2721 glBindTexture(GL_TEXTURE_2D, textureID);
2724 glGenerateMipmap(GL_TEXTURE_2D);
2728 textureLoc = scap->TextureUnit[0];
2729 textureMatrix0 = scap->TextureMatrix[0];
2730 glUniformMatrix4fv(textureMatrix0, 1, GL_FALSE, matrixIdentity);
2731 glUniform1i(scap->nTexMatrix, 1);
2733 glUniform1i(textureLoc, 0);
2734 glUniform1i(scap->textureCount, 1);
2740 glUniformMatrix4fv(scap->ProjectionMatrix, 1, GL_FALSE, matrixIdentity);
2742 glUniformMatrix4fv(scap->ModelViewMatrix, 1, GL_FALSE, matrixIdentity);
2745 glDrawArrays(GL_TRIANGLES,0,self->nelements);
2747 glDrawElements(GL_TRIANGLES,self->nelements,GL_UNSIGNED_INT,self->index);
2750 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
2751 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
2753 restoreGlobalShader();
2754 FW_GL_DEPTHMASK(GL_TRUE);
2755 glEnable(GL_DEPTH_TEST);
2763 int nx, ny, nelements, nvert;
2765 GLfloat *vert, *vert2, *tex, *norm, dx, tx;
2769void render_orientation(
void *_self);
2770void orientation_render(
void *_self){
2771 contenttype *c, *self;
2772 ttglobal tg = gglobal();
2773 self = (contenttype *)_self;
2774 pushnset_viewport(self->t1.viewport);
2775 c = self->t1.contents;
2778 if(c->t1.itype == CONTENT_STAGE){
2780 int fbowidth,fboheight;
2785 vpstack = (Stack*)tg->Mainloop._vportstack;
2786 ivport = stack_top(
ivec4,vpstack);
2787 switch(tg->Mainloop.screenOrientation2){
2791 fbowidth = ivport.H;
2792 fboheight = ivport.W;
2798 fbowidth = ivport.W;
2799 fboheight = ivport.H;
2803 if(s->ivport.W != fbowidth || s->ivport.H != fboheight)
2804 stage_resize(c,fbowidth,fboheight);
2805 if(tg->Mainloop.screenOrientation2 == 0){
2806 c->t1.contents->t1.render(c->t1.contents);
2813 if(tg->Mainloop.screenOrientation2 != 0)
2814 render_orientation(_self);
2819int orientation_pick(
void *_self,
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
2822 contenttype *c, *self;
2824 self = (contenttype *)_self;
2826 if(checknpush_viewport(self->t1.viewport,mouseX,mouseY)){
2829 ttglobal tg = gglobal();
2830 ivport = stack_top(
ivec4,(Stack*)tg->Mainloop._vportstack);
2831 switch(tg->Mainloop.screenOrientation2){
2833 x = ivport.H - mouseY;
2837 x = ivport.W - mouseX;
2838 y = ivport.H - mouseY;
2842 y = ivport.W - mouseX;
2852 c = self->t1.contents;
2854 if(tg->Mainloop.screenOrientation2 == 0)
2855 iret = c->t1.contents->t1.pick(c,mev,butnum,x,y,ID, windex);
2857 iret = c->t1.pick(c,mev,butnum,x,y,ID, windex);
2865void render_orientation(
void *_self);
2870GLfloat quad1Vert[] = {
2876GLfloat quad1Tex[] = {
2882GLuint quad1TriangleInd[] = {
2886contenttype *new_contenttype_orientation(){
2888 register_contenttype(self);
2889 init_tcontenttype(&self->t1);
2890 self->t1.itype = CONTENT_ORIENTATION;
2891 self->t1.render = orientation_render;
2892 self->t1.pick = orientation_pick;
2897 self->vert = quad1Vert;
2898 self->tex = quad1Tex;
2899 self->index = quad1TriangleInd;
2900 self->nelements = 6;
2904 return (contenttype*)self;
2906static GLfloat matrix180[] = {
2907 -1.f, 0.0f, 0.0f, 0.0f,
2908 0.0f,-1.0f, 0.0f, 0.0f,
2909 0.0f, 0.0f, 1.0f, 0.0f,
2910 0.0f, 0.0f, 0.0f, 1.0f
2912static GLfloat matrix270[] = {
2913 0.0f, 1.0f, 0.0f, 0.0f,
2914 -1.f, 0.0f, 0.0f, 0.0f,
2915 0.0f, 0.0f, 1.0f, 0.0f,
2916 0.0f, 0.0f, 0.0f, 1.0f
2918static GLfloat matrix90[] = {
2919 0.0f, -1.0f, 0.0f, 0.0f,
2920 1.0f, 0.0f, 0.0f, 0.0f,
2921 0.0f, 0.0f, 1.0f, 0.0f,
2922 0.0f, 0.0f, 0.0f, 1.0f
2926unsigned int getCircleCursorTextureID();
2927void render_orientation(
void* _self) {
2930 GLint positionLoc, texCoordLoc, textureLoc;
2931 GLint textureMatrix0;
2933 float* orientationMatrix;
2934 s_shader_capabilities_t* scap;
2937 haveTexture = FALSE;
2938 if (self->t1.contents && self->t1.contents->t1.itype == CONTENT_STAGE) {
2940 if (s->type == STAGETYPE_FBO) {
2942 textureID = s->itexturebuffer;
2953 switch (gglobal()->Mainloop.screenOrientation2) {
2955 orientationMatrix = matrix180;
2958 orientationMatrix = matrix270;
2961 orientationMatrix = matrix90;
2967 orientationMatrix = matrixIdentity;
2971 FW_GL_DEPTHMASK(GL_FALSE);
2972 glDisable(GL_DEPTH_TEST);
2980 s_shader_capabilities_t* scap;
2983 shader_requirements.debug = 7;
2984 scap = getMyShaders(shader_requirements);
2985 enableGlobalShader(scap);
2987 glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, self->vert);
2990 glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex);
2991 glEnableVertexAttribArray(positionLoc);
2992 glEnableVertexAttribArray(texCoordLoc);
2995 int ia = glGetUniformLocation(scap->myShaderProgram,
"textureUnit");
2997 glActiveTexture(GL_TEXTURE0);
2998 glBindTexture(GL_TEXTURE_2D, textureID);
3000 int modelviewMatrixLoc = glGetUniformLocation(scap->myShaderProgram,
"fw_ModelViewMatrix");
3001 glUniformMatrix4fv(modelviewMatrixLoc, 1, GL_FALSE, orientationMatrix);
3006 scap = getMyShader(ONE_TEX_APPEARANCE_SHADER);
3007 enableGlobalShader(scap);
3008 positionLoc = scap->Vertices;
3009 glVertexAttribPointer(positionLoc, 3, GL_FLOAT,
3010 GL_FALSE, 0, self->vert);
3012 texCoordLoc = scap->TexCoords[0];
3013 glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, self->tex);
3014 glUniform1i(scap->nTexCoordChannels, 1);
3015 glUniform1i(scap->flipuv, 0);
3016 glEnableVertexAttribArray(positionLoc);
3017 glEnableVertexAttribArray(texCoordLoc);
3020 glActiveTexture(GL_TEXTURE0);
3021 glBindTexture(GL_TEXTURE_2D, textureID);
3022 glUniform1i(scap->textureCount, 1);
3024 textureLoc = scap->TextureUnit[0];
3025 textureMatrix0 = scap->TextureMatrix[0];
3026 glUniformMatrix4fv(textureMatrix0, 1, GL_FALSE, matrixIdentity);
3027 glUniform1i(scap->nTexMatrix, 1);
3029 glUniform1i(textureLoc, 0);
3034 glUniformMatrix4fv(scap->ProjectionMatrix, 1, GL_FALSE, matrixIdentity);
3035 glUniformMatrix4fv(scap->ModelViewMatrix, 1, GL_FALSE, orientationMatrix);
3038 glDrawElements(GL_TRIANGLES, self->nelements, GL_UNSIGNED_INT, self->index);
3040 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
3041 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
3043 restoreGlobalShader();
3044 FW_GL_DEPTHMASK(GL_TRUE);
3045 glEnable(GL_DEPTH_TEST);
3053int frame_increment_even_odd_frame_count(
int ieo){
3055 ieo = ieo > 1 ? 0 : 1;
3066 freewrl_params_t params;
3069void init_targetwindow(
void *_self){
3073 self->swapbuf = TRUE;
3103 char* PluginFullPath;
3108 struct Vector *SensorEvents;
3111 GLint viewPort2[10];
3112 GLint viewpointScreenX[2], viewpointScreenY[2];
3118 double BrowserStartTime;
3119 double BrowserInitTime;
3122 int keypress_wait_for_settle;
3123 char * keypress_string;
3125 unsigned int loop_count;
3127 unsigned int slowloop_count;
3128 unsigned int total_loop_count;
3137 unsigned int currentTouch;
3138 struct Touch touchlist[20];
3146 int draw_initialized;
3148 char keywaitstring[25];
3149 int fps_sleep_remainder;
3150 double screenorientationmatrix[16];
3151 double viewtransformmatrix[16];
3152 double posorimatrix[16];
3153 double stereooffsetmatrix[2][16];
3154 int targets_initialized;
3156 void *hyper_switch[4];
3160 void* selectedViewpoint;
3163 Stack *_framebufferstack;
3164 struct Vector *contenttype_registry;
3170void *Mainloop_constructor(){
3171 void *v = MALLOCV(
sizeof(
struct pMainloop));
3175void Mainloop_init(
struct tMainloop *t){
3178 t->gl_linewidth= 1.0f;
3181 t->BrowserFPS = 100.0;
3182 t->BrowserSpeed = 0.0;
3183 t->BrowserDescription =
"libfreewrl opensource virtual reality player library";
3184 t->trisThisLoop = 0;
3187 t->currentFileVersion = 0;
3189 t->HaveSensitive = FALSE;
3194 t->tmpFileLocation = MALLOC(
char *, 5);
3195 strcpy(t->tmpFileLocation,
"/tmp");
3196 t->replaceWorldRequest = NULL;
3197 t->replaceWorldRequestMulti = NULL;
3199 t->prv = Mainloop_constructor();
3201 ppMainloop p = (ppMainloop)t->prv;
3208 p->doEvents = FALSE;
3215 p->SensorEvents = newVector(
struct SensStruct *,0);
3217 p->bufferarray[0] = FW_GL_BACK;
3218 p->bufferarray[1] = 0;
3221 p->BrowserInitTime = 0.0;
3224 p->keypress_wait_for_settle = 100;
3225 p->keypress_string=NULL;
3229 p->slowloop_count = 0;
3240 p->currentTouch = 0;
3242 p->touch_type = TOUCHTYPE_SINGLE;
3243 memset(p->touchlist,0,20*
sizeof(
struct Touch));
3250 p->keySensorMode = 1;
3251 p->draw_initialized = FALSE;
3253 p->keywaitstring[0] = (char)0;
3254 p->fps_sleep_remainder = 0;
3257 p->targets_initialized = 0;
3258 for(i=0;i<4;i++) init_targetwindow(&p->cwindows[i]);
3260 p->selectedViewpoint = NULL;
3261 p->_vportstack = newStack(
ivec4);
3262 t->_vportstack = (
void *)p->_vportstack;
3263 p->_stagestack = newStack(
void*);
3264 t->_stagestack = (
void *)p->_stagestack;
3265 p->_framebufferstack = newStack(
int);
3266 t->_framebufferstack = (
void*)p->_framebufferstack;
3267 stack_push(
int,p->_framebufferstack,FW_GL_BACK);
3268 p->contenttype_registry = NULL;
3271 memset(&p->pedalstate,0,
sizeof(
struct pedal_state));
3272 p->visit_stack = NULL;
3275void Mainloop_clear(
struct tMainloop *t){
3276 FREE_IF_NZ(t->scene_name);
3277 FREE_IF_NZ(t->scene_suff);
3278 FREE_IF_NZ(t->replaceWorldRequest);
3279 FREE_IF_NZ(t->tmpFileLocation);
3282 ppMainloop p = (ppMainloop)t->prv;
3283 for(k=0;k<vectorSize(p->SensorEvents);k++){
3287 deleteVector(
struct SensStruct*,p->SensorEvents);
3288 deleteVector(
ivec4,p->_vportstack);
3289 deleteVector(
void*,p->_stagestack);
3290 deleteVector(
int,p->_framebufferstack);
3291 free_contenttypes();
3292 deleteVector(contenttype*,p->contenttype_registry);
3295double BrowserStartTime() {
3297 ttglobal tg = gglobal();
3298 p = (ppMainloop)tg->Mainloop.prv;
3299 return p->BrowserStartTime;
3305 ttglobal tg = gglobal();
3306 p = (ppMainloop)tg->Mainloop.prv;
3309int fwl_hwnd_to_windex(
void *hWnd){
3313 ttglobal tg = gglobal();
3314 p = (ppMainloop)tg->Mainloop.prv;
3319 if(!targets[i].hwnd){
3321 targets[i].hwnd = hWnd;
3322 targets[i].swapbuf = TRUE;
3324 if(targets[i].hwnd == hWnd)
return i;
3329void get_view_matrix(
double *savePosOri,
double *saveView) {
3335 ttglobal tg = gglobal();
3338 bstack = getActiveBindableStacks(tg);
3339 matcopy(saveView,bstack->viewtransformmatrix);
3340 matcopy(savePosOri,bstack->posorimatrix);
3343static void set_view_matrix(
double *savePosOri,
double *saveView){
3345 ttglobal tg = gglobal();
3346 p = (ppMainloop)tg->Mainloop.prv;
3349 matcopy(p->viewtransformmatrix,saveView);
3350 matcopy(p->posorimatrix,savePosOri);
3353 bstack = getActiveBindableStacks(tg);
3354 matcopy(bstack->viewtransformmatrix,saveView);
3355 matcopy(bstack->posorimatrix,savePosOri);
3360void fwl_getWindowSize(
int *width,
int *height){
3364 ttglobal tg = gglobal();
3365 *width = tg->display.screenWidth;
3366 *height = tg->display.screenHeight;
3369void fwl_getWindowSize1(
int windex,
int *width,
int *height){
3374 ttglobal tg = gglobal();
3375 p = (ppMainloop)tg->Mainloop.prv;
3377 ivport = p->cwindows[windex].ivport;
3384int isBrowserPlugin = FALSE;
3385void fwl_set_touchtype(
int ion){
3386 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
3387 p->touch_type = ion;
3393int fwl_get_touchtype(){
3394 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
3395 return p->touch_type;
3413#define SEND_BIND_IF_REQUIRED(node) \
3414 if (node != NULL) { send_bind_to(X3D_NODE(node),1); node = NULL; }
3418void setup_viewpoint();
3419void set_viewmatrix();
3422static void sendDescriptionToStatusBar(
struct X3D_Node *CursorOverSensitive);
3424void render_collisions(
int Viewer_type);
3425int slerp_viewpoint2();
3426int slerp_viewpoint3();
3427static void render_pre(
void);
3429int setup_pickside(
int x,
int y);
3430void setup_projection();
3431void setup_pickray(
int x,
int y);
3433void get_hyperhit(
void);
3434static void sendSensorEvents(
struct X3D_Node *COS,
int ev,
int butStatus,
int status);
3436void activate_OSCsensors();
3448#if !defined(_MSC_VER)
3451double Time1970sec(
void) {
3452 struct timeval mytime;
3453 gettimeofday(&mytime, NULL);
3454 return (
double) mytime.tv_sec + (double)mytime.tv_usec/1000000.0;
3461#define DJ_KEEP_COMPILER_WARNING 0
3462#if DJ_KEEP_COMPILER_WARNING
3463#define TI(_tv) gettimeofdat(&_tv)
3464#define TID(_tv) ((double)_tv.tv_sec + (double)_tv.tv_usec/1000000.0)
3469void fwl_do_keyPress0(
int key,
int type);
3470void handle0(
const int mev,
const unsigned int button,
const float x,
const float y);
3471void fwl_handle_aqua_multi(
const int mev,
const unsigned int button,
int x,
int y,
int ID,
int windex);
3473void fwl_RenderSceneUpdateScene0(
double dtime);
3474void splitpath_local_suffix(
const char *url,
char **local_name,
char **suff);
3476void fwl_gotoCurrentViewPoint()
3478 struct tProdCon *t = &gglobal()->ProdCon;
3481 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes, t->currboundvpno),cn);
3487 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,t->viewpointNodes, t->currboundvpno);
3494 printf(
"exiting with value=%d hit Enter:",val);
3499void render_statusbar0(
void){
3500 #if defined(STATUSBAR_HUD)
3502 finishedWithGlobalShader();
3504 restoreGlobalShader();
3542void fwl_RenderSceneUpdateSceneNORMAL() {
3544 ttglobal tg = gglobal();
3545 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
3547 dtime = Time1970sec();
3548 fwl_RenderSceneUpdateScene0(dtime);
3557ivec4 childViewport(
ivec4 parentViewport,
float *clipBoundary);
3601void targetwindow_set_params(
int itargetwindow, freewrl_params_t* params){
3603 ttglobal tg = gglobal();
3604 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
3606 twindows = p->cwindows;
3607 twindows[itargetwindow].params = *params;
3608 if(itargetwindow > 0){
3609 twindows[itargetwindow -1].next = &twindows[itargetwindow];
3611 p->nwindow = max(p->nwindow,itargetwindow+1);
3615 printf(
"windex=%d t->next = %p\n",itargetwindow,t->next);
3618 printf(
"hows that?\n");
3621freewrl_params_t* targetwindow_get_params(
int itargetwindow){
3623 ttglobal tg = gglobal();
3624 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
3626 twindows = p->cwindows;
3627 return &twindows[itargetwindow].params;
3630void fwl_setScreenDim1(
int wi,
int he,
int itargetwindow){
3633 ttglobal tg = gglobal();
3634 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
3641 twindows = p->cwindows;
3642 twindows[itargetwindow].ivport = window_rect;
3649void register_contenttype(
void *ct){
3650 ttglobal tg = gglobal();
3651 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
3652 if(!p->contenttype_registry)
3653 p->contenttype_registry = newVector(
void *,4);
3659 vector_pushBack(
void*,p->contenttype_registry,ct);
3662void free_contenttypes(){
3663 ttglobal tg = gglobal();
3664 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
3665 if(p->contenttype_registry){
3667 for(i=0;i<p->contenttype_registry->n;i++){
3669 ct = vector_get(
void*,p->contenttype_registry,i);
3678void setup_stagesNORMAL(){
3682 ttglobal tg = gglobal();
3683 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
3688 for(i=0;i<p->nwindow;i++){
3689 contenttype *cstage, *cswitch, **last;
3690 freewrl_params_t *dp;
3695 dp = (freewrl_params_t*)tg->display.params;
3696 if(t->params.context != dp->context){
3697 tg->display.params = (
void*)&t->params;
3698 fv_change_GLcontext((freewrl_params_t*)tg->display.params);
3702 cstage = new_contenttype_stage();
3703 cswitch = new_contenttype_switch();
3704 p->hyper_switch[i] = cswitch;
3705 cstage->t1.contents = cswitch;
3706 last = &cswitch->t1.contents;
3708 p->hyper_case[i] = 0;
3717 contenttype *cscene, *csbh;
3719 csbh = new_contenttype_statusbar();
3720 cscene = new_contenttype_scene();
3722 csbh->t1.contents = cscene;
3725 last = &csbh->t1.next;
3733 contenttype *cmultitouch, *cscene, *csbh;
3735 cmultitouch = new_contenttype_multitouch();
3736 cscene = new_contenttype_scene();
3737 csbh = new_contenttype_statusbar();
3739 cmultitouch->t1.contents = csbh;
3740 csbh->t1.contents = cscene;
3742 *last = cmultitouch;
3743 last = &cmultitouch->t1.next;
3752 contenttype *csbh, *cscene, *ctextpanel, *ctext;
3755 csbh = new_contenttype_statusbar();
3756 cscene = new_contenttype_scene();
3757 ctextpanel = new_contenttype_textpanel(
"VeraMono",8,60,120,TRUE);
3758 ccolor = vec4_init(1.0f,.6f,0.0f,1.0f);
3759 ctext = new_contenttype_captiontext(
"VeraMono",12,ccolor);
3763 captiontext_setString(ctext,
"ABCDEDFGHIJKLMNOPQRSTUVWXYZabcd");
3764 ctext->t1.viewport[0] = .1f;
3765 ctext->t1.viewport[1] = .6f;
3766 ctext->t1.viewport[2] = 1.0f;
3767 ctext->t1.viewport[3] = .5f;
3770 textpanel_register_as_console(ctextpanel);
3773 csbh->t1.contents = ctextpanel;
3774 ctextpanel->t1.contents = cscene;
3775 ctextpanel->t1.next = ctext;
3778 last = &csbh->t1.next;
3785 contenttype *cscene, *csbh, *ctext;
3788 csbh = new_contenttype_statusbar();
3789 ccolor = vec4_init(1.0f,.6f,0.0f,1.0f);
3791 ctext = new_contenttype_captiontext(
"freewrl_wingding",10,ccolor);
3793 cscene = new_contenttype_scene();
3802 captiontext_setString(ctext,
"abcdABCDEDFGHIJKLMNOPQRSTUVWXYZ");
3804 ctext->t1.viewport[0] = .1f;
3805 ctext->t1.viewport[1] = .6f;
3806 ctext->t1.viewport[2] = .4f;
3807 ctext->t1.viewport[3] = .5f;
3809 csbh->t1.contents = cscene;
3810 cscene->t1.next = ctext;
3813 last = &csbh->t1.next;
3820 contenttype *csbh, *cscene, *ce3dmouse;
3822 csbh = new_contenttype_statusbar();
3823 ce3dmouse = new_contenttype_e3dmouse();
3825 cscene = new_contenttype_scene();
3827 csbh->t1.contents = ce3dmouse;
3828 ce3dmouse->t1.contents = cscene;
3829 cscene->t1.next = NULL;
3831 last = &csbh->t1.next;
3839 contenttype *csbh, *cscene, *cstagefbo, *ctexturegrid, *cmultitouch;
3841 cmultitouch = new_contenttype_multitouch();
3842 ctexturegrid = new_contenttype_texturegrid(2,2);
3843 cstagefbo = new_contenttype_stagefbo(512,512);
3844 csbh = new_contenttype_statusbar();
3845 cscene = new_contenttype_scene();
3847 cmultitouch->t1.contents = ctexturegrid;
3848 ctexturegrid->t1.contents = cstagefbo;
3849 cstagefbo->t1.contents = csbh;
3850 csbh->t1.contents = cscene;
3852 *last = cmultitouch;
3853 last = &cmultitouch->t1.next;
3860 contenttype *csbh, *cscene, *corientation, *cmultitouch, *cstagefbo;
3862 cmultitouch = new_contenttype_multitouch();
3863 corientation = new_contenttype_orientation();
3864 cstagefbo = new_contenttype_stagefbo(512,512);
3865 csbh = new_contenttype_statusbar();
3866 cscene = new_contenttype_scene();
3868 cmultitouch->t1.contents = corientation;
3869 corientation->t1.contents = cstagefbo;
3870 cstagefbo->t1.contents = csbh;
3871 csbh->t1.contents = cscene;
3873 *last = cmultitouch;
3874 last = &cmultitouch->t1.next;
3882 contenttype *csbh, *cscene, *corientation, *cmultitouch, *cstagefbo;
3884 cmultitouch = new_contenttype_multitouch();
3885 csbh = new_contenttype_statusbar();
3886 corientation = new_contenttype_orientation();
3887 cstagefbo = new_contenttype_stagefbo(512,512);
3888 cscene = new_contenttype_scene();
3890 cmultitouch->t1.contents = csbh;
3891 csbh->t1.contents = corientation;
3892 corientation->t1.contents = cstagefbo;
3893 cstagefbo->t1.contents = cscene;
3895 *last = cmultitouch;
3896 last = &cmultitouch->t1.next;
3903 contenttype *cscene0, *cscene1, *cscene2;
3904 contenttype *cstereo1, *cstereo2, *cstereo3, *cstereo4, *cswitch0;
3905 contenttype *csbh, *ctextpanel;
3907 csbh = new_contenttype_statusbar();
3908 ctextpanel = new_contenttype_textpanel(
"VeraMono",8,60,120,TRUE);
3909 cswitch0 = new_contenttype_switch();
3910 cstereo1 = new_contenttype_stereo_shutter();
3911 cstereo2 = new_contenttype_stereo_sidebyside();
3912 cstereo3 = new_contenttype_stereo_anaglyph();
3913 cstereo4 = new_contenttype_stereo_updown();
3915 contenttype_switch_set_which_ptr(cswitch0,&tg->Viewer.stereotype);
3919 cscene0 = new_contenttype_scene();
3920 cscene1 = new_contenttype_scene();
3921 cscene0->t1.next = cscene1;
3923 cscene2 = new_contenttype_scene();
3927 textpanel_register_as_console(ctextpanel);
3930 csbh->t1.contents = ctextpanel;
3931 ctextpanel->t1.contents = cswitch0;
3932 cswitch0->t1.contents = cscene2;
3933 cscene2->t1.next = cstereo1;
3934 cstereo1->t1.contents = cscene0;
3935 cstereo2->t1.contents = cscene0;
3936 cstereo3->t1.contents = cscene0;
3937 cstereo4->t1.contents = cscene0;
3938 cstereo1->t1.next = cstereo2;
3939 cstereo2->t1.next = cstereo3;
3940 cstereo3->t1.next = cstereo4;
3943 last = &csbh->t1.next;
3950 contenttype *cscene0, *cscene1;
3951 contenttype *cstereo;
3952 contenttype *cstagefbo0, *cstagefbo1;
3953 contenttype *ctexturegrid0, *ctexturegrid1;
3956 csbh = new_contenttype_statusbar();
3957 cstereo = new_contenttype_stereo_sidebyside();
3959 cstagefbo0 = new_contenttype_stagefbo(512,512);
3960 ctexturegrid0 = new_contenttype_texturegrid(5,5);
3962 cstagefbo1 = new_contenttype_stagefbo(512,512);
3963 ctexturegrid1 = new_contenttype_texturegrid(5,5);
3964 cscene0 = new_contenttype_scene();
3965 cscene1 = new_contenttype_scene();
3970 X3D_Viewer *
viewer = Viewer();
3973 xc = 1.0f - (float)
viewer->screendist;
3974 texturegrid_barrel_distort2(ctexturegrid0, xc,.1f);
3975 xc = (float)
viewer->screendist;
3976 texturegrid_barrel_distort2(ctexturegrid1, xc,.1f);
3980 csbh->t1.contents = cstereo;
3981 cstereo->t1.contents = ctexturegrid0;
3982 ctexturegrid0->t1.next = ctexturegrid1;
3983 ctexturegrid0->t1.contents = cstagefbo0;
3984 ctexturegrid1->t1.contents = cstagefbo1;
3985 cstagefbo0->t1.contents = cscene0;
3986 cstagefbo1->t1.contents = cscene1;
3989 last = &csbh->t1.next;
3996 contenttype *cscene0, *cscene1, *cscene2, *cscene3;
3997 contenttype *csbh, *cquadrant;
3999 csbh = new_contenttype_statusbar();
4000 cquadrant = new_contenttype_quadrant();
4002 cscene0 = new_contenttype_scene();
4003 cscene1 = new_contenttype_scene();
4004 cscene2 = new_contenttype_scene();
4005 cscene3 = new_contenttype_scene();
4007 csbh->t1.contents = cquadrant;
4008 cquadrant->t1.contents = cscene0;
4009 cscene0->t1.next = cscene1;
4010 cscene1->t1.next = cscene2;
4011 cscene2->t1.next = cscene3;
4014 last = &csbh->t1.next;
4024 contenttype *cscene0, *cscene1, *cscene2;
4025 contenttype *cstereo1, *cstereo2, *cstereo3, *cstereo4, *cswitch0;
4026 contenttype *csbh, *ctextpanel, **next;
4033 contenttype *corientation, *cstagefbo;
4035 corientation = new_contenttype_orientation();
4036 cstagefbo = new_contenttype_stagefbo(512,512);
4038 *next = corientation;
4039 corientation->t1.contents = cstagefbo;
4040 next = &cstagefbo->t1.contents;
4043 csbh = new_contenttype_statusbar();
4045 next = &csbh->t1.next;
4048 ctextpanel = new_contenttype_textpanel(
"VeraMono",8,60,120,TRUE);
4049 cswitch0 = new_contenttype_switch();
4050 cstereo1 = new_contenttype_stereo_shutter();
4051 cstereo2 = new_contenttype_stereo_sidebyside();
4052 cstereo3 = new_contenttype_stereo_anaglyph();
4053 cstereo4 = new_contenttype_stereo_updown();
4055 contenttype_switch_set_which_ptr(cswitch0,&tg->Viewer.stereotype);
4059 cscene0 = new_contenttype_scene();
4060 cscene1 = new_contenttype_scene();
4061 cscene0->t1.next = cscene1;
4063 cscene2 = new_contenttype_scene();
4067 textpanel_register_as_console(ctextpanel);
4070 next = &ctextpanel->t1.contents;
4071 csbh->t1.contents = ctextpanel;
4074 contenttype *cmultitouch;
4076 cmultitouch = new_contenttype_multitouch();
4077 *next = cmultitouch;
4078 next = &cmultitouch->t1.contents;
4083 cswitch0->t1.contents = cscene2;
4084 cscene2->t1.next = cstereo1;
4085 cstereo1->t1.contents = cscene0;
4086 cstereo2->t1.contents = cscene0;
4087 cstereo3->t1.contents = cscene0;
4088 cstereo4->t1.contents = cscene0;
4089 cstereo1->t1.next = cstereo2;
4090 cstereo2->t1.next = cstereo3;
4091 cstereo3->t1.next = cstereo4;
4092 next = &cstereo4->t1.next;
4095 contenttype *cscene0, *cscene1;
4096 contenttype *cstereo;
4097 contenttype *cstagefbo0, *cstagefbo1;
4098 contenttype *ctexturegrid0, *ctexturegrid1;
4100 cstereo = new_contenttype_stereo_sidebyside();
4102 cstagefbo0 = new_contenttype_stagefbo(512,512);
4103 ctexturegrid0 = new_contenttype_texturegrid(5,5);
4105 cstagefbo1 = new_contenttype_stagefbo(512,512);
4106 ctexturegrid1 = new_contenttype_texturegrid(5,5);
4107 cscene0 = new_contenttype_scene();
4108 cscene1 = new_contenttype_scene();
4113 X3D_Viewer *
viewer = Viewer();
4116 xc = 1.0f - (float)
viewer->screendist;
4117 texturegrid_barrel_distort2(ctexturegrid0, xc,.1f);
4118 xc = (float)
viewer->screendist;
4119 texturegrid_barrel_distort2(ctexturegrid1, xc,.1f);
4123 cstereo->t1.contents = ctexturegrid0;
4124 ctexturegrid0->t1.next = ctexturegrid1;
4125 ctexturegrid0->t1.contents = cstagefbo0;
4126 ctexturegrid1->t1.contents = cstagefbo1;
4127 cstagefbo0->t1.contents = cscene0;
4128 cstagefbo1->t1.contents = cscene1;
4130 next = &cstereo->t1.next;
4134 contenttype *cscene0, *cscene1, *cscene2, *cscene3;
4135 contenttype *cquadrant;
4137 cquadrant = new_contenttype_quadrant();
4139 cscene0 = new_contenttype_scene();
4140 cscene1 = new_contenttype_scene();
4141 cscene2 = new_contenttype_scene();
4142 cscene3 = new_contenttype_scene();
4145 cquadrant->t1.contents = cscene0;
4146 cscene0->t1.next = cscene1;
4147 cscene1->t1.next = cscene2;
4148 cscene2->t1.next = cscene3;
4150 next = &cquadrant->t1.next;
4165void initialize_targets_simple(){
4167 ttglobal tg = gglobal();
4168 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4173 setup_stagesNORMAL();
4177 p->targets_initialized = 1;
4180void update_navigation();
4181void fwl_lockTestMutex();
4182void fwl_unlockTestMutex();
4184void snaapshot_touchstate_for_frame();
4186void fwl_RenderSceneUpdateSceneTARGETWINDOWS() {
4192 ttglobal tg = gglobal();
4193 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4197 if(!p->targets_initialized)
4198 initialize_targets_simple();
4200 dtime = Time1970sec();
4202 vportstack = (Stack *)tg->Mainloop._vportstack;
4203 defaultvport = ivec4_init(0,0,100,100);
4204 pushviewport(vportstack,defaultvport);
4205 snaapshot_touchstate_for_frame();
4207 fwl_RenderSceneUpdateScene0(dtime);
4208 popviewport(vportstack);
4216 static double starttime = 0.0;
4217 if(starttime == 0.0) starttime = dtime;
4218 if(dtime - starttime < 2.0)
return;
4221 for(i=0;i<p->nwindow;i++){
4223 freewrl_params_t *dp;
4228 hyper_switch = p->hyper_switch[i];
4229 hyper_case = p->hyper_case[i];
4230 contenttype_switch_set_which(hyper_switch,hyper_case);
4235 s = (
stage*)(t->stage);
4236 if(s->type == STAGETYPE_BACKBUF){
4237 s->ivport = t->ivport;
4242 fwl_setScreenDim0(s->ivport.W, s->ivport.H);
4243 dp = (freewrl_params_t*)tg->display.params;
4244 if(t->params.context != dp->context){
4245 tg->display.params = (
void*)&t->params;
4246 fv_change_GLcontext((freewrl_params_t*)tg->display.params);
4250 vportstack = (Stack *)tg->Mainloop._vportstack;
4251 pushviewport(vportstack,t->ivport);
4254 popviewport(vportstack);
4256 if(t->swapbuf) { FW_GL_SWAPBUFFERS }
4259 update_navigation();
4266int fwl_handle_mouse_multi_yup(
int mev,
int butnum,
int mouseX,
int yup,
unsigned int ID,
int windex){
4272 ttglobal tg = gglobal();
4273 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4277 t = &p->cwindows[windex];
4278 s = (
stage*)t->stage;
4280 if(s->type == STAGETYPE_BACKBUF)
4281 s->ivport = t->ivport;
4282 vportstack = (Stack *)tg->Mainloop._vportstack;
4283 pushviewport(vportstack,s->ivport);
4284 ihit = s->t1.pick(s,mev,butnum,mouseX,yup,ID,windex);
4285 popviewport(vportstack);
4291void render_multitouch2(
struct TouchState2 *touchlist,
int ntouch){
4293 ttglobal tg = gglobal();
4294 p = (ppMainloop)tg->Mainloop.prv;
4296 if(p->touch_type == TOUCHTYPE_EMULATE_MULTITOUCH) {
4298 for(i=0;i<ntouch;i++){
4299 int kd = touchlist[i].ID;
4303 if(touchlist[i].windex == p->windex)
4306 touch = &touchlist[i];
4307 fiducialDrawB(CURSOR_CIRCLE,touch->rx,touch->ry);
4314void record_multitouch(
struct TouchState2 *touchlist,
int mev,
int butnum,
int mouseX,
int mouseY,
int ID,
int windex,
int ihandle){
4317 touch = &touchlist[ID];
4320 touch->inUse = FALSE;
4324 touch->windex = windex;
4325 touch->stageId = current_stageId();
4327 touch->buttonState = mev == ButtonPress;
4330 touch->angle = 0.0f;
4335int emulate_multitouch2(
struct TouchState2 *touchlist,
int ntouch,
int *IDD,
int *lastbut,
int *mev,
unsigned int *button,
int x,
int y,
int *ID,
int windex)
4341 int i,ihandle, inoisy=0;
4343 static int idone = 0;
4346 printf(
"Use RMB (right mouse button) to create and delete touches\n");
4347 printf(
"Use LMB to drag touches (+- 5 pixel selection window)\n");
4353 if(*mev == ButtonPress && (*button == LMB || *button == RMB)){
4357 for(i=0;i<ntouch;i++){
4358 touch = &touchlist[i];
4360 if(touch->windex == windex )
4361 if((abs(x - touch->rx) < 10) && (abs(y - touch->ry) < 10)){
4363 if(inoisy) printf(
"drag found ID %d\n",*IDD);
4370 if(*lastbut == LMB){
4371 if( *mev == MotionNotify ) {
4375 *mev = MotionNotify;
4379 touch = &touchlist[*IDD];
4384 }
else if(*mev == ButtonRelease){
4387 }
else if(*lastbut == RMB){
4388 if( *mev == ButtonPress )
4391 if(*IDD > -1 && touch){
4392 *mev = ButtonRecycle;
4398 if(inoisy) printf(
"delete ID=%d windex=%d ihandle=%d\n",*IDD,windex,ihandle);
4403 for(i=1;i<ntouch;i++){
4404 touch = &touchlist[i];
4405 if(touch->inUse == FALSE) {
4413 touch->inUse = TRUE;
4414 if(inoisy) printf(
"create ID=%d windex=%d\n",i,windex);
4426int fwl_handle_mouse_multi(
int mev,
int butnum,
int mouseX,
int mouseY,
unsigned int ID,
int windex){
4430 ttglobal tg = gglobal();
4431 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4433 t = &p->cwindows[windex];
4436 yup = t->ivport.H - mouseY;
4437 fwl_handle_mouse_multi_yup(mev,butnum,mouseX,yup,ID,windex);
4438 return getCursorStyle();
4446void fwl_handle_mouse_window_leave() {
4447 ttglobal tg = gglobal();
4448 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4458 if (targets[i].hwnd != NULL) {
4459 fwl_handle_mouse(ButtonRelease,1,0,0,i);
4460 fwl_handle_mouse(ButtonRelease,2,0,0,i);
4461 fwl_handle_mouse(ButtonRelease,3,0,0,i);
4467int fwl_handle_mouse0(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex){
4468 int cstyle, tactic_up_drag;
4469 static unsigned int ID = 1;
4470 ttglobal tg = gglobal();
4471 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4473 cstyle = fwl_handle_mouse_multi(mev,butnum,mouseX,mouseY,ID,windex);
4477int fwl_handle_mouse(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex) {
4478 if (fwl_get_modeRecord())
4479 record_mouse(mev, butnum, mouseX, mouseY, windex);
4480 return fwl_handle_mouse0(mev, butnum, mouseX, mouseY, windex);
4482int fwl_handle_touch0(
int mev,
unsigned int ID,
int mouseX,
int mouseY,
int windex) {
4489 cstyle = fwl_handle_mouse_multi(mev, ibut, mouseX, mouseY, ID, windex);
4493int fwl_handle_touch(
int mev,
unsigned int ID,
int mouseX,
int mouseY,
int windex) {
4494 if (fwl_get_modeRecord())
4495 record_touch(mev, ID, mouseX, mouseY, windex);
4496 return fwl_handle_touch0(mev, ID, mouseX, mouseY, windex);
4501void viewer_getpose(
double *quat4,
double *vec3);
4502void viewer_setpose(
double *quat4,
double *vec3);
4503static int using_sensors_for_navigation = 1;
4504static int using_magnetic = 0;
4505static int using_gyro = 1;
4507void fwl_handle_gyro(
float rx,
float ry,
float rz) {
4508 if(using_sensors_for_navigation && using_gyro){
4509 double axyz[3], dd[3], quat4[4], vec3[3];
4510 static double dt, lasttime, curtime;
4511 Quaternion qq0, qq2, qq;
4512 static int initialized = 0;
4515 lasttime = Time1970sec();
4519 curtime = Time1970sec();
4520 dt = curtime - lasttime;
4523 viewer_getpose(quat4, vec3);
4524 double2quat(&qq0, quat4);
4525 quaternion_normalize(&qq0);
4527 axyz[0] = (double)rx;
4528 axyz[2] = -(double)ry;
4529 axyz[1] = -(double)rz;
4532 if (fabs(axyz[0]) < .01) axyz[0] = 0.0;
4533 if (fabs(axyz[1]) < .01) axyz[1] = 0.0;
4534 if (fabs(axyz[2]) < .01) axyz[2] = 0.0;
4535 vecscaled(dd, axyz, dt);
4539 euler2quat(&qq2, dd[0], dd[1], dd[2]);
4540 quaternion_multiply(&qq, &qq2, &qq0);
4541 quaternion_normalize(&qq);
4543 quat2double(quat4, &qq);
4544 viewer_setpose(quat4, vec3);
4548void fwl_handle_accelerometer(
float ax,
float ay,
float az){
4552void fwl_handle_magnetic(
float azimuth,
float pitch,
float roll) {
4553 if (using_sensors_for_navigation && using_magnetic) {
4557 double rxyz[3], dd[3], Rxyz[3], quat4[4], vec3[3];
4558 static double ddlast[3];
4559 Quaternion qq0, qq2, qq, qqlast;
4560 static int initialized = 0;
4564 Rxyz[0] = (double)azimuth;
4565 Rxyz[2] = -(double)roll;
4566 Rxyz[1] = -(double)pitch;
4567 vecscaled(ddlast,ddlast,0.0);
4571 viewer_getpose(quat4, vec3);
4572 double2quat(&qq0, quat4);
4573 quaternion_normalize(&qq0);
4575 rxyz[0] = (double)azimuth;
4576 rxyz[2] = -(double)roll;
4577 rxyz[1] = -(double)pitch;
4579 vecdifd(dd,rxyz,Rxyz);
4580 vecscaled(dd, dd, .05);
4582 euler2quat(&qqlast,ddlast[0],ddlast[1],ddlast[2]);
4583 quaternion_normalize(&qqlast);
4584 quaternion_inverse(&qqlast,&qqlast);
4585 quaternion_normalize(&qqlast);
4586 quaternion_multiply(&qq0,&qqlast,&qq0);
4587 quaternion_normalize(&qq0);
4590 euler2quat(&qq2, dd[0], dd[1], dd[2]);
4591 quaternion_multiply(&qq, &qq2, &qq0);
4592 quaternion_normalize(&qq);
4594 quat2double(quat4, &qq);
4595 viewer_setpose(quat4, vec3);
4596 veccopyd(ddlast,dd);
4601OLDCODE
void fwl_handle_magnetic_old(
float azimuth,
float pitch,
float roll) {
4602OLDCODE ConsoleMessage(
"hi from handle_magnetic %f %f %f\n", azimuth, pitch, roll);
4603OLDCODE
if(using_sensors_for_navigation && using_magnetic){
4604OLDCODE
static int initialized = 0;
4605OLDCODE
static float home_azimuth = 0.0f, home_pitch = 0.0f, home_roll = 0.0f;
4606OLDCODE
static double lasttime, curtime, dt;
4607OLDCODE Quaternion qq, qq2;
4608OLDCODE
static Quaternion qq0;
4609OLDCODE
float dazimuth,ddazimuth, dpitch, droll;
4610OLDCODE
double quat4[4], vec3[3], rxyz[3];
4611OLDCODE
static double ypr[3];
4612OLDCODE
static float lazimuth, lpitch, lroll;
4618OLDCODE
if(!initialized){
4619OLDCODE home_azimuth = azimuth;
4620OLDCODE home_pitch = pitch;
4621OLDCODE home_roll = roll;
4622OLDCODE lazimuth = azimuth;
4623OLDCODE lpitch = pitch;
4624OLDCODE lroll = roll;
4625OLDCODE lasttime = Time1970sec();
4626OLDCODE initialized = 1;
4628OLDCODE viewer_getpose(quat4, vec3);
4629OLDCODE double2quat(&qq0, quat4);
4630OLDCODE quaternion_normalize(&qq0);
4632OLDCODE quat2euler(ypr,0,&qq0);
4646OLDCODE curtime = Time1970sec();
4647OLDCODE dt = curtime - lasttime;
4648OLDCODE lasttime = curtime;
4651OLDCODE viewer_getpose(quat4, vec3);
4652OLDCODE double2quat(&qq0,quat4);
4653OLDCODE quaternion_normalize(&qq0);
4655OLDCODE quat2euler(ypr,0,&qq0);
4658OLDCODE dazimuth = (azimuth - home_azimuth);
4659OLDCODE ddazimuth = dazimuth - lazimuth;
4660OLDCODE lazimuth = dazimuth;
4661OLDCODE
if (fabs(ddazimuth) < .7f)
4662OLDCODE dazimuth = 0.0;
4663OLDCODE
if(fabs(ddazimuth) < 2.0f)
4664OLDCODE dazimuth = .01f * dazimuth;
4665OLDCODE
if(fabs(ddazimuth) < 10.0f)
4666OLDCODE dazimuth = .1f * dazimuth;
4668OLDCODE dpitch = (pitch - home_pitch);
4669OLDCODE droll = (roll - home_roll);
4673OLDCODE rxyz[2] = dazimuth*PI/180.0;
4674OLDCODE rxyz[1] = (50.0 - droll )*PI/50.0*dt;
4676OLDCODE rxyz[0] = 0.0;
4677OLDCODE rxyz[1] = 0.0;
4682OLDCODE euler2quat(&qq2,rxyz[0],rxyz[1],-rxyz[2]);
4683OLDCODE quaternion_multiply(&qq,&qq2,&qq0);
4684OLDCODE quaternion_normalize(&qq);
4686OLDCODE quat2double(quat4,&qq);
4687OLDCODE viewer_setpose(quat4,vec3);
4689OLDCODE home_pitch = pitch;
4696void (*fwl_RenderSceneUpdateScenePTR)() = fwl_RenderSceneUpdateSceneTARGETWINDOWS;
4705void fwl_RenderSceneUpdateScene(
void){
4707 fwl_RenderSceneUpdateScenePTR();
4709void setup_picking();
4710void setup_projection();
4711void rbp_run_physics();
4712void fwl_sendreceive_DIS();
4713void fps_histo_collect();
4714static int vp_new_way = 0;
4715int is_vp_new_way() {
4728void visit_check_sound(
struct X3D_Node* node,
unsigned int iframe);
4729void visit_check(
unsigned int iframe) {
4730 ttglobal tg = gglobal();
4731 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4733 Stack* visit_stack = p->visit_stack;
4734 if (!visit_stack)
return;
4735 for (
int i = 0; i < vectorSize(visit_stack); i++) {
4736 struct X3D_Node* node = vector_get(
void*, visit_stack, i);
4737 switch (node->_nodeType) {
4738 case NODE_AudioClip:
4740 case NODE_AudioDestination:
4741 case NODE_BiquadFilter:
4742 case NODE_BufferAudioSource:
4743 case NODE_ChannelMerger:
4744 case NODE_ChannelSelector:
4745 case NODE_ChannelSplitter:
4746 case NODE_Convolver:
4748 case NODE_DynamicsCompressor:
4750 case NODE_ListenerPointSource:
4751 case NODE_MicrophoneSource:
4752 case NODE_OscillatorSource:
4753 case NODE_PeriodicWave:
4755 case NODE_SpatialSound:
4756 case NODE_StreamAudioDestination:
4757 case NODE_StreamAudioSource:
4758 case NODE_WaveShaper:
4759 visit_check_sound(node, iframe);
4766void register_visit_check(
struct X3D_Node* node) {
4767 ttglobal tg = gglobal();
4768 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4770 Stack* visit_stack = p->visit_stack;
4773 visit_stack = newStack(
void*);
4774 p->visit_stack = visit_stack;
4776 stack_push(
void*, visit_stack, node);
4778void fwl_RenderSceneUpdateScene0(
double dtime) {
4784 ttglobal tg = gglobal();
4785 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
4794 PRINT_GL_ERROR_IF_ANY(
"start of renderSceneUpdateScene");
4796 DEBUG_RENDER(
"start of MainLoop (parsing=%s) (url loaded=%s)\n",
4797 BOOL_STR(fwl_isinputThreadParsing()), BOOL_STR(resource_is_root_loaded()));
4800 p->doEvents = (!fwl_isinputThreadParsing()) && (!fwl_isTextureParsing()) && fwl_isInputThreadInitialized();
4804 p->BrowserStartTime = dtime;
4805 tg->Mainloop.TickTime = p->BrowserStartTime;
4806 tg->Mainloop.lastTime = tg->Mainloop.TickTime - 0.01;
4807 if(p->BrowserInitTime == 0.0)
4808 p->BrowserInitTime = dtime;
4814 static int debugg_time = FALSE;
4819 static int frame_count = 0;
4821 dtime = .02 * (double)frame_count;
4824 fps_histo_collect();
4828 if(!((freewrl_params_t*)(tg->display.params))->frontend_handles_display_thread){
4843 double elapsed_time_per_frame, suggested_wait_time, target_time_per_frame, kludgefactor;
4844 int wait_time_micro_sec, target_frames_per_second;
4845 static int emulating_fps_stutter = 0;
4847 target_frames_per_second = fwl_get_target_fps();
4849 if(target_frames_per_second > 0){
4851 elapsed_time_per_frame = TickTime() - lastTime();
4852 if(target_frames_per_second > 0)
4853 target_time_per_frame = 1.0/(double)target_frames_per_second;
4855 target_time_per_frame = 1.0/30.0;
4856 suggested_wait_time = target_time_per_frame - elapsed_time_per_frame;
4857 suggested_wait_time *= kludgefactor;
4858 if(emulating_fps_stutter){
4859 p->total_loop_count++;
4861 if(((p->total_loop_count / 5) % 10) == 0){
4863 suggested_wait_time += .5;
4866 wait_time_micro_sec = (int)(suggested_wait_time * 1000000.0);
4867 if(wait_time_micro_sec > 1)
4868 usleep(wait_time_micro_sec);
4878 if(emulating_fps_stutter){
4879 p->total_loop_count++;
4881 if(((p->total_loop_count / 5) % 10) == 0){
4893 tg->Mainloop.lastTime = tg->Mainloop.TickTime;
4894 tg->Mainloop.TickTime = dtime;
4896 #if !defined(FRONTEND_DOES_SNAPSHOTS)
4898 if (tg->Snapshot.doSnapshot) {
4903 fwl_sendreceive_DIS();
4912 initializeAnyScripts();
4918 if (tg->RenderFuncs.BrowserAction) {
4919 tg->RenderFuncs.BrowserAction = doBrowserAction ();
4925 OcclusionStartofRenderSceneUpdateScene();
4927 startOfLoopNodeUpdates();
4929 if (p->loop_count == 25) {
4930 tg->Mainloop.BrowserFPS = 25.0 / (TickTime()-p->BrowserStartTime);
4931 setMenuFps((
float)tg->Mainloop.BrowserFPS);
4935 p->BrowserStartTime = TickTime();
4940 visit_check(tg->Mainloop.iframe);
4941 tg->Mainloop.iframe++;
4942 tg->Mainloop.trisThisLoop = 0;
4944 if(p->slowloop_count == 1009) p->slowloop_count = 0 ;
4946 if ((p->slowloop_count % 256) == 0) {
4952 activate_OSCsensors() ;
4958 p->slowloop_count++ ;
4961 if (p->keypress_string && p->doEvents) {
4962 if (p->keypress_wait_for_settle > 0) {
4963 p->keypress_wait_for_settle--;
4966 if (*p->keypress_string) {
4968#if !defined( _MSC_VER )
4969 DEBUG_XEV(
"CMD LINE GEN EVENT: %c\n", *p->keypress_string);
4970 fwl_do_keyPress(*p->keypress_string,KeyPress);
4972 p->keypress_string++;
4974 p->keypress_string=NULL;
4985#if defined(TARGET_X11)
4989 for(kw=0;kw<p->nwindow;kw++)
4991 void * xdpy = p->cwindows[kw].params.display;
4993 while(XPending(xdpy)) {
4994 XNextEvent(xdpy, &event);
4995 DEBUG_XEV(
"EVENT through XNextEvent\n");
4996 handle_Xevents(event);
5003 PRINT_GL_ERROR_IF_ANY(
"before xtdispatch");
5004#if defined(TARGET_MOTIF)
5007 frontendUpdateButtons();
5010 while (XtAppPending(Xtcx)!= 0) {
5011 XtAppNextEvent(Xtcx, &event);
5012#ifdef XEVENT_VERBOSE
5015 switch (event.type) {
5017 mev = &
event.xmotion;
5018 TRACE_MSG(
"mouse motion event: win=%u, state=%d\n",mev->window, mev->state);
5022 bev = &
event.xbutton;
5023 TRACE_MSG(
"mouse button event: win=%u, state=%d\n",bev->window, bev->state);
5028 DEBUG_XEV(
"EVENT through XtDispatchEvent\n");
5029 XtDispatchEvent (&event);
5039 PRINT_GL_ERROR_IF_ANY(
"after handle_tick")
5050 if (!is_vp_new_way())
5051 SEND_BIND_IF_REQUIRED(tg->ProdCon.setViewpointBindInRender)
5052 SEND_BIND_IF_REQUIRED(tg->ProdCon.setFogBindInRender)
5053 SEND_BIND_IF_REQUIRED(tg->ProdCon.setBackgroundBindInRender)
5054 SEND_BIND_IF_REQUIRED(tg->ProdCon.setNavigationBindInRender)
5060 process_eventsProcessed();
5062 #if !defined(EXCLUDE_EAI)
5073 int socketVerbose = fwlio_RxTx_control(CHANNEL_EAI, RxTx_GET_VERBOSITY) ;
5075 if ( socketVerbose <= 1 || (socketVerbose > 1 && ((p->slowloop_count % 256) == 0)) ) {
5076 if(fwlio_RxTx_control(CHANNEL_EAI, RxTx_REFRESH) == 0) {
5078 if ( socketVerbose > 1 ) {
5079 printf(
"%s:%d Nothing to be done\n",__FILE__,__LINE__) ;
5082 if ( socketVerbose > 1 ) {
5083 printf(
"%s:%d Test RxTx_PENDING\n",__FILE__,__LINE__) ;
5085 if(fwlio_RxTx_control(CHANNEL_EAI, RxTx_PENDING) > 0) {
5087 if ( socketVerbose != 0 ) {
5088 printf(
"%s:%d Something pending\n",__FILE__,__LINE__) ;
5090 tempEAIdata = fwlio_RxTx_getbuffer(CHANNEL_EAI) ;
5091 if(tempEAIdata != (
char *)NULL) {
5094 if ( socketVerbose != 0 ) {
5095 printf(
"%s:%d Something for EAI to do with buffer addr %p\n",__FILE__,__LINE__,tempEAIdata ) ;
5099 replyData = fwl_EAI_handleBuffer(tempEAIdata);
5103 if(replyData != NULL && strlen(replyData) != 0) {
5104 fwlio_RxTx_sendbuffer(__FILE__,__LINE__,CHANNEL_EAI, replyData) ;
5110 EAI_StillToDo = fwl_EAI_allDone();
5112 if ( socketVerbose != 0 ) {
5113 printf(
"%s:%d Something still in EAI buffer? %d\n",__FILE__,__LINE__,EAI_StillToDo ) ;
5115 replyData = fwl_EAI_handleRest();
5117 }
while(EAI_StillToDo) ;
5127 printf(
"RENDER STEP----------\n");
5137void set_viewmatrix0(
int iplace);
5138struct Touch *currentTouch();
5140void snaapshot_touchstate_for_frame(){
5142 ttglobal tg = gglobal();
5143 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
5144 struct Touch *touch;
5145 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5146 touch = &p->touchlist[ktouch];
5147 touch->last_state = touch->frame_state;
5148 touch->frame_state = touch->state;
5149 touch->changed = FALSE;
5150 if(memcmp(&touch->frame_state,&touch->last_state,
sizeof(
struct TouchState))) {
5151 touch->changed = TRUE;
5157void mainloop_update_touch_hyperhit_matrix(
int touchID,
double *netTao){
5159 struct Touch *touch;
5160 ttglobal tg = gglobal();
5161 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
5162 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5163 touch = &p->touchlist[ktouch];
5164 if(touch->ID == touchID){
5165 matmultiplyAFFINE(touch->justModel,netTao,touch->justModel);
5182void setup_picking(){
5191 ttglobal tg = gglobal();
5192 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
5193 static int loop_count = 0;
5195 if(loop_count < 5)
return;
5199 if (!Viewer()->LookatMode && !tg->Mainloop.SHIFT) {
5201 int x,yup,ktouch,priorclaimants, isOver;
5202 struct Touch *touch;
5203 priorclaimants = TOUCHCLAIMANT_PEDAL;
5204 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5205 touch = &p->touchlist[ktouch];
5206 if(!touch->frame_state.inUse) {
5209 if(touch->windex != windex)
continue;
5210 if(touch->stageId != current_stageId())
continue;
5211 x = touch->frame_state.x;
5212 yup = touch->frame_state.y;
5213 tg->RenderFuncs.touchID = touch->ID;
5214 int dragStart = touch->frame_state.buttonState[1] == 1 && touch->last_state.buttonState[1] == 0 ? TRUE : FALSE;
5215 int dragEnd = touch->frame_state.buttonState[1] == 0 && touch->last_state.buttonState[1] == 1 ? TRUE : FALSE;
5216 int dragStart2 = touch->frame_state.buttonState[2] == 1 && touch->last_state.buttonState[2] == 0 ? TRUE : FALSE;
5217 int dragEnd2 = touch->frame_state.buttonState[2] == 0 && touch->last_state.buttonState[2] == 1 ? TRUE : FALSE;
5218 isOver = (touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants);
5223 if(touch->claimant == TOUCHCLAIMANT_SENSOR || isOver || dragStart || dragStart2 || touch->claimant == TOUCHCLAIMANT_NAVIGATION) {
5224 if(setup_pickside(x,yup)){
5232 setup_pickray(x,yup);
5235 tg->RenderFuncs.hypersensitive = touch->hypersensitive;
5236 tg->RenderFuncs.hyperhit = touch->hyperhit;
5238 if(!touch->hyperhit ){
5241 if(ku)printf(
"doing picking pass dragstart=%d\n",dragStart ? 1 : 0);
5242 render_hier(rootNode(),VF_Sensitive | VF_Geom);
5243 touch->CursorOverSensitive = getRayHit();
5244 if(ku)printf(
"hpdist = %lf\n",(
double)tg->RenderFuncs.hitPointDist);
5245 touch->hitPointDist = tg->RenderFuncs.hitPointDist;
5247 if(ku)printf(
"hitNode %d ", rh->hitNode != NULL ? 1 : 0);
5249 pointxyz2double(center,tg->RenderFuncs.hp);
5250 transformAFFINEd(&touch->ray[3],center,getPickrayMatrix(0));
5252 transformAFFINEd(touch->ray,center,getPickrayMatrix(0));
5253 if(dragStart || dragStart2) veccopyd(touch->pin_point,&touch->ray[3]);
5255 if(ku)printf(
"pin %lf %lf %lf\n",touch->pin_point[0],touch->pin_point[1],touch->pin_point[2]);
5256 memcpy( touch->justModel, ((
struct currayhit *)(tg->RenderFuncs.rayHit))->justModel, 16 *
sizeof(
double));
5257 memcpy( &touch->hp, tg->RenderFuncs.hp,
sizeof(
struct point_XYZ));
5260 touch->CursorOverSensitive = NULL;
5264 memcpy(((
struct currayhit *)(tg->RenderFuncs.rayHit))->justModel, touch->justModel, 16 *
sizeof(
double));
5265 memcpy( tg->RenderFuncs.hp, &touch->hp,
sizeof(
struct point_XYZ));
5269 if(dragStart || dragStart2){
5270 if(touch->CursorOverSensitive){
5271 touch->claimant = TOUCHCLAIMANT_SENSOR;
5273 touch->passed |= TOUCHCLAIMANT_SENSOR;
5277 if (touch->lastOver != touch->CursorOverSensitive) {
5279 printf (
"%lf over changed, p->lastOver %u p->cursorOverSensitive %u, p->butDown1 %d\n",
5280 TickTime(), (
unsigned int) touch->lastOver, (
unsigned int) touch->CursorOverSensitive,
5281 touch->ButDown[p->currentCursor][1]);
5283 if (touch->frame_state.buttonState[1] == 0) {
5287 if (!touch->lastOverButtonPressed) {
5288 sendSensorEvents(touch->lastOver, overMark, 0, FALSE);
5289 sendSensorEvents(touch->CursorOverSensitive, overMark, 0, TRUE);
5290 touch->lastOver = touch->CursorOverSensitive;
5292 touch->lastOverButtonPressed = FALSE;
5294 touch->lastOverButtonPressed = TRUE;
5298 if (p->CursorOverSensitive != NULL)
5299 printf(
"COS %d (%s)\n", (
unsigned int) p->CursorOverSensitive, stringNodeType(p->CursorOverSensitive->_nodeType));
5302 if(touch->claimant != TOUCHCLAIMANT_SENSOR && !isOver) {
5306 if (dragStart && touch->frame_state.buttonState[1] && (touch->lastPressedOver==NULL)) {
5308 touch->lastPressedOver = touch->CursorOverSensitive;
5309 sendSensorEvents(touch->lastPressedOver, ButtonPress, dragStart, TRUE);
5311 if(dragEnd && touch->lastPressedOver!=NULL) {
5315 sendSensorEvents(touch->lastPressedOver, ButtonRelease, touch->frame_state.buttonState[1], TRUE);
5316 touch->lastPressedOver = NULL;
5317 touch->claimant = TOUCHCLAIMANT_UNCLAIMED;
5329 sendSensorEvents(touch->CursorOverSensitive,MotionNotify, touch->frame_state.buttonState[1], TRUE);
5332 sendSensorEvents(touch->lastPressedOver,MotionNotify, touch->frame_state.buttonState[1], TRUE);
5337 sensornode = touch->lastPressedOver ? touch->lastPressedOver : touch->CursorOverSensitive;
5338 sendDescriptionToStatusBar(sensornode);
5339 if (touch->CursorOverSensitive!= NULL) {
5343 if ((touch->lastPressedOver==NULL) && (touch->CursorOverSensitive != touch->oldCOS)) {
5344 sendSensorEvents(touch->oldCOS,MapNotify,touch->frame_state.buttonState[1], FALSE);
5345 sendSensorEvents(touch->CursorOverSensitive,MapNotify,touch->frame_state.buttonState[1], TRUE);
5346 touch->oldCOS = touch->CursorOverSensitive;
5351 if ((touch->oldCOS != NULL) && touch->frame_state.buttonState[1] == 0) {
5352 sendSensorEvents(touch->oldCOS, MapNotify, touch->frame_state.buttonState[1], FALSE);
5354 touch->oldCOS = NULL;
5357 touch->hypersensitive = tg->RenderFuncs.hypersensitive;
5358 touch->hyperhit = tg->RenderFuncs.hyperhit;
5363 else if(Viewer()->LookatMode){
5365 int ktouch, kcount, priorclaimants;
5367 struct Touch *touch;
5368 priorclaimants = TOUCHCLAIMANT_PEDAL;
5371 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5372 touch = &p->touchlist[ktouch];
5373 if(!touch->frame_state.inUse)
continue;
5374 if(touch->windex != windex)
continue;
5375 if(touch->stageId != current_stageId())
continue;
5377 if(touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants)
5378 touch->passed |= TOUCHCLAIMANT_SENSOR;
5380 if(Viewer()->LookatMode == 2 ){
5381 x = touch->frame_state.x;
5382 yup = touch->frame_state.y;
5383 if(setup_pickside(x,yup)){
5385 setup_pickray(x,yup);
5388 render_hier(rootNode(),VF_Sensitive | VF_Geom);
5389 getRayHitAndSetLookatTarget();
5396 int ktouch, priorclaimants;
5397 struct Touch *touch;
5398 priorclaimants = TOUCHCLAIMANT_PEDAL;
5399 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5400 touch = &p->touchlist[ktouch];
5401 if(!touch->frame_state.inUse) {
5404 if(touch->claimant == TOUCHCLAIMANT_UNCLAIMED && touch->passed == priorclaimants){
5405 touch->passed |= TOUCHCLAIMANT_SENSOR;
5412void (*handlePTR)(
const int mev,
const unsigned int button,
const float x,
const float y) = handle0;
5413void handle(
const int mev,
const unsigned int button,
const float x,
const float y)
5415 handlePTR(mev, button, x, y);
5420void SSR_test_cumulative_pose();
5422static void render_pre() {
5423 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
5441 static double toggleTime = 0.0;
5442 static int runTest = 0;
5445 if(dtime - toggleTime > 5.0){
5447 runTest = 1 - runTest;
5450 if(runTest) SSR_test_cumulative_pose();
5456 if (fwl_getCollision() == 1) {
5457 profile_start(
"collision");
5458 render_collisions(Viewer()->type);
5459 profile_end(
"collision");
5471 profile_start(
"hier_prox");
5472 render_hier(rootNode(), VF_Proximity);
5473 profile_end(
"hier_prox");
5477 PRINT_GL_ERROR_IF_ANY(
"GLBackend::render_pre");
5480int setup_pickside0(
int x,
int y,
int *iside,
ivec4 *vportleft,
ivec4 *vportright){
5487 int sideleft, sideright, userPreferredPickSide, ieither;
5488 ivec4 vport, vportscene;
5493 ttglobal tg = gglobal();
5495 userPreferredPickSide =
viewer->dominantEye;
5496 ieither =
viewer->eitherDominantEye;
5499 pt = ivec2_init(x,y);
5500 vportstack = (Stack*)tg->Mainloop._vportstack;
5501 vport = stack_top(
ivec4,vportstack);
5503 vportscene.Y = vport.Y + tg->Mainloop.clipPlane;
5504 vportscene.H = vport.H - tg->Mainloop.clipPlane;
5506 *vportleft = vportscene;
5507 *vportright = vportscene;
5513 vportright->X = vportleft->X + vportleft->W;
5518 *vportright = vportscene;
5519 vportright->Y += tg->Mainloop.clipPlane;
5520 vportright->H -= tg->Mainloop.clipPlane;
5521 *vportleft = *vportright;
5523 vportleft->Y += vportscene.H;
5527 sideleft = sideright=0;
5528 sideleft = pointinsideviewport(*vportleft,pt);
5529 sideright = pointinsideviewport(*vportright,pt);;
5530 if(sideleft && sideright)
5531 *iside = userPreferredPickSide;
5533 *iside = sideleft? 0 : sideright ? 1 : 0;
5534 if(!ieither) *iside = userPreferredPickSide;
5535 return sideleft || sideright;
5537int setup_pickside(
int x,
int y){
5538 ivec4 vpleft, vpright;
5541 inside = setup_pickside0(x,y,&iside,&vpleft,&vpright);
5545void fw_gluPerspective_2(GLDOUBLE xcenter, GLDOUBLE fovy, GLDOUBLE aspect, GLDOUBLE zNear, GLDOUBLE zFar);
5546void setup_projection()
5555 GLDOUBLE fieldofview2;
5557 GLint scissorxl,scissorxr;
5562 ttglobal tg = gglobal();
5563 GLsizei screenwidth2;
5564 GLsizei screenheight, bottom, top;
5565 static int counter = 0;
5567 p = (ppMainloop)tg->Mainloop.prv;
5569 vportstack = (Stack*)tg->Mainloop._vportstack;
5570 vport = stack_top(
ivec4,vportstack);
5572 screenwidth2 = vport.W;
5574 top = vport.Y + vport.H;
5575 bottom = vport.Y + tg->Mainloop.clipPlane;
5576 screenheight = top - bottom;
5578 PRINT_GL_ERROR_IF_ANY(
"XEvents::start of setup_projection");
5581 scissorxr = xvp + screenwidth2;
5582 fieldofview2 =
viewer->fieldofview;
5584 aspect2 = (double)(scissorxr - scissorxl)/(double)(screenheight);
5586 if(
viewer->type==VIEWER_SPHERICAL)
5587 fieldofview2*=
viewer->fovZoom;
5592 xr = xvp + screenwidth2;
5613 expand =
viewer->screendist > .5f;
5614 expansion =
viewer->screendist - .5;
5615 expansion = fabs(expansion);
5616 iexpand = (GLint)(expansion * screenwidth2);
5618 xr -= screenwidth2/4;
5619 xl -= screenwidth2/4;
5620 scissorxr = xvp + screenwidth2/2;
5623 xl += screenwidth2/2;
5624 xr += screenwidth2/2;
5625 scissorxl += screenwidth2/2;
5626 scissorxr += screenwidth2/2;
5645 screenheight = vport.H;
5648 bottom += screenheight;
5650 top -= screenheight;
5652 screenheight -= tg->Mainloop.clipPlane;
5657 printf(
"in setup_projection\n");
5660 aspect2 = (double)(xr - xl)/(double)(screenheight);
5662 screenwidth2 = xr-xl;
5666 FW_GL_MATRIX_MODE(GL_PROJECTION);
5675 FW_GL_SCISSOR(scissorxl,bottom,scissorxr-scissorxl,screenheight);
5676 glEnable(GL_SCISSOR_TEST);
5681 p->viewpointScreenX[
viewer->iside] = xvp + screenwidth2/2;
5682 p->viewpointScreenY[
viewer->iside] = top;
5684 FW_GL_VIEWPORT(xvp - screenwidth2 / 2, bottom, screenwidth2 * 2, screenheight);
5687 FW_GL_VIEWPORT(xvp, bottom, screenwidth2, screenheight);
5690 FW_GL_LOAD_IDENTITY();
5694 double minX, maxX, minY, maxY;
5697 minX =
viewer->orthoField[0];
5698 minY =
viewer->orthoField[1];
5699 maxX =
viewer->orthoField[2];
5700 maxY =
viewer->orthoField[3];
5702 if (screenheight != 0) {
5704 numerator = (maxY - minY) * ((
float) screenwidth2) / ((float) screenheight);
5705 maxX = numerator/2.0f;
5706 minX = -(numerator/2.0f);
5709 FW_GL_ORTHO (minX, maxX, minY, maxY,
5714 if ((fieldofview2 <= 0.0) || (fieldofview2 > 180.0))
5718 if(0) FW_GLU_PERSPECTIVE(fieldofview2, aspect2,
viewer->nearPlane,
viewer->farPlane);
5719 if(1) fw_gluPerspective_2(
viewer->xcenter,fieldofview2, aspect2,
viewer->nearPlane,
viewer->farPlane);
5720 tg->Mainloop.fieldOfView = (float)fieldofview2;
5722 FW_GL_MATRIX_MODE(GL_MODELVIEW);
5723 PRINT_GL_ERROR_IF_ANY(
"XEvents::setup_projection");
5727void getPickrayXY(
int *x,
int *y){
5728 ttglobal tg = gglobal();
5729 *x = tg->Mainloop.pickray_x;
5730 *y = tg->Mainloop.pickray_y;
5733void setPickrayXY(
int x,
int y){
5734 ttglobal tg = gglobal();
5735 tg->Mainloop.pickray_x = x;
5736 tg->Mainloop.pickray_y = y;
5739void setup_pickray0()
5762 double mvident[16], pickMatrix[16], pmi[16], proj[16], R1[16], R2[16], R3[16], T[16];
5763 int viewport[4], x, y;
5764 double A[3], B[3], C[3], a[3], b[3];
5765 double yaw, pitch, yy,xx;
5768 getPickrayXY(&x,&y);
5769 loadIdentityMatrix(mvident);
5770 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
5771 FW_GL_GETINTEGERV(GL_VIEWPORT,viewport);
5781 a[0] = xx; a[1] = yy; a[2] = 0.0;
5782 FW_GLU_UNPROJECT(a[0], a[1], a[2], mvident, proj, viewport,
5784 mattranslate(T,A[0],A[1],A[2]);
5786 b[0] = xx; b[1] = yy; b[2] = 1.0;
5787 FW_GLU_UNPROJECT(b[0], b[1], b[2], mvident, proj, viewport,
5791 if(0) printf(
"Cdif %f %f %f\n",C[0],C[1],C[2]);
5799 yaw = atan2(C[0],-C[2]);
5800 matrixFromAxisAngle4d(R1, -yaw, 0.0, 1.0, 0.0);
5802 transformAFFINEd(C,C,R1);
5803 if(0) printf(
"Yawed Cdif %f %f %f\n",C[0],C[1],C[2]);
5804 pitch = atan2(C[1],-C[2]);
5806 double hypotenuse = sqrt(C[0]*C[0] + C[2]*C[2]);
5807 pitch = atan2(C[1],hypotenuse);
5809 if(0) printf(
"atan2 yaw=%f pitch=%f\n",yaw,pitch);
5812 if(0) printf(
"[yaw=%f pitch=%f\n",yaw,pitch);
5814 matrotate(R1, -pitch, 1.0, 0.0, 0.0);
5815 matrotate(R2, -yaw, 0.0, 1.0, 0.0);
5817 matrixFromAxisAngle4d(R1, pitch, 1.0, 0.0, 0.0);
5818 if(0) printmatrix2(R1,
"pure R1");
5819 matrixFromAxisAngle4d(R2, yaw, 0.0, 1.0, 0.0);
5820 if(0) printmatrix2(R2,
"pure R2");
5822 matmultiplyAFFINE(R3,R1,R2);
5823 if(0) printmatrix2(R3,
"R3=R1*R2");
5825 matmultiplyAFFINE(pickMatrix,R3, T);
5826 matinverseAFFINE(pmi,pickMatrix);
5833 matcopy(pickMatrix,R3);
5834 matinverseAFFINE(pmi,pickMatrix);
5835 if(0)printmatrix2(R3,
"R3[12]=A");
5837 if(0) printmatrix2(pmi,
"inverted");
5838 setPickrayMatrix(0,pickMatrix);
5839 setPickrayMatrix(1,pmi);
5842 double rA[3], rB[3];
5843 transformAFFINEd(rA,A,pmi);
5844 transformAFFINEd(rB,B,pmi);
5845 printf(
" A %f %f %f B %f %f %f \n",A[0],A[1],A[2],B[0],B[1],B[2]);
5846 printf(
"rA %f %f %f rB %f %f %f \n",rA[0],rA[1],rA[2],rB[0],rB[1],rB[2]);
5851void setup_pickray(
int x,
int y){
5855void generate_GeneratedCubeMapTextures();
5856void generate_GlobalShadowMaps();
5858int get_n_depth_slices();
5859void get_depth_slice(
int islice,
double *znear,
double *zfar);
5860void fw_depth_slice_push(
double nearplane,
double farplane);
5861void fw_depth_slice_pop();
5862void clear_renderstate();
5863void lightTable_clear();
5864void render_debug_quad();
5869 int count, nslice, islice;
5871 static double shuttertime;
5872 static int shutterside;
5875 ttglobal tg = gglobal();
5876 p = (ppMainloop)tg->Mainloop.prv;
5878 push_group_extent_default();
5880 generate_GeneratedCubeMapTextures();
5891 for (count = 0; count < p->maxbuffers; count++) {
5893 viewer->buffer = (unsigned)p->bufferarray[count];
5900 if(
viewer->shutterGlasses == 2)
5902 if(TickTime() - shuttertime > 2.0)
5904 shuttertime = TickTime();
5905 if(shutterside > 0) shutterside = 0;
5906 else shutterside = 1;
5908 if(count != shutterside)
continue;
5914 Viewer_anaglyph_clearSides();
5916 Viewer_anaglyph_setSide(count);
5919 BackEndClearBuffer(2);
5920 if(Viewer()->anaglyph)
5921 Viewer_anaglyph_setSide(count);
5926 BackEndClearBuffer(2);
5929 projectorTable_clear();
5931 clear_renderstate();
5932 render_bound_background();
5934 nslice = get_n_depth_slices();
5936 for(islice=0;islice<nslice;islice++){
5937 get_depth_slice(islice,&znear,&zfar);
5938 fw_depth_slice_push(znear,zfar);
5939 glClear(GL_DEPTH_BUFFER_BIT);
5941 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, before render_hier");
5942 push_group_extent_default();
5943 render_hier(rootNode(), VF_globalLight );
5946 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_globalLight)");
5947 render_hier(rootNode(), VF_Other );
5952 profile_start(
"hier_geom");
5953 push_group_extent_default();
5954 render_hier(rootNode(), VF_Geom);
5955 profile_end(
"hier_geom");
5956 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_Geom)");
5959 if (tg->RenderFuncs.have_transparency) {
5961 render_hier(rootNode(), VF_Geom | VF_Blend);
5962 PRINT_GL_ERROR_IF_ANY(
"XEvents::render, render_hier(VF_Geom)");
5965 extent6f_copy(rootNode()->_extent,peek_group_extent());
5968 fw_depth_slice_pop();
5975 fiducialDrawB(CURSOR_FIDUCIALS,p->viewpointScreenX[count],p->viewpointScreenY[count]);
5979 glColorMask(1,1,1,1);
5986 struct Touch *touch;
5987 for(ktouch=0;ktouch<p->ntouch;ktouch++){
5988 touch = &p->touchlist[ktouch];
5989 if(touch->frame_state.inUse){
5991 if(touch->stageId == current_stageId()){
5995 cstyle = CURSOR_DOWN;
5996 if(touch->frame_state.buttonState == 0) cstyle = CURSOR_HOVER;
5997 if(touch->lastOverButtonPressed || touch->CursorOverSensitive)
5998 cstyle = CURSOR_OVER;
5999 if(touch->frame_state.buttonState > 0 || touch->updraw_none == FALSE)
6000 fiducialDrawB(cstyle,touch->frame_state.x,touch->frame_state.y);
6005 render_debug_quad();
6011static int currentViewerLandPort = 0;
6012static int rotatingCCW = FALSE;
6013static double currentViewerAngle = 0.0;
6014static double requestedViewerAngle = 0.0;
6017void setup_viewpoint_part1() {
6036 ttglobal tg = gglobal();
6039 bstack = getActiveBindableStacks(tg);
6041 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6042 FW_GL_LOAD_IDENTITY();
6045 if (
viewer->screenOrientation != currentViewerLandPort) {
6048 rotatingCCW = FALSE;
6049 switch (currentViewerLandPort) {
6051 rotatingCCW= (Viewer()->screenOrientation == 270);
6055 rotatingCCW = (Viewer()->screenOrientation == 0);
6059 rotatingCCW = (Viewer()->screenOrientation != 270);
6063 rotatingCCW = (Viewer()->screenOrientation != 0);
6067 currentViewerLandPort =
viewer->screenOrientation;
6068 requestedViewerAngle = (double)
viewer->screenOrientation;
6071 if (!(APPROX(currentViewerAngle,requestedViewerAngle))) {
6074 currentViewerAngle -= 10.0;
6075 if (currentViewerAngle < -5.0) currentViewerAngle = 360.0;
6078 currentViewerAngle +=10.0;
6079 if (currentViewerAngle > 365.0) currentViewerAngle = 0.0;
6082 FW_GL_ROTATE_D (currentViewerAngle,0.0,0.0,1.0);
6083 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->screenorientationmatrix);
6088 bstack->isStereo =
viewer->isStereo;
6089 bstack->iside =
viewer->iside;
6093 FW_GL_LOAD_IDENTITY();
6094 set_stereo_offset0();
6095 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->stereooffsetmatrix[0]);
6098 FW_GL_LOAD_IDENTITY();
6099 set_stereo_offset0();
6100 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->stereooffsetmatrix[1]);
6102 FW_GL_LOAD_IDENTITY();
6105 viewer_togl(
viewer->fieldofview);
6106 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->posorimatrix);
6108 FW_GL_LOAD_IDENTITY();
6110struct X3D_Node *getActiveLayerBoundViewpoint(){
6113 ttglobal tg = gglobal();
6114 bstack = getActiveBindableStacks(tg);
6117 if(bstack->viewpoint){
6118 if( vectorSize(bstack->viewpoint) > 0){
6119 boundvp = vector_back(
struct X3D_Node*,bstack->viewpoint);
6125struct X3D_Node* getSelectedViewpoint() {
6126 if (is_vp_new_way()) {
6128 ttglobal tg = gglobal();
6129 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
6130 if (p->selectedViewpoint)
6131 return p->selectedViewpoint;
6133 return getActiveLayerBoundViewpoint();
6136 return getActiveLayerBoundViewpoint();
6139void setSelectedViewpoint(
void* viewpoint) {
6140 ttglobal tg = gglobal();
6141 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
6142 p->selectedViewpoint = viewpoint;
6144int render_foundLayerViewpoint(){
6154 boundvp = (
struct X3D_Viewpoint*)getActiveLayerBoundViewpoint();
6161 iret = boundvp->_donethispass;
6164int render_foundSelectedViewpoint() {
6166 if (is_vp_new_way()) {
6169 iret = selectedvp->_donethispass;
6172 iret = render_foundLayerViewpoint();
6176int update_renderFlagC(
struct X3D_Node* p,
int flag,
int setaction);
6177void setup_viewpoint_part2() {
6200 profile_start(
"vp_hier");
6205 boundvp = (
struct X3D_Viewpoint*)getActiveLayerBoundViewpoint();
6207 boundvp->_donethispass = 0;
6208 render_hier(rootNode(), VF_Viewpoint | VF_Background);
6210 boundvp->_donethispass = 0;
6213 profile_end(
"vp_hier");
6217void setup_viewpoint_part3() {
6233 double viewmatrix[16];
6237 ttglobal tg = gglobal();
6240 bstack = getActiveBindableStacks(tg);
6242 PRINT_GL_ERROR_IF_ANY(
"XEvents::setup_viewpoint");
6243 fw_glGetDoublev(GL_MODELVIEW_MATRIX, bstack->viewtransformmatrix);
6261 matcopy(viewmatrix,bstack->screenorientationmatrix);
6264 matmultiplyAFFINE(viewmatrix,bstack->posorimatrix,viewmatrix);
6266 matmultiplyAFFINE(viewmatrix,bstack->viewtransformmatrix,viewmatrix);
6267 fw_glSetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6273void setup_viewpoint(){
6275 setup_viewpoint_part1();
6276 setup_viewpoint_part2();
6277 setup_viewpoint_part3();
6282void set_viewmatrix0(
int iplace) {
6286 double viewmatrix[16];
6290 ttglobal tg = gglobal();
6293 bstack = getActiveBindableStacks(tg);
6295 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6296 matcopy(viewmatrix,bstack->screenorientationmatrix);
6298 int iside = Viewer()->isideB;
6299 matmultiplyAFFINE(viewmatrix,bstack->stereooffsetmatrix[iside],viewmatrix);
6302 int iside = Viewer()->iside;
6303 matmultiplyAFFINE(viewmatrix,bstack->stereooffsetmatrix[iside],viewmatrix);
6305 matmultiplyAFFINE(viewmatrix,bstack->posorimatrix,viewmatrix);
6306 matmultiplyAFFINE(bstack->viewmatrix,bstack->viewtransformmatrix,viewmatrix);
6307 fw_glSetDoublev(GL_MODELVIEW_MATRIX, bstack->viewmatrix);
6309void set_viewmatrix() {
6314char *nameLogFileFolderNORMAL(
char *logfilename,
int size){
6315 strcat(logfilename,
"freewrl_tmp");
6316 fw_mkdir(logfilename);
6317 strcat(logfilename,
"/");
6318 strcat(logfilename,
"logfile");
6321char * (*nameLogFileFolderPTR)(
char *logfilename,
int size) = nameLogFileFolderNORMAL;
6326 ttglobal tg = gglobal();
6327 p = (ppMainloop)tg->Mainloop.prv;
6333 freopen(
"CON",
"w",stdout);
6339 printf(
"logging off\n");
6342 if(p->logfname == NULL){
6343 char logfilename[1000];
6345 logfilename[0] =
'\0';
6346 nameLogFileFolderPTR(logfilename, 1000);
6347 strcat(logfilename,
".log");
6348 p->logfname = STRDUP(logfilename);
6350 printf(
"logging to %s\n",p->logfname);
6351 p->logfile = freopen(p->logfname, mode, stdout );
6356#if defined(_MSC_VER)
6357#define strncasecmp _strnicmp
6359void fwl_set_logfile(
char *lname){
6361 ttglobal tg = gglobal();
6362 p = (ppMainloop)tg->Mainloop.prv;
6363 if (strncasecmp(lname,
"-", 1) == 0) {
6364 printf(
"FreeWRL: output to stdout/stderr\n");
6366 p->logfname = STRDUP(lname);
6371int unload_broto(
struct X3D_Proto* node);
6373void fwl_clearWorld(){
6376 ttglobal tg = gglobal();
6380 unload_broto(X3D_PROTO(rn));
6381 printf(
"unloaded scene as broto\n");
6386 tg->Mainloop.replaceWorldRequest = NULL;
6387 tg->threads.flushing =
true;
6392void sendKeyToKeySensor(
const char key,
int upDown);
6406char lookup_fly_key(
int key);
6408void dump_scenegraph(
int method);
6409void fps_histo_toggle();
6410void toggleTileViewFrozen();
6411void fwl_do_keyPress0(
int key,
int type) {
6414 ttglobal tg = gglobal();
6415 p = (ppMainloop)tg->Mainloop.prv;
6419 if(
key == 27 && type == 1)
6422 p->keySensorMode = 1 - p->keySensorMode;
6424 if (p->keySensorMode && KeySensorNodePresent()) {
6425 sendKeyToKeySensor(
key,type);
6427 int handled = isAqua;
6430 if(type == KEYPRESS){
6440 int len = strlen(p->keywaitstring);
6444 fwl_commandline(p->keywaitstring);
6446 p->keywaitstring[0] =
'\0';
6447 ConsoleMessage(
"%c",
'\n');
6449 ConsoleMessage(
"%c",lkp);
6450 if(lkp ==
'\b' && len){
6451 p->keywaitstring[len-1] =
'\0';
6453 p->keywaitstring[len] = lkp;
6454 p->keywaitstring[len+1] =
'\0';
6462 if(type == KEYPRESS)
6468 case 'n': { fwl_clearWorld();
break; }
6469 case 'e': { fwl_set_viewer_type (VIEWER_EXAMINE);
break; }
6470 case 'w': { fwl_set_viewer_type (VIEWER_WALK);
break; }
6471 case 'd': { fwl_set_viewer_type (VIEWER_FLY);
break; }
6472 case 'f': { fwl_set_viewer_type (VIEWER_EXFLY);
break; }
6473 case 'y': { fwl_set_viewer_type (VIEWER_SPHERICAL);
break; }
6474 case 't': { fwl_set_viewer_type(VIEWER_TURNTABLE);
break; }
6475 case 'm': { fwl_set_viewer_type(VIEWER_LOOKAT);
break; }
6476 case 'g': { fwl_set_viewer_type(VIEWER_EXPLORE);
break; }
6477 case 'h': { fwl_toggle_headlight();
break; }
6478 case 'H': { fps_histo_toggle();
break; }
6479 case '/': { print_viewer();
break; }
6481 case '\\': { dump_scenegraph(1);
break; }
6482 case '|': { dump_scenegraph(2);
break; }
6484 case '+': { dump_scenegraph(4);
break; }
6485 case '-': { dump_scenegraph(5);
break; }
6486 case '`': { toggleLogfile();
break; }
6487 case '$': resource_tree_dump(0, (resource_item_t*)tg->resources.root_res);
break;
6488 case '*': resource_tree_list_files(0, (resource_item_t*)tg->resources.root_res);
break;
6489 case 'q': {
if (!RUNNINGASPLUGIN) {
6490 fwl_doQuit(__FILE__,__LINE__);
6494 case 'c': { toggle_collision();
break;}
6495 case 'v': {fwl_Next_ViewPoint();
break;}
6496 case 'b': {fwl_Prev_ViewPoint();
break;}
6497 case '.': {profile_print_all();
break;}
6498 case ' ': p->keywait = TRUE; ConsoleMessage(
"\n%c",
':'); p->keywaitstring[0] =
'\0';
break;
6499 case ',': toggle_debugging_trigger();
break;
6500 case '=': toggleTileViewFrozen();
break;
6501#if !defined(FRONTEND_DOES_SNAPSHOTS)
6502 case 'x': {Snapshot();
break;}
6506 printf(
"didn't handle key=[%c][%d] type=%d\n",lkp,(
int)lkp,type);
6516 kp = lookup_fly_key(
key);
6519 int keystate = type % 10 == KEYDOWN ? 1 : 0;
6522 tg->Mainloop.CTRL = keystate;
break;
6524 tg->Mainloop.SHIFT = keystate;
break;
6526 case HOME_KEY:
if(keystate) fwl_First_ViewPoint();
break;
6527 case END_KEY:
if(keystate) fwl_Last_ViewPoint();
break;
6528 case PGUP_KEY:
if(keystate) fwl_Prev_ViewPoint();
break;
6529 case PGDN_KEY:
if(keystate) fwl_Next_ViewPoint();
break;
6537 if(tg->Mainloop.SHIFT){
6538 if(type%10 == KEYDOWN && (
key == LEFT_KEY ||
key == RIGHT_KEY)){
6541 ichord = viewer_getKeyChord();
6542 if(
key == LEFT_KEY) ichord--;
6543 if(
key == RIGHT_KEY) ichord++;
6544 viewer_setKeyChord(ichord);
6547 double keytime = Time1970sec();
6548 if(type%10 == KEYDOWN)
6549 handle_key(kp,keytime);
6550 if(type%10 == KEYUP)
6551 handle_keyrelease(kp,keytime);
6558 ttglobal tg = gglobal();
6559 return tg->Mainloop.SHIFT;
6561void fwl_setShift(
int ishift){
6562 ttglobal tg = gglobal();
6563 tg->Mainloop.SHIFT = ishift;
6567 ttglobal tg = gglobal();
6568 return tg->Mainloop.CTRL;
6572int platform2web3dActionKey(
int platformKey);
6574void fwl_do_rawKeyPress(
int key,
int type) {
6575 if (fwl_get_modeRecord())
6576 record_rawkeypress(
key, type);
6577 fwl_do_keyPress0(
key,type);
6580void fwl_do_keyPress(
char kp,
int type) {
6587 ConsoleMessage(
"key pressed decimal = %d\n",
key);
6588 if (type != KEYPRESS)
6589 actionKey = platform2web3dActionKey(
key);
6591 fwl_do_rawKeyPress(actionKey,type+10);
6593 fwl_do_rawKeyPress(
key,type);
6598void fwl_gotoViewpoint (
char *findThisOne) {
6601 struct tProdCon *t = &gglobal()->ProdCon;
6604 if (findThisOne != NULL) {
6605 for (i=0; i<vectorSize(t->viewpointNodes); i++) {
6606 switch ((vector_get(
struct X3D_Node*, t->viewpointNodes,i)->_nodeType)) {
6607 case NODE_Viewpoint:
6608 if (strcmp(findThisOne,
6609 X3D_VIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6615 case NODE_GeoViewpoint:
6616 if (strcmp(findThisOne,
6617 X3D_GEOVIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6622 case NODE_OrthoViewpoint:
6623 if (strcmp(findThisOne,
6624 X3D_ORTHOVIEWPOINT(vector_get(
struct X3D_Node *,t->viewpointNodes,i))->description->strptr) == 0) {
6635 if (whichnode != -1) {
6637 t->setViewpointBindInRender = vector_get(
struct X3D_Node *,t->viewpointNodes,whichnode);
6642void setup_viewpoint_slerp3(
double *center,
double pivot_radius,
double vp_radius);
6644int getRayHitAndSetLookatTarget() {
6651 double pivot_radius, vp_radius;
6654 ttglobal tg = gglobal();
6657 if(tg->RenderFuncs.hitPointDist >= 0) {
6662 if (rh->hitNode == NULL) {
6663 Viewer()->LookatMode = 0;
6666 double center[3], radius;
6668 if(Viewer()->type == VIEWER_LOOKAT){
6670 GLDOUBLE smin[3], smax[3], shapeMBBmin[3], shapeMBBmax[3];
6676 shapeMBBmin[i] = node->_extent[i*2 + 1];
6677 shapeMBBmax[i] = node->_extent[i*2];
6679 transformMBB(smin,smax,rh->modelMatrix,shapeMBBmin,shapeMBBmax);
6682 center[i] = (smax[i] + smin[i])*.5;
6683 radius = max(radius,(max(fabs(smax[i]-center[i]),fabs(smin[i]-center[i]))));
6685 viewerdist = Viewer()->Dist;
6686 vp_radius = max(viewerdist, radius + 5.0);
6693 Viewer()->LookatMode = 3;
6694 setup_viewpoint_slerp3(center,pivot_radius,vp_radius);
6695 }
else if(Viewer()->type == VIEWER_EXPLORE){
6698 pointxyz2double(center,tg->RenderFuncs.hp);
6699 transformAFFINEd(center,center,getPickrayMatrix(0));
6701 vp_radius = .8 * veclengthd(center);
6702 Viewer()->LookatMode = 3;
6703 setup_viewpoint_slerp3(center,pivot_radius,vp_radius);
6715 return Viewer()->LookatMode;
6717void prepare_model_view_pickmatrix_inverse(GLDOUBLE *mvpi);
6736 ttglobal tg = gglobal();
6737 p = (ppMainloop)tg->Mainloop.prv;
6741 if(tg->RenderFuncs.hitPointDist >= 0) {
6746 if (rh->hitNode == NULL){
6763 if (rh->hitNode != NULL)
6770 for(i=0;i<vectorSize(p->SensorEvents);i++){
6771 se = vector_get(
struct SensStruct *,p->SensorEvents,i);
6772 if (se->fromnode == rh->hitNode) {
6774 retnode = ((
struct X3D_Node*) rh->hitNode);
6781 if(retnode != NULL){
6784 GLDOUBLE viewmatrix[16], viewinverse[16];
6786 rh = (
struct currayhit *)tg->RenderFuncs.rayHit;
6788 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6789 fw_glGetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6790 matinverseAFFINE(viewinverse,viewmatrix);
6791 matmultiplyAFFINE(rh->justModel,rh->modelMatrix,viewinverse);
6808 void (*myp)(
unsigned *);
6811 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
6813 switch (datanode->_nodeType) {
6815 case NODE_TouchSensor: myp = (
void *)do_TouchSensor;
break;
6816 case NODE_GeoTouchSensor: myp = (
void *)do_GeoTouchSensor;
break;
6817 case NODE_LineSensor: myp = (
void *)do_LineSensor;
break;
6818 case NODE_PointSensor: myp = (
void *)do_PointSensor;
break;
6819 case NODE_PlaneSensor: myp = (
void *)do_PlaneSensor;
break;
6820 case NODE_MultiTouchSensor: myp = (
void *)do_MultiTouchSensor;
break;
6821 case NODE_CylinderSensor: myp = (
void *)do_CylinderSensor;
break;
6822 case NODE_SphereSensor: myp = (
void *)do_SphereSensor;
break;
6823 case NODE_ProximitySensor:
return;
break;
6824 case NODE_GeoProximitySensor:
return;
break;
6827 case NODE_Anchor: myp = (
void *)do_Anchor; parentNode = datanode;
break;
6836 for (i=0; i<vectorSize(p->SensorEvents); i++) {
6837 se = vector_get(
struct SensStruct *,p->SensorEvents,i);
6838 if ((se->fromnode == parentNode) &&
6839 (se->datanode == datanode) &&
6840 (se->interpptr == (
void *)myp)) {
6846 if (datanode == 0) {
6847 printf (
"setSensitive: datastructure is zero for type %s\n",stringNodeType(datanode->_nodeType));
6854 se->fromnode = parentNode;
6855 se->datanode = datanode;
6856 se->interpptr = (
void *)myp;
6857 vector_pushBack(
struct SensStruct *,p->SensorEvents,se);
6861 int n = vectorSize(ec->__DEFnames);
6864 for (
int i = 0; i < n; i++) {
6865 def = vector_get(
struct brotoDefpair, ec->__DEFnames, i);
6867 if (def.node == node) {
6875char* getNodeDescription(
struct X3D_Node* node) {
6877 int type, kind, iifield;
6879 int iret = getFieldFromNodeAndName(node,
"description", &type, &kind, &iifield, &value);
6881 return value->sfstring->strptr;
6884void dis_send_sensor(
struct X3D_Node* fromNode ,
struct X3D_Node* datanode,
int ev,
int butStatus2,
int status,
float *posn3,
float *norm3);
6887static void sendSensorEvents(
struct X3D_Node* COS,
int ev,
int butStatus,
int status) {
6895 p = (ppMainloop)tg->Mainloop.prv;
6898 if (COS==NULL)
return;
6900 for (count = 0; count < vectorSize(p->SensorEvents); count++) {
6901 se = vector_get(
struct SensStruct *,p->SensorEvents,count);
6903 if (se->fromnode == COS) {
6904 butStatus2 = butStatus;
6906 if (ev==ButtonPress) {
6907 tg->RenderFuncs.hypersensitive = se->fromnode;
6908 tg->RenderFuncs.hyperhit = 1;
6910 }
else if (ev==ButtonRelease) {
6911 tg->RenderFuncs.hypersensitive = 0;
6912 tg->RenderFuncs.hyperhit = 0;
6914 }
else if (ev==MotionNotify) {
6921 printf(
"nodetype %s ", stringNodeType(se->datanode->_nodeType));
6922 printf(
"Sensor description %s ", getNodeDescription(se->datanode));
6923 printf(
"sensor def %s ", lookup_brotoDefname(X3D_PROTO(se->datanode->_executionContext), se->datanode));
6924 vecprint3fb(
"\nhitray ", tg->RenderFuncs.ray_save_posn,
"");
6926 vecprint3fb(
"hitnorm ", norm,
"");
6927 printf(
"but %d status %d", butStatus2, status);
6930 dis_send_sensor(se->fromnode,se->datanode, ev, butStatus2, status, tg->RenderFuncs.hyp_save_posn, tg->RenderFuncs.hyp_save_norm);
6933 se->interpptr(se->datanode, ev,butStatus2, status);
6939int getSensorCount() {
6940 ttglobal tg = gglobal();
6942 p = (ppMainloop)tg->Mainloop.prv;
6943 return p->SensorEvents ? vectorSize(p->SensorEvents) : 0;
6945void getSensor(
int sensorIndex,
struct X3D_Node** fromnode,
struct X3D_Node** datanode) {
6946 ttglobal tg = gglobal();
6948 p = (ppMainloop)tg->Mainloop.prv;
6950 *fromnode = se->fromnode;
6951 *datanode = se->datanode;
6954void dis_recv_sensor(
int sensorIndex,
int ev,
int butStatus2,
int status,
float* posn3,
float* norm3)
6956 ttglobal tg = gglobal();
6958 p = (ppMainloop)tg->Mainloop.prv;
6960 veccopy3f(tg->RenderFuncs.hyp_save_norm, norm3);
6961 veccopy3f(tg->RenderFuncs.hyp_save_posn, posn3);
6962 se->interpptr(se->datanode, ev, butStatus2, status);
6965void prepare_model_view_pickmatrix_inverse0(GLDOUBLE *modelMatrix, GLDOUBLE *mvpi);
6966void prepare_model_view_pickmatrix_inverse(GLDOUBLE *mvpi){
6975 GLDOUBLE viewmatrix[16], mv[16];
6976 ttglobal tg = gglobal();
6978 rh = (
struct currayhit *)tg->RenderFuncs.rayHit;
6981 FW_GL_MATRIX_MODE(GL_MODELVIEW);
6982 fw_glGetDoublev(GL_MODELVIEW_MATRIX, viewmatrix);
6984 matmultiplyAFFINE(mv,rh->justModel,viewmatrix);
6988 prepare_model_view_pickmatrix_inverse0(mv, mvpi);
7002void get_hyperhit() {
7023 double x1,y1,z1,x2,y2,z2,x3,y3,z3;
7025 struct point_XYZ r11 = {.x=0.0,.y=0.0,.z=1.0};
7029 ttglobal tg = gglobal();
7036 prepare_model_view_pickmatrix_inverse(mvpi);
7038 transform(&tp,&r11,mvpi);
7039 x1 = tp.x; y1 = tp.y; z1 = tp.z;
7040 transform(&tp,&r2,mvpi);
7041 x2 = tp.x; y2 = tp.y; z2 = tp.z;
7043 transform(&tp,tg->RenderFuncs.hp,mvpi);
7044 x3 = tp.x; y3 = tp.y; z3 = tp.z;
7046 printf(
"get_hyperhit\n");
7054 tg->RenderFuncs.hyp_save_posn[0] = (float) x1; tg->RenderFuncs.hyp_save_posn[1] = (float) y1; tg->RenderFuncs.hyp_save_posn[2] = (float) z1;
7055 tg->RenderFuncs.hyp_save_norm[0] = (float) x2; tg->RenderFuncs.hyp_save_norm[1] = (float) y2; tg->RenderFuncs.hyp_save_norm[2] = (float) z2;
7057 tg->RenderFuncs.ray_save_posn[0] = (float) x3; tg->RenderFuncs.ray_save_posn[1] = (float) y3; tg->RenderFuncs.ray_save_posn[2] = (float) z3;
7063void setStereoBufferStyle(
int itype)
7065 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
7069 p->bufferarray[0]=GL_BACK_LEFT;
7070 p->bufferarray[1]=GL_BACK_RIGHT;
7076 p->bufferarray[0]=FW_GL_BACK;
7077 p->bufferarray[1]=FW_GL_BACK;
7080 printf(
"maxbuffers=%d\n",p->maxbuffers);
7082void setStereoBufferStyleB(
int itype,
int iside,
int ibuffer)
7084 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
7089 p->bufferarray[ibuffer]=GL_BACK_LEFT;
7091 p->bufferarray[ibuffer]=GL_BACK_RIGHT;
7096 p->bufferarray[ibuffer]=FW_GL_BACK;
7105 if (vp_parent->_nodeType != NODE_ViewpointGroup)
return TRUE;
7107 if (vp_parent->__proxNode != NULL) {
7109 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]))) {
7110 printf (
"size is zero\n");
7114 return X3D_PROXIMITYSENSOR(vp_parent->__proxNode)->isActive;
7120static int moreThanOneValidViewpoint(
void) {
7122 struct tProdCon *t = &gglobal()->ProdCon;
7124 if (vectorSize(t->viewpointNodes)<=1)
7127 for (count=0; count < vectorSize(t->viewpointNodes); count++) {
7128 if (count != t->currboundvpno) {
7129 struct Vector *me = vector_get(
struct X3D_Node*, t->viewpointNodes,count)->_parentVector;
7134 if (vectorSize(me) > 0) {
7138 vector_get(
struct X3D_Node *,t->viewpointNodes,count)->_parentVector, 0),
7154void fwl_Last_ViewPoint() {
7155 if (moreThanOneValidViewpoint()) {
7159 struct tProdCon *t = &gglobal()->ProdCon;
7164 vp_to_go_to = vectorSize(t->viewpointNodes);
7165 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind--) {
7169 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
7170 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
7178 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),0);
7179 t->currboundvpno = vp_to_go_to;
7180 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
7181 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),1);
7187 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,
7188 t->viewpointNodes,vp_to_go_to);
7189 t->currboundvpno = vp_to_go_to;
7190 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
7199char* fwl_currentBoundVPname() {
7200 char* retval = NULL;
7201 struct tProdCon* t = &gglobal()->ProdCon;
7202 if (t->viewpointNodes && t->viewpointNodes->n > 0) {
7203 struct X3D_Node* cn = vector_get(
struct X3D_Node*, t->viewpointNodes, t->currboundvpno);
7204 if (cn->_nodeType == NODE_Viewpoint)
7207 retval = vp->description->strptr;
7209 else if (cn->_nodeType == NODE_OrthoViewpoint) {
7211 retval = vp->description->strptr;
7214 else if (cn->_nodeType == NODE_GeoViewpoint) {
7216 retval = vp->description->strptr;
7222void fwl_First_ViewPoint() {
7223 if (moreThanOneValidViewpoint()) {
7227 struct tProdCon *t = &gglobal()->ProdCon;
7233 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind++) {
7237 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
7238 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
7239 struct X3D_Node* , t->viewpointNodes,vp_to_go_to),cn);
7247 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),0);
7248 t->currboundvpno = vp_to_go_to;
7249 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
7250 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),1);
7255 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,t->viewpointNodes,vp_to_go_to);
7256 t->currboundvpno = vp_to_go_to;
7257 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
7267void fwl_Prev_ViewPoint() {
7268 if (moreThanOneValidViewpoint()) {
7272 struct tProdCon *t = &gglobal()->ProdCon;
7277 vp_to_go_to = t->currboundvpno;
7278 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind--) {
7282 if (vp_to_go_to<0) vp_to_go_to=vectorSize(t->viewpointNodes)-1;
7283 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
7292 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),0);
7293 t->currboundvpno = vp_to_go_to;
7294 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
7295 send_bind_to(vector_get(
struct X3D_Node*,t->viewpointNodes,t->currboundvpno),1);
7300 t->setViewpointBindInRender = vector_get(
struct X3D_Node*,
7301 t->viewpointNodes,vp_to_go_to);
7302 t->currboundvpno = vp_to_go_to;
7303 if (t->currboundvpno>=vectorSize(t->viewpointNodes)) t->currboundvpno=0;
7314void fwl_Next_ViewPoint() {
7315 if (moreThanOneValidViewpoint()) {
7319 struct tProdCon *t = &gglobal()->ProdCon;
7324 vp_to_go_to = t->currboundvpno;
7325 printf(
"number of vp nodes %d\n", vectorSize(t->viewpointNodes));
7326 for (ind = 0; ind < vectorSize(t->viewpointNodes); ind++) {
7330 if (vp_to_go_to>=vectorSize(t->viewpointNodes)) vp_to_go_to=0;
7331 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, vector_get(
7332 struct X3D_Node*, t->viewpointNodes,vp_to_go_to),cn);
7342 t->setViewpointBindInRender = vector_get(
7343 struct X3D_Node*,t->viewpointNodes,vp_to_go_to);
7344 t->currboundvpno = vp_to_go_to;
7345 if (t->currboundvpno>=vectorSize(t->viewpointNodes))
7353 printf(
"only one valid Viewpoint\n");
7358void fwl_initializeRenderSceneUpdateScene() {
7361 ttglobal tg = gglobal();
7373 new_text_tessellation();
7375 viewer_postGLinit_init();
7378 if( ((freewrl_params_t*)(tg->display.params))->fullscreen && newResetGeometry != NULL) newResetGeometry();
7393static int workers_waiting(){
7395 ttglobal tg = gglobal();
7396 waiting = tg->threads.ResourceThreadWaiting && tg->threads.TextureThreadWaiting;
7400static void workers_stop()
7402 resitem_queue_exit();
7403 texitem_queue_exit();
7405static int workers_running(){
7407 ttglobal tg = gglobal();
7408 more = tg->threads.ResourceThreadRunning || tg->threads.TextureThreadRunning;
7428 ttglobal tg = gglobal();
7429 ppMainloop p = (ppMainloop)tg->Mainloop.prv;
7435 ret = (!fwl_isinputThreadParsing()) && (!fwl_isTextureParsing()) && fwl_isInputThreadInitialized();
7436 ret = ret && workers_waiting();
7438 dtime = tg->Mainloop.TickTime - p->BrowserInitTime;
7439 ret = ret && (dtime > 10.0);
7443void end_of_run_tests(){
7447 int i, notfreed, notfreedt;
7451 for(i=0;i<100000;i++){
7452 if(glIsBuffer(i)) {notfreed++; printf(
"b%d ",i);}
7453 if(glIsTexture(i)) {notfreedt++; printf(
"t%d ",i);}
7455 printf(
"\ngl buffers not freed = %d\n",notfreed);
7456 printf(
"gl textures not freed = %d\n",notfreedt);
7461static void finalizeRenderSceneUpdateScene() {
7464 ttglobal tg = gglobal();
7465 printf (
"finalizeRenderSceneUpdateScene\n");
7468 if (newResetGeometry != NULL) newResetGeometry();
7470 killErrantChildren();
7474 deleteVector(
struct X3D_Node*,rn->_parentVector);
7475 freeMallocedNodeFields(rn);
7481 iglobal_destructor(tg);
7483 void scanMallocTableOnQuit(
void);
7484 scanMallocTableOnQuit();
7490int checkReplaceWorldRequest(){
7491 ttglobal tg = gglobal();
7492 if (tg->Mainloop.replaceWorldRequest || tg->Mainloop.replaceWorldRequestMulti){
7493 tg->threads.flushing =
true;
7495 return tg->threads.flushing;
7497static int exitRequest = 0;
7498int checkExitRequest(){
7502static int checkQuitRequest(){
7503 ttglobal tg = gglobal();
7504 if ((tg->threads.MainLoopQuit) == 1){
7506 tg->threads.flushing =
true;
7508 return tg->threads.MainLoopQuit;
7510void doReplaceWorldRequest()
7512 resource_item_t *res,*resm;
7515 ttglobal tg = gglobal();
7517 req = tg->Mainloop.replaceWorldRequest;
7518 tg->Mainloop.replaceWorldRequest = NULL;
7521 res = resource_create_single(req);
7523 resitem_enqueue(ml_new(res));
7526 resm = (resource_item_t *)tg->Mainloop.replaceWorldRequestMulti;
7528 tg->Mainloop.replaceWorldRequestMulti = NULL;
7530 resm->new_root =
true;
7531 gglobal()->resources.root_res = (
void*)resm;
7533 resitem_enqueue(ml_new(resm));
7535 tg->threads.flushing =
false;
7537static int(*view_initialize)() = NULL;
7541#if defined(_ANDROID) || defined(ANDROIDNDK) || defined(WINRT)
7542int view_initialize0(
void){
7544 if (!fv_display_initialize()) {
7545 ERROR_MSG(
"initFreeWRL: error in display initialization.\n");
7551int view_initialize0(
void){
7553 if (!fv_display_initialize_desktop()) {
7554 ERROR_MSG(
"initFreeWRL: error in display initialization.\n");
7569 ttglobal tg = gglobal();
7570 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
7571 p = (ppMainloop)tg->Mainloop.prv;
7574 if (!p->draw_initialized){
7576 view_initialize = view_initialize0;
7577 if (view_initialize)
7578 more = view_initialize();
7581 fwl_initializeRenderSceneUpdateScene();
7583 p->draw_initialized = TRUE;
7586 switch (tg->threads.MainLoopQuit){
7591 if (tg->threads.flushing ==
false)
7594 profile_end(
"frontend");
7595 profile_start(
"mainloop");
7597 fwl_RenderSceneUpdateScene();
7598 profile_end(
"mainloop");
7599 profile_start(
"frontend");
7601 PRINT_GL_ERROR_IF_ANY(
"XEvents::render");
7602 checkReplaceWorldRequest();
7607 if (workers_waiting())
7612 tg->threads.flushing =
false;
7613 if (tg->threads.MainLoopQuit)
7614 tg->threads.MainLoopQuit++;
7616 doReplaceWorldRequest();
7619 tg->threads.MainLoopQuit++;
7630 tg->threads.MainLoopQuit++;
7634 more = workers_running();
7637 finalizeRenderSceneUpdateScene();
7648void fwl_initialize_parser()
7651 if (rootNode() == NULL) {
7652 setRootNode( createNewX3DNode (NODE_Proto) );
7654 doNotRegisterThisNodeForDestroy(X3D_NODE(rootNode()));
7658void fwl_init_SnapSeq() {
7659#ifdef DOSNAPSEQUENCE
7661 set_snapsequence(TRUE);
7666void fwl_set_LineWidth(
float lwidth) {
7667 gglobal()->Mainloop.gl_linewidth = lwidth;
7670void fwl_set_KeyString(
const char* kstring)
7672 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
7673 p->keypress_string = STRDUP(kstring);
7681void outOfMemory(
const char *msg) {
7682 ConsoleMessage (
"FreeWRL has encountered a memory allocation problem\n"\
7683 "and is exiting. -- %s--",msg);
7688void _disposeThread(
void *globalcontext);
7691void fwl_doQuitInstance(
void *tg_remote)
7693 ttglobal tg = gglobal();
7694printf (
"fwl_doQuitInstance called\n");
7696 if (tg_remote == tg)
7698 fwl_doQuit(__FILE__,__LINE__);
7701 fwl_clearCurrentHandle();
7703 pthread_create(&tg->threads.disposeThread, NULL, (
void *(*)(
void *))&_disposeThread, tg);
7708void __iglobal_destructor(ttglobal tg);
7710void _disposeThread(
void *globalcontext)
7713 ttglobal tg = globalcontext;
7714 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
7716 while((more = workers_running()) && more > 0)
7722 markForDispose(rootNode(), TRUE);
7726 finalizeRenderSceneUpdateScene();
7728#if defined(WRAP_MALLOC) || defined(DEBUG_MALLOC)
7729 freewrlFreeAllRegisteredAllocations();
7730 freewrlDisposeMemTable();
7732 __iglobal_destructor(tg);
7737void fwl_doQuit(
char *fl,
int ln)
7739 ttglobal tg = gglobal();
7740 tg->threads.MainLoopQuit = max(1,tg->threads.MainLoopQuit);
7745void fwl_doQuitAndWait(){
7746 pthread_t displaythread;
7747 ttglobal tg = gglobal();
7748 displaythread = tg->threads.DispThrd;
7749 fwl_doQuit(__FILE__,__LINE__);
7750 pthread_join(displaythread,NULL);
7756void fwl_tmpFileLocation(
char *tmpFileLocation) {
7758 if (tmpFileLocation == NULL)
return;
7760 FREE_IF_NZ(tg->Mainloop.tmpFileLocation);
7761 tg->Mainloop.tmpFileLocation = MALLOC(
char *,strlen(tmpFileLocation)+1);
7762 strcpy(tg->Mainloop.tmpFileLocation,tmpFileLocation);
7765void close_internetHandles();
7766void freewrlDie (
const char *format) {
7767 ConsoleMessage (
"Catastrophic error: %s\n",format);
7768 fwl_doQuit(__FILE__,__LINE__);
7774struct Touch * AllocTouch(
unsigned int ID){
7778 ttglobal tg = gglobal();
7779 p = (ppMainloop)tg->Mainloop.prv;
7780 for(i=0;i<p->ntouch;i++)
7781 if(p->touchlist[i].ID == ID && p->touchlist[i].state.inUse){
7783 p->touchlist[i].state.inUse = 2;
7784 return &p->touchlist[i];
7786 for(i=0;i<p->ntouch;i++)
7787 if(!p->touchlist[i].state.inUse){
7788 memset(&p->touchlist[i],0,
sizeof(
struct Touch));
7789 p->touchlist[i].state.inUse = 2;
7790 p->touchlist[i].ID = ID;
7791 return &p->touchlist[i];
7795struct Touch * GetTouch(
unsigned int ID){
7799 ttglobal tg = gglobal();
7800 p = (ppMainloop)tg->Mainloop.prv;
7801 for(i=0;i<p->ntouch;i++)
7802 if(p->touchlist[i].ID == ID && (p->touchlist[i].state.inUse || ID == 0) ){
7803 return &p->touchlist[i];
7807void ReleaseTouch(
unsigned int ID){
7812 ttglobal tg = gglobal();
7813 p = (ppMainloop)tg->Mainloop.prv;
7814 for(i=0;i<p->ntouch;i++)
7815 if(p->touchlist[i].ID == ID ){
7816 p->touchlist[i].state.inUse = 0;
7837void setCurrentTouchID(
unsigned int ID){
7839 ttglobal tg = gglobal();
7840 p = (ppMainloop)tg->Mainloop.prv;
7841 p->currentTouch = ID;
7843struct Touch *currentTouch(){
7845 ttglobal tg = gglobal();
7846 p = (ppMainloop)tg->Mainloop.prv;
7849 return GetTouch(p->currentTouch);
7852void handle_pedal(
int mev,
int x,
int y,
ivec4 vport){
7855 ttglobal tg = gglobal();
7856 p = (ppMainloop)tg->Mainloop.prv;
7857 pstate = &p->pedalstate;
7858 if(mev == ButtonPress) {
7859 if(!pstate->initialized){
7862 pstate->initialized = TRUE;
7866 pstate->isDown = TRUE;
7867 }
else if (mev == MotionNotify) {
7869 pstate->x += x - pstate->rx;
7870 pstate->y += y - pstate->ry;
7874 }
else if(mev == ButtonRelease) {
7876 pstate->x += x - pstate->rx;
7877 pstate->y += y - pstate->ry;
7879 pstate->isDown = FALSE;
7883void viewer_setNextDragChord();
7884void fwl_handle_aqua_multiNORMAL(
const int mev,
const unsigned int button,
int x,
int y,
unsigned int ID,
int windex) {
7931 int ibutton, passed, claimant;
7933 struct Touch *touch;
7937 ttglobal tg = gglobal();
7938 p = (ppMainloop)tg->Mainloop.prv;
7951 if(fwl_getHover()) ibutton = 0;
7953 vportstack = (Stack*)tg->Mainloop._vportstack;
7954 vport = stack_top(
ivec4,vportstack);
7958 passed = TOUCHCLAIMANT_PEDAL;
7959 claimant = TOUCHCLAIMANT_UNCLAIMED;
7960 if (fwl_getPedal()) {
7961 handle_pedal(mev, x, y, vport);
7965 claimant = TOUCHCLAIMANT_PEDAL;
7974 touch = GetTouch(ID);
7977 touch = AllocTouch(ID);
7978 if(currentTouch()->ID == 0) {
7981 setCurrentTouchID(ID);
7983 touch->windex = windex;
7984 touch->stageId = current_stageId();
7986 touch->claimant = claimant;
7987 touch->passed = passed;
7992 if(imev == ButtonPress && ibutton < 4){
7994 touch->state.buttonState[ibutton] = ibutton ? 1 : 0;
7995 touch->claimant = claimant;
7996 touch->passed = passed;
7999 }
else if((imev == ButtonRelease || imev == ButtonRecycle) && ibutton < 4){
8003 if(imev == ButtonRecycle) touch->updraw_none = TRUE;
8004 touch->state.buttonState[ibutton] = 0;
8005 if(touch->claimant == TOUCHCLAIMANT_PEDAL) {
8009 }
else if(imev == MotionNotify) {
8012 touch->netweheel += 1;
8014 touch->netweheel -= 1;
8018 touch->state.x = p->pedalstate.x;
8019 touch->state.y = p->pedalstate.y;
8024 fx = (float)(touch->state.x - vport.X) / (float)vport.W;
8025 fy = (float)(touch->state.y - vport.Y) / (float)vport.H;
8026 touch->state.fx = fx;
8027 touch->state.fy = fy;
8028 touch->state.angle = 0.0f;
8031static struct Touch *static_touch = NULL;
8032void set_static_touch(
struct Touch *touch){
8033 static_touch = touch;
8036double * get_touch_pin_point(){
8037 double *ppoint = NULL;
8038 if(static_touch) ppoint = static_touch->pin_point;
8041double * get_touch_ray(){
8043 if(static_touch) ray = static_touch->ray;
8046double get_touch_hitPointDist(){
8048 if(static_touch) hpd = static_touch->hitPointDist;
8051void update_navigation(){
8057 struct Touch *curTouch;
8059 ttglobal tg = gglobal();
8060 p = (ppMainloop)tg->Mainloop.prv;
8061 static int lastframe = 0;
8062 if(lastframe == tg->Mainloop.iframe)
return;
8063 lastframe = tg->Mainloop.iframe;
8065 for(i=0;i<p->ntouch;i++){
8067 curTouch = &p->touchlist[i];
8068 set_static_touch(curTouch);
8069 if(curTouch->frame_state.inUse && curTouch->changed){
8072 int priorclaimants = TOUCHCLAIMANT_PEDAL | TOUCHCLAIMANT_SENSOR;
8073 if(curTouch->claimant == TOUCHCLAIMANT_UNCLAIMED && curTouch->passed == priorclaimants ){
8076 curTouch->claimant = TOUCHCLAIMANT_NAVIGATION;
8078 curTouch->passed |= TOUCHCLAIMANT_NAVIGATION;
8080 if(curTouch->claimant == TOUCHCLAIMANT_NAVIGATION){
8081 int ibutstate, dragStart, dragEnd;
8086 for(
int j=3; j>0; j--){
8088 ibutstate = curTouch->frame_state.buttonState[j];
8089 if(ibutstate) ibut = j;
8090 dragStart = ibutstate == 1 && curTouch->last_state.buttonState[j] == 0;
8091 dragEnd = ibutstate == 0 && curTouch->last_state.buttonState[j] == 1;
8093 if (dragStart || (dragEnd)) {
8099 imev = ButtonRelease;
8100 curTouch->claimant = TOUCHCLAIMANT_UNCLAIMED;
8101 curTouch->passed = TOUCHCLAIMANT_PEDAL;
8105 handle(imev, ibut, curTouch->frame_state.fx,curTouch->frame_state.fy);
8107 if(j>1 && !ibut)
continue;
8108 imev = MotionNotify;
8110 handle (imev, ibut, curTouch->frame_state.fx, curTouch->frame_state.fy);
8118 int netwheel = curTouch->netweheel;
8120 imev = MotionNotify;
8121 ibut = netwheel < 0 ? 5 : 4;
8122 int nwheel = netwheel < 0 ? -netwheel : netwheel;
8123 for(
int j=0;j<nwheel;j++)
8124 handle (imev, ibut, curTouch->frame_state.fx, curTouch->frame_state.fy);
8125 curTouch->netweheel = 0;
8135void fwl_setOrientation (
int orient) {
8143 Viewer()->screenOrientation = orient;
8147 ConsoleMessage (
"invalid orientation %d\n",orient);
8148 Viewer()->screenOrientation = 0;
8152int fwl_getOrientation(){
8153 return Viewer()->screenOrientation;
8156void fwl_setOrientation2 (
int orient) {
8164 gglobal()->Mainloop.screenOrientation2 = orient;
8169 ConsoleMessage (
"invalid orientation2 %d\n",orient);
8170 gglobal()->Mainloop.screenOrientation2 = 0;
8174int fwl_getOrientation2(){
8176 return gglobal()->Mainloop.screenOrientation2;
8181 RUNNINGASPLUGIN = TRUE;
8217void setDisplayed (
int state) {
8218 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
8221 if (state) printf (
"WE ARE DISPLAYED\n");
8222 else printf (
"we are now iconic\n");
8224 p->onScreen = state;
8227void fwl_init_EaiVerbose() {
8229#if !defined(EXCLUDE_EAI)
8230 gglobal()->EAI_C_CommonFunctions.eaiverbose = TRUE;
8231 fwlio_RxTx_control(CHANNEL_EAI, RxTx_MOREVERBOSE);
8237#if defined (_ANDROID)
8239void fwl_Android_replaceWorldNeeded() {
8247 resetSensorEvents();
8250 gglobal()->resources.root_res = NULL;
8251 Android_reset_viewer_to_defaults();
8253 struct tProdCon *t = &gglobal()->ProdCon;
8256 if (vectorSize(t->viewpointNodes) > t->currboundvpno) {
8257 send_bind_to(vector_get(
struct X3D_Node*, t->viewpointNodes,t->currboundvpno),0);
8260 if (rootNode() != NULL) {
8263 for (i=0; i<proto->__children.n; i++) {
8264 markForDispose(proto->__children.p[i], TRUE);
8269 proto->__children.n = 0;
8274 closeConsoleMessage();
8287 killKeySensorNodeList();
8294 setMenuStatus(NULL);
8297 kill_userDefinedShaders();
8304 #if !defined(EXCLUDE_EAI)
8308 fwlio_RxTx_control(CHANNEL_EAI, RxTx_STOP) ;
8313 sprintf (mystring,
"QUIT");
8314 Sound_toserver(mystring);
8318 if (globalParser != NULL) {
8319 parser_destroyData(globalParser);
8321 gglobal()->CParse.globalParser = NULL;
8328 setMenuStatus(
"NONE");
8334#if !defined(_ANDROID) || defined(ANDROIDNDK)
8339char *strBackslash2fore(
char *);
8340void fwl_replaceWorldNeeded(
char* str)
8342 ConsoleMessage(
"file to load: %s\n",str);
8343 FREE_IF_NZ(gglobal()->Mainloop.replaceWorldRequest);
8344 gglobal()->Mainloop.replaceWorldRequest = strBackslash2fore(STRDUP(str));
8346void fwl_replaceWorldNeededRes(resource_item_t *multiResWithParent){
8347 gglobal()->Mainloop.replaceWorldRequestMulti = (
void*)(multiResWithParent);
8353 ConsoleMessage(
"fwl_reload called");
8360void sendDescriptionToStatusBar(
struct X3D_Node *CursorOverSensitive) {
8364 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
8366 if (CursorOverSensitive == NULL) setSensorStatus(NULL);
8371 for (tmp=0; tmp<vectorSize(p->SensorEvents); tmp++) {
8372 se = vector_get(
struct SensStruct *,p->SensorEvents,tmp);
8373 if (se->fromnode == CursorOverSensitive) {
8374 switch (se->datanode->_nodeType) {
8375 case NODE_Anchor: ns = ((
struct X3D_Anchor *)se->datanode)->description->strptr;
break;
8376 case NODE_LineSensor: ns = ((
struct X3D_LineSensor *)se->datanode)->description->strptr;
break;
8377 case NODE_PointSensor: ns = ((
struct X3D_PointSensor *)se->datanode)->description->strptr;
break;
8378 case NODE_PlaneSensor: ns = ((
struct X3D_PlaneSensor *)se->datanode)->description->strptr;
break;
8379 case NODE_MultiTouchSensor: ns = ((
struct X3D_MultiTouchSensor *)se->datanode)->description->strptr;
break;
8380 case NODE_SphereSensor: ns = ((
struct X3D_SphereSensor *)se->datanode)->description->strptr;
break;
8381 case NODE_TouchSensor: ns = ((
struct X3D_TouchSensor *)se->datanode)->description->strptr;
break;
8382 case NODE_GeoTouchSensor: ns = ((
struct X3D_GeoTouchSensor *)se->datanode)->description->strptr;
break;
8383 case NODE_CylinderSensor: ns = ((
struct X3D_CylinderSensor *)se->datanode)->description->strptr;
break;
8384 default: {printf (
"sendDesc; unknown node type %d\n",se->datanode->_nodeType);}
8387 if (ns == NULL) {ns =
"(over sensitive)";}
8388 else if (ns[0] ==
'\0') ns = (
char *)stringNodeType(se->datanode->_nodeType);
8391 setSensorStatus(ns);
8399void resetSensorEvents(
void) {
8401 ppMainloop p = (ppMainloop)gglobal()->Mainloop.prv;
8403 for(ktouch=0;ktouch<20;ktouch++){
8404 struct Touch *touch;
8405 touch = &p->touchlist[ktouch];
8406 if(touch->state.inUse){
8407 if (touch->oldCOS != NULL)
8408 sendSensorEvents(touch->oldCOS,MapNotify,touch->state.buttonState[1], FALSE);
8412 sendDescriptionToStatusBar(NULL);
8413 memset(touch,0,
sizeof(
struct Touch));
8415 for(ktouch=0;ktouch<vectorSize(p->SensorEvents);ktouch++){
8419 vector_clear(p->SensorEvents);
8420 gglobal()->RenderFuncs.hypersensitive = NULL;
8421 gglobal()->RenderFuncs.hyperhit = 0;