FreeWRL/FreeX3D  3.0.0
EAI_C_Node.c
1 
2 /****************************************************************************
3  This file is part of the FreeWRL/FreeX3D Distribution.
4 
5  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
6 
7  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
8  it under the terms of the GNU Lesser Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
19 ****************************************************************************/
20 
21 
22 // for compiler warning mitigation, we require the following few lines.
23 #define UNUSED(v) ((void) v)
24 
25 
26 /* function protos */
27 #ifndef WIN32
28 #include "config.h"
29 #include "system.h"
30 #endif
31 #include "EAI_C.h"
32 
33 
34 /* get a node pointer */
35 X3DNode *X3D_getNode (char *name) {
36  char *ptr;
37  int adr;
38  X3DNode *retval;
39 
40  retval = malloc (sizeof(X3DNode));
41  retval->X3D_SFNode.type = FIELDTYPE_SFNode;
42  /* retval->X3D_SFNode.SFNodeType = '\0'; */
43 
44  retval->X3D_SFNode.adr = 0;
45 
46  /* get the node address. save the address. */
47  ptr = _X3D_make1StringCommand(GETNODE,name);
48  //printf ("X3D_getNode, stringCommand is :%s:\n",ptr);
49 
50  if (sscanf (ptr,"%d", &adr) != 1) {
51  printf ("error getting %s\n",name);
52  } else {
53  #ifdef VERBOSE
54  printf ("X3D_getNode, ptr %s\n",ptr);
55  printf ("adr %d\n",adr);
56  #endif
57 
58  if (adr == 0) {
59  printf ("node %s does not exist\n",name);
60  return 0;
61  }
62 
63 
64  retval->X3D_SFNode.adr = adr;
65  }
66  REMOVE_EOT
67  return retval;
68 }
69 
70 //writes all the parents of a given node into an allocated array and passes the address of it to the outParentArray argument. Caller should free the array.
71 //returns the number of parents, "0" if none found, "-1" if an error occurred
72 int X3D_getParentNodes(X3DNode* child, X3DNode** outParentArray)
73 {
74  char *ptr;
75  int adr;
76  char arg[10];
77  X3DNode* tmpBuf;
78  X3DNode* tmpReallocBuf;
79  char* parentToken;
80  char* next_token;
81  int parentAdr;
82  int parentCount;
83 
84  parentToken=NULL;
85  next_token=NULL;
86 
87  if((child->X3D_SFNode.type != FIELDTYPE_SFNode) && (child->X3D_MFNode.type != FIELDTYPE_MFNode)) {
88  printf ("X3D_getParentNodes, expected a node, got a %s\n",FIELDTYPES[child->X3D_SFNode.type]);
89  return -1;
90  }
91 
92  if (child->X3D_SFNode.type == FIELDTYPE_SFNode) {
93  adr = child->X3D_SFNode.adr;
94  } else {
95  if (child->X3D_MFNode.n != 1) {
96  printf ("warning - will only get event for first child = have %d nodes\n",child->X3D_MFNode.n);
97  }
98  /* get the first address in the list */
99  adr = child->X3D_MFNode.p[5].adr;
100  }
101 
102  snprintf(arg, 10, "%d", adr);
103 
104  ptr = _X3D_make1StringCommand(GETNODEPARENTS,arg);
105 
106  REMOVE_EOT;
107 
108  //start tokenizer
109  parentToken = STRTOK_S(ptr," ",&next_token);
110 
111  sscanf(parentToken,"%d",&parentAdr);
112 
113  //parent search did not found parents or encountered an error?
114  if(parentAdr <= 0)
115  {
116  *outParentArray = NULL;
117  return parentAdr;
118  }
119 
120  tmpBuf = (X3DNode*) calloc(10,sizeof(X3DNode));
121  parentCount=0;
122 
123  while(parentToken)
124  {
125  //parentCount is a multiply of 10?
126  if(parentCount && parentCount%10==0)
127  {
128  //reallocate the buffer with 10 more slots
129  tmpReallocBuf =(X3DNode*) realloc(tmpBuf,(sizeof(X3DNode)*(parentCount+10)));
130 
131  //buffer was not reallocated, we exit
132  if(!tmpReallocBuf)
133  {
134  *outParentArray = tmpBuf;
135  return -1;
136  }
137 
138  tmpBuf = tmpReallocBuf;
139  }
140 
141  tmpBuf[parentCount].X3D_SFNode.type = FIELDTYPE_SFNode;
142 
143  sscanf(parentToken,"%d",&parentAdr);
144 
145  //parent search did not found parents or encountered an error?
146  if(parentAdr <= 0)
147  {
148  *outParentArray = tmpBuf;
149  return parentAdr;
150  }
151 
152  tmpBuf[parentCount].X3D_SFNode.adr = parentAdr;
153 
154  parentCount++;
155 
156  //find next parent address
157  parentToken = STRTOK_S(NULL," ",&next_token);
158  }
159 
160  *outParentArray = tmpBuf;
161 
162  return parentCount;
163 }
164 
165 //same as above, but also get the child node using the DEF name passed and copy the address of it into the outChildNode argument.
166 int X3D_getParentNodesbyName(char *childName, X3DNode** outChildNode, X3DNode** outParentArray)
167 {
168  *outChildNode = X3D_getNode(childName);
169 
170  if(*outChildNode)
171  return X3D_getParentNodes(*outChildNode, outParentArray);
172  else
173  return -1;
174 }
175 
176 
177 /* get an eventIn */
178 
179 X3DEventIn *_X3D_getEvent(X3DNode *node, char *name, int into) {
180  char *ptr;
181  int origPtr;
182  int offset;
183  int nds;
184  X3DEventIn *retval;
185  int adr;
186 
187  retval = malloc (sizeof (struct _intX3DEventIn));
188  retval->offset = 0;
189  retval->nodeptr = 0;
190  retval->datasize = 0;
191  retval->field = NULL;
192  retval->scripttype = 0;
193 
194  if((node->X3D_SFNode.type != FIELDTYPE_SFNode) && (node->X3D_MFNode.type != FIELDTYPE_MFNode)) {
195  printf ("X3D_getEvent, expected a node, got a %s\n",FIELDTYPES[node->X3D_SFNode.type]);
196  free(retval);
197  return 0;
198  }
199 
200  if (node->X3D_SFNode.type == FIELDTYPE_SFNode) {
201  adr = node->X3D_SFNode.adr;
202  } else {
203  if (node->X3D_MFNode.n != 1) {
204  int i;
205  printf ("warning - will only get event for first node = have %d nodes\n",node->X3D_MFNode.n);
206  for (i=0; i<node->X3D_MFNode.n; i++) {
207  printf ("... node %d nodetype %d\n",i,node->X3D_MFNode.p[i].adr);
208  }
209  }
210  /* get the first address in the list */
211  adr = node->X3D_MFNode.p[0].adr;
212  }
213 
214  /* printf ("getting eventin for address %d, field %s\n",adr, name); */
215  //if (into) ptr = _X3D_Browser_SendEventType(adr, name, "eventIn");
216  //else ptr = _X3D_Browser_SendEventType(adr, name, "eventOut");
217 
218  switch(into)
219  {
220  case 0: //specifing a "eventOut" access method
221  ptr = _X3D_Browser_SendEventType(adr, name, "eventOut");
222  break;
223  case 1: //specifing a "eventIn" access method
224  ptr = _X3D_Browser_SendEventType(adr, name, "eventIn");
225  break;
226  case -1: //we do not want to specify an access method, we only ask for the field definition
227  ptr = _X3D_Browser_SendEventType(adr, name, "");
228  break;
229  default:
230  //TODO: FOR NOW WE FORCE TO AN "EVENTIN" CASE. IT WOULD BE BETTER TO THROW AN ERROR
231  ptr = _X3D_Browser_SendEventType(adr, name, "eventIn");
232  break;
233  }
234 
235  /* ptr should point to , for example: 161412616 116 0 q 0 eventIn
236  where we have
237  newnodepoiner,
238  field offset,
239  node datasize,
240  field type (as an ascii char - eg 'q' for X3D_MFNODE
241  ScriptType,
242  and whether this is an eventIn or not.
243  printf ("getEvent: ptr is %s\n",ptr);
244  */
245 
246  /* eg: ptr is 161412616 116 0 q 0 eventIn */
247  if (sscanf(ptr,"%d %d %d", &origPtr, &offset, &nds) != 3) {
248  printf ("error in getEventIn\n");
249  free(retval);
250  return 0;
251  }
252 
253  /* do the pointers match? they should.. */
254  if (origPtr != adr) {
255  printf ("error in getEventIn, origptr and node ptr do not match\n");
256  free(retval);
257  return 0;
258  }
259 
260  /* save the first 3 fields */
261  retval->nodeptr = origPtr;
262  retval->offset = offset;
263  retval->datasize = nds;
264 
265  /* go to the data type. will be a character, eg 'q' */
266  SKIP_CONTROLCHARS /* should now be at the copy of the memory pointer */
267  SKIP_IF_GT_SPACE /* should now be at end of memory pointer */
268  SKIP_CONTROLCHARS /* should now be at field offset */
269  SKIP_IF_GT_SPACE /* should now be at end of field offset */
270  SKIP_CONTROLCHARS /* should now be at the nds parameter */
271  SKIP_IF_GT_SPACE /* should now be at ehd of the nds parameter */
272  SKIP_CONTROLCHARS /* should now be at start of the type */
273 
274 
275  retval->datatype = mapEAItypeToFieldType(*ptr);
276  SKIP_IF_GT_SPACE
277  SKIP_CONTROLCHARS
278 
279  /* should be sitting at field type */
280  if (sscanf (ptr,"%d",&(retval->scripttype)) != 1) {
281  printf ("No Event %s found!\n", name);
282  free(retval);
283  return 0;
284  }
285 
286  SKIP_IF_GT_SPACE
287  SKIP_CONTROLCHARS
288 
289 /*
290  if (into) {
291  if (strncmp(ptr,"eventIn",strlen("eventIn")) != 0)
292  if (strncmp(ptr,"exposedField",strlen("exposedField")) != 0)
293  } else {
294  if (strncmp(ptr,"eventOut",strlen("eventOut")) != 0)
295  if (strncmp(ptr,"exposedField",strlen("exposedField")) != 0)
296  printf ("WARNING: expected for field %seventOut or exposedField, got %s\n",name,ptr);
297  }
298 */
299 
300 
301  retval->field = strdup(name);
302 
303  REMOVE_EOT
304  return retval;
305 }
306 
307 
308 X3DEventIn *X3D_getEventIn(X3DNode *node, char *name) {
309  X3DEventIn *retval;
310  retval = _X3D_getEvent(node, name,TRUE);
311  return retval;
312 }
313 
314 //#define SYSTEMROOTNODE "_Sarah_this_is_the_FreeWRL_System_Root_Node"
315 /* get the scene root node */
316 X3DNode* X3D_getExecutionContext()
317 {
318  return X3D_getNode (SYSTEMROOTNODE);
319 }
320 
321 void X3D_rootNodeHandling(X3DNode *scene, X3DNode *node, int action)
322 {
323  if(action == 1){
324  X3DEventIn *addChildren = X3D_getEventIn(scene,"addChildren");
325  X3D_setValue(addChildren, node);
326  }else if(action ==2){
327  X3DEventIn *removeChildren = X3D_getEventIn(scene,"removeChildren");
328  X3D_setValue(removeChildren, node);
329  }
330 }
331 
332 X3DEventOut *X3D_getEventOut(X3DNode *node, char *name) {
333  X3DEventOut *retval;
334  retval = _X3D_getEvent(node, name,FALSE);
335  return retval;
336 
337 }
338 
339 X3DFieldDef* X3D_getFieldDef(X3DNode *node, char *name){
340  X3DEventOut *retval;
341  retval = _X3D_getEvent(node, name,-1);
342  return retval;
343 }
344 
345 //gets the list of fields of the standard node
346 char* X3D_getFieldDefs(int nodeAdr)
347 {
348  char myline[200];
349  char *ptr;
350  char *res;
351  sprintf (myline,"%d",nodeAdr);
352 
353  // INCOMPLETE: we get a string containing the fields but we actually do nothing with it.
354  ptr = _X3D_make1StringCommand(GETFIELDDEFS,myline);
355 
356  res = strdup(ptr);
357 
358  return res;
359 }
360 
361 void X3D_addRoute (X3DEventOut *from, X3DEventIn *to) {
362  char myline[200];
363  char *ptr;
364  UNUSED(ptr); // for compiler warning mitigation
365 
366  sprintf (myline,"%d %s %d %s",from->nodeptr,from->field,to->nodeptr,to->field);
367  ptr = _X3D_make1StringCommand(ADDROUTE,myline);
368 }
369 
370 void X3D_deleteRoute (X3DEventOut *from, X3DEventIn *to) {
371  char myline[200];
372  char *ptr;
373  UNUSED(ptr); // for compiler warning mitigation
374 
375  sprintf (myline,"%d %s %d %s",from->nodeptr,from->field,to->nodeptr,to->field);
376  ptr = _X3D_make1StringCommand(DELETEROUTE,myline);
377 }
378 
379 X3DNode* X3D_getValue (X3DEventOut *src) {
380  char myline[4128];
381  char tstring[1024];
382  int num;
383  int retvals;
384  int adr;
385  char* ptr;
386  float a, b, c, d;
387  double db;
388  int i, j;
389  char ttok[4126];
390  int val;
391  float fval;
392  int mytmp;
393  char* temp;
394  int len;
395 
396  X3DNode* value;
397  value = malloc (sizeof(X3DNode));
398  bzero(value, sizeof(X3DNode));
399  value->type = src->datatype;
400  sprintf(myline, "%d %d %c %d", src->nodeptr, src->offset, mapFieldTypeToEAItype(src->datatype), src->datasize);
401  ptr = _X3D_make1StringCommand(GETVALUE, myline);
402 
403  switch (src->datatype) {
404  case FIELDTYPE_SFVec3f:
405  sscanf(ptr, "%f %f %f", &a, &b, &c);
406 
407  value->X3D_SFVec3f.c[0] = a;
408  value->X3D_SFVec3f.c[1] = b;
409  value->X3D_SFVec3f.c[2] = c;
410 
411  break;
412  case FIELDTYPE_SFColor:
413 
414  sscanf(ptr, "%f %f %f", &a, &b, &c);
415 
416  value->X3D_SFColor.c[0] = a;
417  value->X3D_SFColor.c[1] = b;
418  value->X3D_SFColor.c[2] = c;
419 
420  break;
421 
422  case FIELDTYPE_SFVec2f:
423 
424  sscanf(ptr, "%f %f", &a, &b);
425 
426  value->X3D_SFVec2f.c[0] = a;
427  value->X3D_SFVec2f.c[1] = b;
428 
429  break;
430 
431  case FIELDTYPE_SFRotation:
432 
433  sscanf(ptr, "%f %f %f %f", &a, &b, &c, &d);
434 
435  value->X3D_SFRotation.r[0] = a;
436  value->X3D_SFRotation.r[1] = b;
437  value->X3D_SFRotation.r[2] = c;
438  value->X3D_SFRotation.r[3] = d;
439 
440  break;
441 
442  case FIELDTYPE_SFColorRGBA:
443 
444  sscanf(ptr, "%f %f %f %f", &a, &b, &c, &d);
445 
446  value->X3D_SFColorRGBA.r[0] = a;
447  value->X3D_SFColorRGBA.r[1] = b;
448  value->X3D_SFColorRGBA.r[2] = c;
449  value->X3D_SFColorRGBA.r[3] = d;
450 
451  break;
452 
453  case FIELDTYPE_SFBool:
454 
455  sscanf(ptr, "%s", tstring);
456 
457  if (!strcmp(tstring, "TRUE"))
458  value->X3D_SFBool.value = 1;
459  else
460  value->X3D_SFBool.value = 0;
461 
462  break;
463 
464  case FIELDTYPE_SFFloat:
465 
466  sscanf(ptr, "%f", &a);
467 
468  value->X3D_SFFloat.value = a;
469 
470  break;
471 
472  case FIELDTYPE_SFTime:
473 
474  sscanf(ptr, "%lf", &db);
475 
476  value->X3D_SFTime.value = db;
477 
478  break;
479 
480  case FIELDTYPE_SFInt32:
481 
482  sscanf(ptr, "%d", &i);
483 
484  value->X3D_SFInt32.value = i;
485 
486  break;
487 
488  case FIELDTYPE_SFString:
489 
490  sscanf(ptr, "\"%s\"", tstring);
491  len = strlen(tstring);
492  len--;
493  tstring[len] = '\0';
494 
495  value->X3D_SFString.strptr = malloc ((strlen(tstring)+1) * sizeof(char));
496  strncpy(value->X3D_SFString.strptr,tstring, strlen(tstring) + 1);
497  value->X3D_SFString.len = strlen(tstring);
498 
499  break;
500 
501  case FIELDTYPE_MFString:
502 
503  bzero(ttok, sizeof(ttok));
504  /* changes from Doug Sanden */
505  temp = strtok(ptr, "\r\n"); /* we will parse manually within "a line" "because we " dont trust blanks */
506 
507  j = 0;
508  while (strncmp(temp, "RE_EOT", 6) && (temp != NULL)) {
509  /* changes from Doug Sanden */
510  /*pre process to get the "" strings*/
511  int start, istart;
512  int stop;
513  int i;
514  istart = 0;
515  do
516  {
517  start = 0;
518  stop = 0;
519  /* find the starting " */
520  for(i=istart;i<strlen(temp);i++)
521  {
522  if( temp[i] == '"' )
523  {
524  if( i > 0 )
525  {
526  if( temp[i-1] != '\\' ) start = i+1; /* the special \" case - ignor as literal */
527  } else {
528  start = i+1;
529  }
530  }
531  if( start ) break;
532  }
533  /* find the stopping " */
534  if(start)
535  {
536  for(i=start;i<strlen(temp);i++)
537  {
538  if( temp[i] == '"' )
539  if( temp[i-1] != '\\' ) stop = i-1;
540  if( stop ) break;
541  }
542  }
543  if( start && stop )
544  {
545  len = stop-start+1;
546  strncpy(tstring,&temp[start],len);
547  tstring[len] = '\0';
548  strcat(ttok, tstring);
549  strcat(ttok, "\r"); /*good delimeter needed for loop below - vrml doesn't allow \r within ""? or other like ~ */
550  j++;
551  istart = stop + 2;
552  }
553  }while(start && stop);
554  temp = strtok(NULL, "\r\n");
555  }
556 
557  value->X3D_MFString.n = j;
558  value->X3D_MFString.p = malloc(j*sizeof(X3DNode));
559 
560  /* changes from Doug Sanden */
561  temp = strtok(ttok, "\r");
562  if (temp != NULL) {
563  value->X3D_MFString.p[0].len = strlen(temp);
564  value->X3D_MFString.p[0].strptr = malloc(sizeof(char)*(STRLEN));
565  strncpy(value->X3D_MFString.p[0].strptr, temp, STRLEN);
566  /* changes from Doug Sanden */
567  value->X3D_MFString.p[0].type = FIELDTYPE_SFString;
568  }
569 
570  for (i = 1; i < j; i++) {
571  /* changes from Doug Sanden */
572  temp = strtok(NULL, "\r");
573  value->X3D_MFString.p[i].len = strlen(temp);
574  value->X3D_MFString.p[i].strptr = malloc(STRLEN);
575  strncpy(value->X3D_MFString.p[i].strptr, temp, STRLEN);
576 
577  /* changes from Doug Sanden */
578  value->X3D_MFString.p[i].type = FIELDTYPE_SFString;
579  }
580  break;
581 
582  case FIELDTYPE_MFInt32:
583 
584  temp = strtok(ptr, " \r\n");
585  num = atoi(temp);
586  value->X3D_MFInt32.n = num;
587  value->X3D_MFInt32.p = malloc(num * sizeof(X3DNode));
588 
589  for (i = 0; i < num; i++) {
590  temp = strtok(NULL, " \r\n");
591  val = atoi(temp);
592  value->X3D_MFInt32.p[i].value = val;
593  value->X3D_MFInt32.p[i].type= FIELDTYPE_SFInt32;
594  }
595 
596  break;
597 
598  case FIELDTYPE_MFBool:
599 
600  temp = strtok(ptr, " \r\n");
601  num = atoi(temp);
602  value->X3D_MFBool.n = num;
603  value->X3D_MFBool.p = malloc(num * sizeof(X3DNode));
604 
605  for (i = 0; i < num; i++) {
606  temp = strtok(NULL, " \r\n");
607  if (!strcmp(temp, "TRUE")) {
608  value->X3D_MFBool.p[i].value = 1;
609  } else {
610  value->X3D_MFBool.p[i].value = 0;
611  }
612  value->X3D_MFBool.p[i].type= FIELDTYPE_SFBool;
613  }
614 
615  break;
616 
617  case FIELDTYPE_MFFloat:
618 
619  temp = strtok(ptr, " \r\n");
620  num = atoi(temp);
621  value->X3D_MFFloat.n = num;
622  value->X3D_MFFloat.p = malloc(num * sizeof(X3DNode));
623 
624  for (i = 0; i < num; i++) {
625  temp = strtok(NULL, " \r\n");
626  fval = atof(temp);
627  value->X3D_MFFloat.p[i].value = fval;
628  value->X3D_MFFloat.p[i].type= FIELDTYPE_SFFloat;
629  }
630 
631  break;
632 
633  case FIELDTYPE_MFVec3f:
634  temp = strtok(ptr, " \r\n");
635  num = atoi(temp);
636 
637  value->X3D_MFVec3f.n = num;
638  value->X3D_MFVec3f.p = malloc(num * sizeof(X3DNode));
639 
640  for (i = 0; i < num; i++) {
641  for (j=0; j < 3; j++) {
642  temp = strtok(NULL, " \r\n");
643  fval = atof(temp);
644  value->X3D_MFVec3f.p[i].c[j] = fval;
645  }
646  value->X3D_MFVec3f.p[i].type = FIELDTYPE_SFVec3f;
647  }
648 
649  break;
650 
651  case FIELDTYPE_MFVec3d:
652  temp = strtok(ptr, " \r\n");
653  num = atoi(temp);
654 
655  value->X3D_MFVec3d.n = num;
656  value->X3D_MFVec3d.p = malloc(num * sizeof(X3DNode));
657 
658  for (i = 0; i < num; i++) {
659  for (j=0; j < 3; j++) {
660  temp = strtok(NULL, " \r\n");
661  fval = atof(temp);
662  value->X3D_MFVec3d.p[i].c[j] = (double) fval;
663  }
664  value->X3D_MFVec3d.p[i].type = FIELDTYPE_SFVec3d;
665  }
666 
667  break;
668 
669  case FIELDTYPE_MFColor:
670  temp = strtok(ptr, " \r\n");
671  num = atoi(temp);
672 
673  value->X3D_MFColor.n = num;
674  value->X3D_MFColor.p = malloc(num * sizeof(X3DNode));
675 
676  for (i = 0; i < num; i++) {
677  for (j=0; j < 3; j++) {
678  temp = strtok(NULL, " \r\n");
679  fval = atof(temp);
680  value->X3D_MFColor.p[i].c[j] = fval;
681  }
682  value->X3D_MFColor.p[i].type = FIELDTYPE_SFColor;
683  }
684 
685  break;
686 
687  case FIELDTYPE_MFVec2f:
688  temp = strtok(ptr, " \r\n");
689  num = atoi(temp);
690 
691  value->X3D_MFVec2f.n = num;
692  value->X3D_MFVec2f.p = malloc(num * sizeof(X3DNode));
693 
694  for (i = 0; i < num; i++) {
695  for (j=0; j < 2; j++) {
696  temp = strtok(NULL, " \r\n");
697  fval = atof(temp);
698  value->X3D_MFVec2f.p[i].c[j] = fval;
699  }
700  value->X3D_MFVec2f.p[i].type = FIELDTYPE_SFVec2f;
701  }
702 
703  break;
704 
705  case FIELDTYPE_MFRotation:
706  temp = strtok(ptr, " \r\n");
707  num = atoi(temp);
708 
709  value->X3D_MFRotation.n = num;
710  value->X3D_MFRotation.p = malloc(num * sizeof(X3DNode));
711 
712  for (i = 0; i < num; i++) {
713  for (j=0; j < 4; j++) {
714  temp = strtok(NULL, " \r\n");
715  fval = atof(temp);
716  value->X3D_MFRotation.p[i].r[j] = fval;
717  }
718  value->X3D_MFRotation.p[i].type = FIELDTYPE_SFRotation;
719  }
720 
721  break;
722 
723  case FIELDTYPE_MFColorRGBA:
724  temp = strtok(ptr, " \r\n");
725  num = atoi(temp);
726 
727  value->X3D_MFColorRGBA.n = num;
728  value->X3D_MFColorRGBA.p = malloc(num * sizeof(X3DNode));
729 
730  for (i = 0; i < num; i++) {
731  for (j=0; j < 4; j++) {
732  temp = strtok(NULL, " \r\n");
733  fval = atof(temp);
734  value->X3D_MFColorRGBA.p[i].r[j] = fval;
735  }
736  value->X3D_MFColorRGBA.p[i].type = FIELDTYPE_SFColorRGBA;
737  }
738 
739  break;
740 
741  case FIELDTYPE_SFNode:
742 
743 
744  sscanf(ptr, "%d", &adr);
745 
746  value->X3D_SFNode.adr= adr;
747 
748  break;
749 
750  case FIELDTYPE_MFNode:
751 
752  retvals = _X3D_countWords(ptr);
753  // decrement, as we will likely have the RE_EOT on the end
754  retvals--;
755  value->X3D_MFNode.p = malloc (retvals/2 * sizeof (X3DNode));
756  value->X3D_MFNode.n = retvals;
757 
758  for (i= 0; i< (retvals); i++) {
759 
760  /* skip to the memory pointer */
761  SKIP_CONTROLCHARS
762 
763  /* read in the memory pointer */
764  sscanf (ptr,"%d",&mytmp); /* changed for 1.18.15 JAS */
765  value->X3D_MFNode.p[i].adr = mytmp;
766 
767  /* skip past this number now */
768  SKIP_IF_GT_SPACE
769  }
770 
771 
772  break;
773 
774  default:
775  printf("XXX - getValue, not implemented yet for type '%s'\n", FIELDTYPES[src->datatype]);
776  return 0;
777  }
778 
779  return value;
780 }
781 
782 
783 void X3D_setValue (X3DEventIn *dest, X3DNode *node) {
784  char myline[2048];
785  int count;
786  int i;
787  char tstring[2048];
788 
789  //JAS printf ("X3D_setValue sanity: event type %s, value type %s (%d, %d)\n",
790  //JAS FIELDTYPES[(int)dest->datatype], FIELDTYPES[node->X3D_SFNode.type],
791  //JAS dest->datatype,node->X3D_SFNode.type);
792 
793 
794  /* sanity check */
795  if (dest->datatype != node->X3D_SFNode.type) {
796  printf ("X3D_setValue mismatch: event type %s, value type %s (%d, %d)\n",
797  FIELDTYPES[(int)dest->datatype], FIELDTYPES[node->X3D_SFNode.type],
798  dest->datatype,node->X3D_SFNode.type);
799  return;
800  }
801 
802 
803  switch (dest->datatype) {
804  default:
805  printf ("XXX - setValue, not implemented yet for type '%s'\n",FIELDTYPES[dest->datatype]);
806  return;
807 
808  case FIELDTYPE_SFVec3d:
809  sprintf (myline, "%c %d %d %d %f %f %f\n",
810  mapFieldTypeToEAItype(dest->datatype),
811  dest->nodeptr, dest->offset, dest->scripttype,
812  node->X3D_SFVec3d.c[0],
813  node->X3D_SFVec3d.c[1],
814  node->X3D_SFVec3d.c[2]);
815  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
816  break;
817 
818 
819  case FIELDTYPE_SFVec3f:
820  case FIELDTYPE_SFColor:
821  sprintf (myline, "%c %d %d %d %f %f %f\n",
822  mapFieldTypeToEAItype(dest->datatype),
823  dest->nodeptr, dest->offset, dest->scripttype,
824  node->X3D_SFVec3f.c[0],
825  node->X3D_SFVec3f.c[1],
826  node->X3D_SFVec3f.c[2]);
827  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
828  break;
829 
830  case FIELDTYPE_SFVec2f:
831  sprintf (myline, "%c %d %d %d %f %f\n",
832  mapFieldTypeToEAItype(dest->datatype),
833  dest->nodeptr, dest->offset, dest->scripttype,
834  node->X3D_SFVec2f.c[0],
835  node->X3D_SFVec2f.c[1]);
836  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
837  break;
838 
839  case FIELDTYPE_SFRotation:
840  case FIELDTYPE_SFColorRGBA:
841  sprintf (myline, "%c %d %d %d %f %f %f %f\n",
842  mapFieldTypeToEAItype(dest->datatype),
843  dest->nodeptr, dest->offset, dest->scripttype,
844  node->X3D_SFRotation.r[0],
845  node->X3D_SFRotation.r[1],
846  node->X3D_SFRotation.r[2],
847  node->X3D_SFRotation.r[3]);
848  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
849  break;
850 
851  case FIELDTYPE_SFBool:
852  if (node->X3D_SFBool.value) {
853  sprintf (myline, "%c %d %d %d TRUE\n",
854  mapFieldTypeToEAItype(dest->datatype),
855  dest->nodeptr, dest->offset, dest->scripttype);
856  } else {
857  sprintf (myline, "%c %d %d %d FALSE\n",
858  mapFieldTypeToEAItype(dest->datatype),
859  dest->nodeptr, dest->offset, dest->scripttype);
860  }
861  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
862  break;
863  case FIELDTYPE_SFInt32:
864  sprintf (myline, "%c %d %d %d %d\n",
865  mapFieldTypeToEAItype(dest->datatype),
866  dest->nodeptr, dest->offset, dest->scripttype,
867  node->X3D_SFBool.value);
868  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
869  break;
870 
871  case FIELDTYPE_SFFloat:
872  sprintf (myline, "%c %d %d %d %f\n",
873  mapFieldTypeToEAItype(dest->datatype),
874  dest->nodeptr, dest->offset, dest->scripttype,
875  node->X3D_SFFloat.value);
876  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
877  break;
878 
879  case FIELDTYPE_SFTime:
880  sprintf (myline, "%c %d %d %d %lf\n",
881  mapFieldTypeToEAItype(dest->datatype),
882  dest->nodeptr, dest->offset, dest->scripttype,
883  node->X3D_SFTime.value);
884  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
885  break;
886 
887  case FIELDTYPE_SFString:
888  sprintf (myline, "%c %d %d %d %d:%s\n",
889  mapFieldTypeToEAItype(dest->datatype),
890  dest->nodeptr, dest->offset, dest->scripttype,
891  node->X3D_SFString.len, node->X3D_SFString.strptr);
892  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
893  break;
894 
895  case FIELDTYPE_MFInt32:
896  sprintf(myline, "%c %d %d %d [",
897  mapFieldTypeToEAItype(dest->datatype),
898  dest->nodeptr, dest->offset, dest->scripttype
899  );
900 
901  for (i = 0; i < node->X3D_MFInt32.n; i++) {
902  sprintf(tstring, "%d", node->X3D_MFInt32.p[i].value);
903  strcat(myline, tstring);
904  strcat(myline, ", ");
905  }
906  strcat(myline, "]");
907  _X3D_sendEvent (SENDEVENT, myline,__LINE__);
908 
909  break;
910 
911  case FIELDTYPE_MFBool:
912  sprintf(myline, "%c %d %d %d [",
913  mapFieldTypeToEAItype(dest->datatype),
914  dest->nodeptr, dest->offset, dest->scripttype
915  );
916 
917  for (i = 0; i < node->X3D_MFBool.n; i++) {
918  if (node->X3D_MFBool.p[i].value) {
919  strcat(myline, "TRUE");
920  } else {
921  strcat(myline, "FALSE");
922  }
923  strcat(myline, ", ");
924  }
925  strcat(myline, "]");
926  _X3D_sendEvent (SENDEVENT, myline,__LINE__);
927 
928  break;
929 
930  case FIELDTYPE_MFFloat:
931  sprintf(myline, "%c %d %d %d [",
932  mapFieldTypeToEAItype(dest->datatype),
933  dest->nodeptr, dest->offset, dest->scripttype
934  );
935 
936  for (i = 0; i < node->X3D_MFFloat.n; i++) {
937  sprintf(tstring, "%f", node->X3D_MFFloat.p[i].value);
938  strcat(myline, tstring);
939  strcat(myline, ", ");
940  }
941  strcat(myline, "]");
942  _X3D_sendEvent (SENDEVENT, myline,__LINE__);
943 
944  break;
945 
946  case FIELDTYPE_MFVec3f:
947  sprintf(myline, "%c %d %d %d [",
948  mapFieldTypeToEAItype(dest->datatype),
949  dest->nodeptr, dest->offset, dest->scripttype
950  );
951 
952  for (i = 0; i < node->X3D_MFVec3f.n; i++) {
953  sprintf(tstring, "%f %f %f, ", node->X3D_MFVec3f.p[i].c[0], node->X3D_MFVec3f.p[i].c[1], node->X3D_MFVec3f.p[i].c[2]);
954  strcat(myline, tstring);
955  }
956  strcat(myline, "]");
957  _X3D_sendEvent(SENDEVENT, myline,__LINE__);
958 
959  break;
960 
961  case FIELDTYPE_MFVec3d:
962  sprintf(myline, "%c %d %d %d [",
963  mapFieldTypeToEAItype(dest->datatype),
964  dest->nodeptr, dest->offset, dest->scripttype
965  );
966 
967  for (i = 0; i < node->X3D_MFVec3d.n; i++) {
968  sprintf(tstring, "%lf %lf %lf, ", node->X3D_MFVec3d.p[i].c[0], node->X3D_MFVec3d.p[i].c[1], node->X3D_MFVec3d.p[i].c[2]);
969  strcat(myline, tstring);
970  }
971  strcat(myline, "]");
972  _X3D_sendEvent(SENDEVENT, myline,__LINE__);
973 
974  break;
975 
976  case FIELDTYPE_MFColor:
977  sprintf(myline, "%c %d %d %d [",
978  mapFieldTypeToEAItype(dest->datatype),
979  dest->nodeptr, dest->offset, dest->scripttype
980  );
981 
982  for (i = 0; i < node->X3D_MFColor.n; i++) {
983  sprintf(tstring, "%f %f %f, ", node->X3D_MFColor.p[i].c[0], node->X3D_MFColor.p[i].c[1], node->X3D_MFColor.p[i].c[2]);
984  strcat(myline, tstring);
985  }
986  strcat(myline, "]");
987  _X3D_sendEvent(SENDEVENT, myline,__LINE__);
988 
989  break;
990 
991  case FIELDTYPE_MFVec2f:
992  sprintf(myline, "%c %d %d %d [",
993  mapFieldTypeToEAItype(dest->datatype),
994  dest->nodeptr, dest->offset, dest->scripttype
995  );
996 
997  for (i = 0; i < node->X3D_MFVec2f.n; i++) {
998  sprintf(tstring, "%f %f, ", node->X3D_MFVec2f.p[i].c[0], node->X3D_MFVec2f.p[i].c[1]);
999  strcat(myline, tstring);
1000  }
1001  strcat(myline, "]");
1002  _X3D_sendEvent(SENDEVENT, myline,__LINE__);
1003 
1004  break;
1005 
1006  case FIELDTYPE_MFRotation:
1007  sprintf(myline, "%c %d %d %d [",
1008  mapFieldTypeToEAItype(dest->datatype),
1009  dest->nodeptr, dest->offset, dest->scripttype
1010  );
1011 
1012  for (i = 0; i < node->X3D_MFRotation.n; i++) {
1013  sprintf(tstring, "%f %f %f %f, ", node->X3D_MFRotation.p[i].r[0], node->X3D_MFRotation.p[i].r[1], node->X3D_MFRotation.p[i].r[2], node->X3D_MFRotation.p[i].r[3]);
1014  strcat(myline, tstring);
1015  }
1016  strcat(myline, "]");
1017  _X3D_sendEvent(SENDEVENT, myline,__LINE__);
1018 
1019  break;
1020 
1021  case FIELDTYPE_MFColorRGBA:
1022  sprintf(myline, "%c %d %d %d [",
1023  mapFieldTypeToEAItype(dest->datatype),
1024  dest->nodeptr, dest->offset, dest->scripttype
1025  );
1026 
1027  for (i = 0; i < node->X3D_MFColorRGBA.n; i++) {
1028  sprintf(tstring, "%f %f %f %f, ", node->X3D_MFColorRGBA.p[i].r[0], node->X3D_MFColorRGBA.p[i].r[1], node->X3D_MFColorRGBA.p[i].r[2], node->X3D_MFColorRGBA.p[i].r[3]);
1029  strcat(myline, tstring);
1030  }
1031  strcat(myline, "]");
1032  _X3D_sendEvent(SENDEVENT, myline,__LINE__);
1033 
1034  break;
1035 
1036  case FIELDTYPE_MFString:
1037  sprintf(myline, "%c %d %d %d [ ",
1038  mapFieldTypeToEAItype(dest->datatype),
1039  dest->nodeptr, dest->offset, dest->scripttype
1040  );
1041 
1042  for (i = 0; i < node->X3D_MFString.n; i++) {
1043  strcat(myline, "\"");
1044  strcat(myline, node->X3D_MFString.p[i].strptr);
1045  strcat(myline, "\" ");
1046  }
1047  strcat(myline, "]");
1048 /*
1049  int len = strlen(myline);
1050  len--;
1051  myline[len] = '\0';
1052 */
1053  _X3D_sendEvent(SENDEVENT, myline,__LINE__);
1054 
1055  break;
1056 
1057  case FIELDTYPE_MFNode:
1058  #ifdef VERBOSE
1059  printf ("sending in %d nodes\n",node->X3D_MFNode.n);
1060  #endif
1061 
1062  for (count = 0; count < node->X3D_MFNode.n; count ++) {
1063  sprintf (myline,"%d %d %s %d\n",
1064  dest->nodeptr,
1065  dest->offset,
1066  dest->field,
1067  node->X3D_MFNode.p[count].adr);
1068 
1069  _X3D_sendEvent (SENDCHILD,myline,__LINE__);
1070  }
1071 
1072  break;
1073 
1074  case FIELDTYPE_SFNode:
1075  sprintf (myline, "%c %d %d %d %d\n",
1076  mapFieldTypeToEAItype(dest->datatype),
1077  dest->nodeptr, dest->offset, dest->scripttype,
1078  node->X3D_SFNode.adr);
1079 
1080  _X3D_sendEvent (SENDEVENT,myline,__LINE__);
1081 
1082  }
1083 
1084 }
1085 
1086 
1087 /*****************************************************************************/
1088 
1089 #ifdef WIN32
1090 void X3D_lastViewpoint(){}
1091 void X3D_firstViewpoint(){}
1092 void X3D_previousViewpoint(){}
1093 void X3D_nextViewpoint(){}
1094 
1095 
1096 #endif
1097 char *descrip = NULL;
1098 
1099 void X3D_setDescription(char *newDesc) {
1100  /* description is held locally. */
1101  if (descrip != NULL)
1102  free (descrip);
1103  descrip = strdup(newDesc);
1104 }
1105 
1106 char *X3D_getDescription() {
1107 
1108  /* description is held locally. */
1109  if (descrip == NULL) {
1110  descrip = strdup("in X3D");
1111  }
1112  return descrip;
1113 }
1114 
1115 char *X3D_getName() {
1116  char *ptr;
1117  ptr = strdup(_X3D_makeShortCommand(GETNAME));
1118  REMOVE_EOT
1119  return ptr;
1120 }
1121 char *X3D_getVersion() {
1122  char *ptr;
1123  ptr = strdup(_X3D_makeShortCommand(GETVERSION));
1124  REMOVE_EOT
1125  return ptr;
1126 }
1127 char *X3D_getWorldURL() {
1128  char *ptr;
1129  ptr = strdup(_X3D_makeShortCommand(GETURL));
1130  REMOVE_EOT
1131  return ptr;
1132 }
1133 
1134 
1135 
1136 float X3D_getCurrentSpeed() {
1137  char *ptr;
1138  float curspeed;
1139  ptr = _X3D_makeShortCommand(GETCURSPEED);
1140  if (sscanf(ptr,"%f",&curspeed) == 0) {
1141  printf ("client, error - problem reading float from %s\n",ptr);
1142  exit(0);
1143  }
1144  return curspeed;
1145 }
1146 
1147 
1148 float X3D_getCurrentFrameRate() {
1149  char *ptr;
1150  float curframe;
1151  ptr = _X3D_makeShortCommand(GETFRAMERATE);
1152  if (sscanf(ptr,"%f",&curframe) == 0) {
1153  printf ("client, error - problem reading float from %s\n",ptr);
1154  exit(0);
1155  }
1156  return curframe;
1157 }
1158 
1159 X3DNode *X3D_createVrmlFromString(char *str) {
1160  X3DNode *retval;
1161  char *ptr;
1162  int retvals;
1163  int count;
1164  int mytmp;
1165 
1166  retval = malloc (sizeof(X3DNode));
1167  retval->X3D_MFNode.type = FIELDTYPE_MFNode;
1168  retval->X3D_MFNode.n = 0;
1169 
1170  #ifdef VERBOSE
1171  printf ("X3D_createVrmlFromString - string %s\n",str);
1172  #endif
1173 
1174  ptr = _X3D_make2StringCommand(CREATEVS,str,"\nEOT\n");
1175 
1176  #ifdef VERBOSE
1177  printf ("return pointer is %s\n",ptr);
1178  #endif
1179 
1180  /* now, how many numbers did it return? */
1181  retvals = _X3D_countWords(ptr);
1182  // decrement, as we will likely have the RE_EOT on the end
1183  retvals--;
1184  retval->X3D_MFNode.p = malloc (retvals * sizeof (X3DNode));
1185  retval->X3D_MFNode.n = retvals;
1186 
1187  for (count = 0; count < retvals; count++) {
1188  /* skip to the memory pointer */
1189  SKIP_CONTROLCHARS
1190 
1191  /* read in the memory pointer */
1192  sscanf (ptr,"%d",&mytmp); /* changed for 1.18.15 JAS */
1193 
1194  retval->X3D_MFNode.p[count].adr = mytmp;
1195 
1196  /* skip past this number now */
1197  SKIP_IF_GT_SPACE
1198  }
1199  #ifdef VERBOSE
1200  printf ("X3D_createVrmlFromString, found %d pointers, they are:\n",retval->X3D_MFNode.n);
1201  for (count=0; count<retval->X3D_MFNode.n; count++) {
1202  printf (" %d\n",(int) retval->X3D_MFNode.p[count].adr);
1203  }
1204  printf ("(end oflist)\n");
1205  #endif
1206  return retval;
1207 }
1208 X3DNode *X3D_createX3DFromString(char *str) {
1209  X3DNode *retval;
1210  char *ptr;
1211  int retvals;
1212  int count;
1213  int mytmp;
1214 
1215  retval = malloc (sizeof(X3DNode));
1216  retval->X3D_MFNode.type = FIELDTYPE_MFNode;
1217  retval->X3D_MFNode.n = 0;
1218 
1219  #ifdef VERBOSE
1220  printf ("X3D_createX3DFromString - string %s\n",str);
1221  #endif
1222 
1223  ptr = _X3D_make2StringCommand(CREATEXS,str,"\nEOT\n");
1224 
1225  #ifdef VERBOSE
1226  printf ("return pointer is %s\n",ptr);
1227  #endif
1228 
1229 
1230  /* now, how many numbers did it return? */
1231  retvals = _X3D_countWords(ptr);
1232  // decrement, as we will likely have the RE_EOT on the end
1233  retvals--;
1234  retval->X3D_MFNode.p = malloc (retvals * sizeof (X3DNode));
1235  retval->X3D_MFNode.n = retvals;
1236  //JAS printf ("X3D_createX3DFromString has %d return nodes\n",retvals);
1237 
1238 
1239  for (count = 0; count < retvals; count++) {
1240  /* skip to the memory pointer */
1241  SKIP_CONTROLCHARS
1242 
1243  /* read in the memory pointer */
1244  sscanf (ptr,"%d",&mytmp); /* changed for 1.18.15 JAS */
1245 
1246  retval->X3D_MFNode.p[count].adr = mytmp;
1247 
1248  /* skip past this number now */
1249  SKIP_IF_GT_SPACE
1250  }
1251  #ifdef VERBOSE
1252  printf ("X3D_createVrmlFromString, found %d pointers, they are:\n",retval->X3D_MFNode.n);
1253  for (count=0; count<retval->X3D_MFNode.n; count++) {
1254  printf (" %d\n",(int) retval->X3D_MFNode.p[count].adr);
1255  }
1256  printf ("(end oflist)\n");
1257  #endif
1258  return retval;
1259 }
1260