37 #include <libFreeWRL.h>
40 #include "../vrml_parser/Structs.h"
41 #include "../input/InputFunctions.h"
42 #include "../opengl/LoadTextures.h"
45 #include "../main/headers.h"
46 #include "../opengl/OpenGL_Utils.h"
47 #include "../scenegraph/RenderFuncs.h"
49 #include "../x3d_parser/Bindable.h"
50 #include "../scenegraph/LinearAlgebra.h"
51 #include "../scenegraph/Collision.h"
52 #include "../scenegraph/quaternion.h"
53 #include "../scenegraph/sounds.h"
54 #include "../vrml_parser/CRoutes.h"
55 #include "../opengl/OpenGL_Utils.h"
56 #include "../opengl/Textures.h"
58 #include "SensInterps.h"
67 void *SensInterps_constructor(){
72 void SensInterps_init(
struct tSensInterps *t)
76 t->prv = SensInterps_constructor();
88 void do_active_inactive (
112 double ticktime = TickTime();
116 printf (
"is active tick %f startt %f stopt %f\n",
117 TickTime(), *startt, *stopt);
120 if (ticktime > *stopt) {
121 if (*startt >= *stopt) {
129 if (! APPROX(speed, 0)) {
131 if (elapsedTime >= fabs(myDuration/speed) ) {
133 printf (
"stopping case x\n");
134 printf (
"TickTime() %f\n",ticktime);
135 printf (
"startt %f\n",*startt);
136 printf (
"myDuration %f\n",myDuration);
137 printf (
"speed %f\n",speed);
147 printf (
"stopping case z\n");
160 if (ticktime >= *startt) {
163 if (ticktime >= *stopt) {
168 if (*startt >= *stopt) {
172 if (!(*startt > 0)) *startt = ticktime;
175 }
else if (*startt >= *stopt) {
176 if (*startt > *inittime) {
191 if (!(*startt > 0)) *startt = ticktime;
200 int find_key (
int kin,
float frac,
float *keys) {
203 for (counter=1; counter <= kin; counter++) {
204 if (frac <keys[counter]) {
213 void do_OintScalar (
void *node) {
223 kvin = px->keyValue.n;
224 kVs = px->keyValue.p;
229 if ((kvin == 0) || (kin == 0)) {
230 px->value_changed = (float) 0.0;
233 if (kin>kvin) kin=kvin;
236 printf (
"ScalarInterpolator, kin %d kvin %d, vc %f\n",kin,kvin,px->value_changed);
240 if (px->set_fraction <= px->key.p[0]) {
241 px->value_changed = kVs[0];
242 }
else if (px->set_fraction >= px->key.p[kin-1]) {
243 px->value_changed = kVs[kvin-1];
246 counter=find_key(kin,(
float)(px->set_fraction),px->key.p);
248 (px->set_fraction - px->key.p[counter-1]) /
249 (px->key.p[counter] - px->key.p[counter-1]) *
250 (kVs[counter] - kVs[counter-1]) +
256 void do_OintNormal(
void *node) {
262 int thisone, prevone;
275 printf (
"debugging OintCoord keys %d kv %d vc %d\n",px->keyValue.n, px->key.n,px->value_changed.n);
281 kvin = px->keyValue.n;
282 kVs = px->keyValue.p;
286 if (kpkv != px->value_changed.n) {
288 printf (
"refactor valuechanged array. n %d sizeof p %d\n",
289 kpkv,
sizeof (
struct SFColor) * kpkv);
291 if (px->value_changed.n != 0) {
292 FREE_IF_NZ (px->value_changed.p);
294 px->value_changed.n = kpkv;
295 px->value_changed.p = MALLOC (
struct SFVec3f*,
sizeof (
struct SFVec3f) * kpkv);
299 valchanged = px->value_changed.p;
303 if ((kvin == 0) || (kin == 0)) {
305 printf (
"no keys or keyValues yet\n");
308 for (indx = 0; indx < kpkv; indx++) {
309 valchanged[indx].c[0] = (float) 0.0;
310 valchanged[indx].c[1] = (float) 0.0;
311 valchanged[indx].c[2] = (float) 0.0;
315 if (kin>kvin) kin=kvin;
319 printf (
"debugging, kpkv %d, px->value_changed.n %d\n", kpkv, px->value_changed.n);
320 printf (
"NormalInterpolator, kpkv %d\n",kpkv);
325 if (px->set_fraction <= px->key.p[0]) {
327 printf (
"COINT out1\n");
330 for (indx = 0; indx < kpkv; indx++) {
331 memcpy ((
void *)&valchanged[indx],
332 (
void *)&kVs[indx],
sizeof (
struct SFColor));
335 printf (
"COINT out1 copied\n");
337 }
else if (px->set_fraction >= px->key.p[kin-1]) {
339 printf (
"COINT out2\n");
342 for (indx = 0; indx < kpkv; indx++) {
343 memcpy ((
void *)&valchanged[indx],
344 (
void *)&kVs[kvin-kpkv+indx],
348 printf (
"COINT out2 finished\n");
352 printf (
"COINT out3\n");
357 printf (
"indx=0, kin %d frac %f\n",kin,px->set_fraction);
360 myKey=find_key(kin,(
float)(px->set_fraction),px->key.p);
362 printf (
"working on key %d\n",myKey);
366 interval = (px->set_fraction - px->key.p[myKey-1]) /
367 (px->key.p[myKey] - px->key.p[myKey-1]);
369 for (indx = 0; indx < kpkv; indx++) {
370 thisone = myKey * kpkv + indx;
371 prevone = (myKey-1) * kpkv + indx;
374 if (thisone >= kvin) {
375 printf (
"CoordinateInterpolator error: thisone %d prevone %d indx %d kpkv %d kin %d kvin %d\n",thisone,prevone,
380 for (tmp=0; tmp<3; tmp++) {
381 valchanged[indx].c[tmp] = kVs[prevone].c[tmp] +
382 interval * (kVs[thisone].c[tmp] -
383 kVs[prevone].c[tmp]);
386 printf (
" 1 %d interval %f prev %f this %f final %f\n",1,interval,kVs[prevone].c[1],kVs[thisone].c[1],valchanged[indx].c[1]);
390 printf (
"COINT out3 finished\n");
396 for (indx = 0; indx < kpkv; indx++) {
397 normalval.x = valchanged[indx].c[0];
398 normalval.y = valchanged[indx].c[1];
399 normalval.z = valchanged[indx].c[2];
400 normalize_vector(&normalval);
401 valchanged[indx].c[0] = (float) normalval.x;
402 valchanged[indx].c[1] = (
float) normalval.y;
403 valchanged[indx].c[2] = (float) normalval.z;
406 printf (
"Done CoordinateInterpolator\n");
411 void do_OintCoord(
void *node) {
417 int thisone, prevone;
428 printf (
"do_OintCoord, frac %f toGPU %d toCPU %d\n",px->set_fraction,px->_GPU_Routes_out, px->_CPU_Routes_out);
429 printf (
"debugging OintCoord keys %d kv %d vc %d\n",px->keyValue.n, px->key.n,px->value_changed.n);
435 if (px->_GPU_Routes_out > 0) {
436 if (px->_keyVBO==0) {
437 glGenBuffers(1,(GLuint *)&px->_keyValueVBO);
438 glGenBuffers(1,(GLuint *)&px->_keyVBO);
439 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,px->_keyValueVBO);
440 printf (
"genning buffer data for %d keyValues, total floats %d\n",px->keyValue.n, px->keyValue.n*3);
441 glBufferData(GL_ARRAY_BUFFER,px->keyValue.n *
sizeof(
float)*3,px->keyValue.p, GL_STATIC_DRAW);
443 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,px->_keyVBO);
444 glBufferData(GL_ARRAY_BUFFER,px->key.n *
sizeof(
float),px->key.p, GL_STATIC_DRAW);
445 printf (
"created VBOs for the CoordinateInterpolator, they are %d and %d\n",
446 px->_keyValueVBO, px->_keyVBO);
452 if (px->_CPU_Routes_out == 0) {
454 printf (
"do_OintCoord, no CPU routes out, no need to do this work\n");
463 kvin = px->keyValue.n;
464 kVs = px->keyValue.p;
468 if (kpkv != px->value_changed.n) {
470 printf (
"refactor valuechanged array. n %d sizeof p %d\n",
471 kpkv,
sizeof (
struct SFVec3f) * kpkv);
473 if (px->value_changed.n != 0) {
474 FREE_IF_NZ (px->value_changed.p);
476 px->value_changed.n = kpkv;
477 px->value_changed.p = MALLOC (
struct SFVec3f*,
sizeof (
struct SFVec3f) * kpkv);
481 valchanged = px->value_changed.p;
485 if ((kvin == 0) || (kin == 0)) {
487 printf (
"no keys or keyValues yet\n");
490 for (indx = 0; indx < kpkv; indx++) {
491 valchanged[indx].c[0] = (float) 0.0;
492 valchanged[indx].c[1] = (float) 0.0;
493 valchanged[indx].c[2] = (float) 0.0;
497 if (kin>kvin) kin=kvin;
501 printf (
"debugging, kpkv %d, px->value_changed.n %d\n", kpkv, px->value_changed.n);
502 printf (
"CoordinateInterpolator, kpkv %d\n",kpkv);
507 if (px->set_fraction <= px->key.p[0]) {
509 printf (
"COINT out1\n");
512 for (indx = 0; indx < kpkv; indx++) {
513 memcpy ((
void *)&valchanged[indx],
514 (
void *)&kVs[indx],
sizeof (
struct SFVec3f));
520 printf (
"COINT out1 copied\n");
522 }
else if (px->set_fraction >= px->key.p[kin-1]) {
524 printf (
"COINT out2\n");
527 for (indx = 0; indx < kpkv; indx++) {
528 memcpy ((
void *)&valchanged[indx],
529 (
void *)&kVs[kvin-kpkv+indx],
533 printf (
"COINT out2 finished\n");
537 printf (
"COINT out3\n");
542 printf (
"indx=0, kin %d frac %f\n",kin,px->set_fraction);
545 myKey=find_key(kin,(
float)(px->set_fraction),px->key.p);
547 printf (
"working on key %d\n",myKey);
551 interval = (px->set_fraction - px->key.p[myKey-1]) /
552 (px->key.p[myKey] - px->key.p[myKey-1]);
554 for (indx = 0; indx < kpkv; indx++) {
555 thisone = myKey * kpkv + indx;
556 prevone = (myKey-1) * kpkv + indx;
559 if (thisone >= kvin) {
560 printf (
"CoordinateInterpolator error: thisone %d prevone %d indx %d kpkv %d kin %d kvin %d\n",thisone,prevone,
565 for (tmp=0; tmp<3; tmp++) {
566 valchanged[indx].c[tmp] = kVs[prevone].c[tmp] +
567 interval * (kVs[thisone].c[tmp] -
568 kVs[prevone].c[tmp]);
571 printf (
" 1 %d interval %f prev %f this %f final %f\n",1,interval,kVs[prevone].c[1],kVs[thisone].c[1],valchanged[indx].c[1]);
575 printf (
"COINT out3 finished\n");
581 printf (
"Done CoordinateInterpolator\n");
585 void do_OintCoord2D(
void *node) {
591 int thisone, prevone;
603 printf (
"debugging OintCoord keys %d kv %d vc %d\n",px->keyValue.n, px->key.n,px->value_changed.n);
609 kvin = px->keyValue.n;
610 kVs = px->keyValue.p;
614 if (kpkv != px->value_changed.n) {
616 printf (
"refactor valuechanged array. n %d sizeof p %d\n",
617 kpkv,
sizeof (
struct SFVec2f) * kpkv);
619 if (px->value_changed.n != 0) {
620 FREE_IF_NZ (px->value_changed.p);
622 px->value_changed.n = kpkv;
623 px->value_changed.p = MALLOC (
struct SFVec2f*,
sizeof (
struct SFVec2f) * kpkv);
627 valchanged = px->value_changed.p;
631 if ((kvin == 0) || (kin == 0)) {
633 printf (
"no keys or keyValues yet\n");
636 for (indx = 0; indx < kpkv; indx++) {
637 valchanged[indx].c[0] = (float) 0.0;
638 valchanged[indx].c[1] = (float) 0.0;
642 if (kin>kvin) kin=kvin;
646 printf (
"debugging, kpkv %d, px->value_changed.n %d\n", kpkv, px->value_changed.n);
647 printf (
"CoordinateInterpolator2D, kpkv %d\n",kpkv);
652 if (px->set_fraction <= px->key.p[0]) {
654 printf (
"COINT out1\n");
657 for (indx = 0; indx < kpkv; indx++) {
658 memcpy ((
void *)&valchanged[indx],
659 (
void *)&kVs[indx],
sizeof (
struct SFVec2f));
664 printf (
"COINT out1 copied\n");
666 }
else if (px->set_fraction >= px->key.p[kin-1]) {
668 printf (
"COINT out2\n");
671 for (indx = 0; indx < kpkv; indx++) {
672 memcpy ((
void *)&valchanged[indx],
673 (
void *)&kVs[kvin-kpkv+indx],
677 printf (
"COINT out2 finished\n");
681 printf (
"COINT out3\n");
686 printf (
"indx=0, kin %d frac %f\n",kin,px->set_fraction);
689 myKey=find_key(kin,(
float)(px->set_fraction),px->key.p);
691 printf (
"working on key %d\n",myKey);
695 interval = (px->set_fraction - px->key.p[myKey-1]) /
696 (px->key.p[myKey] - px->key.p[myKey-1]);
698 for (indx = 0; indx < kpkv; indx++) {
699 thisone = myKey * kpkv + indx;
700 prevone = (myKey-1) * kpkv + indx;
703 if (thisone >= kvin) {
704 printf (
"CoordinateInterpolator2D error: thisone %d prevone %d indx %d kpkv %d kin %d kvin %d\n",thisone,prevone,
709 for (tmp=0; tmp<2; tmp++) {
710 valchanged[indx].c[tmp] = kVs[prevone].c[tmp] +
711 interval * (kVs[thisone].c[tmp] -
712 kVs[prevone].c[tmp]);
716 printf (
"COINT out3 finished\n");
722 printf (
"Done CoordinateInterpolator2D\n");
726 void do_OintPos2D(
void *node) {
733 int kin, kvin, counter, tmp;
742 kvin = px->keyValue.n;
743 kVs = px->keyValue.p;
746 printf(
"do_Oint2: Position interp2D, node %u kin %d kvin %d set_fraction %f\n",
747 node, kin, kvin, px->set_fraction);
751 if ((kvin == 0) || (kin == 0)) {
752 px->value_changed.c[0] = (float) 0.0;
753 px->value_changed.c[1] = (float) 0.0;
756 if (kin>kvin) kin=kvin;
760 if (px->set_fraction <= ((px->key).p[0])) {
761 memcpy ((
void *)&px->value_changed,
762 (
void *)&kVs[0], sizeof (
struct SFVec2f));
763 }
else if (px->set_fraction >= px->key.p[kin-1]) {
764 memcpy ((
void *)&px->value_changed,
765 (
void *)&kVs[kvin-1], sizeof (
struct SFVec2f));
768 counter = find_key(kin,((
float)(px->set_fraction)),px->key.p);
769 for (tmp=0; tmp<2; tmp++) {
770 px->value_changed.c[tmp] =
771 (px->set_fraction - px->key.p[counter-1]) /
772 (px->key.p[counter] - px->key.p[counter-1]) *
773 (kVs[counter].c[tmp] -
774 kVs[counter-1].c[tmp]) +
775 kVs[counter-1].c[tmp];
779 printf (
"Pos/Col, new value (%f %f)\n",
780 px->value_changed.c[0],px->value_changed.c[1]);
792 void do_ColorInterpolator (
void *node) {
794 int kin, kvin, counter, tmp;
800 kvin = px->keyValue.n;
801 kVs = px->keyValue.p;
807 printf(
"do_ColorInt: Position/Color interp, node %u kin %d kvin %d set_fraction %f\n",
808 node, kin, kvin, px->set_fraction);
812 if ((kvin == 0) || (kin == 0)) {
813 px->value_changed.c[0] = (float) 0.0;
814 px->value_changed.c[1] = (float) 0.0;
815 px->value_changed.c[2] = (float) 0.0;
819 if (kin>kvin) kin=kvin;
822 if (px->set_fraction <= ((px->key).p[0])) {
823 memcpy ((
void *)&px->value_changed, (
void *)&kVs[0], sizeof (
struct SFColor));
824 }
else if (px->set_fraction >= px->key.p[kin-1]) {
825 memcpy ((
void *)&px->value_changed, (
void *)&kVs[kvin-1], sizeof (
struct SFColor));
828 counter = find_key(kin,((
float)(px->set_fraction)),px->key.p);
829 for (tmp=0; tmp<3; tmp++) {
830 px->value_changed.c[tmp] =
831 (px->set_fraction - px->key.p[counter-1]) /
832 (px->key.p[counter] - px->key.p[counter-1]) *
833 (kVs[counter].c[tmp] - kVs[counter-1].c[tmp]) + kVs[counter-1].c[tmp];
837 printf (
"Pos/Col, new value (%f %f %f)\n",
838 px->value_changed.c[0],px->value_changed.c[1],px->value_changed.c[2]);
843 void do_PositionInterpolator (
void *node) {
845 int kin, kvin, counter, tmp;
851 kvin = px->keyValue.n;
852 kVs = px->keyValue.p;
858 printf(
"do_PositionInt: Position/Vec3f interp, node %u kin %d kvin %d set_fraction %f\n",
859 node, kin, kvin, px->set_fraction);
863 if ((kvin == 0) || (kin == 0)) {
864 px->value_changed.c[0] = (float) 0.0;
865 px->value_changed.c[1] = (float) 0.0;
866 px->value_changed.c[2] = (float) 0.0;
870 if (kin>kvin) kin=kvin;
873 if (px->set_fraction <= ((px->key).p[0])) {
874 memcpy ((
void *)&px->value_changed, (
void *)&kVs[0], sizeof (
struct SFVec3f));
875 }
else if (px->set_fraction >= px->key.p[kin-1]) {
876 memcpy ((
void *)&px->value_changed, (
void *)&kVs[kvin-1], sizeof (
struct SFVec3f));
879 counter = find_key(kin,((
float)(px->set_fraction)),px->key.p);
880 for (tmp=0; tmp<3; tmp++) {
881 px->value_changed.c[tmp] =
882 (px->set_fraction - px->key.p[counter-1]) /
883 (px->key.p[counter] - px->key.p[counter-1]) *
884 (kVs[counter].c[tmp] - kVs[counter-1].c[tmp]) + kVs[counter-1].c[tmp];
888 printf (
"Pos/Col, new value (%f %f %f)\n",
889 px->value_changed.c[0],px->value_changed.c[1],px->value_changed.c[2]);
898 void do_Oint4 (
void *node) {
913 kvin = ((px->keyValue).n);
914 kVs = ((px->keyValue).p);
917 printf (
"starting do_Oint4; keyValue count %d and key count %d\n",
925 if ((kvin == 0) || (kin == 0)) {
926 px->value_changed.c[0] = (float) 0.0;
927 px->value_changed.c[1] = (float) 0.0;
928 px->value_changed.c[2] = (float) 0.0;
929 px->value_changed.c[3] = (float) 0.0;
932 if (kin>kvin) kin=kvin;
936 if (px->set_fraction <= ((px->key).p[0])) {
937 memcpy ((
void *)&px->value_changed,
939 }
else if (px->set_fraction >= ((px->key).p[kin-1])) {
940 memcpy ((
void *)&px->value_changed,
941 (
void *)&kVs[kvin-1], sizeof (
struct SFRotation));
943 counter = find_key(kin,(
float)(px->set_fraction),px->key.p);
944 interval = (px->set_fraction - px->key.p[counter-1]) /
945 (px->key.p[counter] - px->key.p[counter-1]);
952 printf (
"counter %d interval %f\n",counter,interval);
953 printf (
"angles %f %f %f %f, %f %f %f %f\n",
963 vrmlrot_to_quaternion (&st, kVs[counter-1].c[0],
964 kVs[counter-1].c[1], kVs[counter-1].c[2], kVs[counter-1].c[3]);
965 vrmlrot_to_quaternion (&fin,kVs[counter].c[0],
966 kVs[counter].c[1], kVs[counter].c[2], kVs[counter].c[3]);
968 quaternion_slerp(&
final, &st, &fin, (
double)interval);
969 quaternion_to_vrmlrot(&
final,&x, &y, &z, &a);
970 px->value_changed.c[0] = (float) x;
971 px->value_changed.c[1] = (float) y;
972 px->value_changed.c[2] = (float) z;
973 px->value_changed.c[3] = (float) a;
976 printf (
"Oint, new angle %f %f %f %f\n",px->value_changed.c[0],
977 px->value_changed.c[1],px->value_changed.c[2], px->value_changed.c[3]);
984 void do_CollisionTick(
void *ptr) {
986 if (cx->__hit == 3) {
988 cx->collideTime = TickTime();
989 MARK_EVENT (ptr, offsetof(
struct X3D_Collision, collideTime));
996 void do_AudioTick(
void *ptr) {
999 double pitch, duration;
1004 if(node->__inittime == 0.0)
1005 node->__inittime = TickTime();
1007 if(TickTime() < node->startTime) {
1011 oldstatus = node->isActive;
1012 pitch = node->pitch;
1014 if(node->__sourceNumber < 0)
return;
1028 duration = return_Duration(node);
1029 do_active_inactive (
1030 &node->isActive, &node->__inittime, &node->startTime,
1031 &node->stopTime,node->loop,duration,
1032 pitch,node->elapsedTime);
1034 if (oldstatus != node->isActive) {
1036 if (node->isActive == 1) {
1039 node->__lasttime = TickTime();
1040 node->elapsedTime = 0.0;
1042 MARK_EVENT (X3D_NODE(node), offsetof(
struct X3D_AudioClip, isActive));
1046 if(node->pauseTime > node->startTime){
1047 if( node->resumeTime < node->pauseTime && !node->isPaused){
1048 node->isPaused = TRUE;
1049 MARK_EVENT (X3D_NODE(node), offsetof(
struct X3D_AudioClip, isPaused));
1050 }
else if(node->resumeTime > node->pauseTime && node->isPaused){
1051 node->isPaused = FALSE;
1052 node->__lasttime = TickTime();
1053 MARK_EVENT (X3D_NODE(node), offsetof(
struct X3D_AudioClip, isPaused));
1057 if(node->isActive == 1 && node->isPaused == FALSE) {
1058 double dtime = TickTime();
1059 node->elapsedTime += dtime - node->__lasttime;
1060 node->__lasttime = dtime;
1062 MARK_EVENT (ptr, offsetof(
struct X3D_AudioClip, elapsedTime));
1070 #define LOAD_STABLE 10 //from component_sound.c
1071 unsigned char *movietexture_get_frame_by_fraction(
struct X3D_Node* node,
float fraction,
int *width,
int *height,
int *nchan);
1072 void do_MovieTextureTick(
void *ptr) {
1089 if(node->__inittime == 0.0)
1090 node->__inittime = TickTime();
1092 if(TickTime() < node->startTime) {
1099 duration = node->duration_changed;
1100 speed = node->speed;
1102 oldstatus = node->isActive;
1103 do_active_inactive (
1104 &node->isActive, &node->__inittime, &node->startTime,
1105 &node->stopTime,node->loop,duration,
1106 speed,node->elapsedTime);
1108 if (oldstatus != node->isActive) {
1109 if (node->isActive == 1) {
1112 node->__lasttime = TickTime();
1113 node->elapsedTime = 0.0;
1119 if(node->pauseTime > node->startTime){
1120 if( node->resumeTime < node->pauseTime && !node->isPaused){
1121 node->isPaused = TRUE;
1123 }
else if(node->resumeTime > node->pauseTime && node->isPaused){
1124 node->isPaused = FALSE;
1125 node->__lasttime = TickTime();
1130 if(node->isActive && node->isPaused == FALSE) {
1131 double dtime = TickTime();
1132 node->elapsedTime += dtime - node->__lasttime;
1133 node->__lasttime = dtime;
1143 myFrac = node->elapsedTime / duration;
1145 tmpTrunc = (int) myFrac;
1146 frac = (float)myFrac - (
float)tmpTrunc;
1151 }
else if (APPROX(speed, 0.0f)) {
1154 node->__frac = frac;
1156 if(node->loop == FALSE && tmpTrunc > 0)
1157 node->__frac = 1.0f;
1163 if(node->__loadstatus == LOAD_STABLE){
1166 unsigned char* texdata;
1167 int width,height,nchan;
1169 texdata = movietexture_get_frame_by_fraction(X3D_NODE(node), node->__frac, &width, &height, &nchan);
1171 int thisTexture = node->__textureTableIndex;
1172 tti = getTableIndex(thisTexture);
1174 static int once = 0;
1178 tti->channels = nchan;
1182 tti->texdata = malloc(tti->x*tti->y*tti->channels);
1183 memcpy(tti->texdata,texdata,tti->x*tti->y*tti->channels);
1184 tti->status = TEX_NEEDSBINDING;
1187 tti->status = TEX_LOADED;
1188 glBindTexture(GL_TEXTURE_2D,tti->OpenGLTexture);
1190 FW_GL_TEXPARAMETERI( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1191 FW_GL_TEXPARAMETERI( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1196 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,texdata);
1198 glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,GL_RGB,GL_UNSIGNED_BYTE,texdata);
1199 glBindTexture(GL_TEXTURE_2D,0);
1213 void do_TouchSensor (
void *ptr,
int ev,
int but1,
int over) {
1219 printf (
"%lf: TS ",TickTime());
1220 if (ev==ButtonPress) printf (
"ButtonPress ");
1221 else if (ev==ButtonRelease) printf (
"ButtonRelease ");
1222 else if (ev==KeyPress) printf (
"KeyPress ");
1223 else if (ev==KeyRelease) printf (
"KeyRelease ");
1224 else if (ev==MotionNotify) printf (
"%lf MotionNotify ");
1225 else printf (
"ev %d ",ev);
1227 if (but1) printf (
"but1 TRUE ");
else printf (
"but1 FALSE ");
1228 if (over) printf (
"over TRUE ");
else printf (
"over FALSE ");
1235 if (node->__oldEnabled != node->enabled) {
1236 node->__oldEnabled = node->enabled;
1237 MARK_EVENT(X3D_NODE(node),offsetof (
struct X3D_TouchSensor, enabled));
1239 if (!node->enabled)
return;
1242 if ((ev == overMark) && (over != node->isOver)) {
1244 printf (
"TS %u, isOver changed %d\n",node, over);
1246 node->isOver = over;
1252 if (ev == ButtonPress) {
1253 node->isActive=TRUE;
1256 printf (
"touchSens %u, butPress\n",node);
1259 node->touchTime = TickTime();
1262 }
else if (ev == ButtonRelease) {
1264 printf (
"touchSens %u, butRelease\n",node);
1266 node->isActive=FALSE;
1272 memcpy ((
void *) &node->_oldhitPoint, (
void *) &tg->RenderFuncs.ray_save_posn,
sizeof(
struct SFColor));
1275 if ((APPROX(node->_oldhitPoint.c[0],node->hitPoint_changed.c[0])!= TRUE) ||
1276 (APPROX(node->_oldhitPoint.c[1],node->hitPoint_changed.c[1])!= TRUE) ||
1277 (APPROX(node->_oldhitPoint.c[2],node->hitPoint_changed.c[2])!= TRUE)) {
1279 memcpy ((
void *) &node->hitPoint_changed, (
void *) &node->_oldhitPoint,
sizeof(
struct SFColor));
1284 normalval.x = tg->RenderFuncs.hyp_save_norm[0];
1285 normalval.y = tg->RenderFuncs.hyp_save_norm[1];
1286 normalval.z = tg->RenderFuncs.hyp_save_norm[2];
1287 normalize_vector(&normalval);
1288 node->_oldhitNormal.c[0] = (float) normalval.x;
1289 node->_oldhitNormal.c[1] = (
float) normalval.y;
1290 node->_oldhitNormal.c[2] = (float) normalval.z;
1293 if ((APPROX(node->_oldhitNormal.c[0],node->hitNormal_changed.c[0])!= TRUE) ||
1294 (APPROX(node->_oldhitNormal.c[1],node->hitNormal_changed.c[1])!= TRUE) ||
1295 (APPROX(node->_oldhitNormal.c[2],node->hitNormal_changed.c[2])!= TRUE)) {
1297 memcpy ((
void *) &node->hitNormal_changed, (
void *) &node->_oldhitNormal,
sizeof(
struct SFColor));
1298 MARK_EVENT(ptr, offsetof (
struct X3D_TouchSensor, hitNormal_changed));
1303 void do_LineSensor(
void *ptr,
int ev,
int but1,
int over) {
1315 float trackpoint[3], translation[3], xxx;
1322 printf(
"%lf: TS ", TickTime());
1323 if (ev == ButtonPress) printf(
"ButtonPress ");
1324 else if (ev == ButtonRelease) printf(
"ButtonRelease ");
1325 else if (ev == KeyPress) printf(
"KeyPress ");
1326 else if (ev == KeyRelease) printf(
"KeyRelease ");
1327 else if (ev == MotionNotify) printf(
"%lf MotionNotify ");
1328 else printf(
"ev %d ", ev);
1330 if (but1) printf(
"but1 TRUE ");
else printf(
"but1 FALSE ");
1331 if (over) printf(
"over TRUE ");
else printf(
"over FALSE ");
1338 if (node->__oldEnabled != node->enabled) {
1339 node->__oldEnabled = node->enabled;
1340 MARK_EVENT(X3D_NODE(node), offsetof(
struct X3D_LineSensor, enabled));
1342 if (!node->enabled)
return;
1353 float origin [] = { 0.0f, 0.0f, 0.0f };
1354 float footpoint2[3], footpoint1[3], v1[3];
1355 vecdif3f(v1, tg->RenderFuncs.hyp_save_norm, tg->RenderFuncs.hyp_save_posn);
1356 vecnormalize3f(v1, v1);
1357 if (!line_intersect_line_3f(tg->RenderFuncs.hyp_save_posn, v1,
1358 origin, node->direction.c, NULL, &tt, footpoint1, footpoint2))
1364 veccopy3f(trackpoint,footpoint2);
1366 if ((ev == ButtonPress) && but1) {
1368 #define LINESENSOR_FLOAT_OFFSET 1
1369 #ifndef LINESENSOR_FLOAT_OFFSET
1371 veccopy3f(op.c, trackpoint);
1372 memcpy((
void *)&node->_origPoint, (
void *)&op,
sizeof(
struct SFColor));
1375 node->_origPoint.c[0] = xxx;
1377 if (node->autoOffset)
1378 node->_origPoint.c[1] = node->offset;
1380 node->_origPoint.c[1] = 0.0f;
1383 node->isActive = TRUE;
1387 else if ((ev == MotionNotify) && (node->isActive) && but1) {
1388 float xxxoffset, xxxorigin;
1391 node->_oldtrackPoint.c[0] = trackpoint[0];
1392 node->_oldtrackPoint.c[1] = trackpoint[1];
1393 node->_oldtrackPoint.c[2] = trackpoint[2];
1395 if ((APPROX(node->_oldtrackPoint.c[0], node->trackPoint_changed.c[0]) != TRUE) ||
1396 (APPROX(node->_oldtrackPoint.c[1], node->trackPoint_changed.c[1]) != TRUE) ||
1397 (APPROX(node->_oldtrackPoint.c[2], node->trackPoint_changed.c[2]) != TRUE)) {
1399 memcpy((
void *)&node->trackPoint_changed, (
void *)&node->_oldtrackPoint,
sizeof(
struct SFColor));
1400 MARK_EVENT(ptr, offsetof(
struct X3D_LineSensor, trackPoint_changed));
1405 #ifdef LINESENSOR_FLOAT_OFFSET
1406 xxxoffset = node->offset;
1407 xxxorigin = node->_origPoint.c[0];
1411 xxxoffset = vecdot3f(node->direction.c,node->offset.c);
1412 xxxorigin = vecdot3f(node->direction.c,node->_origPoint.c);
1417 if (node->maxPosition >= node->minPosition) {
1418 if (xxx < node->minPosition) {
1419 xxx = node->minPosition;
1421 else if (xxx > node->maxPosition) {
1422 xxx = node->maxPosition;
1426 vecscale3f(translation, node->direction.c, xxx);
1428 #ifndef LINESENSOR_FLOAT_OFFSET
1431 vecscale3f(diroffset, node->direction.c, xxxoffset);
1433 vecdif3f(nondiroffset, node->offset.c, diroffset);
1435 vecadd3f(translation, translation, nondiroffset);
1438 node->_oldtranslation.c[0] = translation[0];
1439 node->_oldtranslation.c[1] = translation[1];
1440 node->_oldtranslation.c[2] = translation[2];
1442 if ((APPROX(node->_oldtranslation.c[0], node->translation_changed.c[0]) != TRUE) ||
1443 (APPROX(node->_oldtranslation.c[1], node->translation_changed.c[1]) != TRUE) ||
1444 (APPROX(node->_oldtranslation.c[2], node->translation_changed.c[2]) != TRUE)) {
1446 memcpy((
void *)&node->translation_changed, (
void *)&node->_oldtranslation,
sizeof(
struct SFColor));
1447 MARK_EVENT(ptr, offsetof(
struct X3D_LineSensor, translation_changed));
1450 node->_origPoint.c[1] = xxx;
1452 else if (ev == ButtonRelease) {
1454 node->isActive = FALSE;
1458 if (node->autoOffset) {
1459 #ifdef LINESENSOR_FLOAT_OFFSET
1460 node->offset = node->_origPoint.c[1];
1462 node->offset.c[0] = node->translation_changed.c[0];
1463 node->offset.c[1] = node->translation_changed.c[1];
1464 node->offset.c[2] = node->translation_changed.c[2];
1473 void do_PlaneSensor (
void *ptr,
int ev,
int but1,
int over) {
1475 float mult, nx, ny, trackpoint[3], *posn;
1482 ConsoleMessage(
"%lf: TS ",TickTime());
1483 if (ev==ButtonPress) ConsoleMessage(
"ButtonPress ");
1484 else if (ev==ButtonRelease) ConsoleMessage(
"ButtonRelease ");
1485 else if (ev==KeyPress) ConsoleMessage(
"KeyPress ");
1486 else if (ev==KeyRelease) ConsoleMessage(
"KeyRelease ");
1487 else if (ev==MotionNotify) ConsoleMessage(
"MotionNotify ");
1488 else ConsoleMessage(
"ev %d ",ev);
1490 if (but1) ConsoleMessage(
"but1 TRUE ");
else ConsoleMessage(
"but1 FALSE ");
1491 if (over) ConsoleMessage(
"over TRUE ");
else ConsoleMessage(
"over FALSE ");
1492 ConsoleMessage (
"\n");
1498 if (node->__oldEnabled != node->enabled) {
1499 node->__oldEnabled = node->enabled;
1500 MARK_EVENT(X3D_NODE(node),offsetof (
struct X3D_PlaneSensor, enabled));
1502 if (!node->enabled)
return;
1510 float N[3] = { 0.0f, 0.0f, 1.0f };
1515 vecnormalize3f(v, vecdif3f(t1, tg->RenderFuncs.hyp_save_norm, tg->RenderFuncs.hyp_save_posn));
1517 axisangle_rotate3f(NS,N, node->axisRotation.c);
1520 posn = tg->RenderFuncs.hyp_save_posn;
1521 if (!line_intersect_planed_3f(posn, v, NS, 0.0f, trackpoint, NULL))
1523 axisangle_rotate3f(trackpoint, trackpoint, node->axisRotation.c);
1526 if ((ev==ButtonPress) && but1) {
1530 posn = tg->RenderFuncs.hyp_save_posn;
1532 veccopy3f(op.c, trackpoint);
1534 memcpy((
void *)&node->_origPoint, (
void *)&op,
sizeof(
struct SFColor));
1536 memcpy ((
void *) &node->_origPoint,
1537 (
void *) posn,
sizeof(
struct SFColor));
1540 node->isActive=TRUE;
1543 }
else if ((ev==MotionNotify) && (node->isActive) && but1) {
1547 mult = (node->_origPoint.c[2] - tg->RenderFuncs.hyp_save_posn[2]) /
1548 (tg->RenderFuncs.hyp_save_norm[2] - tg->RenderFuncs.hyp_save_posn[2]);
1549 nx = tg->RenderFuncs.hyp_save_posn[0] + mult * (tg->RenderFuncs.hyp_save_norm[0] - tg->RenderFuncs.hyp_save_posn[0]);
1550 ny = tg->RenderFuncs.hyp_save_posn[1] + mult * (tg->RenderFuncs.hyp_save_norm[1] - tg->RenderFuncs.hyp_save_posn[1]);
1553 nx = trackpoint[0]; ny = trackpoint[1];
1556 ConsoleMessage (
"now, mult %f nx %f ny %f op %f %f %f\n",mult,nx,ny,
1557 node->_origPoint.c[0],node->_origPoint.c[1],
1558 node->_origPoint.c[2]);
1563 node->_oldtrackPoint.c[0] = nx;
1564 node->_oldtrackPoint.c[1] = ny;
1565 node->_oldtrackPoint.c[2] = node->_origPoint.c[2];
1568 veccopy3f(node->_oldtrackPoint.c, trackpoint);
1571 if ((APPROX(node->_oldtrackPoint.c[0],node->trackPoint_changed.c[0])!= TRUE) ||
1572 (APPROX(node->_oldtrackPoint.c[1],node->trackPoint_changed.c[1])!= TRUE) ||
1573 (APPROX(node->_oldtrackPoint.c[2],node->trackPoint_changed.c[2])!= TRUE)) {
1575 memcpy ((
void *) &node->trackPoint_changed, (
void *) &node->_oldtrackPoint,
sizeof(
struct SFColor));
1576 MARK_EVENT(ptr, offsetof (
struct X3D_PlaneSensor, trackPoint_changed));
1581 tr.c[0] = nx - node->_origPoint.c[0] + node->offset.c[0];
1582 tr.c[1] = ny - node->_origPoint.c[1] + node->offset.c[1];
1583 tr.c[2] = node->offset.c[2];
1585 for (tmp=0; tmp<2; tmp++) {
1586 if (node->maxPosition.c[tmp] >= node->minPosition.c[tmp]) {
1587 if (tr.c[tmp] < node->minPosition.c[tmp]) {
1588 tr.c[tmp] = node->minPosition.c[tmp];
1589 }
else if (tr.c[tmp] > node->maxPosition.c[tmp]) {
1590 tr.c[tmp] = node->maxPosition.c[tmp];
1595 node->_oldtranslation.c[0] = tr.c[0];
1596 node->_oldtranslation.c[1] = tr.c[1];
1597 node->_oldtranslation.c[2] = tr.c[2];
1599 if ((APPROX(node->_oldtranslation.c[0],node->translation_changed.c[0])!= TRUE) ||
1600 (APPROX(node->_oldtranslation.c[1],node->translation_changed.c[1])!= TRUE) ||
1601 (APPROX(node->_oldtranslation.c[2],node->translation_changed.c[2])!= TRUE)) {
1603 memcpy ((
void *) &node->translation_changed, (
void *) &node->_oldtranslation,
sizeof(
struct SFColor));
1604 MARK_EVENT(ptr, offsetof (
struct X3D_PlaneSensor, translation_changed));
1607 }
else if (ev==ButtonRelease) {
1609 node->isActive=FALSE;
1613 if (node->autoOffset) {
1614 node->offset.c[0] = node->translation_changed.c[0];
1615 node->offset.c[1] = node->translation_changed.c[1];
1616 node->offset.c[2] = node->translation_changed.c[2];
1626 void do_Anchor (
void *ptr,
int ev,
int but1,
int over) {
1634 if (ev==ButtonRelease) {
1637 if (node->url.n < 1)
return;
1638 setAnchorsAnchor( node );
1640 OLDCODE FREE_IF_NZ(tg->RenderFuncs.OSX_replace_world_from_console);
1643 tg->RenderFuncs.BrowserAction = TRUE;
1648 void do_CylinderSensor (
void *ptr,
int ev,
int but1,
int over) {
1650 double rot, radius, ang, length;
1651 double det, pos, neg, temp;
1652 double acute_angle, disk_angle, height;
1653 float Y[3] = { 0.0f, 1.0f, 0.0f }, ZERO[3] = { 0.0f, 0.0f, 0.0f };
1654 float as[3], bs[3], v[3], rps[3];
1658 GLDOUBLE modelMatrix[16];
1665 if (node->__oldEnabled != node->enabled) {
1666 node->__oldEnabled = node->enabled;
1669 if (!node->enabled)
return;
1679 axisangle_rotate3f(as, tg->RenderFuncs.hyp_save_posn, node->axisRotation.c);
1680 axisangle_rotate3f(bs, tg->RenderFuncs.hyp_save_norm, node->axisRotation.c);
1681 vecnormalize3f(v, vecdif3f(v, bs, as));
1682 axisangle_rotate3f(rps,tg->RenderFuncs.ray_save_posn, node->axisRotation.c);
1685 if (ev==ButtonPress) {
1688 memcpy((
void *)&node->_origPoint,
1689 (
void *)&tg->RenderFuncs.ray_save_posn,
sizeof(
struct SFColor));
1700 dot = vecdot3f(v, Y);
1701 acute_angle = acos(dot);
1702 ang = min(acute_angle,PI - acute_angle);
1706 radius = veclength3f(rs);
1707 vecnormalize3f(rs, rs);
1708 if (ang < node->diskAngle){
1710 disk_angle = -atan2(rs[2], rs[0]);
1713 float travelled, cylpoint[3], axispoint[3], dif[3];
1714 line_intersect_line_3f(as, v, ZERO, Y, NULL, NULL, cylpoint, axispoint);
1715 travelled = veclength3f(vecdif3f(dif, cylpoint, axispoint));
1716 if (det3f(v, dif, Y) > 0.0f) travelled = -travelled;
1717 disk_angle = travelled / (2.0f * PI * radius) * (2.0f * PI);
1719 node->_radius = (float)radius;
1721 origPoint.c[0] = (float)disk_angle;
1722 origPoint.c[1] = (float)-height;
1723 memcpy((
void *)&node->_origPoint,(
void *)&origPoint,
sizeof(
struct SFColor));
1726 node->isActive=TRUE;
1732 node->_radius = tg->RenderFuncs.ray_save_posn[0] * tg->RenderFuncs.ray_save_posn[0] +
1733 tg->RenderFuncs.ray_save_posn[1] * tg->RenderFuncs.ray_save_posn[1] +
1734 tg->RenderFuncs.ray_save_posn[2] * tg->RenderFuncs.ray_save_posn[2];
1736 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1747 temp = modelMatrix[1] * modelMatrix[6] * modelMatrix[8];
1748 if (temp >= 0.0) pos += temp;
else neg += temp;
1749 temp = -modelMatrix[2] * modelMatrix[5] * modelMatrix[8];
1750 if (temp >= 0.0) pos += temp;
else neg += temp;
1751 temp = -modelMatrix[0] * modelMatrix[6] * modelMatrix[9];
1752 if (temp >= 0.0) pos += temp;
else neg += temp;
1753 temp = modelMatrix[2] * modelMatrix[4] * modelMatrix[9];
1754 if (temp >= 0.0) pos += temp;
else neg += temp;
1755 temp = modelMatrix[0] * modelMatrix[5] * modelMatrix[10];
1756 if (temp >= 0.0) pos += temp;
else neg += temp;
1757 temp = -modelMatrix[1] * modelMatrix[4] * modelMatrix[10];
1758 if (temp >= 0.0) pos += temp;
else neg += temp;
1763 bv.x = (modelMatrix[4] * modelMatrix[9] - modelMatrix[5] * modelMatrix[8]) * det;
1764 bv.y = -(modelMatrix[0] * modelMatrix[9] - modelMatrix[1] * modelMatrix[8]) * det;
1765 bv.z = (modelMatrix[0] * modelMatrix[5] - modelMatrix[1] * modelMatrix[4]) * det;
1767 quaternion_normalize(&bv);
1769 if (ang > (M_PI / 2)) { ang = M_PI - ang; }
1771 if (ang < node->diskAngle) {
1772 node->_dlchange=TRUE;
1774 node->_dlchange=FALSE;
1779 if ((ev == MotionNotify) && (node->isActive)) {
1782 memcpy((
void *)&node->_oldtrackPoint, (
void *)&tg->RenderFuncs.ray_save_posn,
sizeof(
struct SFColor));
1784 veccopy3f(node->_oldtrackPoint.c, rps);
1785 if ((APPROX(node->_oldtrackPoint.c[0], node->trackPoint_changed.c[0]) != TRUE) ||
1786 (APPROX(node->_oldtrackPoint.c[1], node->trackPoint_changed.c[1]) != TRUE) ||
1787 (APPROX(node->_oldtrackPoint.c[2], node->trackPoint_changed.c[2]) != TRUE)) {
1789 memcpy((
void *)&node->trackPoint_changed, (
void *)&node->_oldtrackPoint,
sizeof(
struct SFColor));
1796 dir1.x = tg->RenderFuncs.ray_save_posn[0];
1798 dir1.z = tg->RenderFuncs.ray_save_posn[2];
1800 if (node->_dlchange) {
1805 radius = (dir1.x * dir1.x + dir1.y * dir1.y + dir1.z * dir1.z);
1808 quaternion_normalize(&dir1);
1810 dir2.x = node->_origPoint.c[0];
1812 dir2.z = node->_origPoint.c[2];
1814 quaternion_normalize(&dir2);
1817 tempV.x = dir2.y * dir1.z - dir2.z * dir1.y;
1818 tempV.y = dir2.z * dir1.x - dir2.x * dir1.z;
1819 tempV.z = dir2.x * dir1.y - dir2.y * dir1.x;
1820 quaternion_normalize(&tempV);
1822 length = tempV.x * tempV.x + tempV.y * tempV.y + tempV.z * tempV.z;
1823 if (APPROX(length, 0.0)) {
return; }
1826 rot = radius * acos((dir1.x*dir2.x + dir1.y*dir2.y + dir1.z*dir2.z));
1828 if (APPROX(tempV.y, -1.0)) rot = -rot;
1835 float diskpoint[3], orig_diskangle, height;
1836 height = node->_origPoint.c[1];
1837 radius = node->_radius;
1838 orig_diskangle = node->_origPoint.c[0];
1839 if (node->_dlchange == TRUE) {
1841 line_intersect_planed_3f(as, v, Y, height, diskpoint, NULL);
1842 vecnormalize3f(diskpoint, diskpoint);
1844 disk_angle = -atan2(diskpoint[2], diskpoint[0]);
1860 float travelled, axispoint[3], dif[3];
1862 line_intersect_line_3f(as, v, ZERO, Y, NULL, NULL, cylpoint, axispoint);
1866 travelled = veclength3f(vecdif3f(dif, cylpoint, axispoint));
1867 if (det3f(v, dif, Y) > 0.0f) travelled = -travelled;
1868 disk_angle = travelled / (2.0f * PI * radius) * (2.0f * PI);
1871 rot = disk_angle - orig_diskangle;
1874 if (node->autoOffset) {
1875 rot = node->offset + rot;
1877 if (node->minAngle < node->maxAngle) {
1878 if (rot < node->minAngle) {
1879 rot = node->minAngle;
1880 }
else if (rot > node->maxAngle) {
1881 rot = node->maxAngle;
1885 node->_oldrotation.c[0] = (float) 0;
1886 node->_oldrotation.c[1] = (float) 1;
1887 node->_oldrotation.c[2] = (float) 0;
1888 node->_oldrotation.c[3] = (float) rot;
1890 if ((APPROX(node->_oldrotation.c[0],node->rotation_changed.c[0])!= TRUE) ||
1891 (APPROX(node->_oldrotation.c[1],node->rotation_changed.c[1])!= TRUE) ||
1892 (APPROX(node->_oldrotation.c[2],node->rotation_changed.c[2])!= TRUE) ||
1893 (APPROX(node->_oldrotation.c[3],node->rotation_changed.c[3])!= TRUE)) {
1895 memcpy ((
void *) &node->rotation_changed, (
void *) &node->_oldrotation,
sizeof(
struct SFRotation));
1900 }
else if (ev==ButtonRelease) {
1902 node->isActive=FALSE;
1905 if (node->autoOffset) {
1906 memcpy ((
void *) &node->offset,
1907 (
void *) &node->rotation_changed.c[3],
1917 #define ORIG_X node->_origPoint.c[0]
1918 #define ORIG_Y node->_origPoint.c[1]
1919 #define ORIG_Z node->_origPoint.c[2]
1920 #define NORM_ORIG_X node->_origNormalizedPoint.c[0]
1921 #define NORM_ORIG_Y node->_origNormalizedPoint.c[1]
1922 #define NORM_ORIG_Z node->_origNormalizedPoint.c[2]
1923 #define CUR_X tg->RenderFuncs.ray_save_posn[0]
1924 #define CUR_Y tg->RenderFuncs.ray_save_posn[1]
1925 #define CUR_Z tg->RenderFuncs.ray_save_posn[2]
1926 #define NORM_CUR_X normalizedCurrentPoint.c[0]
1927 #define NORM_CUR_Y normalizedCurrentPoint.c[1]
1928 #define NORM_CUR_Z normalizedCurrentPoint.c[2]
1929 #define RADIUS node->_radius
1941 void do_SphereSensor (
void *ptr,
int ev,
int but1,
int over) {
1957 if (node->__oldEnabled != node->enabled) {
1958 node->__oldEnabled = node->enabled;
1967 if (ev==ButtonPress) {
1974 RADIUS = (float) sqrt(CUR_X * CUR_X + CUR_Y * CUR_Y + CUR_Z * CUR_Z);
1976 if (APPROX(RADIUS,0.0)) {
1977 printf (
"warning, RADIUS %lf == 0, can not compute\n",RADIUS);
1982 NORM_ORIG_X = CUR_X / RADIUS;
1983 NORM_ORIG_Y = CUR_Y / RADIUS;
1984 NORM_ORIG_Z = CUR_Z / RADIUS;
1989 vrmlrot_normalize(node->offset.c);
1992 node->isActive=TRUE;
1995 }
else if (ev==ButtonRelease) {
1997 node->isActive=FALSE;
2000 if (node->autoOffset) {
2001 memcpy ((
void *) &node->offset,
2002 (
void *) &node->rotation_changed,
2005 }
else if ((ev==MotionNotify) && (node->isActive)) {
2009 struct SFColor normalizedCurrentPoint;
2013 newRad = sqrt(CUR_X * CUR_X + CUR_Y * CUR_Y + CUR_Z * CUR_Z);
2016 if (APPROX(newRad,0.0)) {
2017 printf (
"warning, newRad %lf == 0, can not compute\n",newRad);
2020 RADIUS = (float) newRad;
2023 NORM_CUR_X = CUR_X / RADIUS;
2024 NORM_CUR_Y = CUR_Y / RADIUS;
2025 NORM_CUR_Z = CUR_Z / RADIUS;
2028 newA.x = ORIG_Y * CUR_Z - ORIG_Z * CUR_Y;
2029 newA.y = ORIG_Z * CUR_X - ORIG_X * CUR_Z;
2030 newA.z = ORIG_X * CUR_Y - ORIG_Y * CUR_X;
2031 normalize_vector(&newA);
2035 dotProd = NORM_ORIG_X * NORM_CUR_X + NORM_ORIG_Y * NORM_CUR_Y + NORM_ORIG_Z * NORM_CUR_Z;
2040 dotProd = acos(dotProd);
2047 if(node->autoOffset)
2070 vrmlrot_to_quaternion(&q1, (
double) newA.x,
2071 (
double) newA.y, (
double) newA.z, (
double) dotProd);
2072 vrmlrot_to_quaternion(&q2, (
double) node->offset.c[0],
2073 (
double) node->offset.c[1], (
double) node->offset.c[2], (
double) node->offset.c[3]);
2075 quaternion_multiply(&qret,&q1,&q2);
2077 quaternion_to_vrmlrot(&qret, &newA.x, &newA.y, &newA.z, &dotProd);
2082 node->rotation_changed.c[0] = (float) newA.x;
2083 node->rotation_changed.c[1] = (
float) newA.y;
2084 node->rotation_changed.c[2] = (float) newA.z;
2085 node->rotation_changed.c[3] = (
float) dotProd;
2088 node->trackPoint_changed.c[0] = NORM_CUR_X;
2089 node->trackPoint_changed.c[1] = NORM_CUR_Y;
2090 node->trackPoint_changed.c[2] = NORM_CUR_Z;