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 > -1){
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}
1212
1213
1214
1215int type_dimension(int itype) {
1216 //checks vector and matrix types for number of values
1217 int ndim = 0;
1218 switch (itype) {
1219 case FIELDTYPE_MFDouble:
1220 case FIELDTYPE_MFFloat: ndim = -1; break; //you;ll have to check
1221 case FIELDTYPE_SFVec2f:
1222 case FIELDTYPE_SFVec2d: ndim = 2; break;
1223 case FIELDTYPE_SFVec3f:
1224 case FIELDTYPE_SFVec3d: ndim = 3; break;
1225 case FIELDTYPE_SFRotation:
1226 case FIELDTYPE_SFVec4f:
1227 case FIELDTYPE_SFVec4d: ndim = 4; break;
1228 case FIELDTYPE_SFMatrix3f:
1229 case FIELDTYPE_SFMatrix3d:
1230 case AUXTYPE_X3DMatrix3: ndim = 9; break;
1231 case FIELDTYPE_SFMatrix4f:
1232 case FIELDTYPE_SFMatrix4d:
1233 case AUXTYPE_X3DMatrix4:
1234 case AUXTYPE_VrmlMatrix:ndim = 16; break;
1235 }
1236 return ndim;
1237}
1238int type_precision(int itype) {
1239 //checks the numeric precision of the type 1=float 2=double
1240 int ipre = 0; //1 float 2 double
1241 switch (itype) {
1242 case FIELDTYPE_SFFloat:
1243 case FIELDTYPE_MFFloat:
1244 case FIELDTYPE_SFVec2f:
1245 case FIELDTYPE_SFVec3f:
1246 case FIELDTYPE_SFVec4f:
1247 case FIELDTYPE_SFRotation:
1248 case FIELDTYPE_SFMatrix3f:
1249 case FIELDTYPE_SFMatrix4f:ipre = 1; break;
1250
1251 case FIELDTYPE_SFDouble:
1252 case FIELDTYPE_MFDouble:
1253 case FIELDTYPE_SFTime:
1254 case FIELDTYPE_SFVec2d:
1255 case FIELDTYPE_SFVec3d:
1256 case FIELDTYPE_SFVec4d:
1257 case FIELDTYPE_SFMatrix3d:
1258 case FIELDTYPE_SFMatrix4d:
1259 case AUXTYPE_X3DMatrix3:
1260 case AUXTYPE_X3DMatrix4:
1261 case AUXTYPE_VrmlMatrix:
1262 ipre = 2; break;
1263 }
1264 return ipre;
1265
1266}
1267int sizeofSForMFduk(int itype) {
1268 int iz = 0;
1269 switch(itype){
1270 case AUXTYPE_X3DMatrix3: iz = sizeof(struct SFMatrix3d); break;
1271 case AUXTYPE_X3DMatrix4: iz = sizeof(struct SFMatrix4d); break;
1272 case AUXTYPE_VrmlMatrix: iz = sizeof(struct SFMatrix4d); break;
1273 default:
1274 iz = sizeofSForMF(itype);
1275 }
1276 return iz;
1277}
1278
1279void deleteMallocedFieldValue(int type,union anyVrml *fieldPtr);
1280
1281void shallow_copy_field_precision(int sourcetypeIndex, int desttypeIndex, union anyVrml* source, union anyVrml* dest)
1282{
1283 int i, src_isize, dst_isize;
1284 int src_sftype, src_isMF, dst_sftype, dst_isMF;
1285 struct Multi_Node* mfs, * mfd;
1286
1287 src_isMF = sourcetypeIndex % 2;
1288 src_sftype = sourcetypeIndex - src_isMF;
1289 dst_isMF = desttypeIndex % 2;
1290 dst_sftype = desttypeIndex - dst_isMF;
1291
1292 //from EAI_C_CommonFunctions.c
1293 //isize = returnElementLength(sftype) * returnElementRowSize(sftype);
1294 src_isize = sizeofSForMFduk(src_sftype);
1295 dst_isize = sizeofSForMFduk(dst_sftype);
1296
1297 if (dst_isMF && src_isMF)
1298 {
1299 int nele;
1300 char* ps, * pd;
1301 mfs = (struct Multi_Node*)source;
1302 mfd = (struct Multi_Node*)dest;
1303 //self assignment is no-op
1304 if (mfs->p != mfd->p) {
1305 //we need to malloc and do more copying
1306 deleteMallocedFieldValue(desttypeIndex, dest);
1307 nele = mfs->n;
1308 if (src_sftype == FIELDTYPE_SFNode) nele = (int)upper_power_of_two(nele);
1309 if (!nele) {
1310 mfd->p = NULL;
1311 mfd->n = 0;
1312 }
1313 else {
1314 mfd->p = MALLOC(struct X3D_Node**, dst_isize * nele);
1315 bzero(mfd->p, dst_isize * nele);
1316 mfd->n = mfs->n;
1317 ps = (char*)mfs->p;
1318 pd = (char*)mfd->p;
1319 for (i = 0; i < mfs->n; i++)
1320 {
1321 shallow_copy_field_precision(src_sftype, dst_sftype, (union anyVrml*)ps, (union anyVrml*)pd);
1322 ps += src_isize;
1323 pd += dst_isize;
1324 }
1325 }
1326 }
1327 }
1328 else {
1329 //isSF
1330 if (source == dest) return; //don't copy over self
1331 switch (desttypeIndex)
1332 {
1333 case FIELDTYPE_SFString:
1334 {
1335 //go deep, same as copy_field
1336 struct Uni_String** ss, * sd;
1337 if (source != dest) {
1338 deleteMallocedFieldValue(desttypeIndex, dest);
1339 ss = (struct Uni_String**)source;
1340 if (*ss) {
1341 sd = (struct Uni_String*)MALLOC(struct Uni_String*, sizeof(struct Uni_String));
1342 memcpy(sd, *ss, sizeof(struct Uni_String));
1343 sd->strptr = STRDUP((*ss)->strptr);
1344 dest->sfstring = sd;
1345 }
1346 }
1347 }
1348 break;
1349 case FIELDTYPE_SFImage:
1350 {
1351 struct SFImage* si, * di;
1352 si = &source->sfimage;
1353 di = &dest->sfimage;
1354 if (di == si) return; //don't copy to self
1355 //we need to malloc and do more copying
1356 //deleteMallocedFieldValue(typeIndex, dest);
1357 FREE_IF_NZ(di->arr.p);
1358 int nele = si->arr.n;
1359 nele = (int)upper_power_of_two(nele);
1360 if (!nele) {
1361 di->arr.p = NULL;
1362 di->arr.n = 0; //should be in here, always 3+
1363 di->whc[0] = di->whc[1] = di->whc[2] = 0;
1364 }
1365 else {
1366 int jsize = sizeof(int);
1367 di->arr.p = MALLOC(int*, jsize * nele);
1368 bzero(di->arr.p, jsize * nele);
1369 di->arr.n = si->arr.n;
1370 memcpy(di->arr.p, si->arr.p, jsize * si->arr.n);
1371 memcpy(di->whc, si->whc, 3 * sizeof(int));
1372 //printf("in shallow_copy_field SFImage: \n");
1373 //for (int k = 0; k < di->n; k++) printf("%d ", di->p[k]);
1374 //printf("\n");
1375 }
1376 }
1377 break;
1378 default:
1379 if (sourcetypeIndex == desttypeIndex) {
1380 //memcpy(dest,source,sizeof(union anyVrml));
1381 memcpy(dest, source, src_isize);
1382 }
1383 else {
1384 //vec3f,3d,matrxi3f,3d,sfrotation should come through here for
1385 // precision conversion
1386 int src_dim = type_dimension(src_sftype);
1387 int dst_dim = type_dimension(dst_sftype);
1388 int src_pre = type_precision(src_sftype);
1389 int dst_pre = type_precision(dst_sftype);
1390 if (src_pre == dst_pre) {
1391 memset(dest, 0, dst_isize);
1392 int nbytes = dst_isize < src_isize ? dst_isize : src_isize;
1393 memcpy(dest, source, nbytes);
1394 }
1395 else {
1396 memset(dest, 0, dst_isize);
1397 int ndim = src_dim < dst_dim ? src_dim : dst_dim;
1398 double* dd, * ds;
1399 float* fd, * fs;
1400 fd = (float*)dest;
1401 dd = (double*)dest;
1402 fs = (float*)source;
1403 ds = (double*)source;
1404 for (int k = 0; k < ndim; k++) {
1405 switch (src_pre + dst_pre * 10) {
1406 case 21:
1407 dd[k] = fs[k];
1408 break;
1409 case 12:
1410 fd[k] = ds[k];
1411 break;
1412 }
1413 }
1414 }
1415 }
1416 break;
1417 }
1418 }
1419} //return copy_field
1420void medium_copy_field0(int itype, void* source, void* dest);
1421void *returnInterpolatorPointer (int nodeType);
1422int SFNode_Setter0(FWType fwt, int index, void *ec, void *fwn, FWval fwval, int isCurrentScriptNode){
1423 // shared between fwSetterNS() and SFNode_Setter
1424 //
1425 struct X3D_Node *node = ((union anyVrml*)fwn)->sfnode;
1426 int ftype, kind, ihave, nr, builtIn; // , interp;
1427 const char *name;
1428 union anyVrml *value;
1429 nr = FALSE;
1430 ihave = getFieldFromNodeAndIterator(node, index, &name, &ftype, &kind, &value, &builtIn);
1431 if(ihave){
1432 //value would be null for script and proto inputOnly, outputOnly fields
1433 //copy W type or primative type, depending on ftype
1434 switch(fwval->itype){
1435 case 'B':
1436 value->sfbool = fwval->_boolean;
1437 break;
1438 case 'I':
1439 value->sfint32 = fwval->_integer;
1440 break;
1441
1442 case 'F':
1443 value->sffloat = (float)fwval->_numeric;
1444 break;
1445
1446 case 'D':
1447 value->sftime = fwval->_numeric;
1448 break;
1449
1450 case 'S':
1451 value->sfstring = newASCIIString(fwval->_string);
1452 break;
1453
1454 default:
1455 if(!strcmp(name,"children")){
1456 //int n;
1457 struct Multi_Node* any = (struct Multi_Node*)fwval->_web3dval.native;
1458 AddRemoveChildren(node,(void*)value,(void*)any->p,any->n,0,__FILE__,__LINE__);
1459 }else{
1460 //medium_copy_field0(ftype,fwval->_web3dval.native,value);
1461 shallow_copy_field_precision(fwval->_web3dval.fieldType, ftype, fwval->_web3dval.native, value);
1462
1463 }
1464 }
1465
1466 if(node->_nodeType == NODE_Script) {
1467 //notify for event processing
1468 struct Shader_Script *script = X3D_SCRIPT(node)->__scriptObj;
1469 struct ScriptFieldDecl *field;
1470 field = Shader_Script_getScriptField(script,index);
1471 if(kind == PKW_inputOutput || kind == PKW_outputOnly)
1472 field->valueChanged = TRUE;
1473 if(!isCurrentScriptNode) {
1474 if(kind == PKW_inputOnly || kind == PKW_inputOutput) {
1475 //if using fwsetter0, we could be writing to ourselves, sending ourselves an eventIn when we really just want an eventOut
1476 //so we should be doing && (gglobal.currentScript != node) and set gglobal.currentScript = thisScriptNode in fwsetter0 (and back to null after call)
1477 field->eventInSet = TRUE; //see runQueuedDirectOutputs()
1478 }
1479 }
1480 }else{
1481 //if directoutput == true
1482 void (* interpolatorPointer)(void*);
1483 interpolatorPointer = returnInterpolatorPointer(node->_nodeType);
1484
1485 if(interpolatorPointer){
1486 //we have something like an orientation interpolator - run it to convert fraction_set to value_changed
1487 interpolatorPointer(node);
1488 }
1489 }
1490 nr = TRUE;
1491 update_node(node);
1492 }
1493 return nr;
1494
1495}
1496int SFNode_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1497 return SFNode_Setter0(fwt,index,ec,fwn,fwval,FALSE);
1498}
1499void * SFNode_Constructor(FWType fwtype, int nargs, FWval fwpars){
1500 struct X3D_Node **ptr = NULL; // = malloc(fwtype->size_of); //garbage collector please
1501 if(nargs == 1){
1502 if(fwpars[0].itype == 'S'){
1503 //SFNode.wrl createFromAString = new SFNode('Cylinder {height 1}');
1504 struct X3D_Group *retGroup;
1505 //char *xstr;
1506 //char *tmpstr;
1507 //char *separator;
1508 int ra;
1509 //int count;
1510 //int wantedsize;
1511 //int MallocdSize;
1512 ttglobal tg = gglobal();
1513 struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
1514 const char *_c = fwpars[0]._string; // fwpars[0]._web3dval.anyvrml->sfstring->strptr;
1515
1516 /* do the call to make the VRML code - create a new browser just for this string */
1517 gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
1518 retGroup = createNewX3DNode(NODE_Group);
1519 ra = EAI_CreateVrml("String",_c,X3D_NODE(retGroup),retGroup);
1520 globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
1521 //if(retGroup->children.n < 1) return 0;
1522 ptr = malloc(sizeof(void *));
1523 *ptr = retGroup->children.p[0];
1524 (*ptr)->_parentVector->n = 0;
1525 }else if(fwpars->itype == 'W'){
1526 if(fwpars->_web3dval.fieldType == FIELDTYPE_SFNode){
1527 //see MFW_getter > Method A
1528 //this is similar - can do new SFNode(MF[i]) but don't really need this extra step for Method A
1529 //might make more sense to instance a new node of this type? And shallow copy its fields?
1530 ptr = malloc(sizeof(void *));
1531 *ptr = ((union anyVrml*)fwpars[0]._web3dval.native)->sfnode;
1532
1533 }
1534 }
1535 }
1536 return ptr;
1537}
1538ArgListType (SFNode_ConstructorArgs)[] = {
1539 {1,-1,0,"S"},
1540 {1,-1,0,"W"},
1541 {-1,0,0,NULL},
1542};
1543/*
1544String getNodeName() Returns the node name
1545Array getNodeType() Returns, in the array, a list of constant values that indicate node typess as provided in the X3DConstants object.
1546FieldDefinitionArray getFieldDefinitions() Returns a list of fields defined for the SFNode object.
1547String 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.
1548String 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.
1549- july 2014 not yet implemented
1550*/
1551
1552
1553int SFNode_getNodeName(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1554 //int found;
1555 char *name = NULL;
1556 int nr = 0;
1557 struct X3D_Node* node = ((union anyVrml*)fwn)->sfnode;
1558 if(node){
1559 //broto warning - DEF name list should be per-executionContext
1560 struct X3D_Proto *context;
1561 context = (struct X3D_Proto *)node->_executionContext;
1562 if(context){
1563 //broto_search_DEFname(ec, fwpars[0]._string);
1564 int i;
1565 struct brotoDefpair def;
1566 if(context->__DEFnames)
1567 for(i=0;i<vectorSize(context->__DEFnames);i++){
1568 def = vector_get(struct brotoDefpair, context->__DEFnames,i);
1569 if(def.node == node){
1570 name = def.name;
1571 break;
1572 }
1573 }
1574 }
1575 if(1){ //if(name){
1576 fwretval->_string = name; //Q should this be &node? to convert it from X3D_Node to anyVrml->sfnode?
1577 fwretval->itype = 'S';
1578 nr = 1;
1579 }
1580 }
1581 return nr;
1582}
1583int SFNode_equals(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1584{
1585 struct X3D_Node *lhs = *(void * *)fwn;
1586 struct X3D_Node *rhs = *(struct X3D_Node **)(fwpars[0]._web3dval.native);
1587
1588 fwretval->_boolean = lhs == rhs;
1589 fwretval->itype = 'B';
1590 return 1;
1591}
1592int SFNode_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1593{
1594 void* *ptr = (void * *)fwn;
1595 if(0){
1596 struct X3D_Node *node = *ptr;
1597 printf("node address=%p nodetype=%s\n",node,stringNodeType(node->_nodeType));
1598 }
1599 if(0){
1600 //see also mfw_getter
1601 void *sfptr = malloc(sizeof(void*));
1602 memcpy(sfptr,(void *)(fwn),sizeof(void*)); //*sfptr = MF.p[i] = &SF
1603 fwretval->_web3dval.native = (void *)sfptr; //native = &sfptr
1604 fwretval->_web3dval.gc = 1;
1605 fwretval->itype = 'W';
1606 }else{
1607 fwretval->_jsobject = *ptr;
1608 fwretval->itype = 'X';
1609 }
1610 return 1;
1611}
1612int SFNode_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
1613{
1614 char str[512];
1615 void **ptr = (void **)fwn;
1616
1617 struct X3D_Node* node = ((union anyVrml*)fwn)->sfnode;
1618
1619 sprintf(str,"_%p_",(*ptr));
1620 fwretval->_string = strdup(str);
1621 fwretval->itype = 'S';
1622 return 1;
1623}
1624FWFunctionSpec (SFNode_Functions)[] = {
1625 {"getNodeName", SFNode_getNodeName, 'S',{0,0,0,NULL}},
1626 // nov 2014 dug9: I was too lazy to implement the following, good luck:
1627 //{"getNodeType", SFNode_getNodeType, 'W',{0,0,0,NULL}},
1628 //{"getFieldDefinitions", SFNode_getFieldDefinitions, 'P',{0,0,0,NULL}},
1629 //{"toVRMLString", SFNode_toVRMLString, 'S',{0,0,0,NULL}},
1630 //{"toXMLString", SFNode_toXMLString, 'S',{0,0,0,NULL}},
1631 {"equals", SFNode_equals, 'B',{1,-1,0,"W"}},
1632 {"valueOf", SFNode_valueOf, 'X',{0,0,0,NULL}},
1633 {"toString", SFNode_toString, 'S',{0,0,0,NULL}},
1634 {0}
1635};
1636FWPropertySpec(SFNode_Properties)[] = {
1637 {NULL,0,0,0},
1638};
1639//#define FIELDTYPE_SFNode 10
1640struct FWTYPE SFNodeType = {
1641 FIELDTYPE_SFNode,
1642 'W',
1643 "SFNode",
1644 sizeof(void*), //sizeof(struct ),
1645 SFNode_Constructor, //constructor
1646 SFNode_ConstructorArgs, //constructor args
1647 NULL, //SFNode_Properties, //Properties,
1648 SFNode_Iterator, //special iterator
1649 SFNode_Getter, //Getter,
1650 SFNode_Setter, //Setter,
1651 0,0, //index prop type,readonly
1652 SFNode_Functions, //functions
1653};
1654
1655
1656
1657//#define FIELDTYPE_MFNode 11
1658struct FWTYPE MFNodeType = {
1659 FIELDTYPE_MFNode,
1660 'W',
1661 "MFNode",
1662 sizeof(struct Multi_Any), //sizeof(struct ),
1663 MFW_Constructor, //constructor
1664 MFW_ConstructorArgs, //constructor args
1665 MFW_Properties, //Properties,
1666 NULL, //special iterator
1667 MFW_Getter, //Getter,
1668 MFW_Setter, //Setter,
1669 'W',0, //index prop type,readonly
1670 MFW_Functions, //functions
1671};
1672
1673
1674/* from http://www.cs.rit.edu/~ncs/color/t_convert.html */
1675double MIND3(double a, double b, double c) {
1676 double min;
1677 if((a<b)&&(a<c))min=a; else if((b<a)&&(b<c))min=b; else min=c; return min;
1678}
1679
1680double MAXD3(double a, double b, double c) {
1681 double max;
1682 if((a>b)&&(a>c))max=a; else if((b>a)&&(b>c))max=b; else max=c; return max;
1683}
1684
1685void convertRGBtoHSV_duk(double r, double g, double b, double *h, double *s, double *v) {
1686 double my_min, my_max, delta;
1687
1688 my_min = MIND3( r, g, b );
1689 my_max = MAXD3( r, g, b );
1690 *v = my_max; /* v */
1691 delta = my_max - my_min;
1692 if( my_max != 0 )
1693 *s = delta / my_max; /* s */
1694 else {
1695 /* r = g = b = 0 */ /* s = 0, v is undefined */
1696 *s = 0;
1697 *h = -1;
1698 return;
1699 }
1700 if( r == my_max )
1701 *h = ( g - b ) / delta; /* between yellow & magenta */
1702 else if( g == my_max )
1703 *h = 2 + ( b - r ) / delta; /* between cyan & yellow */
1704 else
1705 *h = 4 + ( r - g ) / delta; /* between magenta & cyan */
1706 *h *= 60; /* degrees */
1707 if( *h < 0 )
1708 *h += 360;
1709}
1710void convertHSVtoRGB_duk( double h, double s, double v ,double *r, double *g, double *b)
1711{
1712 int i;
1713 double f, p, q, t;
1714 if( s == 0 ) {
1715 /* achromatic (grey) */
1716 *r = *g = *b = v;
1717 return;
1718 }
1719 h /= 60; /* sector 0 to 5 */
1720 i = (int) floor( h );
1721 f = h - i; /* factorial part of h */
1722 p = v * ( 1 - s );
1723 q = v * ( 1 - s * f );
1724 t = v * ( 1 - s * ( 1 - f ) );
1725 switch( i ) {
1726 case 0: *r = v; *g = t; *b = p; break;
1727 case 1: *r = q; *g = v; *b = p; break;
1728 case 2: *r = p; *g = v; *b = t; break;
1729 case 3: *r = p; *g = q; *b = v; break;
1730 case 4: *r = t; *g = p; *b = v; break;
1731 default: *r = v; *g = p; *b = q; break;
1732 }
1733}
1734
1735
1736int SFColor_getHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1737 //argc should == 0 for getHSV
1738 struct SFVec3d *sf3d;
1739 struct SFColor *ptr = (struct SFColor *)fwn;
1740 double xp[3];
1741 /* convert rgb to hsv */
1742 convertRGBtoHSV_duk((double)ptr->c[0], (double)ptr->c[1], (double)ptr->c[2],&xp[0],&xp[1],&xp[2]);
1743 //supposed to return numeric[3] - don't have that set up so sfvec3d
1744 sf3d = malloc(sizeof(struct SFVec3d)); //garbage collector please
1745 memcpy(sf3d->c,xp,sizeof(double)*3);
1746 fwretval->_web3dval.native = sf3d;
1747 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
1748 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
1749 fwretval->itype = 'W';
1750 return 1;
1751}
1752
1753int SFColor_setHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1754 //argc should == 3 for setHSV
1755 struct SFColor *ptr = (struct SFColor *)fwn;
1756 double xp[3];
1757 /* convert rgb to hsv */
1758 convertHSVtoRGB_duk((double)fwpars[0]._numeric, (double)fwpars[1]._numeric, (double)fwpars[2]._numeric,&xp[0],&xp[1],&xp[2]);
1759 ptr->c[0] = (float)xp[0];
1760 ptr->c[1] = (float)xp[1];
1761 ptr->c[2] = (float)xp[2];
1762 return 0;
1763}
1764
1765int SFColor_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1766 struct SFColor *ptr = (struct SFColor *)fwn;
1767 char buff[STRING], *str;
1768 int len;
1769 memset(buff, 0, STRING);
1770 sprintf(buff, "%.3g %.3g %.3g",
1771 ptr->c[0], ptr->c[1], ptr->c[2]);
1772 len = strlen(buff);
1773 str = malloc(len+1); //leak
1774 strcpy(str,buff);
1775 fwretval->_string = str;
1776 fwretval->itype = 'S';
1777 return 1;
1778}
1779
1780FWFunctionSpec (SFColor_Functions)[] = {
1781 {"getHSV", SFColor_getHSV, 'W',{0,0,0,NULL}},
1782 {"setHSV", SFColor_setHSV, 0,{3,-1,'T',"DDD"}},
1783 {"toString", SFColor_toString, 'S',{0,-1,0,NULL}},
1784 {0}
1785};
1786
1787int SFColor_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1788 struct SFColor *ptr = (struct SFColor *)fwn;
1789 int nr = 0;
1790 //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)
1791 if(index > -1 && index < 3){
1792 nr = 1;
1793 switch(index){
1794 case 0: //r
1795 case 1: //g
1796 case 2: //b
1797 fwretval->_numeric = ptr->c[index];
1798 break;
1799 default:
1800 nr = 0;
1801 }
1802 }
1803 fwretval->itype = 'F';
1804 return nr;
1805}
1806int SFColor_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1807 struct SFColor *ptr = (struct SFColor *)fwn;
1808 //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)
1809 if(index > -1 && index < 3){
1810 switch(index){
1811 case 0: //r
1812 case 1: //g
1813 case 2: //b
1814 ptr->c[index] = (float) fwval->_numeric;
1815 break;
1816 }
1817 return TRUE;
1818 }
1819 return FALSE;
1820}
1821//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
1822void * SFColor_Constructor(FWType fwtype, int ic, FWval fwpars){
1823 int i;
1824 struct SFColor *ptr = malloc(fwtype->size_of); //garbage collector please
1825 if(fwtype->ConstructorArgs[0].nfixedArg == 3){
1826 for(i=0;i<3;i++)
1827 ptr->c[i] = (float) fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
1828 }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
1829 //new SFxxx(myMF[i]);
1830 shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
1831 }
1832 return (void *)ptr;
1833}
1834
1835FWPropertySpec (SFColor_Properties)[] = {
1836 {"r", 0, 'F', 0},
1837 {"g", 1, 'F', 0},
1838 {"b", 2, 'F', 0},
1839 {NULL,0,0,0},
1840};
1841
1842//typedef struct ArgListType {
1843// char nfixedArg;
1844// char iVarArgStartsAt; //-1 no varargs
1845// char fillMissingFixedWithZero; //T/F if F then complain if short
1846// char *argtypes; //if varargs, then argtypes[nfixedArg] == type of varArg, and all varargs are assumed the same type
1847//} ArgListType;
1848ArgListType (SFColor_ConstructorArgs)[] = {
1849 {3,0,'T',"FFF"},
1850 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
1851 {-1,0,0,NULL},
1852};
1853//#define FIELDTYPE_SFColor 12
1854struct FWTYPE SFColorType = {
1855 FIELDTYPE_SFColor,
1856 'W',
1857 "SFColor",
1858 sizeof(struct SFColor), //sizeof(struct ),
1859 SFColor_Constructor, //constructor
1860 SFColor_ConstructorArgs, //constructor args
1861 SFColor_Properties, //Properties,
1862 NULL, //special iterator
1863 SFColor_Getter, //Getter,
1864 SFColor_Setter, //Setter,
1865 'F',0, //index prop type,readonly
1866 SFColor_Functions, //functions
1867};
1868
1869
1870//#define FIELDTYPE_MFColor 13
1871struct FWTYPE MFColorType = {
1872 FIELDTYPE_MFColor,
1873 'W',
1874 "MFColor",
1875 sizeof(struct Multi_Any), //sizeof(struct ),
1876 MFW_Constructor, //constructor
1877 MFW_ConstructorArgs, //constructor args
1878 MFW_Properties, //Properties,
1879 NULL, //special iterator
1880 MFW_Getter, //Getter,
1881 MFW_Setter, //Setter,
1882 'W',0, //index prop type,readonly
1883 MFW_Functions, //functions
1884};
1885
1886
1887int SFColorRGBA_getHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1888 //argc should == 0 for getHSV
1889 struct SFVec3d *sf3d;
1890 struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1891 double xp[3];
1892 /* convert rgb to hsv */
1893 convertRGBtoHSV_duk((double)ptr->c[0], (double)ptr->c[1], (double)ptr->c[2],&xp[0],&xp[1],&xp[2]);
1894 //supposed to return numeric[3] - don't have that set up so sfvec3d
1895 sf3d = malloc(sizeof(struct SFVec3d)); //garbage collector please
1896 memcpy(sf3d->c,xp,sizeof(double)*3);
1897 fwretval->_web3dval.native = sf3d;
1898 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
1899 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
1900 fwretval->itype = 'W';
1901 return 1;
1902}
1903
1904int SFColorRGBA_setHSV(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1905 //argc should == 3 for setHSV
1906 struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1907 double xp[3];
1908 /* convert rgb to hsv */
1909 convertHSVtoRGB_duk((double)fwpars[0]._numeric, (double)fwpars[1]._numeric, (double)fwpars[2]._numeric,&xp[0],&xp[1],&xp[2]);
1910 ptr->c[0] = (float)xp[0];
1911 ptr->c[1] = (float)xp[1];
1912 ptr->c[2] = (float)xp[2];
1913 ptr->c[3] = 1.0f;
1914 return 0;
1915}
1916
1917int SFColorRGBA_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
1918 struct SFColor *ptr = (struct SFColor *)fwn;
1919 char buff[STRING], *str;
1920 int len;
1921 memset(buff, 0, STRING);
1922 sprintf(buff, "%.3g %.3g %.3g %.3g",
1923 ptr->c[0], ptr->c[1], ptr->c[2], ptr->c[3]);
1924 len = strlen(buff);
1925 str = malloc(len+1); //leak
1926 strcpy(str,buff);
1927 fwretval->_string = str;
1928 fwretval->itype = 'S';
1929 return 1;
1930}
1931
1932FWFunctionSpec (SFColorRGBA_Functions)[] = {
1933 {"getHSV", SFColor_getHSV, 'W',{0,0,0,NULL}},
1934 {"setHSV", SFColor_setHSV, 0,{3,-1,'T',"DDD"}},
1935 {"toString", SFColorRGBA_toString, 'S',{0,-1,0,NULL}},
1936 {0}
1937};
1938
1939int SFColorRGBA_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
1940 struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1941 int nr = 0;
1942 //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)
1943 if(index > -1 && index < 4){
1944 nr = 1;
1945 switch(index){
1946 case 0: //r
1947 case 1: //g
1948 case 2: //b
1949 case 3: //a
1950 fwretval->_numeric = ptr->c[index];
1951 break;
1952 default:
1953 nr = 0;
1954 }
1955 }
1956 fwretval->itype = 'F';
1957 return nr;
1958}
1959int SFColorRGBA_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
1960 struct SFColorRGBA *ptr = (struct SFColorRGBA *)fwn;
1961 //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)
1962 if(index > -1 && index < 4){
1963 switch(index){
1964 case 0: //r
1965 case 1: //g
1966 case 2: //b
1967 case 3: //a
1968 ptr->c[index] = (float) fwval->_numeric;
1969 break;
1970 }
1971 return TRUE;
1972 }
1973 return FALSE;
1974}
1975//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
1976void * SFColorRGBA_Constructor(FWType fwtype, int ic, FWval fwpars){
1977 int i;
1978 struct SFColorRGBA *ptr = malloc(fwtype->size_of); //garbage collector please
1979 if(ic == 4){
1980 for(i=0;i<4;i++)
1981 ptr->c[i] = (float) fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
1982 } else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
1983 //new SFxxx(myMF[i]);
1984 shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
1985 }
1986
1987 return (void *)ptr;
1988}
1989
1990FWPropertySpec (SFColorRGBA_Properties)[] = {
1991 {"r", 0, 'F', 0},
1992 {"g", 1, 'F', 0},
1993 {"b", 2, 'F', 0},
1994 {"a", 3, 'F', 0},
1995 {NULL,0,0,0},
1996};
1997
1998//typedef struct ArgListType {
1999// char nfixedArg;
2000// char iVarArgStartsAt; //-1 no varargs
2001// char fillMissingFixedWithZero; //T/F if F then complain if short
2002// char *argtypes; //if varargs, then argtypes[nfixedArg] == type of varArg, and all varargs are assumed the same type
2003//} ArgListType;
2004ArgListType (SFColorRGBA_ConstructorArgs)[] = {
2005 {4,0,'T',"FFFF"},
2006 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
2007 {-1,0,0,NULL},
2008};
2009
2010
2011//#define FIELDTYPE_SFColorRGBA 14
2012struct FWTYPE SFColorRGBAType = {
2013 FIELDTYPE_SFColorRGBA,
2014 'W',
2015 "SFColorRGBA",
2016 sizeof(struct SFColorRGBA), //sizeof(struct ),
2017 SFColorRGBA_Constructor, //constructor
2018 SFColorRGBA_ConstructorArgs, //constructor args
2019 SFColorRGBA_Properties, //Properties,
2020 NULL, //special iterator
2021 SFColorRGBA_Getter, //Getter,
2022 SFColorRGBA_Setter, //Setter,
2023 'F',0, //index prop type,readonly
2024 SFColorRGBA_Functions, //functions
2025};
2026//#define FIELDTYPE_MFColorRGBA 15
2027struct FWTYPE MFColorRGBAType = {
2028 FIELDTYPE_MFColorRGBA,
2029 'W',
2030 "MFColorRGBA",
2031 sizeof(struct Multi_Any), //sizeof(struct ),
2032 MFW_Constructor, //constructor
2033 MFW_ConstructorArgs, //constructor args
2034 MFW_Properties, //Properties,
2035 NULL, //special iterator
2036 MFW_Getter, //Getter,
2037 MFW_Setter, //Setter,
2038 'W',0, //index prop type,readonly
2039 MFW_Functions, //functions
2040};
2041
2042int SFDouble_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
2043{
2044 double *ptr = (double *)fwn;
2045 fwretval->_numeric = *(ptr);
2046 fwretval->itype = 'D';
2047 return 1;
2048}
2049int SFDouble_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
2050{
2051 char str[512];
2052 double *ptr = (double *)fwn;
2053 sprintf(str,"%g",(*ptr));
2054 fwretval->_string = strdup(str);
2055 fwretval->itype = 'S';
2056 return 1;
2057}
2058
2059FWFunctionSpec (SFDouble_Functions)[] = {
2060 {"valueOf", SFDouble_valueOf, 'D',{0,0,0,NULL}},
2061 {"toString", SFDouble_toString, 'S',{0,0,0,NULL}},
2062 {0}
2063};
2064
2065//#define FIELDTYPE_SFTime 16
2066struct FWTYPE SFTimeType = {
2067 FIELDTYPE_SFTime,
2068 'D',
2069 "SFTime",
2070 sizeof(double), //sizeof(struct ),
2071 NULL, //constructor
2072 NULL, //constructor args
2073 NULL, //Properties,
2074 NULL, //special iterator
2075 NULL, //Getter,
2076 NULL, //Setter,
2077 0,0, //index prop type,readonly
2078 SFDouble_Functions, //functions
2079};
2080
2081void * MFTime_Constructor(FWType fwtype, int argc, FWval fwpars){
2082 int i, lenSF;
2083 char *p;
2084 struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
2085 lenSF = sizeofSF(fwtype->itype);
2086 ptr->n = argc;
2087 ptr->p = NULL;
2088 if(ptr->n)
2089 ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
2090 p = ptr->p;
2091 for(i=0;i<ptr->n;i++){
2092 if(fwpars[i].itype == 'W')
2093 memcpy(p,&fwpars[i]._web3dval.native,lenSF);
2094 else if(fwpars[i].itype == 'D')
2095 memcpy(p,&fwpars[i]._numeric,lenSF);
2096 p += lenSF;
2097 }
2098 return (void *)ptr;
2099}
2100ArgListType (MFTime_ConstructorArgs)[] = {
2101 {0,0,0,"D"},
2102 {-1,0,0,NULL},
2103};
2104
2105
2106//#define FIELDTYPE_MFTime 17
2107struct FWTYPE MFTimeType = {
2108 FIELDTYPE_MFTime,
2109 'W',
2110 "MFTime",
2111 sizeof(struct Multi_Any), //sizeof(struct ),
2112 MFTime_Constructor, //constructor
2113 MFTime_ConstructorArgs, //constructor args
2114 MFW_Properties, //Properties,
2115 NULL, //special iterator
2116 MFW_Getter, //Getter,
2117 MFW_Setter, //Setter,
2118 'D',0, //index prop type,readonly
2119 MFW_Functions, //functions
2120};
2121
2122int SFString_valueOf(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
2123{
2124 struct Uni_String *ptr = (struct Uni_String *)fwn;
2125 fwretval->_string = ptr->strptr;
2126 fwretval->itype = 'S';
2127 return 1;
2128}
2129int SFString_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval)
2130{
2131 struct Uni_String *ptr = (struct Uni_String *)fwn;
2132 fwretval->_string = strdup(ptr->strptr);
2133 fwretval->itype = 'S';
2134 return 1;
2135}
2136
2137FWFunctionSpec (SFString_Functions)[] = {
2138 {"valueOf", SFString_valueOf, 'S',{0,0,0,NULL}},
2139 {"toString", SFString_toString, 'S',{0,0,0,NULL}},
2140 {0}
2141};
2142
2143//#define FIELDTYPE_SFString 18
2144struct FWTYPE SFStringType = {
2145 FIELDTYPE_SFString,
2146 'S',
2147 "SFString",
2148 sizeof(void *), //sizeof(struct ),
2149 NULL, //constructor
2150 NULL, //constructor args
2151 NULL, //Properties,
2152 NULL, //special iterator
2153 NULL, //Getter,
2154 NULL, //Setter,
2155 0,0, //index prop type,readonly //Q. should string[i] return 'I' == char, like SFImage indexer?
2156 SFString_Functions, //functions
2157};
2158
2159void * MFString_Constructor(FWType fwtype, int argc, FWval fwpars){
2160 int i, lenSF;
2161 char *p;
2162 struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
2163 lenSF = sizeofSF(fwtype->itype);
2164 ptr->n = argc;
2165 ptr->p = NULL;
2166 if(ptr->n)
2167 ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
2168 p = ptr->p;
2169 for(i=0;i<ptr->n;i++){
2170 //float ff = (float)fwpars[i]._numeric; //fwpars[i]._web3dval.native;
2171 if(fwpars[i].itype == 'W' && fwpars[i]._web3dval.fieldType == FIELDTYPE_SFString)
2172 memcpy(p,&fwpars[i]._web3dval.native,lenSF);
2173 else if(fwpars[i].itype == 'S'){
2174 void *tmp = newASCIIString(fwpars[i]._string);
2175 memcpy(p,&tmp,lenSF);
2176 //(*p) = (char *)
2177 }else if(fwpars[i].itype == 'F' || fwpars[i].itype == 'D'){
2178 void *tmp;
2179 char str[100];
2180 sprintf(str,"%f", fwpars[i]._numeric);
2181 tmp = newASCIIString(str);
2182 memcpy(p,&tmp,lenSF);
2183 }else if(fwpars[i].itype == 'I' ){
2184 void *tmp;
2185 char str[100];
2186 sprintf(str,"%d", fwpars[i]._integer);
2187 tmp = newASCIIString(str);
2188 memcpy(p,&tmp,lenSF);
2189 }else if(fwpars[i].itype == 'B' ){
2190 void *tmp;
2191 const char *str = "false";
2192 if(fwpars[i]._boolean) str = "true";
2193 tmp = newASCIIString(str);
2194 memcpy(p,&tmp,lenSF);
2195
2196 }
2197 p += lenSF;
2198 }
2199 return (void *)ptr;
2200}
2201ArgListType (MFString_ConstructorArgs)[] = {
2202 {0,0,0,"S"},
2203 {0,0,0,"F"},
2204 {0,0,0,"D"},
2205 {0,0,0,"I"},
2206 {0,0,0,"B"},
2207 {-1,0,0,NULL},
2208};
2209//#define FIELDTYPE_MFString 19
2210struct FWTYPE MFStringType = {
2211 FIELDTYPE_MFString,
2212 'W',
2213 "MFString",
2214 sizeof(struct Multi_Any),
2215 MFString_Constructor, //constructor
2216 MFString_ConstructorArgs, //constructor args
2217 MFW_Properties, //Properties,
2218 NULL, //special iterator
2219 MFW_Getter, //Getter,
2220 MFW_Setter, //Setter,
2221 'S',0, //index prop type,readonly
2222 MFW_Functions, //functions
2223};
2224
2225
2226/* SFVec2f
2227Constructor
2228SFVec2f (numeric x, numeric y) Missing values default to 0.0d+00.
2229props
2230numeric x No First value of the vector
2231numeric y No Second value of the vector
2232funcs
2233SFVec2f add(SFVec2f vec) Returns the value of the passed value added, component-wise, to the object.
2234SFVec2f divide(numeric n) Returns the value of the object divided by the passed value.
2235numeric dot(SFVec2f vec) Returns the dot product of this vector and the passed value.
2236numeric length() Returns the geometric length of this vector.
2237SFVec2f multiply(numeric n) Returns the value of the object multiplied by the passed value.
2238SFVec2f normalize() Returns the object converted to unit length .
2239SFVec2f subtract(SFVec2f vec) Returns the value of the passed value subtracted, component-wise, from the object.
2240String 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).
2241*/
2242
2243int SFVec2f_add(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2244 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2245 struct SFVec2f *rhs = fwpars[0]._web3dval.native;
2246 struct SFVec2f *res = malloc(fwtype->size_of);
2247 vecadd2f(res->c,ptr->c,rhs->c);
2248 fwretval->_web3dval.native = res;
2249 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2250 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2251 fwretval->itype = 'W';
2252 return 1;
2253}
2254int SFVec2f_subtract(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2255 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2256 struct SFVec2f *rhs = fwpars[0]._web3dval.native;
2257 struct SFVec2f *res = malloc(fwtype->size_of);
2258 vecdif2f(res->c,ptr->c,rhs->c);
2259 fwretval->_web3dval.native = res;
2260 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2261 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2262 fwretval->itype = 'W';
2263 return 1;
2264}
2265int SFVec2f_divide(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2266 struct SFVec2f *res;
2267 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2268 double rhs = fwpars[0]._numeric;
2269 if(rhs == 0.0){
2270 return 0;
2271 }
2272 rhs = 1.0/rhs;
2273 res = malloc(fwtype->size_of);
2274 vecscale2f(res->c,ptr->c,(float)rhs);
2275 fwretval->_web3dval.native = res;
2276 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2277 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2278 fwretval->itype = 'W';
2279 return 1;
2280}
2281int SFVec2f_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2282 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2283 double rhs = fwpars[0]._numeric;
2284 struct SFVec2f *res = malloc(fwtype->size_of);
2285 vecscale2f(res->c,ptr->c,(float)rhs);
2286 fwretval->_web3dval.native = res;
2287 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2288 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2289 fwretval->itype = 'W';
2290 return 1;
2291}
2292int SFVec2f_normalize(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2293 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2294 struct SFVec2f *res = malloc(fwtype->size_of);
2295 vecnormal2f(res->c,ptr->c);
2296 fwretval->_web3dval.native = res;
2297 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2f;
2298 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2299 fwretval->itype = 'W';
2300 return 1;
2301}
2302
2303int SFVec2f_length(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2304 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2305 double res;
2306 res = veclength2f(ptr->c);
2307 fwretval->_numeric = res;
2308 fwretval->itype = 'F';
2309 return 1;
2310}
2311int SFVec2f_dot(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2312 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2313 struct SFVec2f *rhs = fwpars[0]._web3dval.native;
2314 double res;
2315 res = vecdot2f(ptr->c,rhs->c);
2316 fwretval->_numeric = res;
2317 fwretval->itype = 'F';
2318 return 1;
2319}
2320
2321int SFVec2f_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2322 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2323 char buff[STRING], *str;
2324 int len;
2325 memset(buff, 0, STRING);
2326 sprintf(buff, "%.9g %.9g",
2327 ptr->c[0], ptr->c[1]);
2328 len = strlen(buff);
2329 str = malloc(len+1); //leak
2330 strcpy(str,buff);
2331 fwretval->_string = str;
2332 fwretval->itype = 'S';
2333 return 1;
2334}
2335FWFunctionSpec (SFVec2f_Functions)[] = {
2336 {"add", SFVec2f_add, 'W',{1,-1,0,"W"}},
2337 {"divide", SFVec2f_divide, 'W',{1,-1,0,"F"}},
2338 {"dot", SFVec2f_dot, 'F',{1,-1,0,"W"}},
2339 {"length", SFVec2f_length, 'F',{0,-1,0,NULL}},
2340 {"multiply", SFVec2f_multiply, 'W',{1,-1,0,"F"}},
2341 {"normalize", SFVec2f_normalize, 'W',{0,-1,0,NULL}},
2342 {"subtract", SFVec2f_subtract, 'W',{1,-1,0,"W"}},
2343 {"toString", SFVec2f_toString, 'S',{0,-1,0,NULL}},
2344 {0}
2345};
2346
2347int SFVec2f_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2348 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2349 int nr = 0;
2350 //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)
2351 if(index > -1 && index < 2){
2352 nr = 1;
2353 switch(index){
2354 case 0: //x
2355 case 1: //y
2356 fwretval->_numeric = ptr->c[index];
2357 break;
2358 default:
2359 nr = 0;
2360 }
2361 }
2362 fwretval->itype = 'F';
2363 return nr;
2364}
2365int SFVec2f_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
2366 struct SFVec2f *ptr = (struct SFVec2f *)fwn;
2367 //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)
2368 if(index > -1 && index < 2){
2369 switch(index){
2370 case 0: //x
2371 case 1: //y
2372 ptr->c[index] = (float) fwval->_numeric;
2373 break;
2374 }
2375 return TRUE;
2376 }
2377 return FALSE;
2378}
2379//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
2380void * SFVec2f_Constructor(FWType fwtype, int ic, FWval fwpars){
2381 int i;
2382 struct SFVec2f *ptr = malloc(fwtype->size_of); //garbage collector please
2383 if(ic == 2){
2384 for(i=0;i<2;i++)
2385 ptr->c[i] = (float) fwpars[i]._numeric;
2386 }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
2387 //new SFxxx(myMF[i]);
2388 shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
2389 }
2390
2391 return (void *)ptr;
2392}
2393
2394FWPropertySpec (SFVec2f_Properties)[] = {
2395 {"x", 0, 'F', 0},
2396 {"y", 1, 'F', 0},
2397 {NULL,0,0,0},
2398};
2399ArgListType (SFVec2f_ConstructorArgs)[] = {
2400 {2,0,'T',"FF"},
2401 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
2402 {-1,0,0,NULL},
2403};
2404
2405//#define FIELDTYPE_SFVec2f 20
2406struct FWTYPE SFVec2fType = {
2407 FIELDTYPE_SFVec2f,
2408 'W',
2409 "SFVec2f",
2410 sizeof(struct SFVec2f), //sizeof(struct ),
2411 SFVec2f_Constructor, //constructor
2412 SFVec2f_ConstructorArgs, //constructor args
2413 SFVec2f_Properties, //Properties,
2414 NULL, //special iterator
2415 SFVec2f_Getter, //Getter,
2416 SFVec2f_Setter, //Setter,
2417 'F',0, //index prop type,readonly
2418 SFVec2f_Functions, //functions
2419};
2420
2421//#define FIELDTYPE_MFVec2f 21
2422struct FWTYPE MFVec2fType = {
2423 FIELDTYPE_MFVec2f,
2424 'W',
2425 "MFVec2f",
2426 sizeof(struct Multi_Any), //sizeof(struct ),
2427 MFW_Constructor, //constructor
2428 MFW_ConstructorArgs, //constructor args
2429 MFW_Properties, //Properties,
2430 NULL, //special iterator
2431 MFW_Getter, //Getter,
2432 MFW_Setter, //Setter,
2433 'W',0, //index prop type,readonly
2434 MFW_Functions, //functions
2435};
2436
2437/* SFImage
2438http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#SFImage
2439constr
2440SFImage (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).
2441props
2442numeric width No Width dimension of the image in pixels
2443numeric height No Height dimension of the image in pixels
2444numeric comp No Number of components of the image
24451.greyscale or alpha
24462.greyscale + alpha
24473.rgb
24484.rgb + alpha
2449MFInt32 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).
2450funcs
2451String 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).
2452*/
2453
2454int SFImage_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2455 //char *str;
2456 //FWType mfint32type = getFWTYPE(FIELDTYPE_MFInt32);
2457 //str = mfToString(mfint32type, fwn);
2458 {
2459 int i, len;
2460 char* str;
2461 struct SFImage* sfimage = (struct SFImage*)fwn;
2462 int width, height, comp;
2463 width = sfimage->whc[0];
2464 height = sfimage->whc[1];
2465 comp = sfimage->whc[2];
2466 len = 5 + 5 + 5 + (width * height * (comp*2 + 3)); //0xFF one comp, 0xFFFF 2 channel 0xFFFFFF 3 chanel 0xFFFFFFFF 4 channel
2467 str = malloc(len + 1);
2468 sprintf(str, "%d %d %d ", width, height, comp);
2469 char buff[20];
2470 char* format = NULL;
2471 switch (comp) {
2472 case 1: format = "%#4x "; break;
2473 case 2: format = "%#6x "; break;
2474 case 3: format = "%#8x "; break;
2475 case 4: format = "%#10x "; break;
2476 default: break;
2477 }
2478 int count = width * height < sfimage->arr.n ? width * height : sfimage->arr.n;
2479 for (i = 0; i < count; i++)
2480 {
2481 sprintf(buff, format, sfimage->arr.p[i]);
2482 str = strcat(str, buff);
2483 }
2484 fwretval->_string = str;
2485
2486 }
2487 //fwretval->_string = strdup("sfimage");// str;
2488 fwretval->itype = 'S';
2489 return 1;
2490}
2491
2492FWFunctionSpec (SFImage_Functions)[] = {
2493 {"toString", SFImage_toString, 'S',{0,-1,0,NULL}},
2494 {0}
2495};
2496
2497int SFImage_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2498 struct SFImage* ptr = (struct SFImage*)fwn;
2499 int nr = 0;
2500 //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)
2501 if(index > -1 && index < 4){
2502 nr = 1;
2503 switch(index){
2504 case 0: //width
2505 case 1: //height
2506 case 2: //comp
2507 fwretval->_integer = ptr->whc[index];
2508 fwretval->itype = 'I';
2509 break;
2510
2511 case 3: //array
2512 fwretval->_web3dval.native = &ptr->arr; //hope they don't go image.array[0] = infinity; which will overwrite width. same for height, comp
2513 fwretval->_web3dval.fieldType = FIELDTYPE_MFInt32;
2514 fwretval->_web3dval.gc = 0;
2515 fwretval->itype = 'W';
2516 break;
2517 default:
2518 nr = 0;
2519 }
2520 }
2521 return nr;
2522}
2523int SFImage_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
2524 struct SFImage *ptr = (struct SFImage*)fwn;
2525 int *p;
2526 //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)
2527 if(index > -1 && index < 4){
2528 switch(index){
2529 case 0: //width
2530 case 1: //height
2531 case 2: //comp
2532 ptr->whc[index] = fwval->_integer;
2533 int* whc = ptr->whc;
2534 p = ptr->arr.p;
2535 if(ptr->arr.n < (whc[0] * whc[1]) ){
2536 //resize
2537 ptr->arr.n = (whc[0] * whc[1]);
2538 ptr->arr.p = realloc(ptr->arr.p,ptr->arr.n);
2539 }
2540 break;
2541
2542 case 3: //array
2543 if(fwval->itype == 'W' && fwval->_web3dval.fieldType == FIELDTYPE_MFInt32 ){
2544 //int width,height,comp;
2545 int ncopy; //i,j,
2546 struct Multi_Int32 *im = fwval->_web3dval.native;
2547 ncopy = ptr->arr.n < im->n ? ptr->arr.n : im->n;
2548 memcpy(ptr->arr.p,im->p,(ncopy)*sizeof(int));
2549 }
2550 break;
2551 default:
2552 break;
2553 }
2554 return TRUE;
2555 }
2556 return FALSE;
2557}
2558//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
2559void * SFImage_Constructor(FWType fwtype, int ic, FWval fwpars){
2560 //around freewrl, SFImage is stored as a MFIn32, with n = 3 x width x height,
2561 //and the first (int,int,int) pixel sacrificed to hold (width,height,comp)
2562 int width, height, comp;
2563 struct SFImage* ptr = malloc(fwtype->size_of); //garbage collector please
2564
2565 if(ic > 2){
2566 width = fwpars[0]._integer;
2567 height = fwpars[1]._integer;
2568 comp = fwpars[2]._integer;
2569 }else {
2570 width = 0;
2571 height = 0;
2572 comp = 3;
2573 }
2574 //https://www.web3d.org/documents/specifications/19775-1/V4.0/Part01/fieldTypes.html#SFImageAndMFImage
2575 //"Each pixel is read as a single unsigned number." that means one 4 byte int number per pixel
2576 ptr->arr.n = width * height; // comp* width* height;
2577 ptr->arr.p = malloc(ptr->arr.n * sizeof(int)); //garbage collector please
2578 memset(ptr->arr.p, 0, ptr->arr.n * sizeof(int));
2579 if (width * height) {
2580 if (fwpars[3].itype == 'W' && fwpars[3]._web3dval.fieldType == FIELDTYPE_MFInt32) {
2581 //the incoming MFInt32 pixel values are one pixel per Int32
2582 int i, j, ncopy, nfill;
2583 struct Multi_Int32* im = fwpars[3]._web3dval.native;
2584 ncopy = ptr->arr.n < im->n ? ptr->arr.n : im->n;
2585 for (i = 0; i < ncopy; i++)
2586 ptr->arr.p[i] = im->p[i];
2587 }
2588 }
2589
2590 ptr->whc[0] = width;
2591 ptr->whc[1] = height;
2592 ptr->whc[2] = comp;
2593 return (void *)ptr;
2594}
2595
2596FWPropertySpec (SFImage_Properties)[] = {
2597 {"width", 0, 'I', 0},
2598 {"height", 1, 'I', 0},
2599 {"comp", 2, 'I', 0},
2600 {"array", 3, 'W', 0},
2601 {NULL,0,0,0},
2602};
2603ArgListType (SFImage_ConstructorArgs)[] = {
2604 {4,3,'T',"IIIW"},
2605 {-1,0,0,NULL},
2606};
2607
2608
2609//#define FIELDTYPE_SFImage 22
2610struct FWTYPE SFImageType = {
2611 FIELDTYPE_SFImage,
2612 'W',
2613 "SFImage",
2614 sizeof(struct SFImage),
2615 SFImage_Constructor, //constructor
2616 SFImage_ConstructorArgs, //constructor args
2617 SFImage_Properties, //Properties,
2618 NULL, //special iterator
2619 SFImage_Getter, //Getter,
2620 SFImage_Setter, //Setter,
2621 0,0, //index prop type,readonly
2622 SFImage_Functions, //functions
2623};
2624
2625
2626struct FWTYPE MFImageType = {
2627 FIELDTYPE_MFImage,
2628 'W',
2629 "MFImage",
2630 sizeof(struct Multi_Any), //sizeof(struct ),
2631 MFW_Constructor, //constructor
2632 MFW_ConstructorArgs, //constructor args
2633 MFW_Properties, //Properties,
2634 NULL, //special iterator
2635 MFW_Getter, //Getter,
2636 MFW_Setter, //Setter,
2637 'W',0, //index prop type,readonly
2638 MFW_Functions, //functions
2639};
2640
2641//#define FIELDTYPE_FreeWRLPTR 23
2642//#define FIELDTYPE_FreeWRLThread 24
2643
2644/*
2645SFVec3d add(SFVec3d vec) Returns the value of the passed value added, component-wise, to the object.
2646SFVec3d cross(SFVec3d vec) Returns the cross product of the object and the passed value.
2647SFVec3d divide(numeric n) Returns the value of the object divided by the passed value.
2648numeric dot(SFVec3d vec) Returns the dot product of this vector and the passed value as a double precision value.
2649numeric length() Returns the geometric length of this vector as a double precision value.
2650SFVec3d multiple(numeric n) Returns the value of the object multiplied by the passed value.
2651SFVec3d negate() Returns the value of the component-wise negation of the object.
2652SFVec3d normalize() Returns the object converted to unit length .
2653SFVec3d subtract(SFVec3f vec) Returns the value of the passed value subtracted, component-wise, from the object.
2654String 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).
2655*/
2656//SFVec3d add(SFVec3d vec) Returns the value of the passed value added, component-wise, to the object.
2657int SFVec3d_add(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2658 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2659 struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2660 struct SFVec3d *res = malloc(fwtype->size_of);
2661 vecaddd(res->c,ptr->c,rhs->c);
2662 fwretval->_web3dval.native = res;
2663 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2664 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2665 fwretval->itype = 'W';
2666 return 1;
2667}
2668int SFVec3d_cross(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2669 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2670 struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2671 struct SFVec3d *res = malloc(fwtype->size_of);
2672 veccrossd(res->c,ptr->c,rhs->c);
2673 fwretval->_web3dval.native = res;
2674 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2675 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2676 fwretval->itype = 'W';
2677 return 1;
2678}
2679int SFVec3d_subtract(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2680 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2681 struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2682 struct SFVec3d *res = malloc(fwtype->size_of);
2683 vecdifd(res->c,ptr->c,rhs->c);
2684 fwretval->_web3dval.native = res;
2685 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2686 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2687 fwretval->itype = 'W';
2688 return 1;
2689}
2690int SFVec3d_divide(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2691 struct SFVec3d *res;
2692 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2693 double rhs = fwpars[0]._numeric;
2694 if(rhs == 0.0){
2695 return 0;
2696 }
2697 rhs = 1.0/rhs;
2698 res = malloc(fwtype->size_of);
2699 vecscaled(res->c,ptr->c,rhs);
2700 fwretval->_web3dval.native = res;
2701 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2702 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2703 fwretval->itype = 'W';
2704 return 1;
2705}
2706int SFVec3d_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2707 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2708 double rhs = fwpars[0]._numeric;
2709 struct SFVec3d *res = malloc(fwtype->size_of);
2710 vecscaled(res->c,ptr->c,rhs);
2711 fwretval->_web3dval.native = res;
2712 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2713 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2714 fwretval->itype = 'W';
2715 return 1;
2716}
2717int SFVec3d_normalize(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2718 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2719 struct SFVec3d *res = malloc(fwtype->size_of);
2720 vecnormald(res->c,ptr->c);
2721 fwretval->_web3dval.native = res;
2722 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2723 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2724 fwretval->itype = 'W';
2725 return 1;
2726}
2727
2728int SFVec3d_negate(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2729 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2730 struct SFVec3d *res = malloc(fwtype->size_of);
2731 vecscaled(res->c,ptr->c,-1.0);
2732 fwretval->_web3dval.native = res;
2733 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
2734 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
2735 fwretval->itype = 'W';
2736 return 1;
2737}
2738int SFVec3d_length(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2739 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2740 double res;
2741 res = veclengthd(ptr->c);
2742 fwretval->_numeric = res;
2743 fwretval->itype = 'D';
2744 return 1;
2745}
2746int SFVec3d_dot(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2747 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2748 struct SFVec3d *rhs = fwpars[0]._web3dval.native;
2749 double res;
2750 res = vecdotd(ptr->c,rhs->c);
2751 fwretval->_numeric = res;
2752 fwretval->itype = 'D';
2753 return 1;
2754}
2755
2756int SFVec3d_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
2757 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2758 char buff[STRING], *str;
2759 int len;
2760 memset(buff, 0, STRING);
2761 sprintf(buff, "%.9g %.9g %.9g",
2762 ptr->c[0], ptr->c[1], ptr->c[2]);
2763 len = strlen(buff);
2764 str = malloc(len+1); //leak
2765 strcpy(str,buff);
2766 fwretval->_string = str;
2767 fwretval->itype = 'S';
2768 return 1;
2769}
2770
2771FWFunctionSpec (SFVec3d_Functions)[] = {
2772 {"add", SFVec3d_add, 'W',{1,-1,0,"W"}},
2773 {"cross", SFVec3d_cross, 'W',{1,-1,0,"W"}},
2774 {"divide", SFVec3d_divide, 'W',{1,-1,0,"D"}},
2775 {"dot", SFVec3d_dot, 'D',{1,-1,0,"W"}},
2776 {"length", SFVec3d_length, 'D',{0,-1,0,NULL}},
2777 {"multiply", SFVec3d_multiply, 'W',{1,-1,0,"D"}},
2778 {"negate", SFVec3d_negate, 'W',{0,-1,0,NULL}},
2779 {"normalize", SFVec3d_normalize, 'W',{0,-1,0,NULL}},
2780 {"subtract", SFVec3d_subtract, 'W',{1,-1,0,"W"}},
2781 {"toString", SFVec3d_toString, 'S',{0,-1,0,NULL}},
2782 {0}
2783};
2784
2785int SFVec3d_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
2786 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2787 int nr = 0;
2788 //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)
2789 if(index > -1 && index < 3){
2790 nr = 1;
2791 switch(index){
2792 case 0: //x
2793 case 1: //y
2794 case 2: //z
2795 fwretval->_numeric = ptr->c[index];
2796 break;
2797 default:
2798 nr = 0;
2799 }
2800 }
2801 fwretval->itype = 'D';
2802 return nr;
2803}
2804int SFVec3d_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
2805 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
2806 //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)
2807 if(index > -1 && index < 3){
2808 switch(index){
2809 case 0: //x
2810 case 1: //y
2811 case 2: //z
2812 ptr->c[index] = fwval->_numeric; //fwval->_web3dval.anyvrml->sffloat;
2813 break;
2814 }
2815 return TRUE;
2816 }
2817 return FALSE;
2818}
2819//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
2820void * SFVec3d_Constructor(FWType fwtype, int ic, FWval fwpars){
2821 int i;
2822 struct SFVec3d *ptr = malloc(fwtype->size_of); //garbage collector please
2823 if(ic == 3){
2824 for(i=0;i<3;i++)
2825 ptr->c[i] = fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
2826 }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
2827 //new SFxxx(myMF[i]);
2828 shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
2829 }
2830
2831 return (void *)ptr;
2832}
2833
2834FWPropertySpec (SFVec3d_Properties)[] = {
2835 {"x", 0, 'D', 0},
2836 {"y", 1, 'D', 0},
2837 {"z", 2, 'D', 0},
2838 {NULL,0,0,0},
2839};
2840ArgListType (SFVec3d_ConstructorArgs)[] = {
2841 {3,0,'T',"DDD"},
2842 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
2843 {-1,0,0,NULL},
2844};
2845//#define FIELDTYPE_SFVec3d 25
2846struct FWTYPE SFVec3dType = {
2847 FIELDTYPE_SFVec3d,
2848 'W',
2849 "SFVec3d",
2850 sizeof(struct SFVec3d), //sizeof(struct ),
2851 SFVec3d_Constructor, //constructor
2852 SFVec3d_ConstructorArgs, //constructor args
2853 SFVec3d_Properties, //Properties,
2854 NULL, //special iterator
2855 SFVec3d_Getter, //Getter,
2856 SFVec3d_Setter, //Setter,
2857 'D',0, //index prop type,readonly
2858 SFVec3d_Functions, //functions
2859};
2860
2861
2862//#define FIELDTYPE_MFVec3d 26
2863struct FWTYPE MFVec3dType = {
2864 FIELDTYPE_MFVec3d,
2865 'W',
2866 "MFVec3d",
2867 sizeof(struct Multi_Any), //sizeof(struct ),
2868 MFW_Constructor, //constructor
2869 MFW_ConstructorArgs, //constructor args
2870 MFW_Properties, //Properties,
2871 NULL, //special iterator
2872 MFW_Getter, //Getter,
2873 MFW_Setter, //Setter,
2874 'W',0, //index prop type,readonly
2875 MFW_Functions, //functions
2876};
2877
2878
2879
2880//#define FIELDTYPE_SFDouble 27
2881struct FWTYPE SFDoubleType = {
2882 FIELDTYPE_SFDouble,
2883 'D',
2884 "SFDouble",
2885 sizeof(double), //sizeof(struct ),
2886 NULL, //constructor
2887 NULL, //constructor args
2888 NULL, //Properties,
2889 NULL, //special iterator
2890 NULL, //Getter,
2891 NULL, //Setter,
2892 0,0, //index prop type,readonly
2893 SFDouble_Functions, //functions
2894};
2895
2896void * MFDouble_Constructor(FWType fwtype, int argc, FWval fwpars){
2897 int i, lenSF;
2898 char *p;
2899 struct Multi_Any *ptr = malloc(sizeof(struct Multi_Any));
2900 lenSF = sizeofSF(fwtype->itype);
2901 ptr->n = argc;
2902 ptr->p = NULL;
2903 if(ptr->n)
2904 ptr->p = malloc(ptr->n * lenSF); // This second part is resizable ie MF[i] = new SF() if i >= (.length), .length is expanded to accomodate
2905 p = ptr->p;
2906 for(i=0;i<ptr->n;i++){
2907 if(fwpars[i].itype == 'W')
2908 memcpy(p,&fwpars[i]._web3dval.native,lenSF);
2909 else if(fwpars[i].itype == 'D')
2910 memcpy(p,&fwpars[i]._numeric,lenSF);
2911 p += lenSF;
2912 }
2913 return (void *)ptr;
2914}
2915ArgListType (MFDouble_ConstructorArgs)[] = {
2916 {0,0,0,"D"},
2917 {-1,0,0,NULL},
2918};
2919
2920//#define FIELDTYPE_MFDouble 28
2921struct FWTYPE MFDoubleType = {
2922 FIELDTYPE_MFDouble,
2923 'W',
2924 "MFDouble",
2925 sizeof(struct Multi_Any), //sizeof(struct ),
2926 MFDouble_Constructor, //constructor
2927 MFDouble_ConstructorArgs, //constructor args
2928 MFW_Properties, //Properties,
2929 NULL, //special iterator
2930 MFW_Getter, //Getter,
2931 MFW_Setter, //Setter,
2932 'D',0, //index prop type,readonly
2933 MFW_Functions, //functions
2934};
2935
2936// http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#Matrix3
2937/* Matrix3
2938Interpretation
2939- x3dmatrix could be done as a javascript prototype: it doesn't need anything in C
2940- in javascript it would be doing all its math in double precision.
2941- so a C version can/should also work in double precision for equivalence
2942- x3dmatrix has no relationship to fieldtypes SFMatrixXX in the specs,
2943-- and javascript 3.3 specs don't show any services on them.
2944- There are 2 possible ways to integrate:
2945-- when assigning a X3DMatrixXX to a SFMatrixXX field and
2946-- when constructing an X3DMatrix with an SFMatrixXX parameter
2947Goals:
29481. flexible precision of input parameters.
2949pre-2023: no policing -assuming parameters are what the specs say they should be and memcpy binary
2950Option 1: strict policing of types to conform to specs
2951Option 2: flexible precision -- policing broken into 2 parts:
2952a) dimension checking -what's passed in should have the right number of dimensions or more-- and
2953b) precision conversion
2954Goal: option 2 flexible precision
29552. integration with SFMatrixXX data types, 2 ways:
2956a) X3DMatrixX( param ) constructor can take an SFMatrixXX of same dimension
2957b) SFMatrixXX field = X3DMatrixX will do dimension checking and precision conversion
29583. SFMatrixXX field types will have basic types so can be constructed, toString, and indexed, but rely on X3DMatrixX for math.
2959Implementation:
29601. change X3DMatrix3, 4 to double precision SFMatrixXd internal storage
29612. convert precision of incoming parameters, and police dimensions
29623. duk: change FWSetter to check dimension and convert precision on assignment
29634. add X3DMatrix types to SM
29645. add SF/MFMatrixXX types with toString, indexed getter/setter, constructor to both duk and sm
2965
2966
2967constr
2968X3DMatrix3 (numeric f11, numeric f12, numeric f13,
2969 numeric f21, numeric f22, numeric f23,
2970 numeric f31, numeric f32, numeric f33) The creation function shall initialize the array using zero or more SFVec3-valued expressions passed as parameters.
2971props
2972- row major single index
2973funcs
2974void setTransform(SFVec2f translation, SFVec3f rotation, SFVec2f scale, SFVec3f scaleOrientation, SFVec2f center)
2975 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.
2976void getTransform(SFVec2f translation, SFVec3f rotation, SFVec2f scale)
2977 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.
2978Matrix3 inverse()
2979 Returns a Matrix whose value is the inverse of this object.
2980Matrix3 transpose()
2981 Returns a Matrix whose value is the transpose of this object.
2982Matrix3 multLeft(Matrix3)
2983 Returns a Matrix whose value is the object multiplied by the passed matrix on the left.
2984Matrix3 multRight(Matrix3)
2985 Returns a Matrix whose value is the object multiplied by the passed matrix on the right.
2986SFVec2f multVecMatrix(SFVec2f vec)
2987 Returns an SFVec3f whose value is the object multiplied by the passed row vector.
2988SFVec2f multMatrixVec(SFVec2f vec)
2989 Returns an SFVec3f whose value is the object multiplied by the passed column vector.
2990String toString() Returns a String containing the matrix contents encoded using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
2991I assume they mean homogenous transform, 2D
2992[x'] [x y 1] X [c*sx s*sy px] [x] //px, py are 2D perspectives
2993[y'] = [-s*sx c*sy py] X [y]
2994[w ] [tx ty 1] [1] //tx,ty are 2D translations
2995x" = x'/w
2996y" = y'/w
2997dug9 complaint about Matrix3.getTransform, .setTransform july 2014:
2998A 2D planar rotation can be represented by a scalar angle. I have no idea where the angle
2999is in the SFVec3f. I could guess the angle is in [4] in the SFRotation, and assume
3000the axis part is 0,0,1.
3001I gather the reason they pass in complex types for rotations in setTransform is
3002a) so null can be used to signal no-value (but 0 for rotation would do the same)
3003b) because they want them returned in getTransform and to get something returned via
3004function args you have to pass in a pointer type, not an ecma primitive value.
3005Primitive values can't be returned through function args only through return vals.
3006They could have:
30071) broken the get into getScale, getRotation, getTranslation, and then the getRotation could return
3008an ecma numeric primitive, or
30092) numeric getTransform(scale,translation) with the numeric return val being the rotation, or
30103) defined an SFFloat complex type and passed it as a pointer object
3011I will implment july 2014 the rotations as scalar/primitive/numerics and do #2, which doesn't comply with specs
3012dug9 july 2023 regarding Matrix3.setTransform, .getTransform
3013Holger says:
3014"""
3015I do it this way:
3016https://create3000.github.io/x_ite/reference/field-services-and-objects#sfmatrix3dsfmatrix3f-object
3017With setTransform the rotation parameter is a number value, describing the rotation angle in radians.
3018With getTransform the rotation is a SFVec3f object, where x, and y are the complex value of the rotation,
3019and the z component is the rotation angle in radians.
3020"""
3021dug9: I'll try Holger way
3022*/
3023
3024
3025int X3DMatrix3_setTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3026 // http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/group.html#Transform
3027 // P' = T * C * R * SR * S * -SR * -C * P
3028 int i;// , j;
3029 double angle, scaleangle;
3030 struct SFVec2d translation;
3031 struct SFVec3d rotation;
3032 struct SFVec2d scale;
3033 struct SFVec3d scaleOrientation;
3034 struct SFVec2d center;
3035 double* matrix[3], m2[9], * mat[3], dtmp[3];
3036
3037 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3038 memset(&translation, 0, sizeof(struct SFVec2d));
3039 memset(&rotation, 0, sizeof(struct SFVec3d));
3040 memset(&center, 0, sizeof(struct SFVec2d));
3041 scale.c[0] = scale.c[1] = 1.0;
3042 memset(&scaleOrientation, 0, sizeof(struct SFVec3d));
3043 angle = scaleangle = 0.0;
3044
3045 //translation
3046 if (fwpars[0].itype == 'W') { //== FIELDTYPE_SFVec3f){
3047 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFVec2d, fwpars[0]._web3dval.native, (union anyVrml*)&translation);
3048 }
3049 //rotation
3050 if(fwpars[1].itype == 'W' ){ //== FIELDTYPE_SFVec3f){
3051 //rotation = fwpars[1]._web3dval.native;
3052 shallow_copy_field_precision(fwpars[1]._web3dval.fieldType, FIELDTYPE_SFVec3d, fwpars[1]._web3dval.native, (union anyVrml*)&rotation);
3053 angle = rotation.c[2]; //Holger getTransform method, last element angle in radians, 0,1 could be cos,sin
3054 }
3055 else if (fwpars[1].itype == 'F') {
3056 angle = (double)fwpars[1]._numeric; //Holger setTransform method, takes numeric
3057 }
3058 //scale
3059 if (fwpars[2].itype == 'W') {
3060 shallow_copy_field_precision(fwpars[2]._web3dval.fieldType, FIELDTYPE_SFVec2d, fwpars[2]._web3dval.native, (union anyVrml*)&scale);
3061 }
3062 //scaleorientation
3063 if(fwpars[3].itype == 'W'){
3064 shallow_copy_field_precision(fwpars[3]._web3dval.fieldType, FIELDTYPE_SFVec3d, fwpars[3]._web3dval.native, (union anyVrml*)&scaleOrientation);
3065 scaleangle = scaleOrientation.c[2]; //Holger getTransform method
3066 }
3067 else if (fwpars[3].itype == 'F') {
3068 scaleangle = (double)fwpars[3]._numeric; //Holger setTransform method
3069 }
3070 //center
3071 if (fwpars[4].itype == 'W') {
3072 shallow_copy_field_precision(fwpars[4]._web3dval.fieldType, FIELDTYPE_SFVec2d, fwpars[4]._web3dval.native, (union anyVrml*)&center);
3073 }
3074
3075 for(i=0;i<3;i++){
3076 matrix[i] = &ptr->c[i*3];
3077 mat[i] = &m2[i*3];
3078 }
3079 //initialize to Identity
3080 matidentity3d(matrix[0]);
3081
3082 //T
3083 //if(translation){
3084 matidentity3d(mat[0]);
3085 veccopy2d(mat[2], translation.c);
3086 matmultiply3d(matrix[0], mat[0], matrix[0]);
3087 //}
3088 //C
3089 //if(center){
3090 matidentity3d(mat[0]);
3091 veccopy2d(mat[2], center.c);
3092 matmultiply3d(matrix[0], mat[0], matrix[0]);
3093 //}
3094 //R
3095 if (angle != 0.0f) {
3096 matidentity3d(mat[0]);
3097 mat[0][0] = mat[1][1] = cos(angle);
3098 mat[0][1] = mat[1][0] = sin(angle);
3099 mat[1][0] = -mat[1][0];
3100 matmultiply3d(matrix[0], mat[0], matrix[0]);
3101 }
3102 //SR
3103 if (scaleangle != 0.0f) {
3104 matidentity3d(mat[0]);
3105 mat[0][0] = mat[1][1] = cos(scaleangle);
3106 mat[0][1] = mat[1][0] = sin(scaleangle);
3107 mat[1][0] = -mat[1][0];
3108 matmultiply3d(matrix[0], mat[0], matrix[0]);
3109 }
3110 //S
3111 //if(scale){
3112 matidentity3d(mat[0]);
3113 for (i = 0; i < 3; i++)
3114 vecmult2d(mat[i], mat[i], scale.c);
3115 matmultiply3d(matrix[0], mat[0], matrix[0]);
3116 //}
3117
3118 //-SR
3119 if (scaleangle != 0.0) {
3120 matidentity3d(mat[0]);
3121 mat[0][0] = mat[1][1] = cos(-scaleangle);
3122 mat[0][1] = mat[1][0] = sin(-scaleangle);
3123 mat[1][0] = -mat[1][0];
3124 matmultiply3d(matrix[0], mat[0], matrix[0]);
3125 }
3126
3127 //-C
3128 //if(center){
3129 matidentity3d(mat[0]);
3130 veccopy2d(mat[2],center.c);
3131 vecscale2d(mat[2], mat[2], -1.0);
3132 matmultiply3d(matrix[0],mat[0],matrix[0]);
3133 //}
3134
3135 return 0;
3136}
3137
3138int X3DMatrix3_getTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3139 //void getTransform(SFVec2f translation, SFVec3f rotation, SFVec2f scale)
3140 //H: we are supposed to return translation, rotation, scale
3141 double angle = 0.0;
3142 int i;
3143 struct SFVec2d scale;
3144 double *matrix[3], retscale[2];
3145
3146 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3147 struct SFVec2d translation;// = fwpars[0]._web3dval.native;
3148 struct SFVec3d rotation ;
3149 //if(fwpars[1].itype == 'W' && fwpars[1]._web3dval.fieldType == FIELDTYPE_SFVec3f){
3150 // rotation = fwpars[1]._web3dval.native;
3151 // angle = rotation->c[3]; //your guess is as good as mine
3152 //}else if(fwpars[1].itype == 'F'){
3153 // angle = (float)fwpars[1]._numeric;
3154 //}
3155 //scale = fwpars[2]._web3dval.native;
3156 for(i=0;i<3;i++)
3157 matrix[i] = &ptr->c[i*3];
3158
3159 //get row scales
3160 for(i=0;i<2;i++)
3161 retscale[i] = sqrt(vecdotd(matrix[i],matrix[i]));
3162 shallow_copy_field_precision(FIELDTYPE_SFVec2d, fwpars[2]._web3dval.fieldType, (union anyVrml*)retscale, fwpars[2]._web3dval.native );
3163 //if (translation) {
3164 veccopy2d(translation.c,matrix[2]);
3165 shallow_copy_field_precision(FIELDTYPE_SFVec2d, fwpars[0]._web3dval.fieldType, (union anyVrml*)&translation, fwpars[0]._web3dval.native);
3166
3167 //}
3168
3169 /* rotation */
3170 if (1) {
3171 /* apply length to each row to normalize upperleft 3x3 to rotations and shears*/
3172 double m2[9], ff;
3173 for(i=0;i<2;i++){
3174 ff = retscale[i];
3175 if(ff != 0.0f) ff = 1/ff;
3176 vecscaled(&m2[i*3],matrix[i],ff);
3177 }
3178 angle = atan2(m2[1],m2[2]); //right indexes? should be 0 and 1?
3179 /* now copy the values over */
3180 //if(rotation)
3181 memset(&rotation, 0, sizeof(struct SFVec3d));
3182 rotation.c[0] = cos(angle);
3183 rotation.c[1] = sin(angle);
3184 rotation.c[2] = angle;
3185 shallow_copy_field_precision(FIELDTYPE_SFVec3d, fwpars[1]._web3dval.fieldType, (union anyVrml*)&rotation, fwpars[1]._web3dval.native);
3186 }
3187
3188 /* scale */
3189 //if (scale) {
3190 // veccopy2f(scale->c,retscale);
3191 //}
3192
3193 fwretval->itype = 'F';
3194 fwretval->_numeric = angle;
3195 return 1;
3196}
3197
3198int X3DMatrix3_inverse(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3199 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3200 struct SFMatrix3d *ret = malloc(sizeof(struct SFMatrix3d));
3201
3202 //matrix3x3_inverse_double(ptr->c, ret->c);
3203 matinverse3d(ret->c, ptr->c);
3204
3205 fwretval->_pointer.native = ret;
3206 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
3207 fwretval->_pointer.gc = 'T';
3208 fwretval->itype = 'P';
3209 return 1;
3210}
3211int X3DMatrix3_transpose(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3212 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3213 struct SFMatrix3d *ret = malloc(sizeof(struct SFMatrix3d));
3214
3215 mattranspose3d(ret->c, ptr->c);
3216
3217 fwretval->_pointer.native = ret;
3218 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
3219 fwretval->_pointer.gc = 'T';
3220 fwretval->itype = 'P';
3221
3222 return 1;
3223}
3224int X3DMatrix3_multLeft(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3225 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3226 struct SFMatrix3d lhs; //= (struct SFMatrix3d*)fwpars[0]._web3dval.native;
3227 struct SFMatrix3d *ret = malloc(sizeof(struct SFMatrix3d));
3228 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix3d, fwpars[0]._web3dval.native, (union anyVrml*)&lhs);
3229
3230 matmultiply3d(ret->c, lhs.c , ptr->c);
3231
3232 fwretval->_pointer.native = ret;
3233 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
3234 fwretval->itype = 'P';
3235 fwretval->_pointer.gc = 'T';
3236 return 1;
3237}
3238int X3DMatrix3_multRight(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3239 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3240 struct SFMatrix3d rhs; //= (struct SFMatrix3f*)fwpars[0]._web3dval.native;
3241 struct SFMatrix3d *ret = malloc(sizeof(struct SFMatrix3d));
3242 fwretval->_pointer.native = ret;
3243 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix3d, fwpars[0]._web3dval.native, (union anyVrml*)&rhs);
3244
3245 matmultiply3d(ret->c, ptr->c, rhs.c);
3246
3247 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix3;
3248 fwretval->_pointer.gc = 'T';
3249 fwretval->itype = 'P';
3250 return 1;
3251}
3252int X3DMatrix3_multVecMatrix(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3253 // vec = mat x vec
3254 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3255 struct SFVec2d rhs; // = (struct SFVec2f*)fwpars[0]._web3dval.native;
3256 struct SFVec2d *ret = malloc(sizeof(struct SFVec2d));
3257
3258 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFVec2d, fwpars[0]._web3dval.native, (union anyVrml*)&rhs);
3259
3260 double a3[3], r3[3];
3261 veccopy2d(a3,rhs.c);
3262 a3[2] = 1.0;
3263 vecmultmat3d(r3, a3, ptr->c);
3264 if(r3[2] != 0.0){
3265 double wi = 1.0/r3[2];
3266 vecscale2d(ret->c,r3,wi);
3267 }else{
3268 veccopy2d(ret->c,r3);
3269 }
3270
3271 fwretval->_web3dval.native = ret;
3272 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3273 fwretval->_web3dval.gc = 'T';
3274 fwretval->itype = 'W';
3275 return 1;
3276}
3277int X3DMatrix3_multMatrixVec(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3278 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3279 struct SFVec2d rhs; // = (struct SFVec2f*)fwpars[0]._web3dval.native;
3280 struct SFVec2d *ret = malloc(sizeof(struct SFVec2d));
3281 double a3[3], r3[3];
3282 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFVec2d, fwpars[0]._web3dval.native, (union anyVrml*)&rhs);
3283
3284 veccopy2d(a3,rhs.c);
3285 a3[2] = 1.0f;
3286 matmultvec3d(r3, ptr->c,a3);
3287 if(r3[2] != 0.0f){
3288 double wi = 1.0/r3[2];
3289 vecscale2d(ret->c,r3,wi);
3290 }else{
3291 veccopy2d(ret->c,r3);
3292 }
3293
3294 fwretval->_web3dval.native = ret;
3295 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3296 fwretval->_web3dval.gc = 'T';
3297 fwretval->itype = 'W';
3298 return 1;
3299}
3300
3301int X3DMatrix3_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3302 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3303 char *str, *r;
3304 int i;
3305 FWType sfvec3dtype = getFWTYPE(FIELDTYPE_SFVec3d);
3306
3307 str = malloc(1);
3308 str[0] = 0;
3309 for(i=0;i<3;i++){
3310 r = sfToString(sfvec3dtype,&ptr->c[i*3]);
3311 str = realloc(str,strlen(str)+strlen(r)+3);
3312 str = strcat(str,r);
3313 str = strcat(str,", ");
3314 }
3315 fwretval->_string = str;
3316 fwretval->itype = 'S';
3317 return 1;
3318}
3319
3320FWFunctionSpec (X3DMatrix3_Functions)[] = {
3321 {"setTransform", X3DMatrix3_setTransform, 0,{5,-1,0,"WWWWW"}},
3322 {"getTransform", X3DMatrix3_getTransform, 'P',{3,-1,0,"WWW"}},
3323 {"inverse", X3DMatrix3_inverse, 'P',{0,-1,0,NULL}},
3324 {"transpose", X3DMatrix3_transpose, 'P',{0,-1,0,NULL}},
3325 {"multLeft", X3DMatrix3_multLeft, 'P',{1,-1,0,"P"}},
3326 {"multRight", X3DMatrix3_multRight, 'P',{1,-1,0,"P"}},
3327 {"multVecMatrix", X3DMatrix3_multVecMatrix, 'W',{1,-1,0,"W"}},
3328 {"multMatrixVec", X3DMatrix3_multMatrixVec, 'W',{1,-1,0,"W"}},
3329 {"toString", X3DMatrix3_toString, 'S',{0,-1,0,NULL}},
3330 {0}
3331};
3332
3333int X3DMatrix3_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
3334 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3335 int nr = 0;
3336 //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)
3337 if (0) {
3338 if (index > -1 && index < 9) {
3339 nr = 1;
3340 fwretval->_numeric = ptr->c[index];
3341 }
3342 fwretval->itype = 'F';
3343 }
3344 else {
3345 //double indexing [4][4], like Instant, Octaga do with VrmlMatrix
3346 double* ret; // = malloc(sizeof(struct SFVec3d));
3347
3348 if (index > -1 && index < 3) {
3349 nr = 1;
3350 //fwretval->_numeric = ptr->c[index];
3351 ret = &ptr->c[index * 3]; //return a row pointer so can do [3][2] double indexing
3352 fwretval->_web3dval.native = ret;
3353 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
3354 fwretval->_web3dval.gc = 0; // 'F';
3355 fwretval->itype = 'W';
3356 }
3357 }
3358
3359 return nr;
3360}
3361int X3DMatrix3_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
3362 struct SFMatrix3d *ptr = (struct SFMatrix3d *)fwn;
3363 //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)
3364 if(index > -1 && index < 9){
3365 if(fwval->itype == 'F'){
3366 ptr->c[index] = fwval->_numeric; //fwval->_web3dval.anyvrml->sffloat;
3367 return TRUE;
3368 }
3369 }
3370 return FALSE;
3371}
3372//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3373void * X3DMatrix3_Constructor(FWType fwtype, int ic, FWval fwpars){
3374 int i;
3375 struct SFMatrix3d *ptr = malloc(fwtype->size_of); //garbage collector please
3376 matidentity3d(ptr->c);
3377 if (fwpars[0].itype == 'W') {
3378 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix3d, fwpars[0]._web3dval.native, (union anyVrml*)ptr);
3379 }
3380 else if (fwpars[0].itype == 'F') {
3381 memset(ptr->c, 0, sizeof(struct SFMatrix3d));
3382 int ncopy = ic < 9 ? ic : 9;
3383 for (i = 0; i < ncopy; i++)
3384 ptr->c[i] = fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
3385 }
3386 return (void *)ptr;
3387}
3388
3389ArgListType (X3DMatrix3_ConstructorArgs)[] = {
3390 {0,0,'F',"FFFFFFFFF"},
3391 {1,0,'T',"W"},
3392 {-1,0,0,NULL},
3393};
3394//#define FIELDTYPE_SFMatrix3f 29
3395struct FWTYPE X3DMatrix3Type = {
3396 AUXTYPE_X3DMatrix3,
3397 'P',
3398 "X3DMatrix3",
3399 sizeof(struct SFMatrix3d), //sizeof(struct ),
3400 X3DMatrix3_Constructor, //constructor
3401 X3DMatrix3_ConstructorArgs, //constructor args
3402 NULL, //Properties,
3403 NULL, //special iterator
3404 X3DMatrix3_Getter, //Getter,
3405 X3DMatrix3_Setter, //Setter,
3406 'F',0, //index prop type,readonly
3407 X3DMatrix3_Functions, //functions
3408};
3409
3410
3411/*
3412Matrix4
3413http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#Matrix4
3414"The translation elements are in the fourth row. For example, x3dMatrixObjectName[3][0] is the X offset"
3415- I assume its a 4x4 homogenous transform matrix
3416[x'] [x y z 1] X [ scale px] where px,py,pz are perspectives ie pz = 1/focal-length
3417[y'] = [ and py]
3418[z'] [ rot pz]
3419[w ] [tx ty tz 1] and tx,ty,tz are translations
3420x" = x'/w
3421y" = y'/w
3422z" = z'/w
3423
3424constr
3425X3DMatrix4 (numeric f11, numeric f12, numeric f13, numeric f14,
3426 numeric f21, numeric f22, numeric f23, numeric f24,
3427 numeric f31, numeric f32, numeric f33, numeric f34,
3428 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.
3429props
3430array-style indexing row-major order
3431funcs
3432void setTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale, SFRotation scaleOrientation, SFVec3f center)
3433 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.
3434void getTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale)
3435 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.
3436Matrix4 inverse() Returns a Matrix whose value is the inverse of this object.
3437Matrix4 transpose() Returns a Matrix whose value is the transpose of this object.
3438Matrix4 multLeft(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the left.
3439Matrix4 multRight(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the right.
3440SFVec3f multVecMatrix(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed row vector.
3441SFVec3f multMatrixVec(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed column vector.
3442String toString() Returns a String containing the matrix contents encoded using the X3D Classic VRML encoding (see part 2 of ISO/IEC 19776).
3443
3444*/
3445
3446int X3DMatrix4_setTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3447 //void setTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale, SFRotation scaleOrientation, SFVec3f center)
3448 // http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/group.html#Transform
3449 // P' = T * C * R * SR * S * -SR * -C * P
3450 int i;// , j;
3451 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3452 struct SFVec3d translation; // = fwpars[0]._web3dval.native;
3453 struct SFRotation rotation; // = fwpars[1]._web3dval.native;
3454 struct SFVec3d scale; // = fwpars[2]._web3dval.native;
3455 struct SFRotation scaleOrientation; // = fwpars[3]._web3dval.native;
3456 struct SFVec3d center; // = fwpars[4]._web3dval.native;
3457 //set up some [][] helpers for clarity
3458 double *matrix[4], *mat[4], m2[16];
3459
3460 memset(&translation, 0, sizeof(struct SFVec3d));
3461 memset(&rotation, 0, sizeof(struct SFRotation));
3462 memset(&scale, 0, sizeof(struct SFVec3d));
3463 memset(&scaleOrientation, 0, sizeof(struct SFRotation));
3464 memset(&center, 0, sizeof(struct SFVec3d));
3465 scale.c[0] = scale.c[1] = scale.c[2] = 1.0;
3466 rotation.c[0] = 1.0f;
3467
3468 if (argc > 0 && fwpars[0].itype == 'W') {
3469 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFVec3d, fwpars[0]._web3dval.native, (union anyVrml*)&translation);
3470 }
3471 if (argc > 1 && fwpars[1].itype == 'W') {
3472 shallow_copy_field_precision(fwpars[1]._web3dval.fieldType, FIELDTYPE_SFRotation, fwpars[1]._web3dval.native, (union anyVrml*)&rotation);
3473 }
3474 if (argc > 2 && fwpars[2].itype == 'W') {
3475 shallow_copy_field_precision(fwpars[2]._web3dval.fieldType, FIELDTYPE_SFVec3d, fwpars[2]._web3dval.native, (union anyVrml*)&scale);
3476 }
3477 if (argc > 3 && fwpars[3].itype == 'W') {
3478 shallow_copy_field_precision(fwpars[3]._web3dval.fieldType, FIELDTYPE_SFRotation, fwpars[3]._web3dval.native, (union anyVrml*)&scaleOrientation);
3479 }
3480 if (argc > 4 && fwpars[4].itype == 'W') {
3481 shallow_copy_field_precision(fwpars[4]._web3dval.fieldType, FIELDTYPE_SFVec3d, fwpars[4]._web3dval.native, (union anyVrml*)&center);
3482 }
3483
3484 for(i=0;i<4;i++){
3485 matrix[i] = &ptr->c[i*4]; //our current matrix3
3486 mat[i] = &m2[i*4]; //scratch matrix
3487 }
3488 //initialize to Identity
3489 matidentity4d(matrix[0]);
3490
3491
3492
3493 //T
3494 //if(translation){
3495 matidentity4d(mat[0]);
3496 veccopyd(mat[3], translation.c);
3497 matmultiplyFULL(matrix[0], mat[0], matrix[0]);
3498 //}
3499 //C
3500 //if(center){
3501 matidentity4d(mat[0]);
3502 veccopyd(mat[3], center.c);
3503 matmultiplyFULL(matrix[0], mat[0], matrix[0]);
3504 //}
3505
3506 //R
3507 //if(rotation){
3508 matidentity4d(mat[0]);
3509 for (i = 0; i < 3; i++)
3510 axisangle_rotate3d(mat[i], mat[i], rotation.c);
3511 matmultiplyFULL(matrix[0], mat[0], matrix[0]);
3512 //}
3513
3514 //SR
3515 //if(scaleOrientation){
3516 matidentity4d(mat[0]);
3517 for (i = 0; i < 3; i++)
3518 axisangle_rotate3d(mat[i], mat[i], scaleOrientation.c);
3519 matmultiplyFULL(matrix[0], mat[0], matrix[0]);
3520 //}
3521
3522 //S
3523 //if(scale){
3524 matidentity4d(mat[0]);
3525 for (i = 0; i < 4; i++)
3526 vecmult3d(mat[i], mat[i], scale.c);
3527 matmultiplyFULL(matrix[0], mat[0], matrix[0]);
3528 //}
3529
3530 //
3531 //-SR
3532 //if(scaleOrientation){
3533 scaleOrientation.c[3] = -scaleOrientation.c[3];
3534 matidentity4d(mat[0]);
3535 for (i = 0; i < 3; i++)
3536 axisangle_rotate3d(mat[i], mat[i], scaleOrientation.c);
3537 matmultiplyFULL(matrix[0], mat[0], matrix[0]);
3538 scaleOrientation.c[3] = -scaleOrientation.c[3];
3539 //}
3540
3541 //-C
3542 //if(center){
3543 matidentity4d(mat[0]);
3544 veccopyd(mat[3], center.c);
3545 vecscaled(mat[3], mat[3], -1.0f);
3546 matmultiplyFULL(matrix[0], mat[0], matrix[0]);
3547 //}
3548
3549 return 0;
3550}
3551
3552int X3DMatrix4_getTransform(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3553 //void getTransform(SFVec3f translation, SFRotation rotation, SFVec3f scale)
3554 int i;
3555 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3556 struct SFVec3d translation; // = fwpars[0]._web3dval.native;
3557 struct SFRotation rotation; // = fwpars[1]._web3dval.native;
3558 struct SFVec3d scale; // = fwpars[2]._web3dval.native;
3559 double *matrix[4], retscale[3];
3560 double matrixd[16];
3561 Quaternion quat;
3562 double qu[4];
3563 //double r0[4], r1[4], r2[4];
3564 for(i=0;i<4;i++)
3565 matrix[i] = &ptr->c[i*4];
3566
3567 //get row scales
3568 for(i=0;i<3;i++)
3569 retscale[i] = sqrt(vecdot4d(matrix[i],matrix[i]));
3570
3571 //if (translation) {
3572 veccopyd(translation.c,matrix[3]);
3573 //}
3574
3575 /* rotation */
3576 //if (rotation) {
3577 /* apply length to each row to normalize upperleft 3x3 to rotations and shears*/
3578 double m2[16], ff;
3579 for(i=0;i<3;i++){
3580 ff = retscale[i];
3581 if(ff != 0.0) ff = 1.0/ff;
3582 vecscale4d(&m2[i*4],matrix[i],ff);
3583 }
3584 /* convert the matrix to a quaternion */
3585 //for(i=0;i<16;i++) matrixd[i] = (double) m2[i];
3586 matrix_to_quaternion(&quat, m2); // matrixd);
3587 #ifdef JSVRMLCLASSESVERBOSE
3588 printf ("quaternion %f %f %f %f\n",quat.x,quat.y,quat.z,quat.w);
3589 #endif
3590
3591 /* convert the quaternion to a VRML rotation */
3592 quaternion_to_vrmlrot(&quat, &qu[0],&qu[1],&qu[2],&qu[3]);
3593
3594 /* now copy the values over */
3595 for (i=0; i<4; i++)
3596 rotation.c[i] = (float) qu[i];
3597 //}
3598
3599 /* scale */
3600 //if (scale) {
3601 veccopyd(scale.c,retscale);
3602 //}
3603 //translation
3604 if (argc > 0 && fwpars[0].itype == 'W') {
3605 shallow_copy_field_precision(FIELDTYPE_SFVec3d, fwpars[0]._web3dval.fieldType, (union anyVrml*)&translation, fwpars[0]._web3dval.native );
3606 }
3607 //rotation
3608 if (argc > 1 && fwpars[1].itype == 'W') {
3609 shallow_copy_field_precision(FIELDTYPE_SFRotation, fwpars[1]._web3dval.fieldType, (union anyVrml*)&rotation, fwpars[1]._web3dval.native);
3610 }
3611 //scale
3612 if (argc > 2 && fwpars[2].itype == 'W') {
3613 shallow_copy_field_precision(FIELDTYPE_SFVec3d, fwpars[2]._web3dval.fieldType, (union anyVrml*)&scale, fwpars[2]._web3dval.native);
3614 }
3615
3616 return 0;
3617}
3618
3619int X3DMatrix4_inverse(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3620 //Matrix4 inverse()
3621 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3622 struct SFMatrix4d *ret = malloc(sizeof(struct SFMatrix4d));
3623
3624 matinverseFULL(ret->c,ptr->c);
3625
3626 fwretval->_pointer.native = ret;
3627 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3628 fwretval->_pointer.gc = 'T';
3629 fwretval->itype = 'P';
3630 return 1;
3631}
3632int X3DMatrix4_transpose(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3633 //Matrix4 transpose() Returns a Matrix whose value is the transpose of this object.
3634 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3635 struct SFMatrix4d *ret = malloc(sizeof(struct SFMatrix4d));
3636
3637 mattranspose(ret->c, ptr->c);
3638
3639 fwretval->_pointer.native = ret;
3640 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3641 fwretval->_pointer.gc = 'T';
3642 fwretval->itype = 'P';
3643
3644 return 1;
3645}
3646int X3DMatrix4_multLeft(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3647 //Matrix4 multLeft(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the left.
3648
3649 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3650 struct SFMatrix4d rhs; //= (struct SFMatrix4d*)fwpars[0]._web3dval.native;
3651 struct SFMatrix4d *ret = malloc(sizeof(struct SFMatrix4d));
3652 matidentity4d(ret->c);
3653 if (argc > 0 && (fwpars[0].itype == 'P' || fwpars[0].itype == 'W')) {
3654 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix4d, fwpars[0]._web3dval.native, (union anyVrml*)&rhs);
3655 matmultiplyFULL(ret->c, rhs.c, ptr->c);
3656 }
3657
3658
3659 fwretval->_pointer.native = ret;
3660 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3661 fwretval->_pointer.gc = 'T';
3662 fwretval->itype = 'P';
3663 return 1;
3664}
3665int X3DMatrix4_multRight(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3666 //Matrix4 multRight(Matrix4 matrix) Returns a Matrix whose value is the object multiplied by the passed matrix on the right.
3667 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3668 struct SFMatrix4d rhs; //= (struct SFMatrix4d*)fwpars[0]._web3dval.native;
3669 struct SFMatrix4d *ret = malloc(sizeof(struct SFMatrix4d));
3670 fwretval->_pointer.native = ret;
3671 matidentity4d(rhs.c);
3672 if (argc > 0 && (fwpars[0].itype == 'W' || fwpars[0].itype == 'P')) {
3673 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix4d, fwpars[0]._web3dval.native, (union anyVrml*)&rhs);
3674 }
3675
3676 matmultiplyFULL(ret->c,ptr->c,rhs.c);
3677
3678 fwretval->_pointer.fieldType = AUXTYPE_X3DMatrix4;
3679 fwretval->_pointer.gc = 'T';
3680 fwretval->itype = 'P';
3681 return 1;
3682}
3683int X3DMatrix4_multVecMatrix(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3684 //SFVec3f multVecMatrix(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed row vector.
3685 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3686 struct SFVec3d rhs; // = (struct SFVec3f*)fwpars[0]._web3dval.native;
3687 struct SFVec3d *ret = malloc(sizeof(struct SFVec3d));
3688 memset(rhs.c,0,sizeof(struct SFVec3d));
3689 if (argc > 0 && fwpars[0].itype == 'W') {
3690 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFVec3d, fwpars[0]._web3dval.native, (union anyVrml*)&rhs);
3691 }
3692
3693 double a4[4], r4[4];
3694 veccopyd(a4,rhs.c);
3695 a4[3] = 1.0;
3696 vecmultmat4d(r4, a4, ptr->c);
3697 if(r4[3] != 0.0){
3698 double wi = 1.0/r4[3];
3699 vecscaled(ret->c,r4,wi);
3700 }else{
3701 veccopyd(ret->c,r4);
3702 }
3703
3704 fwretval->_web3dval.native = ret;
3705 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
3706 fwretval->_web3dval.gc = 'T';
3707 fwretval->itype = 'W';
3708 return 1;
3709}
3710int X3DMatrix4_multMatrixVec(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3711 //SFVec3f multMatrixVec(SFVec3f vec) Returns an SFVec3f whose value is the object multiplied by the passed column vector.
3712 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3713 struct SFVec3d rhs; // = (struct SFVec3f*)fwpars[0]._web3dval.native;
3714 struct SFVec3d *ret = malloc(sizeof(struct SFVec3d));
3715//float* matmultvec4f(float* r4, float *mat4, float* a4 );
3716 double a4[4], r4[4];
3717
3718 memset(rhs.c, 0, sizeof(struct SFVec3d));
3719 if (argc > 0 && fwpars[0].itype == 'W') {
3720 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFVec3d, fwpars[0]._web3dval.native, (union anyVrml*)&rhs);
3721 }
3722
3723 veccopyd(a4,rhs.c);
3724 a4[3] = 1.0;
3725 matmultvec4d(r4, ptr->c, a4 );
3726 if(r4[3] != 0.0){
3727 double wi = 1.0/r4[3];
3728 vecscaled(ret->c,r4,wi);
3729 }else{
3730 veccopyd(ret->c,r4);
3731 }
3732
3733 fwretval->_web3dval.native = ret;
3734 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec3d;
3735 fwretval->_web3dval.gc = 'T';
3736 fwretval->itype = 'W';
3737 return 1;
3738}
3739
3740int X3DMatrix4_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3741 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3742 char *str, *r;
3743 int i;
3744 FWType sfvec4dtype = getFWTYPE(FIELDTYPE_SFVec4d);
3745
3746 str = malloc(1);
3747 str[0] = 0;
3748 for(i=0;i<4;i++){
3749 r = sfToString(sfvec4dtype,&ptr->c[i*4]);
3750 str = realloc(str,strlen(str)+strlen(r)+3);
3751 str = strcat(str,r);
3752 str = strcat(str, ", ");
3753 }
3754 fwretval->_string = str;
3755 fwretval->itype = 'S';
3756 return 1;
3757}
3758
3759
3760FWFunctionSpec (X3DMatrix4_Functions)[] = {
3761 {"setTransform", X3DMatrix4_setTransform, 0,{5,-1,0,"WWWWW"}},
3762 {"getTransform", X3DMatrix4_getTransform, 'P',{3,-1,0,"WWW"}},
3763 {"inverse", X3DMatrix4_inverse, 'P',{0,-1,0,NULL}},
3764 {"transpose", X3DMatrix4_transpose, 'P',{0,-1,0,NULL}},
3765 {"multLeft", X3DMatrix4_multLeft, 'P',{1,-1,0,"P"}},
3766 {"multRight", X3DMatrix4_multRight, 'P',{1,-1,0,"P"}},
3767 {"multVecMatrix", X3DMatrix4_multVecMatrix, 'W',{1,-1,0,"W"}},
3768 {"multMatrixVec", X3DMatrix4_multMatrixVec, 'W',{1,-1,0,"W"}},
3769 {"toString", X3DMatrix4_toString, 'S',{0,-1,0,NULL}},
3770 {0}
3771};
3772
3773int X3DMatrix4_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
3774 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3775 int nr = 0;
3776 //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)
3777 if (1) {
3778 //double indexing [4][4], like Instant, Octaga do with VrmlMatrix
3779 double *ret; // = malloc(sizeof(struct SFVec3d));
3780
3781 if (index > -1 && index < 4) {
3782 nr = 1;
3783 //fwretval->_numeric = ptr->c[index];
3784 ret = &ptr->c[index * 4]; //return a row pointer so can do [3][2] double indexing
3785 fwretval->_web3dval.native = ret;
3786 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec4d;
3787 fwretval->_web3dval.gc = 0; // 'F';
3788 fwretval->itype = 'W';
3789 }
3790 }
3791 else {
3792 //single indexing
3793 if (index > -1 && index < 16) {
3794 nr = 1;
3795 fwretval->_numeric = ptr->c[index];
3796 }
3797 fwretval->itype = 'F';
3798 }
3799 return nr;
3800}
3801int X3DMatrix4_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
3802 struct SFMatrix4d *ptr = (struct SFMatrix4d *)fwn;
3803 //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)
3804 if (1) {
3805 //double indexing
3806 printf("Matrix4 setter itype == %d\n ",fwval->itype);
3807 }
3808 else {
3809 if (index > -1 && index < 16) {
3810 if (fwval->itype == 'F') {
3811 ptr->c[index] = fwval->_numeric; //fwval->_web3dval.anyvrml->sffloat;
3812 return TRUE;
3813 }
3814 }
3815 }
3816 return FALSE;
3817}
3818//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3819void * X3DMatrix4_Constructor(FWType fwtype, int ic, FWval fwpars){
3820 int i;
3821 struct SFMatrix4d *ptr = malloc(fwtype->size_of); //garbage collector please
3822 matidentity4d(ptr->c);
3823
3824 if (ic > 0 && fwpars[0].itype == 'W') {
3825 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix4d, fwpars[0]._web3dval.native, (union anyVrml*)ptr);
3826 }
3827 else if (ic > 0 && fwpars[0].itype == 'F') {
3828 memset(ptr->c, 0, sizeof(struct SFMatrix4d));
3829 int ncopy = ic < 16 ? ic : 16;
3830 for (i = 0; i < ncopy; i++)
3831 ptr->c[i] = fwpars[i]._numeric;
3832 }
3833 return (void *)ptr;
3834}
3835
3836ArgListType (X3DMatrix4_ConstructorArgs)[] = {
3837 {0,0,'F',"FFFFFFFFFFFFFFFF"},
3838 {1,0,'T',"W"},
3839 {-1,0,0,NULL},
3840};
3841
3842struct FWTYPE X3DMatrix4Type = {
3843 AUXTYPE_X3DMatrix4,
3844 'P',
3845 "X3DMatrix4",
3846 sizeof(struct SFMatrix4d), //sizeof(struct ),
3847 X3DMatrix4_Constructor, //constructor
3848 X3DMatrix4_ConstructorArgs, //constructor args
3849 NULL, //Properties,
3850 NULL, //special iterator
3851 X3DMatrix4_Getter, //Getter,
3852 X3DMatrix4_Setter, //Setter,
3853 'F',0, //index prop type,readonly
3854 X3DMatrix4_Functions, //functions
3855};
3856
3857// VrmlMatrix (same as Matrix4, can delegate)
3858
3859int VrmlMatrix_setTransform(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3860 int iret = X3DMatrix4_setTransform(fwtype, ec, fwn, argc, fwpars, fwretval);
3861 return iret;
3862}
3863
3864int VrmlMatrix_getTransform(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3865 int iret = X3DMatrix4_getTransform(fwtype, ec, fwn, argc,fwpars, fwretval);
3866 return iret;
3867}
3868
3869int VrmlMatrix_inverse(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3870 int iret = X3DMatrix4_inverse(fwtype, ec, fwn, argc, fwpars, fwretval);
3871 fwretval->_pointer.fieldType = AUXTYPE_VrmlMatrix;
3872 return iret;
3873}
3874int VrmlMatrix_transpose(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3875 int iret = X3DMatrix4_transpose(fwtype, ec, fwn, argc, fwpars, fwretval);
3876 fwretval->_pointer.fieldType = AUXTYPE_VrmlMatrix;
3877 return iret;
3878}
3879int VrmlMatrix_multLeft(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3880 int iret = X3DMatrix4_multLeft(fwtype, ec, fwn, argc, fwpars, fwretval);
3881 fwretval->_pointer.fieldType = AUXTYPE_VrmlMatrix;
3882 return iret;
3883}
3884int VrmlMatrix_multRight(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3885 int iret = X3DMatrix4_multRight(fwtype, ec, fwn, argc, fwpars, fwretval);
3886 fwretval->_pointer.fieldType = AUXTYPE_VrmlMatrix;
3887 return iret;
3888}
3889int VrmlMatrix_multVecMatrix(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3890 int iret = X3DMatrix4_multVecMatrix(fwtype, ec, fwn, argc, fwpars, fwretval);
3891 return iret;
3892}
3893int VrmlMatrix_multMatrixVec(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3894 int iret = X3DMatrix4_multMatrixVec(fwtype, ec, fwn, argc, fwpars, fwretval);
3895 return iret;
3896}
3897
3898int VrmlMatrix_toString(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
3899 int iret = X3DMatrix4_toString(fwtype, ec, fwn, argc, fwpars, fwretval);
3900 return iret;
3901}
3902
3903
3904FWFunctionSpec(VrmlMatrix_Functions)[] = {
3905 {"setTransform", VrmlMatrix_setTransform, 0,{5,-1,0,"WWWWW"}},
3906 {"getTransform", VrmlMatrix_getTransform, 'P',{3,-1,0,"WWW"}},
3907 {"inverse", VrmlMatrix_inverse, 'P',{0,-1,0,NULL}},
3908 {"transpose", VrmlMatrix_transpose, 'P',{0,-1,0,NULL}},
3909 {"multLeft", VrmlMatrix_multLeft, 'P',{1,-1,0,"P"}},
3910 {"multRight", VrmlMatrix_multRight, 'P',{1,-1,0,"P"}},
3911 {"multVecMatrix", VrmlMatrix_multVecMatrix, 'W',{1,-1,0,"W"}},
3912 {"multMatrixVec", VrmlMatrix_multMatrixVec, 'W',{1,-1,0,"W"}},
3913 {"toString", VrmlMatrix_toString, 'S',{0,-1,0,NULL}},
3914 {0}
3915};
3916
3917int VrmlMatrix_Getter(FWType fwt, int index, void* ec, void* fwn, FWval fwretval) {
3918 int iret = X3DMatrix4_Getter(fwt, index, ec, fwn, fwretval);
3919 return iret;
3920}
3921int VrmlMatrix_Setter(FWType fwt, int index, void* ec, void* fwn, FWval fwval) {
3922 int iret = X3DMatrix4_Setter(fwt, index, ec, fwn, fwval);
3923 return iret;
3924}
3925//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
3926void* VrmlMatrix_Constructor(FWType fwtype, int ic, FWval fwpars) {
3927 void* ret = X3DMatrix4_Constructor(fwtype, ic, fwpars);
3928 return ret;
3929}
3930
3931ArgListType(VrmlMatrix_ConstructorArgs)[] = {
3932 {0,0,'F',"FFFFFFFFFFFFFFFF"},
3933 {1,0,'T',"W"},
3934 {-1,0,0,NULL},
3935};
3936
3937struct FWTYPE VrmlMatrixType = {
3938 AUXTYPE_VrmlMatrix,
3939 'P',
3940 "VrmlMatrix",
3941 sizeof(struct SFMatrix4d), //sizeof(struct ),
3942 VrmlMatrix_Constructor, //constructor
3943 VrmlMatrix_ConstructorArgs, //constructor args
3944 NULL, //Properties,
3945 NULL, //special iterator
3946 VrmlMatrix_Getter, //Getter,
3947 VrmlMatrix_Setter, //Setter,
3948 'F',0, //index prop type,readonly
3949 VrmlMatrix_Functions, //functions
3950};
3951
3952
3953
3954
3955// http://www.web3d.org/files/specifications/19777-1/V3.0/Part1/functions.html#SFVec2d
3956/* SFVec2d
3957Constructor
3958SFVec2d (numeric x, numeric y) Missing values default to 0.0d+00.
3959props
3960numeric x No First value of the vector
3961numeric y No Second value of the vector
3962funcs
3963SFVec2d add(SFVec2d vec) Returns the value of the passed value added, component-wise, to the object.
3964SFVec2d divide(numeric n) Returns the value of the object divided by the passed value.
3965numeric dot(SFVec2d vec) Returns the dot product of this vector and the passed value.
3966numeric length() Returns the geometric length of this vector.
3967SFVec2d multiply(numeric n) Returns the value of the object multiplied by the passed value.
3968SFVec2d normalize() Returns the object converted to unit length .
3969SFVec2d subtract(SFVec2d vec) Returns the value of the passed value subtracted, component-wise, from the object.
3970String 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).
3971*/
3972
3973int SFVec2d_add(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3974 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3975 struct SFVec2d *rhs = fwpars[0]._web3dval.native;
3976 struct SFVec2d *res = malloc(fwtype->size_of);
3977 vecadd2d(res->c,ptr->c,rhs->c);
3978 fwretval->_web3dval.native = res;
3979 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3980 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
3981 fwretval->itype = 'W';
3982 return 1;
3983}
3984int SFVec2d_subtract(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3985 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3986 struct SFVec2d *rhs = fwpars[0]._web3dval.native;
3987 struct SFVec2d *res = malloc(fwtype->size_of);
3988 vecdif2d(res->c,ptr->c,rhs->c);
3989 fwretval->_web3dval.native = res;
3990 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
3991 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
3992 fwretval->itype = 'W';
3993 return 1;
3994}
3995int SFVec2d_divide(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
3996 struct SFVec2d *res;
3997 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
3998 double rhs = fwpars[0]._numeric;
3999 if(rhs == 0.0){
4000 return 0;
4001 }
4002 rhs = 1.0/rhs;
4003 res = malloc(fwtype->size_of);
4004 vecscale2d(res->c,ptr->c,rhs);
4005 fwretval->_web3dval.native = res;
4006 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
4007 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
4008 fwretval->itype = 'W';
4009 return 1;
4010}
4011int SFVec2d_multiply(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
4012 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
4013 double rhs = fwpars[0]._numeric;
4014 struct SFVec2d *res = malloc(fwtype->size_of);
4015 vecscale2d(res->c,ptr->c,rhs);
4016 fwretval->_web3dval.native = res;
4017 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
4018 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
4019 fwretval->itype = 'W';
4020 return 1;
4021}
4022int SFVec2d_normalize(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
4023 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
4024 struct SFVec2d *res = malloc(fwtype->size_of);
4025 vecnormal2d(res->c,ptr->c);
4026 fwretval->_web3dval.native = res;
4027 fwretval->_web3dval.fieldType = FIELDTYPE_SFVec2d;
4028 fwretval->_web3dval.gc = 'T'; //garbage collect .native (with C free(.native)) when proxy obj is gc'd.
4029 fwretval->itype = 'W';
4030 return 1;
4031}
4032
4033int SFVec2d_length(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
4034 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
4035 double res;
4036 res = veclength2d(ptr->c);
4037 fwretval->_numeric = res;
4038 fwretval->itype = 'D';
4039 return 1;
4040}
4041int SFVec2d_dot(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
4042 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
4043 struct SFVec2d *rhs = fwpars[0]._web3dval.native;
4044 double res;
4045 res = vecdot2d(ptr->c,rhs->c);
4046 fwretval->_numeric = res;
4047 fwretval->itype = 'D';
4048 return 1;
4049}
4050int SFVec2d_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
4051 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
4052 char buff[STRING], *str;
4053 int len;
4054 memset(buff, 0, STRING);
4055 sprintf(buff, "%.9g %.9g",
4056 ptr->c[0], ptr->c[1]);
4057 len = strlen(buff);
4058 str = malloc(len+1); //leak
4059 strcpy(str,buff);
4060 fwretval->_string = str;
4061 fwretval->itype = 'S';
4062 return 1;
4063}
4064FWFunctionSpec (SFVec2d_Functions)[] = {
4065 {"add", SFVec2d_add, 'W',{1,-1,0,"W"}},
4066 {"divide", SFVec2d_divide, 'W',{1,-1,0,"D"}},
4067 {"dot", SFVec2d_dot, 'D',{1,-1,0,"W"}},
4068 {"length", SFVec2d_length, 'D',{0,-1,0,NULL}},
4069 {"multiply", SFVec2d_multiply, 'W',{1,-1,0,"D"}},
4070 {"normalize", SFVec2d_normalize, 'W',{0,-1,0,NULL}},
4071 {"subtract", SFVec2d_subtract, 'W',{1,-1,0,"W"}},
4072 {"toString", SFVec2d_toString, 'S',{0,-1,0,NULL}},
4073 {0}
4074};
4075
4076int SFVec2d_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
4077 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
4078 int nr = 0;
4079 //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)
4080 if(index > -1 && index < 2){
4081 nr = 1;
4082 switch(index){
4083 case 0: //x
4084 case 1: //y
4085 fwretval->_numeric = ptr->c[index];
4086 break;
4087 default:
4088 nr = 0;
4089 }
4090 }
4091 fwretval->itype = 'D';
4092 return nr;
4093}
4094int SFVec2d_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
4095 struct SFVec2d *ptr = (struct SFVec2d *)fwn;
4096 //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)
4097 if(index > -1 && index < 2){
4098 switch(index){
4099 case 0: //x
4100 case 1: //y
4101 ptr->c[index] = fwval->_numeric;
4102 break;
4103 }
4104 return TRUE;
4105 }
4106 return FALSE;
4107}
4108//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
4109void * SFVec2d_Constructor(FWType fwtype, int ic, FWval fwpars){
4110 int i;
4111 struct SFVec2d *ptr = malloc(fwtype->size_of); //garbage collector please
4112 memset(ptr,0,fwtype->size_of);
4113 if(ic == 2){
4114 for(i=0;i<2;i++)
4115 ptr->c[i] = fwpars[i]._numeric;
4116 }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
4117 //new SFxxx(myMF[i]);
4118 shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
4119 }
4120
4121 return (void *)ptr;
4122}
4123
4124FWPropertySpec (SFVec2d_Properties)[] = {
4125 {"x", 0, 'D', 0},
4126 {"y", 1, 'D', 0},
4127 {NULL,0,0,0},
4128};
4129ArgListType (SFVec2d_ConstructorArgs)[] = {
4130 {2,0,'T',"DD"},
4131 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
4132 {-1,0,0,NULL},
4133};
4134
4135//#define FIELDTYPE_SFVec2d 37
4136struct FWTYPE SFVec2dType = {
4137 FIELDTYPE_SFVec2d,
4138 'W',
4139 "SFVec2d",
4140 sizeof(struct SFVec2d), //sizeof(struct ),
4141 SFVec2d_Constructor, //constructor
4142 SFVec2d_ConstructorArgs, //constructor args
4143 SFVec2d_Properties, //Properties,
4144 NULL, //special iterator
4145 SFVec2d_Getter, //Getter,
4146 SFVec2d_Setter, //Setter,
4147 'D',0, //index prop type,readonly
4148 SFVec2d_Functions, //functions
4149};
4150
4151//#define FIELDTYPE_MFVec2d 38
4152struct FWTYPE MFVec2dType = {
4153 FIELDTYPE_MFVec2d,
4154 'W',
4155 "MFVec2d",
4156 sizeof(struct Multi_Any), //sizeof(struct ),
4157 MFW_Constructor, //constructor
4158 MFW_ConstructorArgs, //constructor args
4159 MFW_Properties, //Properties,
4160 NULL, //special iterator
4161 MFW_Getter, //Getter,
4162 MFW_Setter, //Setter,
4163 'W',0, //index prop type,readonly
4164 MFW_Functions, //functions
4165};
4166
4167int SFVec4f_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
4168 struct SFVec4f *ptr = (struct SFVec4f *)fwn;
4169 char buff[STRING], *str;
4170 int len;
4171 memset(buff, 0, STRING);
4172 sprintf(buff, "%.9g %.9g %.9g %.9g",
4173 ptr->c[0], ptr->c[1], ptr->c[2], ptr->c[3]);
4174 len = strlen(buff);
4175 str = malloc(len+1); //leak
4176 strcpy(str,buff);
4177 fwretval->_string = str;
4178 fwretval->itype = 'S';
4179 return 1;
4180}
4181
4182FWFunctionSpec (SFVec4f_Functions)[] = {
4183 {"toString", SFVec4f_toString, 'S',{0,-1,0,NULL}},
4184 {0}
4185};
4186
4187int SFVec4f_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
4188 struct SFVec4f *ptr = (struct SFVec4f *)fwn;
4189 int nr = 0;
4190 //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)
4191 if(index > -1 && index < 4){
4192 nr = 1;
4193 switch(index){
4194 case 0: //x
4195 case 1: //y
4196 case 2: //z
4197 case 3: //t
4198 fwretval->_numeric = ptr->c[index];
4199 break;
4200 default:
4201 nr = 0;
4202 }
4203 }
4204 fwretval->itype = 'F';
4205 return nr;
4206}
4207int SFVec4f_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
4208 struct SFVec4f *ptr = (struct SFVec4f *)fwn;
4209 //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)
4210 if(index > -1 && index < 4){
4211 switch(index){
4212 case 0: //x
4213 case 1: //y
4214 case 2: //z
4215 case 3: //t
4216 ptr->c[index] = (float)fwval->_numeric;
4217 break;
4218 }
4219 return TRUE;
4220 }
4221 return FALSE;
4222}
4223//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
4224void * SFVec4f_Constructor(FWType fwtype, int ic, FWval fwpars){
4225 int i;
4226 struct SFVec4f *ptr = malloc(fwtype->size_of); //garbage collector please
4227 if(ic == 4){
4228 for(i=0;i<4;i++)
4229 ptr->c[i] = (float)fwpars[i]._numeric; //fwpars[i]._web3dval.anyvrml->sffloat; //
4230 }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
4231 //new SFxxx(myMF[i]);
4232 shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
4233 }
4234
4235 return (void *)ptr;
4236}
4237
4238FWPropertySpec (SFVec4f_Properties)[] = {
4239 {"x", 0, 'F', 0},
4240 {"y", 1, 'F', 0},
4241 {"z", 2, 'F', 0},
4242 {"w", 3, 'F', 0},
4243 {NULL,0,0,0},
4244};
4245ArgListType (SFVec4f_ConstructorArgs)[] = {
4246 {4,0,'T',"FFFF"},
4247 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
4248 {-1,0,0,NULL},
4249};
4250
4251
4252//#define FIELDTYPE_SFVec4f 39
4253struct FWTYPE SFVec4fType = {
4254 FIELDTYPE_SFVec4f,
4255 'W',
4256 "SFVec4f",
4257 sizeof(struct SFVec4f), //sizeof(struct ),
4258 SFVec4f_Constructor, //constructor
4259 SFVec4f_ConstructorArgs, //constructor args
4260 SFVec4f_Properties, //Properties,
4261 NULL, //special iterator
4262 SFVec4f_Getter, //Getter,
4263 SFVec4f_Setter, //Setter,
4264 'F',0, //index prop type,readonly
4265 SFVec4f_Functions, //functions
4266};
4267
4268//#define FIELDTYPE_MFVec4f 40
4269struct FWTYPE MFVec4fType = {
4270 FIELDTYPE_MFVec4f,
4271 'W',
4272 "MFVec4f",
4273 sizeof(struct Multi_Any), //sizeof(struct ),
4274 MFW_Constructor, //constructor
4275 MFW_ConstructorArgs, //constructor args
4276 MFW_Properties, //Properties,
4277 NULL, //special iterator
4278 MFW_Getter, //Getter,
4279 MFW_Setter, //Setter,
4280 'W',0, //index prop type,readonly
4281 MFW_Functions, //functions
4282};
4283
4284int SFVec4d_toString(FWType fwtype, void *ec, void *fwn, int argc, FWval fwpars, FWval fwretval){
4285 struct SFVec4d *ptr = (struct SFVec4d *)fwn;
4286 char buff[STRING], *str;
4287 int len;
4288 memset(buff, 0, STRING);
4289 sprintf(buff, "%.9g %.9g %.9g %.9g",
4290 ptr->c[0], ptr->c[1], ptr->c[2], ptr->c[3]);
4291 len = strlen(buff);
4292 str = malloc(len+1); //leak
4293 strcpy(str,buff);
4294 fwretval->_string = str;
4295 fwretval->itype = 'S';
4296 return 1;
4297}
4298FWFunctionSpec (SFVec4d_Functions)[] = {
4299 {"toString", SFVec4d_toString, 'S',{0,-1,0,NULL}},
4300 {0}
4301};
4302
4303int SFVec4d_Getter(FWType fwt, int index, void *ec, void *fwn, FWval fwretval){
4304 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
4305 int nr = 0;
4306 //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)
4307 if(index > -1 && index < 4){
4308 nr = 1;
4309 switch(index){
4310 case 0: //x
4311 case 1: //y
4312 case 2: //z
4313 case 3: //t
4314 fwretval->_numeric = ptr->c[index];
4315 break;
4316 default:
4317 nr = 0;
4318 }
4319 }
4320 fwretval->itype = 'D';
4321 return nr;
4322}
4323int SFVec4d_Setter(FWType fwt, int index, void *ec, void *fwn, FWval fwval){
4324 struct SFVec3d *ptr = (struct SFVec3d *)fwn;
4325 //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)
4326 if(index > -1 && index < 4){
4327 switch(index){
4328 case 0: //x
4329 case 1: //y
4330 case 2: //z
4331 case 3: //t
4332 ptr->c[index] = fwval->_numeric; ;
4333 break;
4334 }
4335 return TRUE;
4336 }
4337 return FALSE;
4338}
4339//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
4340void * SFVec4d_Constructor(FWType fwtype, int ic, FWval fwpars){
4341 int i;
4342 struct SFVec3d *ptr = malloc(fwtype->size_of); //garbage collector please
4343 memset(ptr,0,fwtype->size_of);
4344 if(ic == 4){
4345 for(i=0;i<4;i++)
4346 ptr->c[i] = fwpars[i]._numeric;
4347 }else if(fwpars[0].itype == 'W' && (fwtype->itype == fwpars[0]._web3dval.fieldType)){
4348 //new SFxxx(myMF[i]);
4349 shallow_copy_field(fwtype->itype,fwpars[0]._web3dval.native,(void*)ptr);
4350 }
4351
4352 return (void *)ptr;
4353}
4354
4355FWPropertySpec (SFVec4d_Properties)[] = {
4356 {"x", 0, 'D', 0},
4357 {"y", 1, 'D', 0},
4358 {"z", 2, 'D', 0},
4359 {"w", 3, 'D', 0},
4360 {NULL,0,0,0},
4361};
4362ArgListType (SFVec4d_ConstructorArgs)[] = {
4363 {3,0,'T',"DDDD"},
4364 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
4365 {-1,0,0,NULL},
4366};
4367//#define FIELDTYPE_SFVec4d 41
4368struct FWTYPE SFVec4dType = {
4369 FIELDTYPE_SFVec4d,
4370 'W',
4371 "SFVec4d",
4372 sizeof(struct SFVec4d), //sizeof(struct ),
4373 SFVec4d_Constructor, //constructor
4374 SFVec4d_ConstructorArgs, //constructor args
4375 SFVec4d_Properties, //Properties,
4376 NULL, //special iterator
4377 SFVec4d_Getter, //Getter,
4378 SFVec4d_Setter, //Setter,
4379 'D',0, //index prop type,readonly
4380 SFVec4d_Functions, //functions
4381};
4382
4383//#define FIELDTYPE_MFVec4d 42
4384struct FWTYPE MFVec4dType = {
4385 FIELDTYPE_MFVec4d,
4386 'W',
4387 "MFVec4d",
4388 sizeof(struct Multi_Any), //sizeof(struct ),
4389 MFW_Constructor, //constructor
4390 MFW_ConstructorArgs, //constructor args
4391 MFW_Properties, //Properties,
4392 NULL, //special iterator
4393 MFW_Getter, //Getter,
4394 MFW_Setter, //Setter,
4395 'W',0, //index prop type,readonly
4396 MFW_Functions, //functions
4397};
4398
4399//SFMatrix3f
4400int SFMatrix3f_toString(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
4401 struct SFMatrix3f* ptr = (struct SFMatrix3f*)fwn;
4402 char* str, * r;
4403 int i;
4404 FWType sfvec3ftype = getFWTYPE(FIELDTYPE_SFVec3f);
4405
4406 str = malloc(1);
4407 str[0] = 0;
4408 for (i = 0; i < 3; i++) {
4409 r = sfToString(sfvec3ftype, &ptr->c[i * 3]);
4410 str = realloc(str, strlen(str) + strlen(r) + 3);
4411 str = strcat(str, r);
4412 str = strcat(str, ", ");
4413 }
4414 fwretval->_string = str;
4415 fwretval->itype = 'S';
4416 return 1;
4417}
4418FWFunctionSpec(SFMatrix3f_Functions)[] = {
4419 {"toString", SFMatrix3f_toString, 'S',{0,-1,0,NULL}},
4420 {0}
4421};
4422
4423int SFMatrix3f_Getter(FWType fwt, int index, void* ec, void* fwn, FWval fwretval) {
4424 struct SFMatrix3f* ptr = (struct SFMatrix3f*)fwn;
4425 int nr = 0;
4426 //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)
4427 if (index > -1 && index < 9) {
4428 fwretval->_numeric = ptr->c[index];
4429 }
4430 fwretval->itype = 'D';
4431 return nr;
4432}
4433int SFMatrix3f_Setter(FWType fwt, int index, void* ec, void* fwn, FWval fwval) {
4434 struct SFMatrix3f* ptr = (struct SFMatrix3f*)fwn;
4435 //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)
4436 if (index > -1 && index < 9) {
4437 ptr->c[index] = fwval->_numeric; ;
4438 return TRUE;
4439 }
4440 return FALSE;
4441}
4442
4443//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
4444void* SFMatrix3f_Constructor(FWType fwtype, int ic, FWval fwpars) {
4445 int i;
4446 struct SFMatrix3f* ptr = malloc(fwtype->size_of); //garbage collector please
4447 matidentity3f(ptr->c);
4448
4449 if (ic == 9) {
4450 for (i = 0; i < 9; i++)
4451 ptr->c[i] = fwpars[i]._numeric;
4452 }
4453 else if (fwpars[0].itype == 'W') {
4454 //new SFxxx(myMF[i]);
4455 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType,FIELDTYPE_SFMatrix3f, fwpars[0]._web3dval.native, (void*)ptr);
4456 }
4457 return (void*)ptr;
4458}
4459
4460FWPropertySpec(SFMatrix3f_Properties)[] = {
4461 {NULL,0,0,0},
4462};
4463ArgListType(SFMatrix3f_ConstructorArgs)[] = {
4464 {9,0,'T',"FFFFFFFFF"},
4465 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
4466 {-1,0,0,NULL},
4467};
4468
4469//#define FIELDTYPE_SFMatrix3f 41
4470struct FWTYPE SFMatrix3fType = {
4471 FIELDTYPE_SFMatrix3f,
4472 'W',
4473 "SFMatrix3f",
4474 sizeof(struct SFMatrix3f), //sizeof(struct ),
4475 SFMatrix3f_Constructor, //constructor
4476 SFMatrix3f_ConstructorArgs, //constructor args
4477 SFMatrix3f_Properties, //Properties,
4478 NULL, //special iterator
4479 SFMatrix3f_Getter, //Getter,
4480 SFMatrix3f_Setter, //Setter,
4481 'D',0, //index prop type,readonly
4482 SFMatrix3f_Functions, //functions
4483};
4484
4485//#define FIELDTYPE_MFMatrix3f
4486struct FWTYPE MFMatrix3fType = {
4487 FIELDTYPE_MFMatrix3f,
4488 'W',
4489 "MFMatrix3f",
4490 sizeof(struct Multi_Any), //sizeof(struct ),
4491 MFW_Constructor, //constructor
4492 MFW_ConstructorArgs, //constructor args
4493 MFW_Properties, //Properties,
4494 NULL, //special iterator
4495 MFW_Getter, //Getter,
4496 MFW_Setter, //Setter,
4497 'W',0, //index prop type,readonly
4498 MFW_Functions, //functions
4499};
4500
4501//SFMatrix3d
4502int SFMatrix3d_toString(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
4503 struct SFMatrix3d* ptr = (struct SFMatrix3d*)fwn;
4504 char* str, * r;
4505 int i;
4506 FWType sfvec3dtype = getFWTYPE(FIELDTYPE_SFVec3d);
4507
4508 str = malloc(1);
4509 str[0] = 0;
4510 for (i = 0; i < 3; i++) {
4511 r = sfToString(sfvec3dtype, &ptr->c[i * 3]);
4512 str = realloc(str, strlen(str) + strlen(r) + 3);
4513 str = strcat(str, r);
4514 str = strcat(str, ", ");
4515 }
4516 fwretval->_string = str;
4517 fwretval->itype = 'S';
4518 return 1;
4519}
4520FWFunctionSpec(SFMatrix3d_Functions)[] = {
4521 {"toString", SFMatrix3d_toString, 'S',{0,-1,0,NULL}},
4522 {0}
4523};
4524
4525int SFMatrix3d_Getter(FWType fwt, int index, void* ec, void* fwn, FWval fwretval) {
4526 struct SFMatrix3d* ptr = (struct SFMatrix3d*)fwn;
4527 int nr = 0;
4528 //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)
4529 if (index > -1 && index < 9) {
4530 fwretval->_numeric = ptr->c[index];
4531 }
4532 fwretval->itype = 'D';
4533 return nr;
4534}
4535int SFMatrix3d_Setter(FWType fwt, int index, void* ec, void* fwn, FWval fwval) {
4536 struct SFMatrix3d* ptr = (struct SFMatrix3d*)fwn;
4537 //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)
4538 if (index > -1 && index < 9) {
4539 ptr->c[index] = fwval->_numeric; ;
4540 return TRUE;
4541 }
4542 return FALSE;
4543}
4544
4545//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
4546void* SFMatrix3d_Constructor(FWType fwtype, int ic, FWval fwpars) {
4547 int i;
4548 struct SFMatrix3d* ptr = malloc(fwtype->size_of); //garbage collector please
4549 matidentity3d(ptr->c);
4550
4551 if (ic == 9) {
4552 for (i = 0; i < 9; i++)
4553 ptr->c[i] = fwpars[i]._numeric;
4554 }
4555 else if (fwpars[0].itype == 'W') {
4556 //new SFxxx(myMF[i]);
4557 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix3d, fwpars[0]._web3dval.native, (void*)ptr);
4558 }
4559 return (void*)ptr;
4560}
4561
4562FWPropertySpec(SFMatrix3d_Properties)[] = {
4563 {NULL,0,0,0},
4564};
4565ArgListType(SFMatrix3d_ConstructorArgs)[] = {
4566 {9,0,'T',"FFFFFFFFF"},
4567 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
4568 {-1,0,0,NULL},
4569};
4570//#define FIELDTYPE_SFMatrix3d 41
4571struct FWTYPE SFMatrix3dType = {
4572 FIELDTYPE_SFMatrix3d,
4573 'W',
4574 "SFMatrix3d",
4575 sizeof(struct SFMatrix3d), //sizeof(struct ),
4576 SFMatrix3d_Constructor, //constructor
4577 SFMatrix3d_ConstructorArgs, //constructor args
4578 SFMatrix3d_Properties, //Properties,
4579 NULL, //special iterator
4580 SFMatrix3d_Getter, //Getter,
4581 SFMatrix3d_Setter, //Setter,
4582 'D',0, //index prop type,readonly
4583 SFMatrix3d_Functions, //functions
4584};
4585
4586//#define FIELDTYPE_MFMatrix3d
4587struct FWTYPE MFMatrix3dType = {
4588 FIELDTYPE_MFMatrix3d,
4589 'W',
4590 "MFMatrix3d",
4591 sizeof(struct Multi_Any), //sizeof(struct ),
4592 MFW_Constructor, //constructor
4593 MFW_ConstructorArgs, //constructor args
4594 MFW_Properties, //Properties,
4595 NULL, //special iterator
4596 MFW_Getter, //Getter,
4597 MFW_Setter, //Setter,
4598 'W',0, //index prop type,readonly
4599 MFW_Functions, //functions
4600};
4601
4602// SFMatrix4f
4603int SFMatrix4f_toString(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
4604 struct SFMatrix4f* ptr = (struct SFMatrix4f*)fwn;
4605 char* str, * r;
4606 int i;
4607 FWType sfvec4ftype = getFWTYPE(FIELDTYPE_SFVec4f);
4608
4609 str = malloc(1);
4610 str[0] = 0;
4611 for (i = 0; i < 4; i++) {
4612 r = sfToString(sfvec4ftype, &ptr->c[i * 4]);
4613 str = realloc(str, strlen(str) + strlen(r) + 3);
4614 str = strcat(str, r);
4615 str = strcat(str, ", ");
4616 }
4617 fwretval->_string = str;
4618 fwretval->itype = 'S';
4619 return 1;
4620}
4621FWFunctionSpec(SFMatrix4f_Functions)[] = {
4622 {"toString", SFMatrix4f_toString, 'S',{0,-1,0,NULL}},
4623 {0}
4624};
4625
4626int SFMatrix4f_Getter(FWType fwt, int index, void* ec, void* fwn, FWval fwretval) {
4627 struct SFMatrix4f* ptr = (struct SFMatrix4f*)fwn;
4628 int nr = 0;
4629 //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)
4630 if (index > -1 && index < 16) {
4631 fwretval->_numeric = ptr->c[index];
4632 }
4633 fwretval->itype = 'D';
4634 return nr;
4635}
4636int SFMatrix4f_Setter(FWType fwt, int index, void* ec, void* fwn, FWval fwval) {
4637 struct SFMatrix4f* ptr = (struct SFMatrix4f*)fwn;
4638 //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)
4639 if (index > -1 && index < 16) {
4640 ptr->c[index] = fwval->_numeric; ;
4641 return TRUE;
4642 }
4643 return FALSE;
4644}
4645
4646//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
4647void* SFMatrix4f_Constructor(FWType fwtype, int ic, FWval fwpars) {
4648 int i;
4649 struct SFMatrix4f* ptr = malloc(fwtype->size_of); //garbage collector please
4650 matidentity4f(ptr->c);
4651
4652 if (ic == 9) {
4653 for (i = 0; i < 9; i++)
4654 ptr->c[i] = fwpars[i]._numeric;
4655 }
4656 else if (fwpars[0].itype == 'W') {
4657 //new SFxxx(myMF[i]);
4658 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix4f, fwpars[0]._web3dval.native, (void*)ptr);
4659 }
4660 return (void*)ptr;
4661}
4662
4663FWPropertySpec(SFMatrix4f_Properties)[] = {
4664 {NULL,0,0,0},
4665};
4666ArgListType(SFMatrix4f_ConstructorArgs)[] = {
4667 {16,0,'T',"FFFFFFFFFFFFFFFF"},
4668 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
4669 {-1,0,0,NULL},
4670};
4671//#define FIELDTYPE_SFMatrix4f
4672struct FWTYPE SFMatrix4fType = {
4673 FIELDTYPE_SFMatrix4f,
4674 'W',
4675 "SFMatrix4f",
4676 sizeof(struct SFMatrix4f), //sizeof(struct ),
4677 SFMatrix4f_Constructor, //constructor
4678 SFMatrix4f_ConstructorArgs, //constructor args
4679 SFMatrix4f_Properties, //Properties,
4680 NULL, //special iterator
4681 SFMatrix4f_Getter, //Getter,
4682 SFMatrix4f_Setter, //Setter,
4683 'D',0, //index prop type,readonly
4684 SFMatrix4f_Functions, //functions
4685};
4686
4687//#define FIELDTYPE_MFMatrix4f
4688struct FWTYPE MFMatrix4fType = {
4689 FIELDTYPE_MFMatrix4f,
4690 'W',
4691 "MFMatrix4f",
4692 sizeof(struct Multi_Any), //sizeof(struct ),
4693 MFW_Constructor, //constructor
4694 MFW_ConstructorArgs, //constructor args
4695 MFW_Properties, //Properties,
4696 NULL, //special iterator
4697 MFW_Getter, //Getter,
4698 MFW_Setter, //Setter,
4699 'W',0, //index prop type,readonly
4700 MFW_Functions, //functions
4701};
4702
4703// SFMatrix4d
4704int SFMatrix4d_toString(FWType fwtype, void* ec, void* fwn, int argc, FWval fwpars, FWval fwretval) {
4705 struct SFMatrix4d* ptr = (struct SFMatrix4d*)fwn;
4706 char* str, * r;
4707 int i;
4708 FWType sfvec4dtype = getFWTYPE(FIELDTYPE_SFVec4d);
4709
4710 str = malloc(1);
4711 str[0] = 0;
4712 for (i = 0; i < 4; i++) {
4713 r = sfToString(sfvec4dtype, &ptr->c[i * 4]);
4714 str = realloc(str, strlen(str) + strlen(r) + 3);
4715 str = strcat(str, r);
4716 str = strcat(str, ", ");
4717 }
4718 fwretval->_string = str;
4719 fwretval->itype = 'S';
4720 return 1;
4721}
4722FWFunctionSpec(SFMatrix4d_Functions)[] = {
4723 {"toString", SFMatrix4d_toString, 'S',{0,-1,0,NULL}},
4724 {0}
4725};
4726
4727int SFMatrix4d_Getter(FWType fwt, int index, void* ec, void* fwn, FWval fwretval) {
4728 struct SFMatrix4d* ptr = (struct SFMatrix4d*)fwn;
4729 int nr = 0;
4730 //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)
4731 if (index > -1 && index < 16) {
4732 fwretval->_numeric = ptr->c[index];
4733 }
4734 fwretval->itype = 'D';
4735 return nr;
4736}
4737int SFMatrix4d_Setter(FWType fwt, int index, void* ec, void* fwn, FWval fwval) {
4738 struct SFMatrix4d* ptr = (struct SFMatrix4d*)fwn;
4739 //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)
4740 if (index > -1 && index < 16) {
4741 ptr->c[index] = fwval->_numeric; ;
4742 return TRUE;
4743 }
4744 return FALSE;
4745}
4746
4747//typedef int (* FWConstructor)(FWType fwtype, int argc, FWval fwpars);
4748void* SFMatrix4d_Constructor(FWType fwtype, int ic, FWval fwpars) {
4749 int i;
4750 struct SFMatrix4d* ptr = malloc(fwtype->size_of); //garbage collector please
4751 matidentity4d(ptr->c);
4752
4753 if (ic == 16) {
4754 for (i = 0; i < 16; i++)
4755 ptr->c[i] = fwpars[i]._numeric;
4756 }
4757 else if (fwpars[0].itype == 'W') {
4758 //new SFxxx(myMF[i]);
4759 shallow_copy_field_precision(fwpars[0]._web3dval.fieldType, FIELDTYPE_SFMatrix4d, fwpars[0]._web3dval.native, (void*)ptr);
4760 }
4761 return (void*)ptr;
4762}
4763
4764FWPropertySpec(SFMatrix4d_Properties)[] = {
4765 {NULL,0,0,0},
4766};
4767ArgListType(SFMatrix4d_ConstructorArgs)[] = {
4768 {16,0,'T',"FFFFFFFFFFFFFFFF"},
4769 {1,-1,'F',"W"}, //new SFxxx(myMF[i]);
4770 {-1,0,0,NULL},
4771};
4772//#define FIELDTYPE_SFMatrix4d
4773struct FWTYPE SFMatrix4dType = {
4774 FIELDTYPE_SFMatrix4d,
4775 'W',
4776 "SFMatrix4d",
4777 sizeof(struct SFMatrix4d), //sizeof(struct ),
4778 SFMatrix4d_Constructor, //constructor
4779 SFMatrix4d_ConstructorArgs, //constructor args
4780 SFMatrix4d_Properties, //Properties,
4781 NULL, //special iterator
4782 SFMatrix4d_Getter, //Getter,
4783 SFMatrix4d_Setter, //Setter,
4784 'D',0, //index prop type,readonly
4785 SFMatrix4d_Functions, //functions
4786};
4787
4788//#define FIELDTYPE_MFMatrix4f
4789struct FWTYPE MFMatrix4dType = {
4790 FIELDTYPE_MFMatrix4d,
4791 'W',
4792 "MFMatrix4d",
4793 sizeof(struct Multi_Any), //sizeof(struct ),
4794 MFW_Constructor, //constructor
4795 MFW_ConstructorArgs, //constructor args
4796 MFW_Properties, //Properties,
4797 NULL, //special iterator
4798 MFW_Getter, //Getter,
4799 MFW_Setter, //Setter,
4800 'W',0, //index prop type,readonly
4801 MFW_Functions, //functions
4802};
4803
4804
4805
4806
4807void initVRMLFields(FWType* typeArray, int *n){
4808 typeArray[*n] = &SFInt32Type; (*n)++;
4809 typeArray[*n] = &MFInt32Type; (*n)++;
4810 typeArray[*n] = &SFFloatType; (*n)++;
4811 typeArray[*n] = &MFFloatType; (*n)++;
4812 typeArray[*n] = &SFTimeType; (*n)++;
4813 typeArray[*n] = &MFTimeType; (*n)++;
4814 typeArray[*n] = &SFDoubleType; (*n)++;
4815 typeArray[*n] = &MFDoubleType; (*n)++;
4816 typeArray[*n] = &SFBoolType; (*n)++;
4817 typeArray[*n] = &MFBoolType; (*n)++;
4818 typeArray[*n] = &SFNodeType; (*n)++;
4819 typeArray[*n] = &MFNodeType; (*n)++;
4820 typeArray[*n] = &SFRotationType; (*n)++;
4821 typeArray[*n] = &MFRotationType; (*n)++;
4822 typeArray[*n] = &SFColorType; (*n)++;
4823 typeArray[*n] = &MFColorType; (*n)++;
4824 typeArray[*n] = &SFColorRGBAType; (*n)++;
4825 typeArray[*n] = &MFColorRGBAType; (*n)++;
4826 typeArray[*n] = &SFStringType; (*n)++;
4827 typeArray[*n] = &MFStringType; (*n)++;
4828 typeArray[*n] = &SFVec2fType; (*n)++;
4829 typeArray[*n] = &MFVec2fType; (*n)++;
4830 typeArray[*n] = &SFVec3fType; (*n)++;
4831 typeArray[*n] = &MFVec3fType; (*n)++;
4832 typeArray[*n] = &SFVec4fType; (*n)++;
4833 typeArray[*n] = &MFVec4fType; (*n)++;
4834 typeArray[*n] = &SFVec2dType; (*n)++;
4835 typeArray[*n] = &MFVec2dType; (*n)++;
4836 typeArray[*n] = &SFVec3dType; (*n)++;
4837 typeArray[*n] = &MFVec3dType; (*n)++;
4838 typeArray[*n] = &SFVec4dType; (*n)++;
4839 typeArray[*n] = &MFVec4dType; (*n)++;
4840
4841 typeArray[*n] = &SFImageType; (*n)++;
4842 typeArray[*n] = &MFImageType; (*n)++;
4843 typeArray[*n] = &SFMatrix3fType; (*n)++;
4844 typeArray[*n] = &MFMatrix3fType; (*n)++;
4845 typeArray[*n] = &SFMatrix3dType; (*n)++;
4846 typeArray[*n] = &MFMatrix3dType; (*n)++;
4847 typeArray[*n] = &SFMatrix4fType; (*n)++;
4848 typeArray[*n] = &MFMatrix4fType; (*n)++;
4849 typeArray[*n] = &SFMatrix4dType; (*n)++;
4850 typeArray[*n] = &MFMatrix4dType; (*n)++;
4851 typeArray[*n] = &X3DMatrix3Type; (*n)++;
4852 typeArray[*n] = &X3DMatrix4Type; (*n)++;
4853 typeArray[*n] = &VrmlMatrixType; (*n)++;
4854 //typeArray[*n] = &FreeWRLPTRType; (*n)++;
4855 //typeArray[*n] = &FreeWRLThreadType; (*n)++;
4856}
4857
4858#endif /* ifdef JAVASCRIPT_DUK */