FreeWRL/FreeX3D  3.0.0
jsVRMLClasses_duk.c
1 /*
2 
3  A substantial amount of code has been adapted from js/src/js.c,
4  which is the sample application included with the javascript engine.
5 
6 */
7 
8 /****************************************************************************
9  This file is part of the FreeWRL/FreeX3D Distribution.
10 
11  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12 
13  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14  it under the terms of the GNU Lesser Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25 ****************************************************************************/
26 /* To do list July 2014
27 SFNode - functions not implemented
28 X3DMatrix3,4 - code implemented but never tested
29 
30 */
31 
32 #include <config.h>
33 #include <system.h>
34 #if defined(JAVASCRIPT_DUK)
35 #include <system_threads.h>
36 #include <display.h>
37 #include <internal.h>
38 
39 #include <libFreeWRL.h>
40 #include <list.h>
41 
42 #include <io_files.h>
43 
44 #include "../vrml_parser/Structs.h"
45 #include "../main/headers.h"
46 #include "../vrml_parser/CParseGeneral.h"
47 #include "../main/Snapshot.h"
48 #include "../scenegraph/LinearAlgebra.h"
49 #include "../scenegraph/Collision.h"
50 #include "../scenegraph/quaternion.h"
51 #include "../scenegraph/Viewer.h"
52 #include "../input/SensInterps.h"
53 #include "../x3d_parser/Bindable.h"
54 #include "../input/InputFunctions.h"
55 
56 #include "JScript.h"
57 #include "CScripts.h"
58 #include "FWTYPE.h"
59 
60 #define LARGESTRING 2048
61 #define STRING 512
62 #define SMALLSTRING 128
63 
64 #ifdef DEBUG_MALLOC
65 #define malloc(A) MALLOCV(A)
66 #define free(A) FREE_IF_NZ(A)
67 #define realloc(A,B) REALLOC(A,B)
68 #endif
69 
70 /********************************************************/
71 /* */
72 /* Second part - SF classes */
73 /* */
74 /********************************************************/
75 
76 /*
77 Notes for the virtual proxy approach used here:
78 The field types represented by primitives in ecmascript have no constructor,
79  gc=0 on their pointer, and valueOf converts to ecma primitives:
80  SFBool boolean
81  SFInt32 numeric
82  SFFloat numeric
83  SFTime numeric
84  SFDouble numeric
85  SFString string
86 For Script node fields they show up as all other field types as properties on the js context global object.
87 But unlike other field types, there's no new SFBool(). Getters and setters convert to/from ecma primitives
88 and set the valueChanged flag when set. Similarly other fieldtype functions and getter/setters convert to/from
89 ecma primitive instead of one of the above, and never generate a new one of these.
90 */
91 
92 int type2SF(int itype);
93 
94 
95 int SFFloat_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
96 {
97  float *ptr = (float *)fwn;
98  fwretval->_numeric = (double)*(ptr);
99  fwretval->itype = 'F';
100  return 1;
101 }
102 int SFFloat_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
103 {
104  char str[512];
105  float *ptr = (float *)fwn;
106  sprintf(str,"%g",(*ptr));
107  fwretval->_string = strdup(str);
108  fwretval->itype = 'S';
109  return 1;
110 }
111 FWFunctionSpec (SFFloat_Functions)[] = {
112  {"valueOf", SFFloat_valueOf, 'F',{0,0,0,NULL}},
113  {"toString", SFFloat_toString, 'S',{0,0,0,NULL}},
114  {0}
115 };
116 
117 
118 //#define FIELDTYPE_SFFloat 0
119 FWTYPE SFFloatType = {
120  FIELDTYPE_SFFloat,
121  'F',
122  "SFFloat",
123  sizeof(float), //sizeof(struct ),
124  NULL, //constructor
125  NULL, //constructor args
126  NULL, //Properties,
127  NULL, //special iterator
128  NULL, //Getter,
129  NULL, //Setter,
130  0,0, //index prop type,readonly
131  SFFloat_Functions, //functions
132 };
133 
134 
135 //MFW for MF types that take web3d (non-ecma-primitive) types ie new MFColor( new SFColor(0,0,0), new SFColor(.1,.2,.3), ...)
136 ArgListType (MFW_ConstructorArgs)[] = {
137  {0,0,0,"W"},
138  {-1,0,0,NULL},
139 };
140 int sizeofSF(int itype); //thunks MF to SF (usually itype-1) and gets sizeof SF
141 void * MFW_Constructor(FWType fwtype, int argc, FWval fwpars){
142  int i, lenSF;
143  char *p;
144  struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
145  lenSF = sizeofSF(fwtype->itype);
146  ptr->n = argc;
147  ptr->p = NULL;
148  if(ptr->n)
149  ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
150  p = ptr->p;
151  for(i=0;i<ptr->n;i++){
152  memcpy(p,fwpars[i]._web3dval.native,lenSF);
153  p += lenSF;
154  }
155  return (void *)ptr;
156 }
157 FWPropertySpec (MFW_Properties)[] = {
158  {"length", -1, 'I', 0},
159  {NULL,0,0,0},
160 };
161 unsigned long upper_power_of_two(unsigned long v);
162 int MFW_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
163  struct Multi_Any *ptr = (struct Multi_Any *)fwn;
164  int nr = 0;
165  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
166  if(index == -1){
167  //length
168  fwretval->_integer = ptr->n;
169  fwretval->itype = 'I';
170  //fwretval->_web3dval.native = &ptr->n;
171  //fwretval->_web3dval.fieldType = FIELDTYPE_SFInt32;
172  //fwretval->itype = 'W';
173  nr = 1;
174  }else if(index > -1 ){
175  int sftype;
176  char *p = (char *)ptr->p;
177  int elen = sizeofSF(fwt->itype);
178  sftype = type2SF(fwt->itype);
179  if(index >= ptr->n){
180  //sept 2015 for white_dune CurveAnimationPROTO.wrl script which writes to empty MF[i].x = x;
181  //we are assigning to an index that hasn't been individually malloced yet
182  //ie MF[i].subfield = value
183  //ideally the javascript programer would first do MF[i] = new SFxxx() before assigning to a subfield.
184  //here we'll cut them some slack by reallocing and mallocing missing elements.
185  //but I think MF[i] = SF will come in to MFW_Setter, not here in MFW_Getter.
186  int newlen;
187  newlen = upper_power_of_two(index+1);
188  ptr->p = realloc(p,newlen * elen);
189  p = ptr->p;
190  memset(&p[ptr->n * elen],0,elen * (index+1 - ptr->n)); //clear just the new section
191  ptr->n = index+1;
192  p = (char *)ptr->p;
193  }
194  if(sftype == FIELDTYPE_SFNode){
195  //Method A return pointer to SF from MF[i] (almost^)
196  //attempt to make SFnode = MFnode[i] so that SF survives gc of MF
197  //^consumers of SFNode will still use 2-step ** -> node*
198  // .. due to plumbing being written with method C in mind
199  // .. (could be pruned out in all SFNode sources and sinks in _duk modules)
200  //can do this costlessly -MF[i] = SF comes in to MFW_Setter that still uses &MF[i]-
201  // but just for SFnode/MFnode
202  void *sfptr = malloc(sizeof(void*));
203  memcpy(sfptr,(void *)(p + index*elen),sizeof(void*)); //*sfptr = MF.p[i] = &SF
204  fwretval->_web3dval.native = (void *)sfptr; //native = &sfptr
205  fwretval->_web3dval.gc = 1;
206  }else{
207  int deepCopyLikeVivaty = FALSE; // FALSE; //TRUE;
208  if(deepCopyLikeVivaty){
209  //Method B - deepcopy SF = MF[i]
210  //cost: can't do this now:
211  //SF = MF[i]; //deep copy SF
212  //SF.x = -1.0;
213  //print(MF[i].toString());
214  //-the -1 won't show up in the MF[i] due to deep copy
215  //* but SF will survive garbage collection of MF
216  void *sfptr = malloc(elen);
217  //memcpy(sfptr,(void *)(p + index*elen),elen); //*sfptr = SF.copy()
218  shallow_copy_field(sftype,(void *)(p + index*elen),sfptr); //*sfptr = SF.copy()
219  fwretval->_web3dval.native = (void *)sfptr; //native = &sfptr
220  fwretval->_web3dval.gc = 1;
221  }else{
222  //Method C - return pointer to MF[i]
223  //SF = MF[i]
224  //takes a pointer to MF[i] so can change SF ie SF.x = -1; and it shows in MF[i]
225  //cost: x but then SF won't survive garbage collection of MF
226  //you need to use vivaty deep copy above, or in js do new SFxx(MF[i]) to deep copy
227  fwretval->_web3dval.native = (void *)(p + index*elen); //native = &MF.p[i]
228  fwretval->_web3dval.gc = 0;
229  }
230  }
231  fwretval->_web3dval.fieldType = type2SF(fwt->itype);
232  fwretval->itype = 'W';
233  nr = 1;
234  }
235 
236  return nr;
237 }
238 int mf2sf(int itype);
239 FWTYPE *getFWTYPE(int itype);
240 char *sfToString(FWType fwt, void *fwn){
241  //caller must free / gc the return string
242  int i;
243  union anyVrml *any = (union anyVrml*)fwn;
244  char strbuf[100];
245  char *str = NULL;
246  switch(fwt->itype){
247  case FIELDTYPE_SFBool:
248  if(any->sfbool) str = strdup("true");
249  else str = strdup("false");
250  break;
251  case FIELDTYPE_SFInt32:
252  sprintf(strbuf,"%d",any->sfint32);
253  str = strdup(strbuf);
254  break;
255  case FIELDTYPE_SFFloat:
256  sprintf(strbuf,"%g",any->sffloat);
257  str = strdup(strbuf);
258  break;
259  case FIELDTYPE_SFDouble:
260  case FIELDTYPE_SFTime:
261  sprintf(strbuf,"%g",any->sfdouble);
262  str = strdup(strbuf);
263  break;
264  case FIELDTYPE_SFString:{
265  str = malloc(strlen(any->sfstring->strptr)+3);
266  strcpy(str,"\"");
267  str = strcat(str,any->sfstring->strptr);
268  str = strcat(str,"\"");
269  }
270  break;
271  default:
272  {
273  //delegate to SF type toString function
274  i = 0;
275  while(fwt->Functions[i].name){
276  if(!strcmp(fwt->Functions[i].name,"toString")){
277  FWval fwpars = NULL;
278  FWVAL fwretval;
279  //typedef int (* FWFunction)(FWType fwtype, void* ec, void * fwn, int argc, FWval fwpars, FWval fwretval);
280  fwt->Functions[i].call(fwt,NULL,fwn,1,fwpars,&fwretval);
281  str = fwretval._string;
282  break;
283  }
284  i++;
285  }
286  break;
287  }
288  }
289  return str;
290 }
291 int type2SF(int itype);
292 char *mfToString(FWType fwt, void * fwn){
293  //caller must free / gc the return string
294  int i, sftype, len, showType, elen;
295  char *p, *str;
296  FWTYPE *fwtsf;
297 
298  struct Multi_Any *ptr = (struct Multi_Any *)fwn;
299  showType = 1; //=1 to see MFColor[], =0 to see []
300  len = strlen("[ ");
301  if(showType) len += strlen(fwt->name);
302  str = malloc(len +1);
303  str[0] = 0;
304  if(showType) strcat(str,fwt->name);
305  str = strcat(str,"[ ");
306  //sftype = mf2sf(fwt->itype);
307  sftype = type2SF(fwt->itype);
308  fwtsf = getFWTYPE(sftype);
309  p = (char *)ptr->p;
310  elen = sizeofSF(fwt->itype);
311  for(i=0;i<ptr->n;i++)
312  {
313  char * sf = sfToString(fwtsf,p);
314  str = realloc(str,strlen(str)+strlen(sf)+2);
315  str = strcat(str,sf);
316  str = strcat(str," ");
317  free(sf);
318  p = p + elen;
319  }
320  str[strlen(str)-1] = ']';
321  return str;
322 }
323 
324 int MFW_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
325  char *str;
326  str = mfToString(fwtype,fwn);
327  fwretval->_string = str;
328  fwretval->itype = 'S';
329  return 1;
330 }
331 
332 FWFunctionSpec (MFW_Functions)[] = {
333  {"toString", MFW_toString, 'S',{0,-1,0,NULL}},
334  {0}
335 };
336 
337 
338 int MFW_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
339  struct Multi_Any *ptr = (struct Multi_Any *)fwn;
340  int nold, nr = FALSE;
341  int elen = sizeofSF(fwt->itype);
342  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
343  if(index == -1){
344  //length
345  nold = ptr->n;
346  ptr->n = fwval->_integer;
347  if(ptr->n > nold){
348  int nelen;
349  nelen = (int) upper_power_of_two(ptr->n);
350  ptr->p = realloc(ptr->p,nelen * elen);
351  }
352  nr = TRUE;
353  }else if(index > -1){
354  char *p;
355  if(index >= ptr->n){
356  int nelen;
357  //nold = ptr->n;
358  ptr->n = index+1;
359  nelen = (int) upper_power_of_two(ptr->n);
360  ptr->p = realloc(ptr->p, nelen *elen); //need power of 2 if SFNode children ptr->n
361  }
362  p = ptr->p + index * elen;
363  if(fwval->itype == 'W')
364  memcpy(p,fwval->_web3dval.native, elen);
365  else{
366  float ff;
367  switch(fwval->itype){
368  case 'B':
369  memcpy(p,&fwval->_boolean,elen); break;
370  case 'I':
371  memcpy(p,&fwval->_integer,elen); break;
372  case 'F':
373  ff = (float)fwval->_numeric;
374  memcpy(p,&ff,elen); break;
375  case 'D':
376  memcpy(p,&fwval->_numeric,elen); break;
377  case 'S':{
378  struct Uni_String *uni = newASCIIString(fwval->_string);
379  memcpy(p,&uni,elen); break;
380  }
381  }
382  }
383  nr = TRUE;
384  }
385  return nr;
386 }
387 
388 void * MFFloat_Constructor(FWType fwtype, int argc, FWval fwpars){
389  int i, lenSF;
390  char *p;
391  struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
392  lenSF = sizeofSF(fwtype->itype);
393  ptr->n = argc;
394  ptr->p = NULL;
395  if(ptr->n)
396  ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
397  p = ptr->p;
398  for(i=0;i<ptr->n;i++){
399  if(fwpars[i].itype == 'W' && fwpars[i]._web3dval.fieldType == FIELDTYPE_SFFloat)
400  memcpy(p,&fwpars[i]._web3dval.native,lenSF);
401  else if(fwpars[i].itype == 'F'){
402  float ff = (float)fwpars[i]._numeric;
403  memcpy(p,&ff,lenSF);
404  }
405 
406  p += lenSF;
407  }
408  return (void *)ptr;
409 }
410 ArgListType (MFFloat_ConstructorArgs)[] = {
411  {0,0,0,"F"},
412  {-1,0,0,NULL},
413 };
414 
415 FWTYPE MFFloatType = {
416  FIELDTYPE_MFFloat,
417  'W',
418  "MFFloat",
419  sizeof(struct Multi_Any), //sizeof(struct ),
420  MFFloat_Constructor, //constructor
421  MFFloat_ConstructorArgs, //constructor args
422  MFW_Properties, //Properties,
423  NULL, //special iterator
424  MFW_Getter, //Getter,
425  MFW_Setter, //Setter,
426  'F',0, //index prop type,readonly
427  MFW_Functions, //functions
428 };
429 
430 
431 // http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#SFRotation
432 // http://www.web3d.org/documents/specifications/14772/V2.0/part1/javascript.html#SFRotation
433 /* SFRotation
434 constructors
435 SFRotation (numeric x, numeric y, numeric z, numeric angle) x, y, and z are the axis of the rotation. angle is the angle of the rotation (in radians). Missing values default to 0.0, except y, which defaults to 1.0.
436 SFRotation (SFVec3f axis, numeric angle) axis is the axis of rotation. angle is the angle of the rotation (in radians)
437 SFRotation (SFVec3f fromVector, SFVec3f toVector) fromVector and toVector are normalized and the rotation value that would rotate from the fromVector to the toVector is stored in the object.
438 props
439 numeric x No first value of the axis vector
440 numeric y No second value of the axis vector
441 numeric z No third value of the axis vector
442 numeric angle No the angle of the rotation (in radians)
443 funcs
444 SFVec3f getAxis() Returns the axis of rotation.
445 SFRotation inverse() Returns the inverse of this object's rotation.
446 SFRotation multiply(SFRotation rot) Returns the object multiplied by the passed value.
447 SFVec3f multiVec(SFVec3f vec) Returns the value of vec multiplied by the matrix corresponding to this object's rotation.
448 void setAxis(SFVec3f vec) Sets the axis of rotation to the value passed in vec.
449 SFRotation slerp(SFRotation dest, numeric t) Returns the value of the spherical linear interpolation between this object's rotation and dest at value 0 = t = 1. For t = 0, the value is this object`s rotation. For t = 1, the value is dest.
450 String toString() Returns a String containing the value of x, y, z, and angle encoding using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
451 */
452 int SFRotation_getAxis(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
453  struct SFRotation *ptr = (struct SFRotation *)fwn;
454  struct SFVec3f *res = malloc(sizeof(struct SFVec3f));
455  veccopy3f(res->c,ptr->c);
456  fwretval->_web3dval.native = res;
457  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
458  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
459  fwretval->itype = 'W';
460  return 1;
461 }
462 
463 int SFRotation_inverse(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
464  struct SFRotation *ptr = (struct SFRotation *)fwn;
465  struct SFRotation *res = malloc(sizeof(struct SFRotation));
466  Quaternion q1,qret;
467  double a,b,c,d;
468 
469  /* convert both rotation to quaternion */
470  vrmlrot_to_quaternion(&q1, (double) ptr->c[0],
471  (double) ptr->c[1], (double) ptr->c[2], (double) ptr->c[3]);
472 
473  /* invert it */
474  quaternion_inverse(&qret,&q1);
475 
476  /* and return the resultant, as a vrml rotation */
477  quaternion_to_vrmlrot(&qret, &a, &b, &c, &d);
478  /* double to floats, can not use pointers... */
479  res->c[0] = (float) a;
480  res->c[1] = (float) b;
481  res->c[2] = (float) c;
482  res->c[3] = (float) d;
483 
484  fwretval->_web3dval.native = res;
485  fwretval->_web3dval.fieldType = FIELDTYPE_SFRotation;
486  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
487  fwretval->itype = 'W';
488  return 1;
489 }
490 
491 int SFRotation_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
492  struct SFRotation *ptr = (struct SFRotation *)fwn;
493  struct SFRotation *rhs = (struct SFRotation *)fwpars[0]._web3dval.native;
494  struct SFRotation *res = malloc(sizeof(struct SFRotation));
495  Quaternion q1,q2,qret;
496  double a,b,c,d;
497 
498  /* convert both rotation to quaternion */
499  vrmlrot_to_quaternion(&q1, (double) ptr->c[0],
500  (double) ptr->c[1], (double) ptr->c[2], (double) ptr->c[3]);
501 
502  vrmlrot_to_quaternion(&q2, (double) rhs->c[0],
503  (double) rhs->c[1], (double) rhs->c[2], (double) rhs->c[3]);
504 
505  /* multiply them */
506  quaternion_multiply(&qret,&q1,&q2);
507 
508  /* and return the resultant, as a vrml rotation */
509  quaternion_to_vrmlrot(&qret, &a, &b, &c, &d);
510  /* double to floats, can not use pointers... */
511  res->c[0] = (float) a;
512  res->c[1] = (float) b;
513  res->c[2] = (float) c;
514  res->c[3] = (float) d;
515 
516  fwretval->_web3dval.native = res;
517  fwretval->_web3dval.fieldType = FIELDTYPE_SFRotation;
518  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
519  fwretval->itype = 'W';
520  return 1;
521 }
522 
523 int SFRotation_multiVec(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
524  struct SFRotation *ptr = (struct SFRotation *)fwn;
525  struct SFVec3f *v = (struct SFVec3f *)fwpars[0]._web3dval.native;
526  struct SFVec3f *res = malloc(sizeof(struct SFVec3f));
527  struct SFVec3f c1, c2, r;
528  double rl,angle,s,c;
529  int i;
530 
531  veccopy3f(r.c,ptr->c);
532  rl = veclength3f(r.c);
533  angle = ptr->c[3];
534  s = (float) sin(angle);
535  c = (float) cos(angle);
536  veccross3f(c1.c,r.c,v->c);
537  vecscale3f(c1.c,c1.c,1.0f/rl);
538  veccross3f(c2.c,r.c,c1.c);
539  vecscale3f(c2.c,c2.c,1.0f/rl);
540  for(i=0;i<3;i++)
541  res->c[i] = (float) (v->c[i] + s * c1.c[i] + (1.0-c) * c2.c[i]);
542 
543  fwretval->_web3dval.native = res;
544  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
545  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
546  fwretval->itype = 'W';
547  return 1;
548 }
549 
550 int SFRotation_setAxis(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
551  struct SFRotation *ptr = (struct SFRotation *)fwn;
552  struct SFVec3f *v = (struct SFVec3f *)fwpars[0]._web3dval.native;
553  veccopy3f(ptr->c,v->c);
554  return 0;
555 }
556 
557 int SFRotation_slerp(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
558  struct SFRotation *rot = (struct SFRotation *)fwn;
559  struct SFRotation *dest = (struct SFRotation *)fwpars[0]._web3dval.native;
560  double t = fwpars[1]._numeric;
561  struct SFRotation *res = malloc(sizeof(struct SFRotation));
562  Quaternion quat,quat_dest,quat_ret;
563  double a,b,c,d;
564 
565  /*
566  * From Annex C, C.6.7.4:
567  *
568  * For t = 0, return object's rotation.
569  * For t = 1, return 1st argument.
570  * For 0 < t < 1, compute slerp.
571  */
572  if (APPROX(t, 0)) {
573  memcpy(res->c,rot->c,4*sizeof(float));
574  } else if (APPROX(t, 1)) {
575  memcpy(res->c,dest->c,4*sizeof(float));
576  } else {
577 
578  vrmlrot_to_quaternion(&quat,
579  rot->c[0],
580  rot->c[1],
581  rot->c[2],
582  rot->c[3]);
583 
584  vrmlrot_to_quaternion(&quat_dest,
585  dest->c[0],
586  dest->c[1],
587  dest->c[2],
588  dest->c[3]);
589 
590  quaternion_slerp(&quat_ret, &quat, &quat_dest, t);
591  quaternion_to_vrmlrot(&quat_ret,&a,&b,&c,&d);
592  /* double to floats, can not use pointers... */
593  res->c[0] = (float) a;
594  res->c[1] = (float) b;
595  res->c[2] = (float) c;
596  res->c[3] = (float) d;
597  }
598  fwretval->_web3dval.native = res;
599  fwretval->_web3dval.fieldType = FIELDTYPE_SFRotation;
600  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
601  fwretval->itype = 'W';
602  return 1;
603 }
604 
605 int SFRotation_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
606  struct SFRotation *ptr = (struct SFRotation *)fwn;
607  char buff[STRING], *str;
608  int len;
609  memset(buff, 0, STRING);
610  sprintf(buff, "%.9g %.9g %.9g %.9g",
611  ptr->c[0], ptr->c[1], ptr->c[2], ptr->c[3]);
612  len = strlen(buff);
613  str = malloc(len+1); //leak
614  strcpy(str,buff);
615  fwretval->_string = str;
616  fwretval->itype = 'S';
617  return 1;
618 }
619 
620 
621 FWFunctionSpec (SFRotation_Functions)[] = {
622  {"getAxis", SFRotation_getAxis, 'W',{0,-1,0,NULL}},
623  {"inverse", SFRotation_inverse, 'W',{0,-1,0,"W"}},
624  {"multiply", SFRotation_multiply, 'W',{1,-1,0,"W"}},
625  {"multVec", SFRotation_multiVec, 'W',{1,-1,0,"W"}}, //freewrl spelling
626  {"multiVec", SFRotation_multiVec, 'W',{1,-1,0,"W"}}, //web3d.org spelling
627  {"setAxis", SFRotation_setAxis, '0',{1,-1,0,"W"}},
628  {"slerp", SFRotation_slerp, 'W',{2,-1,0,"WF"}},
629  {"toString", SFRotation_toString, 'S',{0,-1,0,NULL}},
630  {0}
631 };
632 int SFRotation_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
633  struct SFRotation *ptr = (struct SFRotation *)fwn;
634  int nr = 0;
635  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
636  if(index > -1 && index < 4){
637  nr = 1;
638  switch(index){
639  case 0: //x
640  case 1: //y
641  case 2: //z
642  case 3: //angle
643  fwretval->_numeric = ptr->c[index];
644  break;
645  default:
646  nr = 0;
647  }
648  }
649  fwretval->itype = 'F';
650  return nr;
651 }
652 int SFRotation_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
653  struct SFRotation *ptr = (struct SFRotation *)fwn;
654  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
655  if(index > -1 && index < 4){
656  switch(index){
657  case 0: //x
658  case 1: //y
659  case 2: //z
660  case 3: //angle
661  ptr->c[index] = (float)fwval->_numeric;
662  break;
663  }
664  return TRUE;
665  }
666  return FALSE;
667 }
668 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
669 void * SFRotation_Constructor(FWType fwtype, int ic, FWval fwpars){
670  int i;
671  struct SFRotation *ptr = malloc(fwtype->size_of); //garbage collector please
672  if(ic == 4){
673  for(i=0;i<4;i++)
674  ptr->c[i] = (float)fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
675  }else if(ic == 2 && fwpars[1].itype == 'F'){
676  //SFVec3f axis, float angle
677  veccopy3f(ptr->c,fwpars[0]._web3dval.native);
678  ptr->c[3] = (float)fwpars[1]._numeric;
679 
680  }else if(ic == 2 && fwpars[1].itype == 'W'){
681  //SFVec3f from SFVec3f to
682  struct SFVec3f *v1 = fwpars[0]._web3dval.native;
683  struct SFVec3f *v2 = fwpars[1]._web3dval.native;
684  float v1len = veclength3f(v1->c);
685  float v2len = veclength3f(v2->c);
686  float v12dp = vecdot3f(v1->c, v2->c);
687  veccross3f(ptr->c,v1->c,v2->c);
688  v12dp /= v1len * v2len;
689  ptr->c[3] = (float) atan2(sqrt(1 - v12dp * v12dp), v12dp);
690  }else if(ic == 1 && fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
691  //new SFxxx(myMF[i]);
692  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
693  }
694 
695  return (void *)ptr;
696 }
697 FWPropertySpec (SFRotation_Properties)[] = {
698  {"x", 0, 'F', 0},
699  {"y", 1, 'F', 0},
700  {"z", 2, 'F', 0},
701  {"angle", 3, 'F', 0},
702  {NULL,0,0,0},
703 };
704 ArgListType (SFRotation_ConstructorArgs)[] = {
705  {4,0,'T',"FFFF"},
706  {2,0,'T',"WF"},
707  {2,-1,'F',"WW"},
708  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
709  {-1,0,0,NULL},
710 };
711 //#define FIELDTYPE_SFRotation 2
712 FWTYPE SFRotationType = {
713  FIELDTYPE_SFRotation,
714  'W',
715  "SFRotation",
716  sizeof(struct SFRotation), //sizeof(struct ),
717  SFRotation_Constructor, //constructor
718  SFRotation_ConstructorArgs, //constructor args
719  SFRotation_Properties, //Properties,
720  NULL, //special iterator
721  SFRotation_Getter, //Getter,
722  SFRotation_Setter, //Setter,
723  'F',0, //index prop type,readonly
724  SFRotation_Functions, //functions
725 };
726 
727 
728 
729 //#define FIELDTYPE_MFRotation 3
730 FWTYPE MFRotationType = {
731  FIELDTYPE_MFRotation,
732  'W',
733  "MFRotation",
734  sizeof(struct Multi_Any), //sizeof(struct ),
735  MFW_Constructor, //constructor
736  MFW_ConstructorArgs, //constructor args
737  MFW_Properties, //Properties,
738  NULL, //special iterator
739  MFW_Getter, //Getter,
740  MFW_Setter, //Setter,
741  'W',0, //index prop type,readonly
742  MFW_Functions, //functions
743 };
744 
745 
746 
747 /*
748 SFVec3f add(SFVec3f vec) Returns the value of the passed value added, component-wise, to the object.
749 SFVec3f cross(SFVec3f vec) Returns the cross product of the object and the passed value.
750 SFVec3f divide(numeric n) Returns the value of the object divided by the passed value.
751 numeric dot(SFVec3f vec) Returns the dot product of this vector and the passed value as a double precision value.
752 numeric length() Returns the geometric length of this vector as a double precision value.
753 SFVec3f multiple(numeric n) Returns the value of the object multiplied by the passed value.
754 SFVec3f negate() Returns the value of the component-wise negation of the object.
755 SFVec3f normalize() Returns the object converted to unit length .
756 SFVec3f subtract(SFVec3f vec) Returns the value of the passed value subtracted, component-wise, from the object.
757 String toString() Returns a String containing the value of x, y, and z encoded using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
758 */
759 #include "../scenegraph/LinearAlgebra.h"
760 //SFVec3f add(SFVec3f vec) Returns the value of the passed value added, component-wise, to the object.
761 int SFVec3f_add(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
762  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
763  struct SFVec3f *rhs = fwpars[0]._web3dval.native;
764  struct SFVec3f *res = malloc(fwtype->size_of);
765  vecadd3f(res->c,ptr->c,rhs->c);
766  fwretval->_web3dval.native = res;
767  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
768  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
769  fwretval->itype = 'W';
770  return 1;
771 }
772 int SFVec3f_cross(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
773  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
774  struct SFVec3f *rhs = fwpars[0]._web3dval.native;
775  struct SFVec3f *res = malloc(fwtype->size_of);
776  veccross3f(res->c,ptr->c,rhs->c);
777  fwretval->_web3dval.native = res;
778  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
779  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
780  fwretval->itype = 'W';
781  return 1;
782 }
783 int SFVec3f_subtract(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
784  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
785  struct SFVec3f *rhs = fwpars[0]._web3dval.native;
786  struct SFVec3f *res = malloc(fwtype->size_of);
787  vecdif3f(res->c,ptr->c,rhs->c);
788  fwretval->_web3dval.native = res;
789  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
790  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
791  fwretval->itype = 'W';
792  return 1;
793 }
794 int SFVec3f_divide(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
795  struct SFVec3f *res;
796  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
797  float rhs = (float)fwpars[0]._numeric;
798  if(rhs == 0.0f){
799  return 0;
800  }
801  rhs = 1.0f/rhs;
802  res = malloc(fwtype->size_of);
803  vecscale3f(res->c,ptr->c,rhs);
804  fwretval->_web3dval.native = res;
805  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
806  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
807  fwretval->itype = 'W';
808  return 1;
809 }
810 int SFVec3f_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
811  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
812  float rhs = (float) fwpars[0]._numeric;
813  struct SFVec3f *res = malloc(fwtype->size_of);
814  vecscale3f(res->c,ptr->c,rhs);
815  fwretval->_web3dval.native = res;
816  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
817  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
818  fwretval->itype = 'W';
819  return 1;
820 }
821 int SFVec3f_normalize(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
822  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
823  struct SFVec3f *res = malloc(fwtype->size_of);
824  vecnormalize3f(res->c,ptr->c);
825  fwretval->_web3dval.native = res;
826  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
827  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
828  fwretval->itype = 'W';
829  return 1;
830 }
831 
832 int SFVec3f_negate(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
833  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
834  struct SFVec3f *res = malloc(fwtype->size_of);
835  vecscale3f(res->c,ptr->c,-1.0f);
836  fwretval->_web3dval.native = res;
837  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
838  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
839  fwretval->itype = 'W';
840  return 1;
841 }
842 int SFVec3f_length(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
843  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
844  float res;
845  res = veclength3f(ptr->c);
846  fwretval->_numeric = res;
847  fwretval->itype = 'F';
848  return 1;
849 }
850 int SFVec3f_dot(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
851  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
852  struct SFVec3f *rhs = fwpars[0]._web3dval.native;
853  double res;
854  res = vecdot3f(ptr->c,rhs->c);
855  fwretval->_numeric = res;
856  fwretval->itype = 'F';
857  return 1;
858 }
859 
860 int SFVec3f_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
861  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
862  char buff[STRING], *str;
863  int len;
864  memset(buff, 0, STRING);
865  sprintf(buff, "%.9g %.9g %.9g",
866  ptr->c[0], ptr->c[1], ptr->c[2]);
867  len = strlen(buff);
868  str = malloc(len+1); //leak
869  strcpy(str,buff);
870  fwretval->_string = str;
871  fwretval->itype = 'S';
872  return 1;
873 }
874 
875 FWFunctionSpec (SFVec3f_Functions)[] = {
876  {"add", SFVec3f_add, 'W',{1,-1,0,"W"}},
877  {"cross", SFVec3f_cross, 'W',{1,-1,0,"W"}},
878  {"divide", SFVec3f_divide, 'W',{1,-1,0,"F"}},
879  {"dot", SFVec3f_dot, 'F',{1,-1,0,"W"}},
880  {"length", SFVec3f_length, 'F',{0,-1,0,NULL}},
881  {"multiply", SFVec3f_multiply, 'W',{1,-1,0,"F"}},
882  {"negate", SFVec3f_negate, 'W',{0,-1,0,NULL}},
883  {"normalize", SFVec3f_normalize, 'W',{0,-1,0,NULL}},
884  {"subtract", SFVec3f_subtract, 'W',{1,-1,0,"W"}},
885  {"toString", SFVec3f_toString, 'S',{0,-1,0,NULL}},
886  {0}
887 };
888 
889 int SFVec3f_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
890  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
891  int nr = 0;
892  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
893  if(index > -1 && index < 3){
894  nr = 1;
895  switch(index){
896  case 0: //x
897  case 1: //y
898  case 2: //z
899  fwretval->_numeric = ptr->c[index];
900  break;
901  default:
902  nr = 0;
903  }
904  }
905  fwretval->itype = 'F';
906  return nr;
907 }
908 int SFVec3f_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
909  struct SFVec3f *ptr = (struct SFVec3f *)fwn;
910  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
911  if(index > -1 && index < 3){
912  switch(index){
913  case 0: //x
914  case 1: //y
915  case 2: //z
916  ptr->c[index] = (float)fwval->_numeric;
917  break;
918  }
919  return TRUE;
920  }
921  return FALSE;
922 }
923 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
924 void * SFVec3f_Constructor(FWType fwtype, int ic, FWval fwpars){
925  int i;
926  struct SFVec3f *ptr = malloc(fwtype->size_of); //garbage collector please
927  if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
928  //new SFxxx(myMF[i]);
929  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
930  }else{
931  //new SFVec3f(1.0,2.0,3.0);
932  for(i=0;i<3;i++)
933  ptr->c[i] = (float) fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
934  }
935  return (void *)ptr;
936 }
937 
938 FWPropertySpec (SFVec3f_Properties)[] = {
939  {"x", 0, 'F', 0},
940  {"y", 1, 'F', 0},
941  {"z", 2, 'F', 0},
942  {NULL,0,0,0},
943 };
944 ArgListType (SFVec3f_ConstructorArgs)[] = {
945  {3,0,'T',"FFF"}, //new SFVec3f(1.0,2.0,3.0)
946  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
947  {-1,0,0,NULL},
948 };
949 
950 
951 //#define FIELDTYPE_SFVec3f 4
952 FWTYPE SFVec3fType = {
953  FIELDTYPE_SFVec3f,
954  'W',
955  "SFVec3f",
956  sizeof(struct SFVec3f), //sizeof(struct ),
957  SFVec3f_Constructor, //constructor
958  SFVec3f_ConstructorArgs, //constructor args
959  SFVec3f_Properties, //Properties,
960  NULL, //special iterator
961  SFVec3f_Getter, //Getter,
962  SFVec3f_Setter, //Setter,
963  'F',0, //index prop type,readonly
964  SFVec3f_Functions, //functions
965 };
966 
967 //#define FIELDTYPE_MFVec3f 5
968 FWTYPE MFVec3fType = {
969  FIELDTYPE_MFVec3f,
970  'W',
971  "MFVec3f",
972  sizeof(struct Multi_Any), //sizeof(struct ),
973  MFW_Constructor, //constructor
974  MFW_ConstructorArgs, //constructor args
975  MFW_Properties, //Properties,
976  NULL, //special iterator
977  MFW_Getter, //Getter,
978  MFW_Setter, //Setter,
979  'W',0, //index prop type,readonly
980  MFW_Functions, //functions
981 };
982 
983 int SFBool_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
984 {
985  int *ptr = (int *)fwn;
986  fwretval->_boolean = *(ptr);
987  fwretval->itype = 'B';
988  return 1;
989 }
990 int SFBool_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
991 {
992  char *str;
993  int *ptr = (int *)fwn;
994  if(*ptr)
995  str = "true";
996  else
997  str = "false";
998  fwretval->_string = strdup(str);
999  fwretval->itype = 'S';
1000  return 1;
1001 }
1002 
1003 FWFunctionSpec (SFBool_Functions)[] = {
1004  {"valueOf", SFBool_valueOf, 'B',{0,0,0,NULL}},
1005  {"toString", SFBool_toString, 'S',{0,0,0,NULL}},
1006  {0}
1007 };
1008 
1009 //#define FIELDTYPE_SFBool 6
1010 FWTYPE SFBoolType = {
1011  FIELDTYPE_SFBool,
1012  'B',
1013  "SFBool",
1014  sizeof(int), //sizeof(struct ),
1015  NULL, //constructor
1016  NULL, //constructor args
1017  NULL, //Properties,
1018  NULL, //special iterator
1019  NULL, //Getter,
1020  NULL, //Setter,
1021  0,0, //index prop type,readonly
1022  SFBool_Functions, //functions
1023 };
1024 
1025 
1026 void * MFBool_Constructor(FWType fwtype, int argc, FWval fwpars){
1027  int i, lenSF;
1028  char *p;
1029  struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
1030  lenSF = sizeofSF(fwtype->itype);
1031  ptr->n = argc;
1032  ptr->p = NULL;
1033  if(ptr->n)
1034  ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
1035  p = ptr->p;
1036  for(i=0;i<ptr->n;i++){
1037  //float ff = (float)fwpars[i]._numeric; //fwpars[i]._web3dval.native;
1038  if(fwpars[i].itype == 'W')
1039  memcpy(p,&fwpars[i]._web3dval.native,lenSF);
1040  else if(fwpars[i].itype == 'B'){
1041  memcpy(p,&fwpars[i]._boolean,lenSF);
1042  }
1043  p += lenSF;
1044  }
1045  return (void *)ptr;
1046 }
1047 ArgListType (MFBool_ConstructorArgs)[] = {
1048  {0,0,0,"B"},
1049  {-1,0,0,NULL},
1050 };
1051 
1052 
1053 //#define FIELDTYPE_MFBool 7
1054 FWTYPE MFBoolType = {
1055  FIELDTYPE_MFBool,
1056  'W',
1057  "MFBool",
1058  sizeof(struct Multi_Any), //sizeof(struct ),
1059  MFBool_Constructor, //constructor
1060  MFBool_ConstructorArgs, //constructor args
1061  MFW_Properties, //Properties,
1062  NULL, //special iterator
1063  MFW_Getter, //Getter,
1064  MFW_Setter, //Setter,
1065  'B',0, //index prop type,readonly
1066  MFW_Functions, //functions
1067 };
1068 
1069 int SFInt32_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1070 {
1071  int *ptr = (int *)fwn;
1072  fwretval->_integer = *(ptr);
1073  fwretval->itype = 'I';
1074  return 1;
1075 }
1076 int SFInt32_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1077 {
1078  char str[16];
1079  int *ptr = (int *)fwn;
1080  sprintf(str,"%d",(*ptr));
1081  fwretval->_string = strdup(str);
1082  fwretval->itype = 'S';
1083  return 1;
1084 }
1085 FWFunctionSpec (SFInt32_Functions)[] = {
1086  {"valueOf", SFInt32_valueOf, 'I',{0,0,0,NULL}},
1087  {"toString", SFInt32_toString, 'S',{0,0,0,NULL}},
1088  {0}
1089 };
1090 //#define FIELDTYPE_SFInt32 8
1091 FWTYPE SFInt32Type = {
1092  FIELDTYPE_SFInt32,
1093  'I',
1094  "SFInt32",
1095  sizeof(int), //sizeof(struct ),
1096  NULL, //constructor
1097  NULL, //constructor args
1098  NULL, //Properties,
1099  NULL, //special iterator
1100  NULL, //Getter,
1101  NULL, //Setter,
1102  0,0, //index prop type,readonly
1103  SFInt32_Functions, //functions
1104 };
1105 
1106 
1107 void * MFInt32_Constructor(FWType fwtype, int argc, FWval fwpars){
1108  int i, lenSF;
1109  char *p;
1110  struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
1111  lenSF = sizeofSF(fwtype->itype);
1112  ptr->n = argc;
1113  ptr->p = NULL;
1114  if(ptr->n)
1115  ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
1116  p = ptr->p;
1117  for(i=0;i<ptr->n;i++){
1118  if(fwpars[i].itype == 'W')
1119  memcpy(p,&fwpars[i]._web3dval.native,lenSF);
1120  else if(fwpars[i].itype == 'I')
1121  memcpy(p,&fwpars[i]._integer,lenSF);
1122  p += lenSF;
1123  }
1124  return (void *)ptr;
1125 }
1126 ArgListType (MFInt32_ConstructorArgs)[] = {
1127  {0,0,0,"I"},
1128  {-1,0,0,NULL},
1129 };
1130 
1131 
1132 //#define FIELDTYPE_MFInt32 9
1133 FWTYPE MFInt32Type = {
1134  FIELDTYPE_MFInt32,
1135  'W',
1136  "MFInt32",
1137  sizeof(struct Multi_Any), //sizeof(struct ),
1138  MFInt32_Constructor, //constructor
1139  MFInt32_ConstructorArgs, //constructor args
1140  MFW_Properties, //Properties,
1141  NULL, //special iterator
1142  MFW_Getter, //Getter,
1143  MFW_Setter, //Setter,
1144  'I',0, //index prop type,readonly
1145  MFW_Functions, //functions
1146 };
1147 
1148 int getFieldFromNodeAndIndex(struct X3D_Node* node, int iifield, const char **fieldname, int *type, int *kind, union anyVrml **value);
1149 int SFNode_Iterator(int index, FWTYPE *fwt, FWPointer *pointer, char **name, int *lastProp, int *jndex, char *type, char *readOnly){
1150  struct X3D_Node *node = ((union anyVrml*)pointer)->sfnode;
1151  int ftype, kind, ihave, iifield;
1152  char ctype;
1153  union anyVrml *value;
1154 
1155  if(!node) return -1;
1156  index ++;
1157  (*jndex) = 0;
1158  iifield = index;
1159  ihave = getFieldFromNodeAndIndex(node, index, name, &ftype, &kind, &value);
1160  switch(ftype){
1161  case FIELDTYPE_SFBool: ctype = 'B'; break;
1162  case FIELDTYPE_SFInt32: ctype = 'I'; break;
1163  case FIELDTYPE_SFFloat: ctype = 'F'; break;
1164  case FIELDTYPE_SFDouble: ctype = 'D'; break;
1165  case FIELDTYPE_SFTime: ctype = 'D'; break;
1166  case FIELDTYPE_SFString: ctype = 'S'; break;
1167  default: ctype = 'W'; break;
1168  }
1169  if(ihave){
1170  (*jndex) = index;
1171  (*lastProp) = index;
1172  (*type) = ctype;
1173  (*readOnly) = 0;
1174  return index;
1175  }
1176  return -1;
1177 }
1178 int SFNode_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1179  struct X3D_Node *node = ((union anyVrml*)fwn)->sfnode;
1180  int ftype, kind, ihave, nr;
1181  const char *name;
1182  union anyVrml *value;
1183  nr = 0;
1184  ihave = getFieldFromNodeAndIndex(node, index, &name, &ftype, &kind, &value);
1185  if(ihave){
1186  fwretval->_web3dval.native = value;
1187  fwretval->_web3dval.fieldType = ftype;
1188  fwretval->_web3dval.kind = kind;
1189  fwretval->_web3dval.gc = 0;
1190  fwretval->itype = 'W';
1191  nr = 1;
1192  }
1193  return nr;
1194 }
1195 void medium_copy_field0(int itype, void* source, void* dest);
1196 void *returnInterpolatorPointer (int nodeType);
1197 int SFNode_Setter0(FWType fwt, int index, void *ec, void *fwn, FWval fwval, int isCurrentScriptNode){
1198  // shared between fwSetterNS() and SFNode_Setter
1199  //
1200  struct X3D_Node *node = ((union anyVrml*)fwn)->sfnode;
1201  int ftype, kind, ihave, nr; // , interp;
1202  const char *name;
1203  union anyVrml *value;
1204  nr = FALSE;
1205  ihave = getFieldFromNodeAndIndex(node, index, &name, &ftype, &kind, &value);
1206  if(ihave){
1207  //copy W type or primative type, depending on ftype
1208  switch(fwval->itype){
1209  case 'B':
1210  value->sfbool = fwval->_boolean;
1211  break;
1212  case 'I':
1213  value->sfint32 = fwval->_integer;
1214  break;
1215 
1216  case 'F':
1217  value->sffloat = (float)fwval->_numeric;
1218  break;
1219 
1220  case 'D':
1221  value->sftime = fwval->_numeric;
1222  break;
1223 
1224  case 'S':
1225  value->sfstring = newASCIIString(fwval->_string);
1226  break;
1227 
1228  default:
1229  if(!strcmp(name,"children")){
1230  //int n;
1231  struct Multi_Node* any = (struct Multi_Node*)fwval->_web3dval.native;
1232  AddRemoveChildren(node,(void*)value,(void*)any->p,any->n,0,__FILE__,__LINE__);
1233  }else{
1234  medium_copy_field0(ftype,fwval->_web3dval.native,value);
1235  }
1236  }
1237 
1238  if(node->_nodeType == NODE_Script) {
1239  //notify for event processing
1240  struct Shader_Script *script = X3D_SCRIPT(node)->__scriptObj;
1241  struct ScriptFieldDecl *field;
1242  field = Shader_Script_getScriptField(script,index);
1243  if(kind == PKW_inputOutput || kind == PKW_outputOnly)
1244  field->valueChanged = TRUE;
1245  if(!isCurrentScriptNode) {
1246  if(kind == PKW_inputOnly || kind == PKW_inputOutput) {
1247  //if using fwsetter0, we could be writing to ourselves, sending ourselves an eventIn when we really just want an eventOut
1248  //so we should be doing && (gglobal.currentScript != node) and set gglobal.currentScript = thisScriptNode in fwsetter0 (and back to null after call)
1249  field->eventInSet = TRUE; //see runQueuedDirectOutputs()
1250  }
1251  }
1252  }else{
1253  //if directoutput == true
1254  void (* interpolatorPointer)(void*);
1255  interpolatorPointer = returnInterpolatorPointer(node->_nodeType);
1256 
1257  if(interpolatorPointer){
1258  //we have something like an orientation interpolator - run it to convert fraction_set to value_changed
1259  interpolatorPointer(node);
1260  }
1261  }
1262  nr = TRUE;
1263  update_node(node);
1264  }
1265  return nr;
1266 
1267 }
1268 int SFNode_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1269  return SFNode_Setter0(fwt,index,ec,fwn,fwval,FALSE);
1270 }
1271 void * SFNode_Constructor(FWType fwtype, int nargs, FWval fwpars){
1272  struct X3D_Node **ptr = NULL; // = malloc(fwtype->size_of); //garbage collector please
1273  if(nargs == 1){
1274  if(fwpars[0].itype == 'S'){
1275  //SFNode.wrl createFromAString = new SFNode('Cylinder {height 1}');
1276  struct X3D_Group *retGroup;
1277  //char *xstr;
1278  //char *tmpstr;
1279  //char *separator;
1280  int ra;
1281  //int count;
1282  //int wantedsize;
1283  //int MallocdSize;
1284  ttglobal tg = gglobal();
1285  struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
1286  const char *_c = fwpars[0]._string; // fwpars[0]._web3dval.anyvrml->sfstring->strptr;
1287 
1288  /* do the call to make the VRML code - create a new browser just for this string */
1289  gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
1290  retGroup = createNewX3DNode(NODE_Group);
1291  ra = EAI_CreateVrml("String",_c,X3D_NODE(retGroup),retGroup);
1292  globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
1293  //if(retGroup->children.n < 1) return 0;
1294  ptr = malloc(sizeof(void *));
1295  *ptr = retGroup->children.p[0];
1296  (*ptr)->_parentVector->n = 0;
1297  }else if(fwpars->itype == 'W'){
1298  if(fwpars->_web3dval.fieldType == FIELDTYPE_SFNode){
1299  //see MFW_getter > Method A
1300  //this is similar - can do new SFNode(MF[i]) but don't really need this extra step for Method A
1301  //might make more sense to instance a new node of this type? And shallow copy its fields?
1302  ptr = malloc(sizeof(void *));
1303  *ptr = ((union anyVrml*)fwpars[0]._web3dval.native)->sfnode;
1304 
1305  }
1306  }
1307  }
1308  return ptr;
1309 }
1310 ArgListType (SFNode_ConstructorArgs)[] = {
1311  {1,-1,0,"S"},
1312  {1,-1,0,"W"},
1313  {-1,0,0,NULL},
1314 };
1315 /*
1316 String getNodeName() Returns the node name
1317 Array getNodeType() Returns, in the array, a list of constant values that indicate node typess as provided in the X3DConstants object.
1318 FieldDefinitionArray getFieldDefinitions() Returns a list of fields defined for the SFNode object.
1319 String toVRMLString() Returns the X3D Classic VRML-encoded string that, if parsed as the value of an SFNode field, would produce this node. If the browser is unable to reproduce this node, the name of the node followed by the open brace and close brace shall be returned. Additional information may be included as one or more Classic VRML comment strings.
1320 String toXMLString() Returns the X3D XML-encoded string that, if parsed as the value of an SFNode field, would produce this node. If the browser is unable to reproduce this node, a simple XML Element definition shall be returned. Additional information may be included as one or more XML comments.
1321 - july 2014 not yet implemented
1322 */
1323 
1324 
1325 int SFNode_getNodeName(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1326  //int found;
1327  char *name = NULL;
1328  int nr = 0;
1329  struct X3D_Node* node = ((union anyVrml*)fwn)->sfnode;
1330  if(node){
1331  //broto warning - DEF name list should be per-executionContext
1332  struct X3D_Proto *context;
1333  context = (struct X3D_Proto *)node->_executionContext;
1334  if(context){
1335  //broto_search_DEFname(ec, fwpars[0]._string);
1336  int i;
1337  struct brotoDefpair def;
1338  if(context->__DEFnames)
1339  for(i=0;i<vectorSize(context->__DEFnames);i++){
1340  def = vector_get(struct brotoDefpair, context->__DEFnames,i);
1341  if(def.node == node){
1342  name = def.name;
1343  break;
1344  }
1345  }
1346  }
1347  if(1){ //if(name){
1348  fwretval->_string = name; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1349  fwretval->itype = 'S';
1350  nr = 1;
1351  }
1352  }
1353  return nr;
1354 }
1355 int SFNode_equals(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1356 {
1357  struct X3D_Node *lhs = *(void * *)fwn;
1358  struct X3D_Node *rhs = *(struct X3D_Node **)(fwpars[0]._web3dval.native);
1359 
1360  fwretval->_boolean = lhs == rhs;
1361  fwretval->itype = 'B';
1362  return 1;
1363 }
1364 int SFNode_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1365 {
1366  void* *ptr = (void * *)fwn;
1367  if(0){
1368  struct X3D_Node *node = *ptr;
1369  printf("node address=%x nodetype=%s\n",node,stringNodeType(node->_nodeType));
1370  }
1371  if(0){
1372  //see also mfw_getter
1373  void *sfptr = malloc(sizeof(void*));
1374  memcpy(sfptr,(void *)(fwn),sizeof(void*)); //*sfptr = MF.p[i] = &SF
1375  fwretval->_web3dval.native = (void *)sfptr; //native = &sfptr
1376  fwretval->_web3dval.gc = 1;
1377  fwretval->itype = 'W';
1378  }else{
1379  fwretval->_jsobject = *ptr;
1380  fwretval->itype = 'X';
1381  }
1382  return 1;
1383 }
1384 int SFNode_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1385 {
1386  char str[512];
1387  void **ptr = (void **)fwn;
1388  sprintf(str,"_%x_",(*ptr));
1389  fwretval->_string = strdup(str);
1390  fwretval->itype = 'S';
1391  return 1;
1392 }
1393 FWFunctionSpec (SFNodeFunctions)[] = {
1394  {"getNodeName", SFNode_getNodeName, 'S',{0,0,0,NULL}},
1395  // nov 2014 dug9: I was too lazy to implement the following, good luck:
1396  //{"getNodeType", SFNode_getNodeType, 'W',{0,0,0,NULL}},
1397  //{"getFieldDefinitions", SFNode_getFieldDefinitions, 'P',{0,0,0,NULL}},
1398  //{"toVRMLString", SFNode_toVRMLString, 'S',{0,0,0,NULL}},
1399  //{"toXMLString", SFNode_toXMLString, 'S',{0,0,0,NULL}},
1400  {"equals", SFNode_equals, 'B',{1,-1,0,"W"}},
1401  {"valueOf", SFNode_valueOf, 'X',{0,0,0,NULL}},
1402  {"toString", SFNode_toString, 'S',{0,0,0,NULL}},
1403  {0}
1404 };
1405 
1406 //#define FIELDTYPE_SFNode 10
1407 FWTYPE SFNodeType = {
1408  FIELDTYPE_SFNode,
1409  'W',
1410  "SFNode",
1411  sizeof(void*), //sizeof(struct ),
1412  SFNode_Constructor, //constructor
1413  SFNode_ConstructorArgs, //constructor args
1414  NULL, //Properties,
1415  SFNode_Iterator, //special iterator
1416  SFNode_Getter, //Getter,
1417  SFNode_Setter, //Setter,
1418  0,0, //index prop type,readonly
1419  SFNodeFunctions, //functions
1420 };
1421 
1422 
1423 
1424 //#define FIELDTYPE_MFNode 11
1425 FWTYPE MFNodeType = {
1426  FIELDTYPE_MFNode,
1427  'W',
1428  "MFNode",
1429  sizeof(struct Multi_Any), //sizeof(struct ),
1430  MFW_Constructor, //constructor
1431  MFW_ConstructorArgs, //constructor args
1432  MFW_Properties, //Properties,
1433  NULL, //special iterator
1434  MFW_Getter, //Getter,
1435  MFW_Setter, //Setter,
1436  'W',0, //index prop type,readonly
1437  MFW_Functions, //functions
1438 };
1439 
1440 
1441 /* from http://www.cs.rit.edu/~ncs/color/t_convert.html */
1442 double MIN(double a, double b, double c) {
1443  double min;
1444  if((a<b)&&(a<c))min=a; else if((b<a)&&(b<c))min=b; else min=c; return min;
1445 }
1446 
1447 double MAX(double a, double b, double c) {
1448  double max;
1449  if((a>b)&&(a>c))max=a; else if((b>a)&&(b>c))max=b; else max=c; return max;
1450 }
1451 
1452 void convertRGBtoHSV(double r, double g, double b, double *h, double *s, double *v) {
1453  double my_min, my_max, delta;
1454 
1455  my_min = MIN( r, g, b );
1456  my_max = MAX( r, g, b );
1457  *v = my_max; /* v */
1458  delta = my_max - my_min;
1459  if( my_max != 0 )
1460  *s = delta / my_max; /* s */
1461  else {
1462  /* r = g = b = 0 */ /* s = 0, v is undefined */
1463  *s = 0;
1464  *h = -1;
1465  return;
1466  }
1467  if( r == my_max )
1468  *h = ( g - b ) / delta; /* between yellow & magenta */
1469  else if( g == my_max )
1470  *h = 2 + ( b - r ) / delta; /* between cyan & yellow */
1471  else
1472  *h = 4 + ( r - g ) / delta; /* between magenta & cyan */
1473  *h *= 60; /* degrees */
1474  if( *h < 0 )
1475  *h += 360;
1476 }
1477 void convertHSVtoRGB( double h, double s, double v ,double *r, double *g, double *b)
1478 {
1479  int i;
1480  double f, p, q, t;
1481  if( s == 0 ) {
1482  /* achromatic (grey) */
1483  *r = *g = *b = v;
1484  return;
1485  }
1486  h /= 60; /* sector 0 to 5 */
1487  i = (int) floor( h );
1488  f = h - i; /* factorial part of h */
1489  p = v * ( 1 - s );
1490  q = v * ( 1 - s * f );
1491  t = v * ( 1 - s * ( 1 - f ) );
1492  switch( i ) {
1493  case 0: *r = v; *g = t; *b = p; break;
1494  case 1: *r = q; *g = v; *b = p; break;
1495  case 2: *r = p; *g = v; *b = t; break;
1496  case 3: *r = p; *g = q; *b = v; break;
1497  case 4: *r = t; *g = p; *b = v; break;
1498  default: *r = v; *g = p; *b = q; break;
1499  }
1500 }
1501 
1502 
1503 int SFColor_getHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1504  //argc should == 0 for getHSV
1505  struct SFVec3d *sf3d;
1506  struct SFColor *ptr = (struct SFColor *)fwn;
1507  double xp[3];
1508  /* convert rgb to hsv */
1509  convertRGBtoHSV((double)ptr->c[0], (double)ptr->c[1], (double)ptr->c[2],&xp[0],&xp[1],&xp[2]);
1510  //supposed to return numeric[3] - don't have that set up so sfvec3d
1511  sf3d = malloc(sizeof(struct SFVec3d)); //garbage collector please
1512  memcpy(sf3d->c,xp,sizeof(double)*3);
1513  fwretval->_web3dval.native = sf3d;
1514  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
1515  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
1516  fwretval->itype = 'W';
1517  return 1;
1518 }
1519 
1520 int SFColor_setHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1521  //argc should == 3 for setHSV
1522  struct SFColor *ptr = (struct SFColor *)fwn;
1523  double xp[3];
1524  /* convert rgb to hsv */
1525  convertHSVtoRGB((double)fwpars[0]._numeric, (double)fwpars[1]._numeric, (double)fwpars[2]._numeric,&xp[0],&xp[1],&xp[2]);
1526  ptr->c[0] = (float)xp[0];
1527  ptr->c[1] = (float)xp[1];
1528  ptr->c[2] = (float)xp[2];
1529  return 0;
1530 }
1531 
1532 int SFColor_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1533  struct SFColor *ptr = (struct SFColor *)fwn;
1534  char buff[STRING], *str;
1535  int len;
1536  memset(buff, 0, STRING);
1537  sprintf(buff, "%.3g %.3g %.3g",
1538  ptr->c[0], ptr->c[1], ptr->c[2]);
1539  len = strlen(buff);
1540  str = malloc(len+1); //leak
1541  strcpy(str,buff);
1542  fwretval->_string = str;
1543  fwretval->itype = 'S';
1544  return 1;
1545 }
1546 
1547 FWFunctionSpec (SFColor_Functions)[] = {
1548  {"getHSV", SFColor_getHSV, 'W',{0,0,0,NULL}},
1549  {"setHSV", SFColor_setHSV, 0,{3,-1,'T',"DDD"}},
1550  {"toString", SFColor_toString, 'S',{0,-1,0,NULL}},
1551  {0}
1552 };
1553 
1554 int SFColor_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1555  struct SFColor *ptr = (struct SFColor *)fwn;
1556  int nr = 0;
1557  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1558  if(index > -1 && index < 3){
1559  nr = 1;
1560  switch(index){
1561  case 0: //r
1562  case 1: //g
1563  case 2: //b
1564  fwretval->_numeric = ptr->c[index];
1565  break;
1566  default:
1567  nr = 0;
1568  }
1569  }
1570  fwretval->itype = 'F';
1571  return nr;
1572 }
1573 int SFColor_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1574  struct SFColor *ptr = (struct SFColor *)fwn;
1575  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1576  if(index > -1 && index < 3){
1577  switch(index){
1578  case 0: //r
1579  case 1: //g
1580  case 2: //b
1581  ptr->c[index] = (float) fwval->_numeric;
1582  break;
1583  }
1584  return TRUE;
1585  }
1586  return FALSE;
1587 }
1588 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
1589 void * SFColor_Constructor(FWType fwtype, int ic, FWval fwpars){
1590  int i;
1591  struct SFColor *ptr = malloc(fwtype->size_of); //garbage collector please
1592  if(fwtype->ConstructorArgs[0].nfixedArg == 3){
1593  for(i=0;i<3;i++)
1594  ptr->c[i] = (float) fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
1595  }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
1596  //new SFxxx(myMF[i]);
1597  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
1598  }
1599  return (void *)ptr;
1600 }
1601 
1602 FWPropertySpec (SFColor_Properties)[] = {
1603  {"r", 0, 'F', 0},
1604  {"g", 1, 'F', 0},
1605  {"b", 2, 'F', 0},
1606  {NULL,0,0,0},
1607 };
1608 
1609 //typedef struct ArgListType {
1610 // char nfixedArg;
1611 // char iVarArgStartsAt; //-1 no varargs
1612 // char fillMissingFixedWithZero; //T/F if F then complain if short
1613 // char *argtypes; //if varargs, then argtypes[nfixedArg] == type of varArg, and all varargs are assumed the same type
1614 //} ArgListType;
1615 ArgListType (SFColor_ConstructorArgs)[] = {
1616  {3,0,'T',"FFF"},
1617  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
1618  {-1,0,0,NULL},
1619 };
1620 //#define FIELDTYPE_SFColor 12
1621 FWTYPE SFColorType = {
1622  FIELDTYPE_SFColor,
1623  'W',
1624  "SFColor",
1625  sizeof(struct SFColor), //sizeof(struct ),
1626  SFColor_Constructor, //constructor
1627  SFColor_ConstructorArgs, //constructor args
1628  SFColor_Properties, //Properties,
1629  NULL, //special iterator
1630  SFColor_Getter, //Getter,
1631  SFColor_Setter, //Setter,
1632  'F',0, //index prop type,readonly
1633  SFColor_Functions, //functions
1634 };
1635 
1636 
1637 //#define FIELDTYPE_MFColor 13
1638 FWTYPE MFColorType = {
1639  FIELDTYPE_MFColor,
1640  'W',
1641  "MFColor",
1642  sizeof(struct Multi_Any), //sizeof(struct ),
1643  MFW_Constructor, //constructor
1644  MFW_ConstructorArgs, //constructor args
1645  MFW_Properties, //Properties,
1646  NULL, //special iterator
1647  MFW_Getter, //Getter,
1648  MFW_Setter, //Setter,
1649  'W',0, //index prop type,readonly
1650  MFW_Functions, //functions
1651 };
1652 
1653 
1654 int SFColorRGBA_getHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1655  //argc should == 0 for getHSV
1656  struct SFVec3d *sf3d;
1657  struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1658  double xp[3];
1659  /* convert rgb to hsv */
1660  convertRGBtoHSV((double)ptr->c[0], (double)ptr->c[1], (double)ptr->c[2],&xp[0],&xp[1],&xp[2]);
1661  //supposed to return numeric[3] - don't have that set up so sfvec3d
1662  sf3d = malloc(sizeof(struct SFVec3d)); //garbage collector please
1663  memcpy(sf3d->c,xp,sizeof(double)*3);
1664  fwretval->_web3dval.native = sf3d;
1665  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
1666  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
1667  fwretval->itype = 'W';
1668  return 1;
1669 }
1670 
1671 int SFColorRGBA_setHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1672  //argc should == 3 for setHSV
1673  struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1674  double xp[3];
1675  /* convert rgb to hsv */
1676  convertHSVtoRGB((double)fwpars[0]._numeric, (double)fwpars[1]._numeric, (double)fwpars[2]._numeric,&xp[0],&xp[1],&xp[2]);
1677  ptr->c[0] = (float)xp[0];
1678  ptr->c[1] = (float)xp[1];
1679  ptr->c[2] = (float)xp[2];
1680  ptr->c[3] = 1.0f;
1681  return 0;
1682 }
1683 
1684 int SFColorRGBA_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1685  struct SFColor *ptr = (struct SFColor *)fwn;
1686  char buff[STRING], *str;
1687  int len;
1688  memset(buff, 0, STRING);
1689  sprintf(buff, "%.3g %.3g %.3g %.3g",
1690  ptr->c[0], ptr->c[1], ptr->c[2], ptr->c[3]);
1691  len = strlen(buff);
1692  str = malloc(len+1); //leak
1693  strcpy(str,buff);
1694  fwretval->_string = str;
1695  fwretval->itype = 'S';
1696  return 1;
1697 }
1698 
1699 FWFunctionSpec (SFColorRGBA_Functions)[] = {
1700  {"getHSV", SFColor_getHSV, 'W',{0,0,0,NULL}},
1701  {"setHSV", SFColor_setHSV, 0,{3,-1,'T',"DDD"}},
1702  {"toString", SFColorRGBA_toString, 'S',{0,-1,0,NULL}},
1703  {0}
1704 };
1705 
1706 int SFColorRGBA_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1707  struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1708  int nr = 0;
1709  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1710  if(index > -1 && index < 4){
1711  nr = 1;
1712  switch(index){
1713  case 0: //r
1714  case 1: //g
1715  case 2: //b
1716  case 3: //a
1717  fwretval->_numeric = ptr->c[index];
1718  break;
1719  default:
1720  nr = 0;
1721  }
1722  }
1723  fwretval->itype = 'F';
1724  return nr;
1725 }
1726 int SFColorRGBA_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1727  struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1728  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
1729  if(index > -1 && index < 4){
1730  switch(index){
1731  case 0: //r
1732  case 1: //g
1733  case 2: //b
1734  case 3: //a
1735  ptr->c[index] = (float) fwval->_numeric;
1736  break;
1737  }
1738  return TRUE;
1739  }
1740  return FALSE;
1741 }
1742 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
1743 void * SFColorRGBA_Constructor(FWType fwtype, int ic, FWval fwpars){
1744  int i;
1745  struct SFColorRGBA *ptr = malloc(fwtype->size_of); //garbage collector please
1746  if(ic == 4){
1747  for(i=0;i<4;i++)
1748  ptr->c[i] = (float) fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
1749  } else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
1750  //new SFxxx(myMF[i]);
1751  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
1752  }
1753 
1754  return (void *)ptr;
1755 }
1756 
1757 FWPropertySpec (SFColorRGBA_Properties)[] = {
1758  {"r", 0, 'F', 0},
1759  {"g", 1, 'F', 0},
1760  {"b", 2, 'F', 0},
1761  {"a", 3, 'F', 0},
1762  {NULL,0,0,0},
1763 };
1764 
1765 //typedef struct ArgListType {
1766 // char nfixedArg;
1767 // char iVarArgStartsAt; //-1 no varargs
1768 // char fillMissingFixedWithZero; //T/F if F then complain if short
1769 // char *argtypes; //if varargs, then argtypes[nfixedArg] == type of varArg, and all varargs are assumed the same type
1770 //} ArgListType;
1771 ArgListType (SFColorRGBA_ConstructorArgs)[] = {
1772  {4,0,'T',"FFFF"},
1773  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
1774  {-1,0,0,NULL},
1775 };
1776 
1777 
1778 //#define FIELDTYPE_SFColorRGBA 14
1779 FWTYPE SFColorRGBAType = {
1780  FIELDTYPE_SFColorRGBA,
1781  'W',
1782  "SFColorRGBA",
1783  sizeof(struct SFColorRGBA), //sizeof(struct ),
1784  SFColorRGBA_Constructor, //constructor
1785  SFColorRGBA_ConstructorArgs, //constructor args
1786  SFColorRGBA_Properties, //Properties,
1787  NULL, //special iterator
1788  SFColorRGBA_Getter, //Getter,
1789  SFColorRGBA_Setter, //Setter,
1790  'F',0, //index prop type,readonly
1791  SFColorRGBA_Functions, //functions
1792 };
1793 //#define FIELDTYPE_MFColorRGBA 15
1794 FWTYPE MFColorRGBAType = {
1795  FIELDTYPE_MFColorRGBA,
1796  'W',
1797  "MFColorRGBA",
1798  sizeof(struct Multi_Any), //sizeof(struct ),
1799  MFW_Constructor, //constructor
1800  MFW_ConstructorArgs, //constructor args
1801  MFW_Properties, //Properties,
1802  NULL, //special iterator
1803  MFW_Getter, //Getter,
1804  MFW_Setter, //Setter,
1805  'W',0, //index prop type,readonly
1806  MFW_Functions, //functions
1807 };
1808 
1809 int SFDouble_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1810 {
1811  double *ptr = (double *)fwn;
1812  fwretval->_numeric = *(ptr);
1813  fwretval->itype = 'D';
1814  return 1;
1815 }
1816 int SFDouble_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1817 {
1818  char str[512];
1819  double *ptr = (double *)fwn;
1820  sprintf(str,"%g",(*ptr));
1821  fwretval->_string = strdup(str);
1822  fwretval->itype = 'S';
1823  return 1;
1824 }
1825 
1826 FWFunctionSpec (SFDouble_Functions)[] = {
1827  {"valueOf", SFDouble_valueOf, 'D',{0,0,0,NULL}},
1828  {"toString", SFDouble_toString, 'S',{0,0,0,NULL}},
1829  {0}
1830 };
1831 
1832 //#define FIELDTYPE_SFTime 16
1833 FWTYPE SFTimeType = {
1834  FIELDTYPE_SFTime,
1835  'D',
1836  "SFTime",
1837  sizeof(double), //sizeof(struct ),
1838  NULL, //constructor
1839  NULL, //constructor args
1840  NULL, //Properties,
1841  NULL, //special iterator
1842  NULL, //Getter,
1843  NULL, //Setter,
1844  0,0, //index prop type,readonly
1845  SFDouble_Functions, //functions
1846 };
1847 
1848 void * MFTime_Constructor(FWType fwtype, int argc, FWval fwpars){
1849  int i, lenSF;
1850  char *p;
1851  struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
1852  lenSF = sizeofSF(fwtype->itype);
1853  ptr->n = argc;
1854  ptr->p = NULL;
1855  if(ptr->n)
1856  ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
1857  p = ptr->p;
1858  for(i=0;i<ptr->n;i++){
1859  if(fwpars[i].itype == 'W')
1860  memcpy(p,&fwpars[i]._web3dval.native,lenSF);
1861  else if(fwpars[i].itype == 'D')
1862  memcpy(p,&fwpars[i]._numeric,lenSF);
1863  p += lenSF;
1864  }
1865  return (void *)ptr;
1866 }
1867 ArgListType (MFTime_ConstructorArgs)[] = {
1868  {0,0,0,"D"},
1869  {-1,0,0,NULL},
1870 };
1871 
1872 
1873 //#define FIELDTYPE_MFTime 17
1874 FWTYPE MFTimeType = {
1875  FIELDTYPE_MFTime,
1876  'W',
1877  "MFTime",
1878  sizeof(struct Multi_Any), //sizeof(struct ),
1879  MFTime_Constructor, //constructor
1880  MFTime_ConstructorArgs, //constructor args
1881  MFW_Properties, //Properties,
1882  NULL, //special iterator
1883  MFW_Getter, //Getter,
1884  MFW_Setter, //Setter,
1885  'D',0, //index prop type,readonly
1886  MFW_Functions, //functions
1887 };
1888 
1889 int SFString_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1890 {
1891  struct Uni_String *ptr = (struct Uni_String *)fwn;
1892  fwretval->_string = ptr->strptr;
1893  fwretval->itype = 'S';
1894  return 1;
1895 }
1896 int SFString_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1897 {
1898  struct Uni_String *ptr = (struct Uni_String *)fwn;
1899  fwretval->_string = strdup(ptr->strptr);
1900  fwretval->itype = 'S';
1901  return 1;
1902 }
1903 
1904 FWFunctionSpec (SFString_Functions)[] = {
1905  {"valueOf", SFString_valueOf, 'S',{0,0,0,NULL}},
1906  {"toString", SFString_toString, 'S',{0,0,0,NULL}},
1907  {0}
1908 };
1909 
1910 //#define FIELDTYPE_SFString 18
1911 FWTYPE SFStringType = {
1912  FIELDTYPE_SFString,
1913  'S',
1914  "SFString",
1915  sizeof(void *), //sizeof(struct ),
1916  NULL, //constructor
1917  NULL, //constructor args
1918  NULL, //Properties,
1919  NULL, //special iterator
1920  NULL, //Getter,
1921  NULL, //Setter,
1922  0,0, //index prop type,readonly //Q. should string[i] return 'I' == char, like SFImage indexer?
1923  SFString_Functions, //functions
1924 };
1925 
1926 void * MFString_Constructor(FWType fwtype, int argc, FWval fwpars){
1927  int i, lenSF;
1928  char *p;
1929  struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
1930  lenSF = sizeofSF(fwtype->itype);
1931  ptr->n = argc;
1932  ptr->p = NULL;
1933  if(ptr->n)
1934  ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
1935  p = ptr->p;
1936  for(i=0;i<ptr->n;i++){
1937  //float ff = (float)fwpars[i]._numeric; //fwpars[i]._web3dval.native;
1938  if(fwpars[i].itype == 'W' && fwpars[i]._web3dval.fieldType == FIELDTYPE_SFString)
1939  memcpy(p,&fwpars[i]._web3dval.native,lenSF);
1940  else if(fwpars[i].itype == 'S'){
1941  void *tmp = newASCIIString(fwpars[i]._string);
1942  memcpy(p,&tmp,lenSF);
1943  //(*p) = (char *)
1944  }else if(fwpars[i].itype == 'F' || fwpars[i].itype == 'D'){
1945  void *tmp;
1946  char str[100];
1947  sprintf(str,"%f", fwpars[i]._numeric);
1948  tmp = newASCIIString(str);
1949  memcpy(p,&tmp,lenSF);
1950  }else if(fwpars[i].itype == 'I' ){
1951  void *tmp;
1952  char str[100];
1953  sprintf(str,"%d", fwpars[i]._integer);
1954  tmp = newASCIIString(str);
1955  memcpy(p,&tmp,lenSF);
1956  }else if(fwpars[i].itype == 'B' ){
1957  void *tmp;
1958  const char *str = "false";
1959  if(fwpars[i]._boolean) str = "true";
1960  tmp = newASCIIString(str);
1961  memcpy(p,&tmp,lenSF);
1962 
1963  }
1964  p += lenSF;
1965  }
1966  return (void *)ptr;
1967 }
1968 ArgListType (MFString_ConstructorArgs)[] = {
1969  {0,0,0,"S"},
1970  {0,0,0,"F"},
1971  {0,0,0,"D"},
1972  {0,0,0,"I"},
1973  {0,0,0,"B"},
1974  {-1,0,0,NULL},
1975 };
1976 //#define FIELDTYPE_MFString 19
1977 FWTYPE MFStringType = {
1978  FIELDTYPE_MFString,
1979  'W',
1980  "MFString",
1981  sizeof(struct Multi_Any),
1982  MFString_Constructor, //constructor
1983  MFString_ConstructorArgs, //constructor args
1984  MFW_Properties, //Properties,
1985  NULL, //special iterator
1986  MFW_Getter, //Getter,
1987  MFW_Setter, //Setter,
1988  'S',0, //index prop type,readonly
1989  MFW_Functions, //functions
1990 };
1991 
1992 
1993 /* SFVec2f
1994 Constructor
1995 SFVec2f (numeric x, numeric y) Missing values default to 0.0d+00.
1996 props
1997 numeric x No First value of the vector
1998 numeric y No Second value of the vector
1999 funcs
2000 SFVec2f add(SFVec2f vec) Returns the value of the passed value added, component-wise, to the object.
2001 SFVec2f divide(numeric n) Returns the value of the object divided by the passed value.
2002 numeric dot(SFVec2f vec) Returns the dot product of this vector and the passed value.
2003 numeric length() Returns the geometric length of this vector.
2004 SFVec2f multiply(numeric n) Returns the value of the object multiplied by the passed value.
2005 SFVec2f normalize() Returns the object converted to unit length .
2006 SFVec2f subtract(SFVec2f vec) Returns the value of the passed value subtracted, component-wise, from the object.
2007 String toString() Returns a String containing the value of x and y encoding using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
2008 */
2009 
2010 int SFVec2f_add(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2011  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2012  struct SFVec2f *rhs = fwpars[0]._web3dval.native;
2013  struct SFVec2f *res = malloc(fwtype->size_of);
2014  vecadd2f(res->c,ptr->c,rhs->c);
2015  fwretval->_web3dval.native = res;
2016  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2017  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2018  fwretval->itype = 'W';
2019  return 1;
2020 }
2021 int SFVec2f_subtract(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2022  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2023  struct SFVec2f *rhs = fwpars[0]._web3dval.native;
2024  struct SFVec2f *res = malloc(fwtype->size_of);
2025  vecdif2f(res->c,ptr->c,rhs->c);
2026  fwretval->_web3dval.native = res;
2027  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2028  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2029  fwretval->itype = 'W';
2030  return 1;
2031 }
2032 int SFVec2f_divide(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2033  struct SFVec2f *res;
2034  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2035  double rhs = fwpars[0]._numeric;
2036  if(rhs == 0.0){
2037  return 0;
2038  }
2039  rhs = 1.0/rhs;
2040  res = malloc(fwtype->size_of);
2041  vecscale2f(res->c,ptr->c,(float)rhs);
2042  fwretval->_web3dval.native = res;
2043  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2044  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2045  fwretval->itype = 'W';
2046  return 1;
2047 }
2048 int SFVec2f_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2049  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2050  double rhs = fwpars[0]._numeric;
2051  struct SFVec2f *res = malloc(fwtype->size_of);
2052  vecscale2f(res->c,ptr->c,(float)rhs);
2053  fwretval->_web3dval.native = res;
2054  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2055  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2056  fwretval->itype = 'W';
2057  return 1;
2058 }
2059 int SFVec2f_normalize(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2060  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2061  struct SFVec2f *res = malloc(fwtype->size_of);
2062  vecnormal2f(res->c,ptr->c);
2063  fwretval->_web3dval.native = res;
2064  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2065  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2066  fwretval->itype = 'W';
2067  return 1;
2068 }
2069 
2070 int SFVec2f_length(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2071  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2072  double res;
2073  res = veclength2f(ptr->c);
2074  fwretval->_numeric = res;
2075  fwretval->itype = 'F';
2076  return 1;
2077 }
2078 int SFVec2f_dot(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2079  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2080  struct SFVec2f *rhs = fwpars[0]._web3dval.native;
2081  double res;
2082  res = vecdot2f(ptr->c,rhs->c);
2083  fwretval->_numeric = res;
2084  fwretval->itype = 'F';
2085  return 1;
2086 }
2087 
2088 int SFVec2f_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2089  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2090  char buff[STRING], *str;
2091  int len;
2092  memset(buff, 0, STRING);
2093  sprintf(buff, "%.9g %.9g",
2094  ptr->c[0], ptr->c[1]);
2095  len = strlen(buff);
2096  str = malloc(len+1); //leak
2097  strcpy(str,buff);
2098  fwretval->_string = str;
2099  fwretval->itype = 'S';
2100  return 1;
2101 }
2102 FWFunctionSpec (SFVec2f_Functions)[] = {
2103  {"add", SFVec2f_add, 'W',{1,-1,0,"W"}},
2104  {"divide", SFVec2f_divide, 'W',{1,-1,0,"F"}},
2105  {"dot", SFVec2f_dot, 'F',{1,-1,0,"W"}},
2106  {"length", SFVec2f_length, 'F',{0,-1,0,NULL}},
2107  {"multiply", SFVec2f_multiply, 'W',{1,-1,0,"F"}},
2108  {"normalize", SFVec2f_normalize, 'W',{0,-1,0,NULL}},
2109  {"subtract", SFVec2f_subtract, 'W',{1,-1,0,"W"}},
2110  {"toString", SFVec2f_toString, 'S',{0,-1,0,NULL}},
2111  {0}
2112 };
2113 
2114 int SFVec2f_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2115  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2116  int nr = 0;
2117  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2118  if(index > -1 && index < 2){
2119  nr = 1;
2120  switch(index){
2121  case 0: //x
2122  case 1: //y
2123  fwretval->_numeric = ptr->c[index];
2124  break;
2125  default:
2126  nr = 0;
2127  }
2128  }
2129  fwretval->itype = 'F';
2130  return nr;
2131 }
2132 int SFVec2f_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
2133  struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2134  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2135  if(index > -1 && index < 2){
2136  switch(index){
2137  case 0: //x
2138  case 1: //y
2139  ptr->c[index] = (float) fwval->_numeric;
2140  break;
2141  }
2142  return TRUE;
2143  }
2144  return FALSE;
2145 }
2146 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
2147 void * SFVec2f_Constructor(FWType fwtype, int ic, FWval fwpars){
2148  int i;
2149  struct SFVec2f *ptr = malloc(fwtype->size_of); //garbage collector please
2150  if(ic == 2){
2151  for(i=0;i<2;i++)
2152  ptr->c[i] = (float) fwpars[i]._numeric;
2153  }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
2154  //new SFxxx(myMF[i]);
2155  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
2156  }
2157 
2158  return (void *)ptr;
2159 }
2160 
2161 FWPropertySpec (SFVec2f_Properties)[] = {
2162  {"x", 0, 'F', 0},
2163  {"y", 1, 'F', 0},
2164  {NULL,0,0,0},
2165 };
2166 ArgListType (SFVec2f_ConstructorArgs)[] = {
2167  {2,0,'T',"FF"},
2168  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
2169  {-1,0,0,NULL},
2170 };
2171 
2172 //#define FIELDTYPE_SFVec2f 20
2173 FWTYPE SFVec2fType = {
2174  FIELDTYPE_SFVec2f,
2175  'W',
2176  "SFVec2f",
2177  sizeof(struct SFVec2f), //sizeof(struct ),
2178  SFVec2f_Constructor, //constructor
2179  SFVec2f_ConstructorArgs, //constructor args
2180  SFVec2f_Properties, //Properties,
2181  NULL, //special iterator
2182  SFVec2f_Getter, //Getter,
2183  SFVec2f_Setter, //Setter,
2184  'F',0, //index prop type,readonly
2185  SFVec2f_Functions, //functions
2186 };
2187 
2188 //#define FIELDTYPE_MFVec2f 21
2189 FWTYPE MFVec2fType = {
2190  FIELDTYPE_MFVec2f,
2191  'W',
2192  "MFVec2f",
2193  sizeof(struct Multi_Any), //sizeof(struct ),
2194  MFW_Constructor, //constructor
2195  MFW_ConstructorArgs, //constructor args
2196  MFW_Properties, //Properties,
2197  NULL, //special iterator
2198  MFW_Getter, //Getter,
2199  MFW_Setter, //Setter,
2200  'W',0, //index prop type,readonly
2201  MFW_Functions, //functions
2202 };
2203 
2204 /* SFImage
2205 http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#SFImage
2206 constr
2207 SFImage (numeric x, numeric y, numeric comp, MFInt32 array) x is the x-dimension of the image. y is the y-dimension of the image. comp is the number of components of the image (1 for greyscale, 2 for greyscale+alpha, 3 for rgb, 4 for rgb+alpha). Array contains the x * y values for the pixels of the image. The format of each pixel is an SFImage as in the PixelTexture node (see part 1 of ISO/IEC 19775).
2208 props
2209 numeric width No Width dimension of the image in pixels
2210 numeric height No Height dimension of the image in pixels
2211 numeric comp No Number of components of the image
2212 1.greyscale or alpha
2213 2.greyscale + alpha
2214 3.rgb
2215 4.rgb + alpha
2216 MFInt32 array No Returns a String containing the value of x, y, comp and array encoded using the Classic VRML encoding (see part 2 of ISO/IEC 19776).
2217 funcs
2218 String toString() Returns a String containing the value of x, y, comp and array encoded using the Classic VRML encoding (see part 2 of ISO/IEC 19776).
2219 */
2220 
2221 int SFImage_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2222  char *str;
2223  FWType mfint32type = getFWTYPE(FIELDTYPE_MFInt32);
2224  str = mfToString(mfint32type, fwn);
2225  fwretval->_string = str;
2226  fwretval->itype = 'S';
2227  return 1;
2228 }
2229 
2230 FWFunctionSpec (SFImage_Functions)[] = {
2231  {"toString", SFImage_toString, 'S',{0,-1,0,NULL}},
2232  {0}
2233 };
2234 
2235 int SFImage_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2236  struct Multi_Int32 *ptr = (struct Multi_Int32 *)fwn;
2237  int nr = 0;
2238  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2239  if(index > -1 && index < 4){
2240  nr = 1;
2241  switch(index){
2242  case 0: //width
2243  case 1: //height
2244  case 2: //comp
2245  fwretval->_integer = ptr->p[index];
2246  fwretval->itype = 'I';
2247  break;
2248 
2249  case 3: //array
2250  fwretval->_web3dval.native = ptr; //hope they don't go image.array[0] = infinity; which will overwrite width. same for height, comp
2251  fwretval->_web3dval.fieldType = FIELDTYPE_MFInt32;
2252  fwretval->_web3dval.gc = 0;
2253  fwretval->itype = 'W';
2254  break;
2255  default:
2256  nr = 0;
2257  }
2258  }
2259  return nr;
2260 }
2261 int SFImage_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
2262  struct Multi_Int32 *ptr = (struct Multi_Int32*)fwn;
2263  int *p;
2264  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2265  if(index > -1 && index < 4){
2266  switch(index){
2267  case 0: //width
2268  case 1: //height
2269  case 2: //comp
2270  ptr->p[index] = fwval->_integer;
2271  p = ptr->p;
2272  if(ptr->n < (p[0] * p[1] * p[2]) ){
2273  //resize
2274  ptr->n = (p[0] * p[1] * p[2]);
2275  ptr->p = realloc(ptr->p,ptr->n);
2276  }
2277  break;
2278 
2279  case 3: //array
2280  if(fwval->itype == 'W' && fwval->_web3dval.fieldType == FIELDTYPE_MFInt32 ){
2281  //int width,height,comp;
2282  int ncopy; //i,j,
2283  struct Multi_Int32 *im = fwval->_web3dval.native;
2284  ncopy = min(ptr->n,im->n);
2285  //don't write over width,height,comp
2286  memcpy(&ptr->p[3],&im->p[3],(ncopy-3)*sizeof(int));
2287  }
2288  break;
2289  default:
2290  break;
2291  }
2292  return TRUE;
2293  }
2294  return FALSE;
2295 }
2296 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
2297 void * SFImage_Constructor(FWType fwtype, int ic, FWval fwpars){
2298  //around freewrl, SFImage is stored as a MFIn32, with n = 3 x width x height,
2299  //and the first (int,int,int) pixel sacrificed to hold (width,height,comp)
2300  int width, height, comp;
2301  struct Multi_Int32 *ptr = malloc(fwtype->size_of); //garbage collector please
2302 
2303  if(ic > 2){
2304  width = fwpars[0]._integer;
2305  height = fwpars[1]._integer;
2306  comp = fwpars[2]._integer;
2307  }else{
2308  width = 1;
2309  height = 1;
2310  comp = 3;
2311  }
2312  ptr->n = comp * width * height;
2313  ptr->p = malloc(ptr->n * sizeof(int)); //garbage collector please
2314  if(fwpars[3].itype == 'W' && fwpars[3]._web3dval.fieldType == FIELDTYPE_MFInt32){
2315  //the incoming MFInt32 pixel values are one pixel per Int32, so we need to expand to 3 ints
2316  int i, ncopy;
2317  struct Multi_Int32 *im = fwpars[3]._web3dval.native;
2318  ncopy = min(ptr->n,im->n);
2319  for(i=0;i<ncopy;i++)
2320  ptr->p[i] = im->p[i];
2321  }
2322  //first 3 ints are sacrificed
2323  ptr->p[0] = width;
2324  ptr->p[1] = height;
2325  ptr->p[2] = comp;
2326  return (void *)ptr;
2327 }
2328 
2329 FWPropertySpec (SFImage_Properties)[] = {
2330  {"width", 0, 'I', 0},
2331  {"height", 1, 'I', 0},
2332  {"comp", 2, 'I', 0},
2333  {"array", 3, 'W', 0},
2334  {NULL,0,0,0},
2335 };
2336 ArgListType (SFImage_ConstructorArgs)[] = {
2337  {4,3,'T',"IIIW"},
2338  {-1,0,0,NULL},
2339 };
2340 
2341 
2342 //#define FIELDTYPE_SFImage 22
2343 FWTYPE SFImageType = {
2344  FIELDTYPE_SFImage,
2345  'W',
2346  "SFImage",
2347  sizeof(struct Multi_Int32),
2348  SFImage_Constructor, //constructor
2349  SFImage_ConstructorArgs, //constructor args
2350  SFImage_Properties, //Properties,
2351  NULL, //special iterator
2352  SFImage_Getter, //Getter,
2353  SFImage_Setter, //Setter,
2354  0,0, //index prop type,readonly
2355  SFImage_Functions, //functions
2356 };
2357 
2358 #define FIELDTYPE_MFImage 43
2359 FWTYPE MFImageType = {
2360  FIELDTYPE_MFImage,
2361  'W',
2362  "MFImage",
2363  sizeof(struct Multi_Any), //sizeof(struct ),
2364  MFW_Constructor, //constructor
2365  MFW_ConstructorArgs, //constructor args
2366  MFW_Properties, //Properties,
2367  NULL, //special iterator
2368  MFW_Getter, //Getter,
2369  MFW_Setter, //Setter,
2370  'W',0, //index prop type,readonly
2371  MFW_Functions, //functions
2372 };
2373 
2374 //#define FIELDTYPE_FreeWRLPTR 23
2375 //#define FIELDTYPE_FreeWRLThread 24
2376 
2377 /*
2378 SFVec3d add(SFVec3d vec) Returns the value of the passed value added, component-wise, to the object.
2379 SFVec3d cross(SFVec3d vec) Returns the cross product of the object and the passed value.
2380 SFVec3d divide(numeric n) Returns the value of the object divided by the passed value.
2381 numeric dot(SFVec3d vec) Returns the dot product of this vector and the passed value as a double precision value.
2382 numeric length() Returns the geometric length of this vector as a double precision value.
2383 SFVec3d multiple(numeric n) Returns the value of the object multiplied by the passed value.
2384 SFVec3d negate() Returns the value of the component-wise negation of the object.
2385 SFVec3d normalize() Returns the object converted to unit length .
2386 SFVec3d subtract(SFVec3f vec) Returns the value of the passed value subtracted, component-wise, from the object.
2387 String toString() Returns a String containing the value of x, y, and z encoded using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
2388 */
2389 //SFVec3d add(SFVec3d vec) Returns the value of the passed value added, component-wise, to the object.
2390 int SFVec3d_add(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2391  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2392  struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2393  struct SFVec3d *res = malloc(fwtype->size_of);
2394  vecaddd(res->c,ptr->c,rhs->c);
2395  fwretval->_web3dval.native = res;
2396  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2397  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2398  fwretval->itype = 'W';
2399  return 1;
2400 }
2401 int SFVec3d_cross(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2402  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2403  struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2404  struct SFVec3d *res = malloc(fwtype->size_of);
2405  veccrossd(res->c,ptr->c,rhs->c);
2406  fwretval->_web3dval.native = res;
2407  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2408  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2409  fwretval->itype = 'W';
2410  return 1;
2411 }
2412 int SFVec3d_subtract(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2413  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2414  struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2415  struct SFVec3d *res = malloc(fwtype->size_of);
2416  vecdifd(res->c,ptr->c,rhs->c);
2417  fwretval->_web3dval.native = res;
2418  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2419  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2420  fwretval->itype = 'W';
2421  return 1;
2422 }
2423 int SFVec3d_divide(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2424  struct SFVec3d *res;
2425  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2426  double rhs = fwpars[0]._numeric;
2427  if(rhs == 0.0){
2428  return 0;
2429  }
2430  rhs = 1.0/rhs;
2431  res = malloc(fwtype->size_of);
2432  vecscaled(res->c,ptr->c,rhs);
2433  fwretval->_web3dval.native = res;
2434  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2435  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2436  fwretval->itype = 'W';
2437  return 1;
2438 }
2439 int SFVec3d_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2440  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2441  double rhs = fwpars[0]._numeric;
2442  struct SFVec3d *res = malloc(fwtype->size_of);
2443  vecscaled(res->c,ptr->c,rhs);
2444  fwretval->_web3dval.native = res;
2445  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2446  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2447  fwretval->itype = 'W';
2448  return 1;
2449 }
2450 int SFVec3d_normalize(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2451  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2452  struct SFVec3d *res = malloc(fwtype->size_of);
2453  vecnormald(res->c,ptr->c);
2454  fwretval->_web3dval.native = res;
2455  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2456  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2457  fwretval->itype = 'W';
2458  return 1;
2459 }
2460 
2461 int SFVec3d_negate(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2462  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2463  struct SFVec3d *res = malloc(fwtype->size_of);
2464  vecscaled(res->c,ptr->c,-1.0);
2465  fwretval->_web3dval.native = res;
2466  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2467  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2468  fwretval->itype = 'W';
2469  return 1;
2470 }
2471 int SFVec3d_length(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2472  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2473  double res;
2474  res = veclengthd(ptr->c);
2475  fwretval->_numeric = res;
2476  fwretval->itype = 'D';
2477  return 1;
2478 }
2479 int SFVec3d_dot(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2480  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2481  struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2482  double res;
2483  res = vecdotd(ptr->c,rhs->c);
2484  fwretval->_numeric = res;
2485  fwretval->itype = 'D';
2486  return 1;
2487 }
2488 
2489 int SFVec3d_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2490  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2491  char buff[STRING], *str;
2492  int len;
2493  memset(buff, 0, STRING);
2494  sprintf(buff, "%.9g %.9g %.9g",
2495  ptr->c[0], ptr->c[1], ptr->c[2]);
2496  len = strlen(buff);
2497  str = malloc(len+1); //leak
2498  strcpy(str,buff);
2499  fwretval->_string = str;
2500  fwretval->itype = 'S';
2501  return 1;
2502 }
2503 
2504 FWFunctionSpec (SFVec3d_Functions)[] = {
2505  {"add", SFVec3d_add, 'W',{1,-1,0,"W"}},
2506  {"cross", SFVec3d_cross, 'W',{1,-1,0,"W"}},
2507  {"divide", SFVec3d_divide, 'W',{1,-1,0,"D"}},
2508  {"dot", SFVec3d_dot, 'D',{1,-1,0,"W"}},
2509  {"length", SFVec3d_length, 'D',{0,-1,0,NULL}},
2510  {"multiply", SFVec3d_multiply, 'W',{1,-1,0,"D"}},
2511  {"negate", SFVec3d_negate, 'W',{0,-1,0,NULL}},
2512  {"normalize", SFVec3d_normalize, 'W',{0,-1,0,NULL}},
2513  {"subtract", SFVec3d_subtract, 'W',{1,-1,0,"W"}},
2514  {"toString", SFVec3d_toString, 'S',{0,-1,0,NULL}},
2515  {0}
2516 };
2517 
2518 int SFVec3d_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2519  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2520  int nr = 0;
2521  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2522  if(index > -1 && index < 3){
2523  nr = 1;
2524  switch(index){
2525  case 0: //x
2526  case 1: //y
2527  case 2: //z
2528  fwretval->_numeric = ptr->c[index];
2529  break;
2530  default:
2531  nr = 0;
2532  }
2533  }
2534  fwretval->itype = 'D';
2535  return nr;
2536 }
2537 int SFVec3d_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
2538  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2539  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2540  if(index > -1 && index < 3){
2541  switch(index){
2542  case 0: //x
2543  case 1: //y
2544  case 2: //z
2545  ptr->c[index] = fwval->_numeric; //fwval->_web3dval.anyvrml->sffloat;
2546  break;
2547  }
2548  return TRUE;
2549  }
2550  return FALSE;
2551 }
2552 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
2553 void * SFVec3d_Constructor(FWType fwtype, int ic, FWval fwpars){
2554  int i;
2555  struct SFVec3d *ptr = malloc(fwtype->size_of); //garbage collector please
2556  if(ic == 3){
2557  for(i=0;i<3;i++)
2558  ptr->c[i] = fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
2559  }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
2560  //new SFxxx(myMF[i]);
2561  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
2562  }
2563 
2564  return (void *)ptr;
2565 }
2566 
2567 FWPropertySpec (SFVec3d_Properties)[] = {
2568  {"x", 0, 'D', 0},
2569  {"y", 1, 'D', 0},
2570  {"z", 2, 'D', 0},
2571  {NULL,0,0,0},
2572 };
2573 ArgListType (SFVec3d_ConstructorArgs)[] = {
2574  {3,0,'T',"DDD"},
2575  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
2576  {-1,0,0,NULL},
2577 };
2578 //#define FIELDTYPE_SFVec3d 25
2579 FWTYPE SFVec3dType = {
2580  FIELDTYPE_SFVec3d,
2581  'W',
2582  "SFVec3d",
2583  sizeof(struct SFVec3d), //sizeof(struct ),
2584  SFVec3d_Constructor, //constructor
2585  SFVec3d_ConstructorArgs, //constructor args
2586  SFVec3d_Properties, //Properties,
2587  NULL, //special iterator
2588  SFVec3d_Getter, //Getter,
2589  SFVec3d_Setter, //Setter,
2590  'D',0, //index prop type,readonly
2591  SFVec3d_Functions, //functions
2592 };
2593 
2594 
2595 //#define FIELDTYPE_MFVec3d 26
2596 FWTYPE MFVec3dType = {
2597  FIELDTYPE_MFVec3d,
2598  'W',
2599  "MFVec3d",
2600  sizeof(struct Multi_Any), //sizeof(struct ),
2601  MFW_Constructor, //constructor
2602  MFW_ConstructorArgs, //constructor args
2603  MFW_Properties, //Properties,
2604  NULL, //special iterator
2605  MFW_Getter, //Getter,
2606  MFW_Setter, //Setter,
2607  'W',0, //index prop type,readonly
2608  MFW_Functions, //functions
2609 };
2610 
2611 
2612 
2613 //#define FIELDTYPE_SFDouble 27
2614 FWTYPE SFDoubleType = {
2615  FIELDTYPE_SFDouble,
2616  'D',
2617  "SFDouble",
2618  sizeof(double), //sizeof(struct ),
2619  NULL, //constructor
2620  NULL, //constructor args
2621  NULL, //Properties,
2622  NULL, //special iterator
2623  NULL, //Getter,
2624  NULL, //Setter,
2625  0,0, //index prop type,readonly
2626  SFDouble_Functions, //functions
2627 };
2628 
2629 void * MFDouble_Constructor(FWType fwtype, int argc, FWval fwpars){
2630  int i, lenSF;
2631  char *p;
2632  struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
2633  lenSF = sizeofSF(fwtype->itype);
2634  ptr->n = argc;
2635  ptr->p = NULL;
2636  if(ptr->n)
2637  ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
2638  p = ptr->p;
2639  for(i=0;i<ptr->n;i++){
2640  if(fwpars[i].itype == 'W')
2641  memcpy(p,&fwpars[i]._web3dval.native,lenSF);
2642  else if(fwpars[i].itype == 'D')
2643  memcpy(p,&fwpars[i]._numeric,lenSF);
2644  p += lenSF;
2645  }
2646  return (void *)ptr;
2647 }
2648 ArgListType (MFDouble_ConstructorArgs)[] = {
2649  {0,0,0,"D"},
2650  {-1,0,0,NULL},
2651 };
2652 
2653 //#define FIELDTYPE_MFDouble 28
2654 FWTYPE MFDoubleType = {
2655  FIELDTYPE_MFDouble,
2656  'W',
2657  "MFDouble",
2658  sizeof(struct Multi_Any), //sizeof(struct ),
2659  MFDouble_Constructor, //constructor
2660  MFDouble_ConstructorArgs, //constructor args
2661  MFW_Properties, //Properties,
2662  NULL, //special iterator
2663  MFW_Getter, //Getter,
2664  MFW_Setter, //Setter,
2665  'D',0, //index prop type,readonly
2666  MFW_Functions, //functions
2667 };
2668 
2669 // http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#Matrix3
2670 /* Matrix3
2671 constr
2672 X3DMatrix3 (numeric f11, numeric f12, numeric f13,
2673  numeric f21, numeric f22, numeric f23,
2674  numeric f31, numeric f32, numeric f33) The creation function shall initialize the array using zero or more SFVec3-valued expressions passed as parameters.
2675 props
2676 - row major single index
2677 funcs
2678 void setTransform(SFVec2f translation, SFVec3f rotation, SFVec2f scale, SFVec3f scaleOrientation, SFVec2f center)
2679  Sets the Matrix to the passed values. Any of the rightmost parameters may be omitted. The function has zero to five parameters. For example, specifying zero parameters results in an identity matrix while specifying one parameter results in a translation and specifying two parameters results in a translation and a rotation. Any unspecified parameter is set to its default as specified for the Transform node. Values are applied to the matrix in the same order as the matrix field calculations for the Transform node.
2680 void getTransform(SFVec2f translation, SFVec3f rotation, SFVec2f scale)
2681  Decomposes the Matrix and returns the components in the passed translation, rotation, and scale objects. The types of these passed objects is the same as the first three arguments to setTransform. If any passed object is not sent, or if the null object is sent for any value, that value is not returned. Any projection or shear information in the matrix is ignored.
2682 Matrix3 inverse()
2683  Returns a Matrix whose value is the inverse of this object.
2684 Matrix3 transpose()
2685  Returns a Matrix whose value is the transpose of this object.
2686 Matrix3 multLeft(Matrix3)
2687  Returns a Matrix whose value is the object multiplied by the passed matrix on the left.
2688 Matrix3 multRight(Matrix3)
2689  Returns a Matrix whose value is the object multiplied by the passed matrix on the right.
2690 SFVec2f multVecMatrix(SFVec2f vec)
2691  Returns an SFVec3f whose value is the object multiplied by the passed row vector.
2692 SFVec2f multMatrixVec(SFVec2f vec)
2693  Returns an SFVec3f whose value is the object multiplied by the passed column vector.
2694 String toString() Returns a String containing the matrix contents encoded using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
2695 I assume they mean homogenous transform, 2D
2696 [x'] [x y 1] X [c*sx s*sy px] [x] //px, py are 2D perspectives
2697 [y'] = [-s*sx c*sy py] X [y]
2698 [w ] [tx ty 1] [1] //tx,ty are 2D translations
2699 x" = x'/w
2700 y" = y'/w
2701 dug9 complaint about Matrix3.getTransform, .setTransform july 2014:
2702 A 2D planar rotation can be represented by a scalar angle. I have no idea where the angle
2703 is in the SFVec3f. I could guess the angle is in [4] in the SFRotation, and assume
2704 the axis part is 0,0,1.
2705 I gather the reason they pass in complex types for rotations in setTransform is
2706 a) so null can be used to signal no-value (but 0 for rotation would do the same)
2707 b) because they want them returned in getTransform and to get something returned via
2708 function args you have to pass in a pointer type, not an ecma primitive value.
2709 Primitive values can't be returned through function args only through return vals.
2710 They could have:
2711 1) broken the get into getScale, getRotation, getTranslation, and then the getRotation could return
2712 an ecma numeric primitive, or
2713 2) numeric getTransform(scale,translation) with the numeric return val being the rotation, or
2714 3) defined an SFFloat complex type and passed it as a pointer object
2715 I will implment july 2014 the rotations as scalar/primitive/numerics and do #2, which doesn't comply with specs
2716 
2717 */
2718 
2719 
2720 int X3DMatrix3_setTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2721  // http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/group.html#Transform
2722  // P' = T * C * R * SR * S * -SR * -C * P
2723  int i;// , j;
2724  float angle, scaleangle;
2725  struct SFVec2f *scale;
2726  struct SFVec3f *scaleOrientation;
2727  struct SFVec2f *center;
2728  float *matrix[3], m2[9], *mat[3];
2729 
2730  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2731  struct SFVec2f *translation = fwpars[0]._web3dval.native;
2732  struct SFVec3f *rotation = NULL;
2733  if(fwpars[1].itype == 'W' && fwpars[1]._web3dval.fieldType == FIELDTYPE_SFVec3f){
2734  rotation = fwpars[1]._web3dval.native;
2735  angle = rotation->c[0]; //your guess is as good as mine what they meant
2736  }
2737  if(fwpars[1].itype == 'F')
2738  angle = (float)fwpars[1]._numeric;
2739  scale = fwpars[2]._web3dval.native;
2740  scaleOrientation = NULL;
2741  if(fwpars[3].itype == 'W' && fwpars[3]._web3dval.fieldType == FIELDTYPE_SFVec3f){
2742  scaleOrientation = fwpars[3]._web3dval.native;
2743  scaleangle = scaleOrientation->c[0]; //your guess is as good as mine what they meant
2744  }
2745  if(fwpars[3].itype == 'F')
2746  scaleangle = (float)fwpars[3]._numeric;
2747  center = fwpars[4]._web3dval.native;
2748  for(i=0;i<3;i++){
2749  matrix[0] = &ptr->c[i*3];
2750  mat[i] = &m2[i*3];
2751  }
2752  //initialize to Identity
2753  matidentity3f(matrix[0]);
2754 
2755  //-C
2756  if(center){
2757  matidentity3f(mat[0]);
2758  veccopy2f(mat[2],center->c);
2759  vecscale2f(mat[2],mat[3],-1.0f);
2760  matmultiply3f(matrix[0],mat[0],matrix[0]);
2761  }
2762  //-SR
2763  if(scaleangle != 0.0f){
2764  matidentity3f(mat[0]);
2765  mat[0][0] = mat[1][1] = cosf(-scaleangle);
2766  mat[0][1] = mat[1][0] = sinf(-scaleangle);
2767  mat[0][1] = -mat[0][1];
2768  matmultiply3f(matrix[0],mat[0],matrix[0]);
2769  }
2770  //S
2771  if(scale){
2772  matidentity4f(mat[0]);
2773  for(i=0;i<3;i++)
2774  vecmult2f(mat[i],mat[i],scale->c);
2775  matmultiply3f(matrix[0],mat[0],matrix[0]);
2776  }
2777  //SR
2778  if(scaleangle != 0.0f){
2779  matidentity3f(mat[0]);
2780  mat[0][0] = mat[1][1] = cosf(scaleangle);
2781  mat[0][1] = mat[1][0] = sinf(scaleangle);
2782  mat[0][1] = -mat[0][1];
2783  matmultiply3f(matrix[0],mat[0],matrix[0]);
2784  }
2785  //R
2786  if(angle != 0.0f){
2787  matidentity3f(mat[0]);
2788  mat[0][0] = mat[1][1] = cosf(angle);
2789  mat[0][1] = mat[1][0] = sinf(angle);
2790  mat[0][1] = -mat[0][1];
2791  matmultiply3f(matrix[0],mat[0],matrix[0]);
2792  }
2793  //C
2794  if(center){
2795  matidentity3f(mat[0]);
2796  veccopy2f(mat[2],center->c);
2797  matmultiply3f(matrix[0],mat[0],matrix[0]);
2798  }
2799  //T
2800  if(translation){
2801  matidentity3f(mat[0]);
2802  veccopy2f(mat[2],translation->c);
2803  matmultiply3f(matrix[0],mat[0],matrix[0]);
2804  }
2805 
2806  return 0;
2807 }
2808 
2809 int X3DMatrix3_getTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2810  //void getTransform(SFVec2f translation, SFVec3f rotation, SFVec2f scale)
2811  float angle = 0.0f;
2812  int i;
2813  struct SFVec2f *scale;
2814  float *matrix[3], retscale[2];
2815 
2816  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2817  struct SFVec2f *translation = fwpars[0]._web3dval.native;
2818  struct SFVec3f *rotation = NULL;
2819  if(fwpars[1].itype == 'W' && fwpars[1]._web3dval.fieldType == FIELDTYPE_SFVec3f){
2820  rotation = fwpars[1]._web3dval.native;
2821  angle = rotation->c[3]; //your guess is as good as mine
2822  }else if(fwpars[1].itype == 'F'){
2823  angle = (float)fwpars[1]._numeric;
2824  }
2825  scale = fwpars[2]._web3dval.native;
2826  for(i=0;i<3;i++)
2827  matrix[i] = &ptr->c[i*3];
2828 
2829  //get row scales
2830  for(i=0;i<2;i++)
2831  retscale[i] = (float)sqrt(vecdot3f(matrix[i],matrix[i]));
2832 
2833  if (translation) {
2834  veccopy2f(translation->c,matrix[2]);
2835  }
2836 
2837  /* rotation */
2838  if (1) {
2839  /* apply length to each row to normalize upperleft 3x3 to rotations and shears*/
2840  float m2[9], ff;
2841  for(i=0;i<2;i++){
2842  ff = retscale[i];
2843  if(ff != 0.0f) ff = 1/ff;
2844  vecscale3f(&m2[i*3],matrix[i],ff);
2845  }
2846  angle = atan2f(m2[1],m2[2]);
2847  /* now copy the values over */
2848  if(rotation)
2849  rotation->c[3] = angle;
2850  }
2851 
2852  /* scale */
2853  if (scale) {
2854  veccopy2f(scale->c,retscale);
2855  }
2856 
2857  fwretval->itype = 'F';
2858  fwretval->_numeric = angle;
2859  return 1;
2860 }
2861 
2862 int X3DMatrix3_inverse(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2863  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2864  struct SFMatrix3f *ret = malloc(sizeof(struct SFMatrix3f));
2865 
2866  matrix3x3_inverse_float(ptr->c, ret->c);
2867 
2868  fwretval->_pointer.native = ret;
2869  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
2870  fwretval->_pointer.gc = 'T';
2871  fwretval->itype = 'P';
2872  return 1;
2873 }
2874 int X3DMatrix3_transpose(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2875  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2876  struct SFMatrix3f *ret = malloc(sizeof(struct SFMatrix3f));
2877 
2878  mattranspose3f(ret->c, ptr->c);
2879 
2880  fwretval->_pointer.native = ret;
2881  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
2882  fwretval->_pointer.gc = 'T';
2883  fwretval->itype = 'P';
2884 
2885  return 1;
2886 }
2887 int X3DMatrix3_multLeft(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2888  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2889  struct SFMatrix3f *lhs = (struct SFMatrix3f *)fwpars[0]._web3dval.native;
2890  struct SFMatrix3f *ret = malloc(sizeof(struct SFMatrix3f));
2891 
2892  matmultiply3f(ret->c, lhs->c , ptr->c);
2893 
2894  fwretval->_pointer.native = ret;
2895  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
2896  fwretval->itype = 'P';
2897  fwretval->_pointer.gc = 'T';
2898  return 1;
2899 }
2900 int X3DMatrix3_multRight(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2901  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2902  struct SFMatrix3f *rhs = (struct SFMatrix3f *)fwpars[0]._web3dval.native;
2903  struct SFMatrix3f *ret = malloc(sizeof(struct SFMatrix3f));
2904  fwretval->_pointer.native = ret;
2905 
2906  matmultiply3f(ret->c, ptr->c, rhs->c);
2907 
2908  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
2909  fwretval->_pointer.gc = 'T';
2910  fwretval->itype = 'P';
2911  return 1;
2912 }
2913 int X3DMatrix3_multVecMatrix(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2914  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2915  struct SFVec2f *rhs = (struct SFVec2f *)fwpars[0]._web3dval.native;
2916  struct SFVec2f *ret = malloc(sizeof(struct SFVec2f));
2917  float a3[3], r3[3];
2918  veccopy2f(a3,rhs->c);
2919  a3[2] = 1.0f;
2920  vecmultmat3f(r3, a3, ptr->c);
2921  if(r3[2] != 0.0f){
2922  float wi = 1.0f/r3[2];
2923  vecscale2f(ret->c,r3,wi);
2924  }else{
2925  veccopy2f(ret->c,r3);
2926  }
2927 
2928  fwretval->_web3dval.native = ret;
2929  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2930  fwretval->_web3dval.gc = 'T';
2931  fwretval->itype = 'W';
2932  return 1;
2933 }
2934 int X3DMatrix3_multMatrixVec(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2935  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2936  struct SFVec2f *rhs = (struct SFVec2f *)fwpars[0]._web3dval.native;
2937  struct SFVec2f *ret = malloc(sizeof(struct SFVec2f));
2938  float a3[3], r3[3];
2939  veccopy2f(a3,rhs->c);
2940  a3[2] = 1.0f;
2941  matmultvec3f(r3, ptr->c,a3);
2942  if(r3[2] != 0.0f){
2943  float wi = 1.0f/r3[2];
2944  vecscale2f(ret->c,r3,wi);
2945  }else{
2946  veccopy2f(ret->c,r3);
2947  }
2948 
2949  fwretval->_web3dval.native = ret;
2950  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2951  fwretval->_web3dval.gc = 'T';
2952  fwretval->itype = 'W';
2953  return 1;
2954 }
2955 
2956 int X3DMatrix3_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2957  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2958  char *str, *r;
2959  int i;
2960  FWType sfvec3ftype = getFWTYPE(FIELDTYPE_SFVec3f);
2961 
2962  str = NULL;
2963  for(i=0;i<3;i++){
2964  r = sfToString(sfvec3ftype,&ptr->c[i*3]);
2965  str = realloc(str,strlen(str)+strlen(r)+2);
2966  str = strcat(str,r);
2967  }
2968  fwretval->_string = str;
2969  fwretval->itype = 'S';
2970  return 1;
2971 }
2972 
2973 FWFunctionSpec (X3DMatrix3_Functions)[] = {
2974  {"setTransform", X3DMatrix3_setTransform, 0,{5,-1,0,"WWWWW"}},
2975  {"getTransform", X3DMatrix3_getTransform, 'P',{1,-1,0,"W"}},
2976  {"inverse", X3DMatrix3_inverse, 'P',{0,-1,0,NULL}},
2977  {"transpose", X3DMatrix3_transpose, 'P',{0,-1,0,NULL}},
2978  {"multLeft", X3DMatrix3_multLeft, 'P',{1,-1,0,"P"}},
2979  {"multRight", X3DMatrix3_multRight, 'P',{1,-1,0,"P"}},
2980  {"multVecMatrix", X3DMatrix3_multVecMatrix, 'W',{1,-1,0,"W"}},
2981  {"multMatrixVec", X3DMatrix3_multMatrixVec, 'W',{1,-1,0,"W"}},
2982  {"toString", X3DMatrix3_toString, 'S',{0,-1,0,NULL}},
2983  {0}
2984 };
2985 
2986 int X3DMatrix3_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2987  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2988  int nr = 0;
2989  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
2990  if(index > -1 && index < 9){
2991  nr = 1;
2992  fwretval->_numeric = ptr->c[index];
2993  }
2994  fwretval->itype = 'F';
2995  return nr;
2996 }
2997 int X3DMatrix3_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
2998  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
2999  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3000  if(index > -1 && index < 9){
3001  if(fwval->itype == 'F'){
3002  ptr->c[index] = (float) fwval->_numeric; //fwval->_web3dval.anyvrml->sffloat;
3003  return TRUE;
3004  }
3005  }
3006  return FALSE;
3007 }
3008 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3009 void * X3DMatrix3_Constructor(FWType fwtype, int ic, FWval fwpars){
3010  int i;
3011  struct SFVec3d *ptr = malloc(fwtype->size_of); //garbage collector please
3012  for(i=0;i<3;i++)
3013  ptr->c[i] = fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
3014  return (void *)ptr;
3015 }
3016 
3017 ArgListType (X3DMatrix3_ConstructorArgs)[] = {
3018  {9,0,'T',"FFFFFFFFF"},
3019  {-1,0,0,NULL},
3020 };
3021 //#define FIELDTYPE_SFMatrix3f 29
3022 FWTYPE X3DMatrix3Type = {
3023  AUXTYPE_X3DMatrix3,
3024  'P',
3025  "X3DMatrix3",
3026  sizeof(struct SFMatrix3f), //sizeof(struct ),
3027  X3DMatrix3_Constructor, //constructor
3028  X3DMatrix3_ConstructorArgs, //constructor args
3029  NULL, //Properties,
3030  NULL, //special iterator
3031  X3DMatrix3_Getter, //Getter,
3032  X3DMatrix3_Setter, //Setter,
3033  'F',0, //index prop type,readonly
3034  X3DMatrix3_Functions, //functions
3035 };
3036 
3037 
3038 /*
3039 Matrix4
3040 http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#Matrix4
3041 "The translation elements are in the fourth row. For example, x3dMatrixObjectName[3][0] is the X offset"
3042 - I assume its a 4x4 homogenous transform matrix
3043 [x'] [x y z 1] X [ scale px] where px,py,pz are perspectives ie pz = 1/focal-length
3044 [y'] = [ and py]
3045 [z'] [ rot pz]
3046 [w ] [tx ty tz 1] and tx,ty,tz are translations
3047 x" = x'/w
3048 y" = y'/w
3049 z" = z'/w
3050 
3051 constr
3052 X3DMatrix4 (numeric f11, numeric f12, numeric f13, numeric f14,
3053  numeric f21, numeric f22, numeric f23, numeric f24,
3054  numeric f31, numeric f32, numeric f33, numeric f34,
3055  numeric f41, numeric f42, numeric f43, numeric f44) The creation function shall initialize the array using zero or more SFVec3-valued expressions passed as parameters.
3056 props
3057 array-style indexing row-major order
3058 funcs
3059 void setTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale, SFRotation scaleOrientation, SFVec3f center)
3060  Sets the Matrix to the passed values. Any of the rightmost parameters may be omitted. The function has zero to five parameters. For example, specifying zero parameters results in an identity matrix while specifying one parameter results in a translation and specifying two parameters results in a translation and a rotation. Any unspecified parameter is set to its default as specified for the Transform node. Values are applied to the matrix in the same order as the matrix field calculations for the Transform node.
3061 void getTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale)
3062  Decomposes the Matrix and returns the components in the passed translation, rotation, and scale objects. The types of these passed objects is the same as the first three arguments to setTransform. If any passed object is not sent, or if the null object is sent for any value, that value is not returned. Any projection or shear information in the matrix is ignored.
3063 Matrix4 inverse() Returns a Matrix whose value is the inverse of this object.
3064 Matrix4 transpose() Returns a Matrix whose value is the transpose of this object.
3065 Matrix4 multLeft(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the left.
3066 Matrix4 multRight(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the right.
3067 SFVec3f multVecMatrix(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed row vector.
3068 SFVec3f multMatrixVec(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed column vector.
3069 String toString() Returns a String containing the matrix contents encoded using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
3070 
3071 */
3072 
3073 int X3DMatrix4_setTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3074  //void setTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale, SFRotation scaleOrientation, SFVec3f center)
3075  // http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/group.html#Transform
3076  // P' = T * C * R * SR * S * -SR * -C * P
3077  int i;// , j;
3078  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3079  struct SFVec3f *translation = fwpars[0]._web3dval.native;
3080  struct SFRotation *rotation = fwpars[1]._web3dval.native;
3081  struct SFVec3f *scale = fwpars[2]._web3dval.native;
3082  struct SFRotation *scaleOrientation = fwpars[3]._web3dval.native;
3083  struct SFVec3f *center = fwpars[4]._web3dval.native;
3084  //set up some [][] helpers for clarity
3085  float *matrix[4], *mat[4], m2[16];
3086  for(i=0;i<4;i++){
3087  matrix[i] = &ptr->c[i*4]; //our current matrix3
3088  mat[i] = &m2[i*4]; //scratch matrix
3089  }
3090  //initialize to Identity
3091  matidentity4f(matrix[0]);
3092  //-C
3093  if(center){
3094  matidentity4f(mat[0]);
3095  veccopy3f(mat[3],center->c);
3096  vecscale3f(mat[3],mat[3],-1.0f);
3097  matmultiply4f(matrix[0],mat[0],matrix[0]);
3098  }
3099  //-SR
3100  if(scaleOrientation){
3101  scaleOrientation->c[3] = -scaleOrientation->c[3];
3102  matidentity4f(mat[0]);
3103  for(i=0;i<3;i++)
3104  axisangle_rotate3f(mat[i], mat[i], scaleOrientation->c);
3105  matmultiply4f(matrix[0],mat[0],matrix[0]);
3106  scaleOrientation->c[3] = -scaleOrientation->c[3];
3107  }
3108  //S
3109  if(scale){
3110  matidentity4f(mat[0]);
3111  for(i=0;i<4;i++)
3112  vecmult3f(mat[i],mat[i],scale->c);
3113  matmultiply4f(matrix[0],mat[0],matrix[0]);
3114  }
3115  //SR
3116  if(scaleOrientation){
3117  matidentity4f(mat[0]);
3118  for(i=0;i<3;i++)
3119  axisangle_rotate3f(mat[i], mat[i], scaleOrientation->c);
3120  matmultiply4f(matrix[0],mat[0],matrix[0]);
3121  }
3122  //R
3123  if(rotation){
3124  matidentity4f(mat[0]);
3125  for(i=0;i<3;i++)
3126  axisangle_rotate3f(mat[i], mat[i], rotation->c);
3127  matmultiply4f(matrix[0],mat[0],matrix[0]);
3128 
3129  }
3130  //C
3131  if(center){
3132  matidentity4f(mat[0]);
3133  veccopy3f(mat[3],center->c);
3134  matmultiply4f(matrix[0],mat[0],matrix[0]);
3135  }
3136  //T
3137  if(translation){
3138  matidentity4f(mat[0]);
3139  veccopy3f(mat[3],translation->c);
3140  matmultiply4f(matrix[0],mat[0],matrix[0]);
3141  }
3142 
3143  return 0;
3144 }
3145 
3146 int X3DMatrix4_getTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3147  //void getTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale)
3148  int i;
3149  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3150  struct SFVec3f *translation = fwpars[0]._web3dval.native;
3151  struct SFRotation *rotation = fwpars[1]._web3dval.native;
3152  struct SFVec3f *scale = fwpars[2]._web3dval.native;
3153  float *matrix[4], retscale[3];
3154  double matrixd[16];
3155  Quaternion quat;
3156  double qu[4];
3157  //double r0[4], r1[4], r2[4];
3158  for(i=0;i<4;i++)
3159  matrix[i] = &ptr->c[i*4];
3160 
3161  //get row scales
3162  for(i=0;i<3;i++)
3163  retscale[i] = (float)sqrt(vecdot4f(matrix[i],matrix[i]));
3164 
3165  if (translation) {
3166  veccopy3f(translation->c,matrix[3]);
3167  }
3168 
3169  /* rotation */
3170  if (rotation) {
3171  /* apply length to each row to normalize upperleft 3x3 to rotations and shears*/
3172  float m2[16], ff;
3173  for(i=0;i<3;i++){
3174  ff = retscale[i];
3175  if(ff != 0.0f) ff = 1/ff;
3176  vecscale4f(&m2[i*4],matrix[i],ff);
3177  }
3178  /* convert the matrix to a quaternion */
3179  for(i=0;i<16;i++) matrixd[i] = (double) m2[i];
3180  matrix_to_quaternion (&quat, matrixd);
3181  #ifdef JSVRMLCLASSESVERBOSE
3182  printf ("quaternion %f %f %f %f\n",quat.x,quat.y,quat.z,quat.w);
3183  #endif
3184 
3185  /* convert the quaternion to a VRML rotation */
3186  quaternion_to_vrmlrot(&quat, &qu[0],&qu[1],&qu[2],&qu[3]);
3187 
3188  /* now copy the values over */
3189  for (i=0; i<4; i++)
3190  rotation->c[i] = (float) qu[i];
3191  }
3192 
3193  /* scale */
3194  if (scale) {
3195  veccopy3f(scale->c,retscale);
3196  }
3197 
3198  return 0;
3199 }
3200 
3201 int X3DMatrix4_inverse(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3202  //Matrix4 inverse()
3203  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3204  struct SFMatrix4f *ret = malloc(sizeof(struct SFMatrix4f));
3205 
3206  matinverse4f(ret->c,ptr->c);
3207 
3208  fwretval->_pointer.native = ret;
3209  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3210  fwretval->_pointer.gc = 'T';
3211  fwretval->itype = 'P';
3212  return 1;
3213 }
3214 int X3DMatrix4_transpose(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3215  //Matrix4 transpose() Returns a Matrix whose value is the transpose of this object.
3216  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3217  struct SFMatrix4f *ret = malloc(sizeof(struct SFMatrix4f));
3218 
3219  mattranspose4f(ret->c, ptr->c);
3220 
3221  fwretval->_pointer.native = ret;
3222  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3223  fwretval->_pointer.gc = 'T';
3224  fwretval->itype = 'P';
3225 
3226  return 1;
3227 }
3228 int X3DMatrix4_multLeft(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3229  //Matrix4 multLeft(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the left.
3230 
3231  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3232  struct SFMatrix4f *rhs = (struct SFMatrix4f *)fwpars[0]._web3dval.native;
3233  struct SFMatrix4f *ret = malloc(sizeof(struct SFMatrix4f));
3234 
3235  matmultiply4f(ptr->c,rhs->c,ptr->c);
3236 
3237  fwretval->_pointer.native = ret;
3238  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3239  fwretval->_pointer.gc = 'T';
3240  fwretval->itype = 'P';
3241  return 1;
3242 }
3243 int X3DMatrix4_multRight(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3244  //Matrix4 multRight(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the right.
3245  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3246  struct SFMatrix4f *rhs = (struct SFMatrix4f *)fwpars[0]._web3dval.native;
3247  struct SFMatrix4f *ret = malloc(sizeof(struct SFMatrix4f));
3248  fwretval->_pointer.native = ret;
3249 
3250  matmultiply4f(ptr->c,ptr->c,rhs->c);
3251 
3252  fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3253  fwretval->_pointer.gc = 'T';
3254  fwretval->itype = 'P';
3255  return 1;
3256 }
3257 int X3DMatrix4_multVecMatrix(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3258  //SFVec3f multVecMatrix(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed row vector.
3259  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3260  struct SFVec3f *rhs = (struct SFVec3f *)fwpars[0]._web3dval.native;
3261  struct SFVec3f *ret = malloc(sizeof(struct SFVec3f));
3262  float a4[4], r4[4];
3263  veccopy3f(a4,rhs->c);
3264  a4[3] = 1.0f;
3265  vecmultmat4f(r4, a4, ptr->c);
3266  if(r4[3] != 0.0f){
3267  float wi = 1.0f/r4[3];
3268  vecscale3f(ret->c,r4,wi);
3269  }else{
3270  veccopy3f(ret->c,r4);
3271  }
3272 
3273  fwretval->_web3dval.native = ret;
3274  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
3275  fwretval->_web3dval.gc = 'T';
3276  fwretval->itype = 'W';
3277  return 1;
3278 }
3279 int X3DMatrix4_multMatrixVec(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3280  //SFVec3f multMatrixVec(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed column vector.
3281  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3282  struct SFVec3f *rhs = (struct SFVec3f *)fwpars[0]._web3dval.native;
3283  struct SFVec3f *ret = malloc(sizeof(struct SFVec3f));
3284 //float* matmultvec4f(float* r4, float *mat4, float* a4 );
3285  float a4[4], r4[4];
3286  veccopy3f(a4,rhs->c);
3287  a4[3] = 1.0f;
3288  matmultvec4f(r4, ptr->c, a4 );
3289  if(r4[3] != 0.0f){
3290  float wi = 1.0f/r4[3];
3291  vecscale3f(ret->c,r4,wi);
3292  }else{
3293  veccopy3f(ret->c,r4);
3294  }
3295 
3296  fwretval->_web3dval.native = ret;
3297  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3f;
3298  fwretval->_web3dval.gc = 'T';
3299  fwretval->itype = 'W';
3300  return 1;
3301 }
3302 
3303 int X3DMatrix4_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3304  struct SFMatrix4f *ptr = (struct SFMatrix4f *)fwn;
3305  char *str, *r;
3306  int i;
3307  FWType sfvec4ftype = getFWTYPE(FIELDTYPE_SFVec4f);
3308 
3309  str = NULL;
3310  for(i=0;i<4;i++){
3311  r = sfToString(sfvec4ftype,&ptr->c[i*4]);
3312  str = realloc(str,strlen(str)+strlen(r)+2);
3313  str = strcat(str,r);
3314  }
3315  fwretval->_string = str;
3316  fwretval->itype = 'S';
3317  return 1;
3318 }
3319 
3320 
3321 FWFunctionSpec (X3DMatrix4_Functions)[] = {
3322  {"setTransform", X3DMatrix4_setTransform, 0,{5,-1,0,"WWWWW"}},
3323  {"getTransform", X3DMatrix4_getTransform, 'P',{1,-1,0,"W"}},
3324  {"inverse", X3DMatrix4_inverse, 'P',{0,-1,0,NULL}},
3325  {"transpose", X3DMatrix4_transpose, 'P',{0,-1,0,NULL}},
3326  {"multLeft", X3DMatrix4_multLeft, 'P',{1,-1,0,"P"}},
3327  {"multRight", X3DMatrix4_multRight, 'P',{1,-1,0,"P"}},
3328  {"multVecMatrix", X3DMatrix4_multVecMatrix, 'W',{1,-1,0,"W"}},
3329  {"multMatrixVec", X3DMatrix4_multMatrixVec, 'W',{1,-1,0,"W"}},
3330  {"toString", X3DMatrix4_toString, 'S',{0,-1,0,NULL}},
3331  {0}
3332 };
3333 
3334 int X3DMatrix4_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
3335  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
3336  int nr = 0;
3337  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3338  if(index > -1 && index < 9){
3339  nr = 1;
3340  fwretval->_numeric = ptr->c[index];
3341  }
3342  fwretval->itype = 'F';
3343  return nr;
3344 }
3345 int X3DMatrix4_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
3346  struct SFMatrix3f *ptr = (struct SFMatrix3f *)fwn;
3347  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3348  if(index > -1 && index < 9){
3349  if(fwval->itype == 'F'){
3350  ptr->c[index] = (float)fwval->_numeric; //fwval->_web3dval.anyvrml->sffloat;
3351  return TRUE;
3352  }
3353  }
3354  return FALSE;
3355 }
3356 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3357 void * X3DMatrix4_Constructor(FWType fwtype, int ic, FWval fwpars){
3358  int i;
3359  struct SFVec3d *ptr = malloc(fwtype->size_of); //garbage collector please
3360  for(i=0;i<3;i++)
3361  ptr->c[i] = fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
3362  return (void *)ptr;
3363 }
3364 
3365 ArgListType (X3DMatrix4_ConstructorArgs)[] = {
3366  {9,0,'T',"FFFFFFFFF"},
3367  {-1,0,0,NULL},
3368 };
3369 
3370 FWTYPE X3DMatrix4Type = {
3371  AUXTYPE_X3DMatrix4,
3372  'P',
3373  "X3DMatrix4",
3374  sizeof(struct SFMatrix3f), //sizeof(struct ),
3375  X3DMatrix4_Constructor, //constructor
3376  X3DMatrix4_ConstructorArgs, //constructor args
3377  NULL, //Properties,
3378  NULL, //special iterator
3379  X3DMatrix4_Getter, //Getter,
3380  X3DMatrix4_Setter, //Setter,
3381  'F',0, //index prop type,readonly
3382  X3DMatrix4_Functions, //functions
3383 };
3384 
3385 
3386 // http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#SFVec2d
3387 /* SFVec2d
3388 Constructor
3389 SFVec2d (numeric x, numeric y) Missing values default to 0.0d+00.
3390 props
3391 numeric x No First value of the vector
3392 numeric y No Second value of the vector
3393 funcs
3394 SFVec2d add(SFVec2d vec) Returns the value of the passed value added, component-wise, to the object.
3395 SFVec2d divide(numeric n) Returns the value of the object divided by the passed value.
3396 numeric dot(SFVec2d vec) Returns the dot product of this vector and the passed value.
3397 numeric length() Returns the geometric length of this vector.
3398 SFVec2d multiply(numeric n) Returns the value of the object multiplied by the passed value.
3399 SFVec2d normalize() Returns the object converted to unit length .
3400 SFVec2d subtract(SFVec2d vec) Returns the value of the passed value subtracted, component-wise, from the object.
3401 String toString() Returns a String containing the value of x and y encoding using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
3402 */
3403 
3404 int SFVec2d_add(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3405  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3406  struct SFVec2d *rhs = fwpars[0]._web3dval.native;
3407  struct SFVec2d *res = malloc(fwtype->size_of);
3408  vecadd2d(res->c,ptr->c,rhs->c);
3409  fwretval->_web3dval.native = res;
3410  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3411  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
3412  fwretval->itype = 'W';
3413  return 1;
3414 }
3415 int SFVec2d_subtract(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3416  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3417  struct SFVec2d *rhs = fwpars[0]._web3dval.native;
3418  struct SFVec2d *res = malloc(fwtype->size_of);
3419  vecdif2d(res->c,ptr->c,rhs->c);
3420  fwretval->_web3dval.native = res;
3421  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3422  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
3423  fwretval->itype = 'W';
3424  return 1;
3425 }
3426 int SFVec2d_divide(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3427  struct SFVec2d *res;
3428  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3429  double rhs = fwpars[0]._numeric;
3430  if(rhs == 0.0){
3431  return 0;
3432  }
3433  rhs = 1.0/rhs;
3434  res = malloc(fwtype->size_of);
3435  vecscale2d(res->c,ptr->c,rhs);
3436  fwretval->_web3dval.native = res;
3437  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3438  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
3439  fwretval->itype = 'W';
3440  return 1;
3441 }
3442 int SFVec2d_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3443  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3444  double rhs = fwpars[0]._numeric;
3445  struct SFVec2d *res = malloc(fwtype->size_of);
3446  vecscale2d(res->c,ptr->c,rhs);
3447  fwretval->_web3dval.native = res;
3448  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3449  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
3450  fwretval->itype = 'W';
3451  return 1;
3452 }
3453 int SFVec2d_normalize(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3454  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3455  struct SFVec2d *res = malloc(fwtype->size_of);
3456  vecnormal2d(res->c,ptr->c);
3457  fwretval->_web3dval.native = res;
3458  fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3459  fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
3460  fwretval->itype = 'W';
3461  return 1;
3462 }
3463 
3464 int SFVec2d_length(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3465  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3466  double res;
3467  res = veclength2d(ptr->c);
3468  fwretval->_numeric = res;
3469  fwretval->itype = 'D';
3470  return 1;
3471 }
3472 int SFVec2d_dot(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3473  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3474  struct SFVec2d *rhs = fwpars[0]._web3dval.native;
3475  double res;
3476  res = vecdot2d(ptr->c,rhs->c);
3477  fwretval->_numeric = res;
3478  fwretval->itype = 'D';
3479  return 1;
3480 }
3481 int SFVec2d_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3482  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3483  char buff[STRING], *str;
3484  int len;
3485  memset(buff, 0, STRING);
3486  sprintf(buff, "%.9g %.9g",
3487  ptr->c[0], ptr->c[1]);
3488  len = strlen(buff);
3489  str = malloc(len+1); //leak
3490  strcpy(str,buff);
3491  fwretval->_string = str;
3492  fwretval->itype = 'S';
3493  return 1;
3494 }
3495 FWFunctionSpec (SFVec2d_Functions)[] = {
3496  {"add", SFVec2d_add, 'W',{1,-1,0,"W"}},
3497  {"divide", SFVec2d_divide, 'W',{1,-1,0,"D"}},
3498  {"dot", SFVec2d_dot, 'D',{1,-1,0,"W"}},
3499  {"length", SFVec2d_length, 'D',{0,-1,0,NULL}},
3500  {"multiply", SFVec2d_multiply, 'W',{1,-1,0,"D"}},
3501  {"normalize", SFVec2d_normalize, 'W',{0,-1,0,NULL}},
3502  {"subtract", SFVec2d_subtract, 'W',{1,-1,0,"W"}},
3503  {"toString", SFVec2d_toString, 'S',{0,-1,0,NULL}},
3504  {0}
3505 };
3506 
3507 int SFVec2d_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
3508  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3509  int nr = 0;
3510  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3511  if(index > -1 && index < 2){
3512  nr = 1;
3513  switch(index){
3514  case 0: //x
3515  case 1: //y
3516  fwretval->_numeric = ptr->c[index];
3517  break;
3518  default:
3519  nr = 0;
3520  }
3521  }
3522  fwretval->itype = 'D';
3523  return nr;
3524 }
3525 int SFVec2d_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
3526  struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3527  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3528  if(index > -1 && index < 2){
3529  switch(index){
3530  case 0: //x
3531  case 1: //y
3532  ptr->c[index] = fwval->_numeric;
3533  break;
3534  }
3535  return TRUE;
3536  }
3537  return FALSE;
3538 }
3539 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3540 void * SFVec2d_Constructor(FWType fwtype, int ic, FWval fwpars){
3541  int i;
3542  struct SFVec2d *ptr = malloc(fwtype->size_of); //garbage collector please
3543  memset(ptr,0,fwtype->size_of);
3544  if(ic == 2){
3545  for(i=0;i<2;i++)
3546  ptr->c[i] = fwpars[i]._numeric;
3547  }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
3548  //new SFxxx(myMF[i]);
3549  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
3550  }
3551 
3552  return (void *)ptr;
3553 }
3554 
3555 FWPropertySpec (SFVec2d_Properties)[] = {
3556  {"x", 0, 'D', 0},
3557  {"y", 1, 'D', 0},
3558  {NULL,0,0,0},
3559 };
3560 ArgListType (SFVec2d_ConstructorArgs)[] = {
3561  {2,0,'T',"DD"},
3562  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
3563  {-1,0,0,NULL},
3564 };
3565 
3566 //#define FIELDTYPE_SFVec2d 37
3567 FWTYPE SFVec2dType = {
3568  FIELDTYPE_SFVec2d,
3569  'W',
3570  "SFVec2d",
3571  sizeof(struct SFVec2d), //sizeof(struct ),
3572  SFVec2d_Constructor, //constructor
3573  SFVec2d_ConstructorArgs, //constructor args
3574  SFVec2d_Properties, //Properties,
3575  NULL, //special iterator
3576  SFVec2d_Getter, //Getter,
3577  SFVec2d_Setter, //Setter,
3578  'D',0, //index prop type,readonly
3579  SFVec2d_Functions, //functions
3580 };
3581 
3582 //#define FIELDTYPE_MFVec2d 38
3583 FWTYPE MFVec2dType = {
3584  FIELDTYPE_MFVec2d,
3585  'W',
3586  "MFVec2d",
3587  sizeof(struct Multi_Any), //sizeof(struct ),
3588  MFW_Constructor, //constructor
3589  MFW_ConstructorArgs, //constructor args
3590  MFW_Properties, //Properties,
3591  NULL, //special iterator
3592  MFW_Getter, //Getter,
3593  MFW_Setter, //Setter,
3594  'W',0, //index prop type,readonly
3595  MFW_Functions, //functions
3596 };
3597 
3598 int SFVec4f_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3599  struct SFVec4f *ptr = (struct SFVec4f *)fwn;
3600  char buff[STRING], *str;
3601  int len;
3602  memset(buff, 0, STRING);
3603  sprintf(buff, "%.9g %.9g %.9g %.9g",
3604  ptr->c[0], ptr->c[1], ptr->c[2], ptr->c[3]);
3605  len = strlen(buff);
3606  str = malloc(len+1); //leak
3607  strcpy(str,buff);
3608  fwretval->_string = str;
3609  fwretval->itype = 'S';
3610  return 1;
3611 }
3612 
3613 FWFunctionSpec (SFVec4f_Functions)[] = {
3614  {"toString", SFVec4f_toString, 'S',{0,-1,0,NULL}},
3615  {0}
3616 };
3617 
3618 int SFVec4f_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
3619  struct SFVec4f *ptr = (struct SFVec4f *)fwn;
3620  int nr = 0;
3621  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3622  if(index > -1 && index < 4){
3623  nr = 1;
3624  switch(index){
3625  case 0: //x
3626  case 1: //y
3627  case 2: //z
3628  case 3: //t
3629  fwretval->_numeric = ptr->c[index];
3630  break;
3631  default:
3632  nr = 0;
3633  }
3634  }
3635  fwretval->itype = 'F';
3636  return nr;
3637 }
3638 int SFVec4f_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
3639  struct SFVec4f *ptr = (struct SFVec4f *)fwn;
3640  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3641  if(index > -1 && index < 4){
3642  switch(index){
3643  case 0: //x
3644  case 1: //y
3645  case 2: //z
3646  case 3: //t
3647  ptr->c[index] = (float)fwval->_numeric;
3648  break;
3649  }
3650  return TRUE;
3651  }
3652  return FALSE;
3653 }
3654 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3655 void * SFVec4f_Constructor(FWType fwtype, int ic, FWval fwpars){
3656  int i;
3657  struct SFVec4f *ptr = malloc(fwtype->size_of); //garbage collector please
3658  if(ic == 4){
3659  for(i=0;i<4;i++)
3660  ptr->c[i] = (float)fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
3661  }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
3662  //new SFxxx(myMF[i]);
3663  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
3664  }
3665 
3666  return (void *)ptr;
3667 }
3668 
3669 FWPropertySpec (SFVec4f_Properties)[] = {
3670  {"x", 0, 'F', 0},
3671  {"y", 1, 'F', 0},
3672  {"z", 2, 'F', 0},
3673  {"w", 3, 'F', 0},
3674  {NULL,0,0,0},
3675 };
3676 ArgListType (SFVec4f_ConstructorArgs)[] = {
3677  {4,0,'T',"FFFF"},
3678  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
3679  {-1,0,0,NULL},
3680 };
3681 
3682 
3683 //#define FIELDTYPE_SFVec4f 39
3684 FWTYPE SFVec4fType = {
3685  FIELDTYPE_SFVec4f,
3686  'W',
3687  "SFVec4f",
3688  sizeof(struct SFVec4f), //sizeof(struct ),
3689  SFVec4f_Constructor, //constructor
3690  SFVec4f_ConstructorArgs, //constructor args
3691  SFVec4f_Properties, //Properties,
3692  NULL, //special iterator
3693  SFVec4f_Getter, //Getter,
3694  SFVec4f_Setter, //Setter,
3695  'F',0, //index prop type,readonly
3696  SFVec4f_Functions, //functions
3697 };
3698 
3699 //#define FIELDTYPE_MFVec4f 40
3700 FWTYPE MFVec4fType = {
3701  FIELDTYPE_MFVec4f,
3702  'W',
3703  "MFVec4f",
3704  sizeof(struct Multi_Any), //sizeof(struct ),
3705  MFW_Constructor, //constructor
3706  MFW_ConstructorArgs, //constructor args
3707  MFW_Properties, //Properties,
3708  NULL, //special iterator
3709  MFW_Getter, //Getter,
3710  MFW_Setter, //Setter,
3711  'W',0, //index prop type,readonly
3712  MFW_Functions, //functions
3713 };
3714 
3715 int SFVec4d_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3716  struct SFVec4d *ptr = (struct SFVec4d *)fwn;
3717  char buff[STRING], *str;
3718  int len;
3719  memset(buff, 0, STRING);
3720  sprintf(buff, "%.9g %.9g %.9g %.9g",
3721  ptr->c[0], ptr->c[1], ptr->c[2], ptr->c[3]);
3722  len = strlen(buff);
3723  str = malloc(len+1); //leak
3724  strcpy(str,buff);
3725  fwretval->_string = str;
3726  fwretval->itype = 'S';
3727  return 1;
3728 }
3729 FWFunctionSpec (SFVec4d_Functions)[] = {
3730  {"toString", SFVec4d_toString, 'S',{0,-1,0,NULL}},
3731  {0}
3732 };
3733 
3734 int SFVec4d_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
3735  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
3736  int nr = 0;
3737  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3738  if(index > -1 && index < 4){
3739  nr = 1;
3740  switch(index){
3741  case 0: //x
3742  case 1: //y
3743  case 2: //z
3744  case 3: //t
3745  fwretval->_numeric = ptr->c[index];
3746  break;
3747  default:
3748  nr = 0;
3749  }
3750  }
3751  fwretval->itype = 'D';
3752  return nr;
3753 }
3754 int SFVec4d_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
3755  struct SFVec3d *ptr = (struct SFVec3d *)fwn;
3756  //fwretval->itype = 'S'; //0 = null, N=numeric I=Integer B=Boolean S=String, W=Object-web3d O-js Object P=ptr F=flexiString(SFString,MFString[0] or ecmaString)
3757  if(index > -1 && index < 4){
3758  switch(index){
3759  case 0: //x
3760  case 1: //y
3761  case 2: //z
3762  case 3: //t
3763  ptr->c[index] = fwval->_numeric; ;
3764  break;
3765  }
3766  return TRUE;
3767  }
3768  return FALSE;
3769 }
3770 //typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3771 void * SFVec4d_Constructor(FWType fwtype, int ic, FWval fwpars){
3772  int i;
3773  struct SFVec3d *ptr = malloc(fwtype->size_of); //garbage collector please
3774  memset(ptr,0,fwtype->size_of);
3775  if(ic == 4){
3776  for(i=0;i<4;i++)
3777  ptr->c[i] = fwpars[i]._numeric;
3778  }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
3779  //new SFxxx(myMF[i]);
3780  shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
3781  }
3782 
3783  return (void *)ptr;
3784 }
3785 
3786 FWPropertySpec (SFVec4d_Properties)[] = {
3787  {"x", 0, 'D', 0},
3788  {"y", 1, 'D', 0},
3789  {"z", 2, 'D', 0},
3790  {"w", 3, 'D', 0},
3791  {NULL,0,0,0},
3792 };
3793 ArgListType (SFVec4d_ConstructorArgs)[] = {
3794  {3,0,'T',"DDDD"},
3795  {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
3796  {-1,0,0,NULL},
3797 };
3798 //#define FIELDTYPE_SFVec4d 41
3799 FWTYPE SFVec4dType = {
3800  FIELDTYPE_SFVec4d,
3801  'W',
3802  "SFVec4d",
3803  sizeof(struct SFVec4d), //sizeof(struct ),
3804  SFVec4d_Constructor, //constructor
3805  SFVec4d_ConstructorArgs, //constructor args
3806  SFVec4d_Properties, //Properties,
3807  NULL, //special iterator
3808  SFVec4d_Getter, //Getter,
3809  SFVec4d_Setter, //Setter,
3810  'D',0, //index prop type,readonly
3811  SFVec4d_Functions, //functions
3812 };
3813 
3814 //#define FIELDTYPE_MFVec4d 42
3815 FWTYPE MFVec4dType = {
3816  FIELDTYPE_MFVec4d,
3817  'W',
3818  "MFVec4d",
3819  sizeof(struct Multi_Any), //sizeof(struct ),
3820  MFW_Constructor, //constructor
3821  MFW_ConstructorArgs, //constructor args
3822  MFW_Properties, //Properties,
3823  NULL, //special iterator
3824  MFW_Getter, //Getter,
3825  MFW_Setter, //Setter,
3826  'W',0, //index prop type,readonly
3827  MFW_Functions, //functions
3828 };
3829 
3830 void initVRMLFields(FWTYPE** typeArray, int *n){
3831  typeArray[*n] = &SFFloatType; (*n)++;
3832  typeArray[*n] = &MFFloatType; (*n)++;
3833  typeArray[*n] = &SFRotationType; (*n)++;
3834  typeArray[*n] = &MFRotationType; (*n)++;
3835  typeArray[*n] = &SFVec3fType; (*n)++;
3836  typeArray[*n] = &MFVec3fType; (*n)++;
3837  typeArray[*n] = &SFBoolType; (*n)++;
3838  typeArray[*n] = &MFBoolType; (*n)++;
3839  typeArray[*n] = &SFInt32Type; (*n)++;
3840  typeArray[*n] = &MFInt32Type; (*n)++;
3841  typeArray[*n] = &SFNodeType; (*n)++;
3842  typeArray[*n] = &MFNodeType; (*n)++;
3843  typeArray[*n] = &SFColorType; (*n)++;
3844  typeArray[*n] = &MFColorType; (*n)++;
3845  typeArray[*n] = &SFColorRGBAType; (*n)++;
3846  typeArray[*n] = &MFColorRGBAType; (*n)++;
3847  typeArray[*n] = &SFTimeType; (*n)++;
3848  typeArray[*n] = &MFTimeType; (*n)++;
3849  typeArray[*n] = &SFStringType; (*n)++;
3850  typeArray[*n] = &MFStringType; (*n)++;
3851  typeArray[*n] = &SFVec2fType; (*n)++;
3852  typeArray[*n] = &MFVec2fType; (*n)++;
3853  typeArray[*n] = &SFImageType; (*n)++;
3854  //typeArray[*n] = &FreeWRLPTRType; (*n)++;
3855  //typeArray[*n] = &FreeWRLThreadType; (*n)++;
3856  typeArray[*n] = &SFVec3dType; (*n)++;
3857  typeArray[*n] = &MFVec3dType; (*n)++;
3858  typeArray[*n] = &SFDoubleType; (*n)++;
3859  typeArray[*n] = &MFDoubleType; (*n)++;
3860  //typeArray[*n] = &SFMatrix3fType; (*n)++;
3861  //typeArray[*n] = &MFMatrix3fType; (*n)++;
3862  //typeArray[*n] = &SFMatrix3dType; (*n)++;
3863  //typeArray[*n] = &MFMatrix3dType; (*n)++;
3864  //typeArray[*n] = &SFMatrix4fType; (*n)++;
3865  //typeArray[*n] = &MFMatrix4fType; (*n)++;
3866  //typeArray[*n] = &SFMatrix4dType; (*n)++;
3867  //typeArray[*n] = &MFMatrix4dType; (*n)++;
3868  typeArray[*n] = &X3DMatrix3Type; (*n)++;
3869  typeArray[*n] = &X3DMatrix4Type; (*n)++;
3870  typeArray[*n] = &SFVec2dType; (*n)++;
3871  typeArray[*n] = &MFVec2dType; (*n)++;
3872  typeArray[*n] = &SFVec4fType; (*n)++;
3873  typeArray[*n] = &MFVec4fType; (*n)++;
3874  typeArray[*n] = &SFVec4dType; (*n)++;
3875  typeArray[*n] = &MFVec4dType; (*n)++;
3876 }
3877 
3878 #endif /* ifdef JAVASCRIPT_DUK */
Definition: FWTYPE.h:64
Definition: FWTYPE.h:112