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