FreeWRL/FreeX3D  3.0.0
Component_Core.c
1 /*
2 
3 
4 X3D Core Component
5 
6 */
7 
8 
9 /****************************************************************************
10  This file is part of the FreeWRL/FreeX3D Distribution.
11 
12  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13 
14  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15  it under the terms of the GNU Lesser Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26 ****************************************************************************/
27 
28 
29 
30 /*******************************************************************
31 
32  X3D Core Component
33 
34 *********************************************************************/
35 
36 #include <config.h>
37 #include <system.h>
38 #include <display.h>
39 #include <internal.h>
40 
41 #include <libFreeWRL.h>
42 
43 #include "../vrml_parser/Structs.h"
44 #include "../main/headers.h"
45 #include "../vrml_parser/CRoutes.h"
46 
47 
48 /************************************************************************************************/
49 /* */
50 /* Metadata standard X3D nodes */
51 /* */
52 /************************************************************************************************/
53 
54 void compile_MetadataBoolean (struct X3D_MetadataBoolean *node) {
55  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataBoolean, metadata));
56  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataBoolean, name));
57  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataBoolean, reference));
58  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataBoolean, value));
59  MARK_NODE_COMPILED;
60 }
61 void compile_MetadataInteger (struct X3D_MetadataInteger *node) {
62  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataInteger, metadata));
63  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataInteger, name));
64  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataInteger, reference));
65  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataInteger, value));
66  MARK_NODE_COMPILED;
67 }
68 void compile_MetadataDouble (struct X3D_MetadataDouble *node) {
69  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataDouble, metadata));
70  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataDouble, name));
71  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataDouble, reference));
72  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataDouble, value));
73  MARK_NODE_COMPILED;
74 }
75 void compile_MetadataFloat (struct X3D_MetadataFloat *node) {
76  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataFloat, metadata));
77  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataFloat, name));
78  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataFloat, reference));
79  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataFloat, value));
80  MARK_NODE_COMPILED;
81 }
82 void compile_MetadataSet (struct X3D_MetadataSet *node) {
83  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataSet, metadata));
84  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataSet, name));
85  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataSet, reference));
86  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataSet, value));
87  MARK_NODE_COMPILED;
88 }
89 void compile_MetadataString (struct X3D_MetadataString *node) {
90  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataString, metadata));
91  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataString, name));
92  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataString, reference));
93  MARK_EVENT (X3D_NODE(node),offsetof (struct X3D_MetadataString, value));
94  MARK_NODE_COMPILED;
95 }
96 
97 
98 /************************************************************************************************/
99 /* */
100 /* MetadataMF and MetadataSF nodes */
101 /* */
102 /************************************************************************************************/
103 
104 #define META_IS_INITIALIZED (node->_ichange != 0)
105 
106 /* anything changed for this PROTO interface datatype? */
107 #define CMD_I32(type) void compile_MetadataSF##type (struct X3D_MetadataSF##type *node) { \
108  if META_IS_INITIALIZED { \
109  if (node->tickTime != TickTime()) { \
110  node->value = node->setValue; \
111  node->valueChanged = node->setValue; \
112  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataSF##type, valueChanged)); \
113  } \
114  } else { \
115  /* initialize fields */ \
116  node->valueChanged = node->value; node->setValue = node->value; \
117  } \
118  node->tickTime = TickTime(); \
119  MARK_NODE_COMPILED \
120 }
121 
122 #define CMD_FL(type) void compile_MetadataSF##type (struct X3D_MetadataSF##type *node) { \
123  if META_IS_INITIALIZED { \
124  if (node->tickTime != TickTime()) { \
125  node->value = node->setValue; \
126  node->valueChanged = node->setValue; \
127  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataSF##type, valueChanged)); \
128  } \
129  } else { \
130  /* initialize fields */ \
131  node->valueChanged = node->value; node->setValue = node->value; \
132  } \
133  node->tickTime = TickTime(); \
134  MARK_NODE_COMPILED \
135 }
136 
137 #define CMD_MFL(type,elelength) void compile_MetadataSF##type (struct X3D_MetadataSF##type *node) { \
138  int count; \
139  if META_IS_INITIALIZED { \
140  for (count=0; count < elelength; count++) { \
141  if (!APPROX(node->value.c[count],node->setValue.c[count])) { \
142  memcpy (&node->value, &node->setValue, sizeof node->value.c[0]* elelength); \
143  memcpy (&node->valueChanged, &node->setValue, sizeof node->value.c[0] * elelength); \
144  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataSF##type, valueChanged)); \
145  return; \
146  } \
147  } \
148  } else { \
149  /* initialize fields */ \
150  memcpy (&node->setValue, &node->value, sizeof node->value.c[0]* elelength); \
151  memcpy (&node->valueChanged, &node->value, sizeof node->value.c[0] * elelength); \
152  } \
153  MARK_NODE_COMPILED \
154 }
155 
156 
157 
158 /* compare element counts, and pointer values */
159 /* NOTE - VALUES CAN NOT BE DESTROYED BY THE KILL PROCESSES, AS THESE ARE JUST COPIES OF POINTERS */
160 #define CMD_MULTI(mtype, type,elelength,dataSize) void compile_MetadataMF##type (struct X3D_MetadataMF##type *node) { \
161  int count; int changed = FALSE; \
162  if META_IS_INITIALIZED { \
163  if (node->value.n != node->setValue.n) changed = TRUE; else { \
164  /* yes, these two array must have the same index counts... */ \
165  for (count=0; count<node->setValue.n; count++) { \
166  int count2; for (count2=0; count2<elelength; count2++) { if (!APPROX(node->value.p[count].c[count2], node->setValue.p[count].c[count2])) changed = TRUE; break; }\
167  if (changed) break; } \
168  } \
169  \
170  if (changed) { \
171  /* printf ("MSFL, change hit, freeing pointers %x and %x\n", node->value.p, node->valueChanged.p); */ \
172  FREE_IF_NZ (node->value.p); \
173  FREE_IF_NZ(node->valueChanged.p); \
174  node->value.p = MALLOC(mtype, dataSize * node->setValue.n * elelength); \
175  node->valueChanged.p = MALLOC(mtype, dataSize * node->setValue.n * elelength); \
176  memcpy(node->value.p, node->setValue.p, dataSize * node->setValue.n * elelength); \
177  memcpy(node->valueChanged.p, node->setValue.p, dataSize * node->setValue.n * elelength); \
178  node->value.n = node->setValue.n; \
179  node->valueChanged.n = node->setValue.n; \
180  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataMF##type, valueChanged)); \
181  } \
182  } else { \
183  /* the "value" will hold everything we need */ \
184  /* initialize it, but do not bother doing any routing on it */ \
185  if ((node->setValue.n != 0) || (node->setValue.p != NULL) || (node->valueChanged.n != 0) || (node->valueChanged.p != NULL)) { printf ("PROTO header - initialization set and changed, but not zero??\n"); \
186  node->setValue.n = 0; FREE_IF_NZ(node->setValue.p); \
187  node->valueChanged.n = 0; FREE_IF_NZ(node->valueChanged.p); } \
188  FREE_IF_NZ (node->setValue.p); \
189  FREE_IF_NZ(node->valueChanged.p); \
190  node->setValue.p = MALLOC(mtype, dataSize * node->value.n * elelength); \
191  node->valueChanged.p = MALLOC(mtype, dataSize * node->value.n * elelength); \
192  memcpy(node->setValue.p, node->value.p, dataSize * node->value.n * elelength); \
193  memcpy(node->valueChanged.p, node->value.p, dataSize * node->value.n * elelength); \
194  node->setValue.n = node->value.n; \
195  node->valueChanged.n = node->value.n; \
196  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataMF##type, valueChanged)); \
197  } \
198  MARK_NODE_COMPILED \
199 }
200 
201 #define CMD_MSFI32(mtype, type,dataSize) void compile_MetadataMF##type (struct X3D_MetadataMF##type *node) { \
202  /* printf ("\nMSFI32:, node %x\n",node); \
203  printf ("MSFI32:, nt %s change %d ichange %d\n",stringNodeType(node->_nodeType),node->_change, node->_ichange); */ \
204  if META_IS_INITIALIZED { \
205  int count; int changed = FALSE; \
206  /* printf ("MSFI32:, so this is initialized; value %d setValue count%d\n",node->value.n,node->setValue.n); */ \
207 /* { int count; char *cptr = (char *)&(node->setValue); for (count = 0; count < 8; count ++) { printf ("%u: %x ",count, *cptr); cptr ++; } \
208  printf ("\n"); \
209 cptr = (char *)&(node->value); for (count = 0; count < 8; count ++) { printf ("%u: %x ",count, *cptr); cptr ++; } \
210  printf ("\n"); \
211 } */\
212  if (node->value.n != node->setValue.n) changed = TRUE; \
213  else { \
214  /* same count, but something caused this to be called; go through each element */ \
215  for (count=0; count<node->setValue.n; count++) { \
216  /* printf ("MSFI32, comparing ele %d %x %x\n",count, node->value.p[count], node->setValue.p[count]); */ \
217  if (node->value.p[count] != node->setValue.p[count]) {changed = TRUE; break; } \
218  } \
219  } \
220  \
221  if (changed) { \
222  /* printf ("MSFI32, change hit, freeing pointers %x and %x\n", node->value.p, node->valueChanged.p); */ \
223  FREE_IF_NZ (node->value.p); \
224  FREE_IF_NZ(node->valueChanged.p); \
225  node->value.p = MALLOC(mtype, dataSize * node->setValue.n); \
226  node->valueChanged.p = MALLOC(mtype, dataSize * node->setValue.n); \
227  memcpy(node->value.p, node->setValue.p, dataSize * node->setValue.n); \
228  memcpy(node->valueChanged.p, node->setValue.p, dataSize * node->setValue.n); \
229  node->value.n = node->setValue.n; \
230  node->valueChanged.n = node->setValue.n; \
231  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataMF##type, valueChanged)); \
232  } \
233  } else { \
234  /* the "value" will hold everything we need */ \
235  /* initialize it, but do not bother doing any routing on it */ \
236  /* printf ("MSFI32: initializing... %d %p %d %p\n", node->setValue.n, node->setValue.p, node->valueChanged.n, node->valueChanged.p); */ \
237  if ((node->setValue.n != 0) || (node->setValue.p != NULL) || (node->valueChanged.n != 0) || (node->valueChanged.p != NULL)) { printf ("PROTO header - initialization set and changed, but not zero??\n"); \
238  node->setValue.n = 0; FREE_IF_NZ(node->setValue.p); \
239  node->valueChanged.n = 0; FREE_IF_NZ(node->valueChanged.p); } \
240  /* printf ("MSFI32 - leaving the setValue and ValueChanged pointers to %x %x\n",node->setValue.p, node->valueChanged.p);*/ \
241  /* printf ("MFSI32, making setValue and valueChanged equal to the value on initialization\n"); */ \
242  FREE_IF_NZ (node->setValue.p); \
243  FREE_IF_NZ(node->valueChanged.p); \
244  node->setValue.p = MALLOC(mtype, dataSize * node->value.n); \
245  node->valueChanged.p = MALLOC(mtype, dataSize * node->value.n); \
246  memcpy(node->setValue.p, node->value.p, dataSize * node->value.n); \
247  memcpy(node->valueChanged.p, node->value.p, dataSize * node->value.n); \
248  node->setValue.n = node->value.n; \
249  node->valueChanged.n = node->value.n; \
250  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataMF##type, valueChanged)); \
251  } \
252  MARK_NODE_COMPILED \
253  /* printf ("MSFI32: DONE; value %d, value_changed.n %d\n", node->value.n,node->valueChanged.n); */ \
254 }
255 
256 
257 
258 
259 
260 
261 
262 /* compare element counts, then individual elements, if the counts are the same */
263 /* NOTE - VALUES CAN NOT BE DESTROYED BY THE KILL PROCESSES, AS THESE ARE JUST COPIES OF POINTERS */
264 #define CMD_MSFL(mtype, type,dataSize) void compile_MetadataMF##type (struct X3D_MetadataMF##type *node) { \
265  int count; int changed = FALSE; \
266  if META_IS_INITIALIZED { \
267  if (node->value.n != node->setValue.n) changed = TRUE; else { \
268  /* yes, these two array must have the same index counts... */ \
269  for (count=0; count<node->setValue.n; count++) if (!APPROX(node->value.p[count], node->setValue.p[count])) { changed = TRUE; break; }}\
270  \
271  if (changed) { \
272  /* printf ("MSFL, change hit, freeing pointers %x and %x\n", node->value.p, node->valueChanged.p); */ \
273  FREE_IF_NZ (node->value.p); \
274  FREE_IF_NZ(node->valueChanged.p); \
275  node->value.p = MALLOC(mtype, dataSize * node->setValue.n); \
276  node->valueChanged.p = MALLOC(mtype, dataSize * node->setValue.n); \
277  memcpy(node->value.p, node->setValue.p, dataSize * node->setValue.n); \
278  memcpy(node->valueChanged.p, node->setValue.p, dataSize * node->setValue.n); \
279  node->value.n = node->setValue.n; \
280  node->valueChanged.n = node->setValue.n; \
281  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataMF##type, valueChanged)); \
282  } \
283  } else { \
284  /* the "value" will hold everything we need */ \
285  /* initialize it, but do not bother doing any routing on it */ \
286  if ((node->setValue.n != 0) || (node->setValue.p != NULL) || (node->valueChanged.n != 0) || (node->valueChanged.p != NULL)) { printf ("PROTO header - initialization set and changed, but not zero??\n"); \
287  node->setValue.n = 0; FREE_IF_NZ(node->setValue.p); \
288  node->valueChanged.n = 0; FREE_IF_NZ(node->valueChanged.p); } \
289  } \
290  MARK_NODE_COMPILED \
291 }
292 
293 
294 CMD_FL(Float)
295 CMD_FL(Time)
296 CMD_FL(Double)
297 CMD_I32(Bool)
298 CMD_I32(Int32)
299 CMD_I32(Node)
300 
301 CMD_MFL(Vec2f,2)
302 CMD_MFL(Vec3f,3)
303 CMD_MFL(Vec4f,4)
304 CMD_MFL(Vec2d,2)
305 CMD_MFL(Vec3d,3)
306 CMD_MFL(Vec4d,4)
307 CMD_MFL(Rotation,4)
308 CMD_MFL(Color,3)
309 CMD_MFL(ColorRGBA,4)
310 CMD_MFL(Matrix3f,9)
311 CMD_MFL(Matrix3d,9)
312 CMD_MFL(Matrix4f,16)
313 CMD_MFL(Matrix4d,16)
314 
315 CMD_MULTI(struct SFRotation *, Rotation,4,sizeof (float))
316 CMD_MULTI(struct SFVec2f *, Vec2f,2,sizeof (float))
317 CMD_MULTI(struct SFVec3f *, Vec3f,3,sizeof (float))
318 CMD_MULTI(struct SFVec4f *, Vec4f,4,sizeof (float))
319 CMD_MULTI(struct SFVec2d *, Vec2d,2,sizeof (double))
320 CMD_MULTI(struct SFVec3d *,Vec3d,3,sizeof (double))
321 CMD_MULTI(struct SFVec4d *,Vec4d,4,sizeof (double))
322 CMD_MULTI(struct SFColor *, Color,3,sizeof (float))
323 CMD_MULTI(struct SFColorRGBA *, ColorRGBA,4,sizeof (float))
324 CMD_MULTI(struct SFMatrix3f *, Matrix3f,9,sizeof (float))
325 CMD_MULTI(struct SFMatrix4f *, Matrix4f,16,sizeof (float))
326 CMD_MULTI(struct SFMatrix3d *, Matrix3d,9,sizeof (double))
327 CMD_MULTI(struct SFMatrix4d *, Matrix4d,16,sizeof (double))
328 
329 CMD_MSFI32(int *, Bool, sizeof(int))
330 CMD_MSFI32(int *, Int32,sizeof (int))
331 CMD_MSFI32(struct X3D_Node **, Node,sizeof (void *))
332 CMD_MSFL(double *, Time,sizeof (double))
333 CMD_MSFL(float *, Float,sizeof (float))
334 CMD_MSFL(double *, Double,sizeof (double))
335 CMD_MSFI32(struct Uni_String **, String,sizeof (void *))
336 
337 
338 void compile_MetadataSFImage (struct X3D_MetadataSFImage *node){ printf ("make compile_Metadata %s\n",stringNodeType(node->_nodeType));}
339 /*
340 struct Uni_String {
341  int len;
342  char * strptr;
343  int touched;
344 };
345 */
346 
347 void compile_MetadataSFString (struct X3D_MetadataSFString *node){
348  int count; int changed = FALSE;
349 
350  if META_IS_INITIALIZED {
351  if (node->value->len != node->setValue->len) changed = TRUE; else {
352  for (count=0; count<node->setValue->len; count++)
353  if (node->value->strptr[count] != node->setValue->strptr[count]) changed = TRUE; }
354 
355  if (changed) {
356  node->value->len = node->setValue->len; node->value->strptr = node->setValue->strptr;
357  node->valueChanged->len = node->setValue->len; node->valueChanged->strptr = node->setValue->strptr;
358  node->value->touched = TRUE; node->valueChanged->touched = TRUE;
359  MARK_EVENT (X3D_NODE(node), offsetof (struct X3D_MetadataSFString, valueChanged));
360  }
361  } else {
362  /* initialize this one */
363  node->valueChanged->len = node->value->len;
364  node->valueChanged->touched = node->value->touched;
365  node->valueChanged->strptr = node->value->strptr;
366  node->setValue->len = node->value->len;
367  node->setValue->touched = node->value->touched;
368  node->setValue->strptr = node->value->strptr;
369  }
370  MARK_NODE_COMPILED
371 }
372