FreeWRL/FreeX3D  3.0.0
capabilitiesHandler.c
1 /*
2 
3  FreeWRL support library.
4  X3D capabilities.
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 
27 
28 
29 #include <config.h>
30 #include <system.h>
31 #include <display.h>
32 #include <internal.h>
33 
34 #include <libFreeWRL.h>
35 #include <io_files.h>
36 
37 #include "../vrml_parser/Structs.h"
38 #include "../main/headers.h"
39 
40 
41 /* table showing which levels are supported by which component */
42 static const int capabilities[] = {
43  COM_Geometry2D, 2, /* May 12, 2009 */
44  COM_Rendering, 5, /* Sep 22, 2016 */
45  COM_Picking, 0, /* May 12, 2009 */
46  COM_DIS, 0, /* May 12, 2009 */
47  COM_EnvironmentalSensor, 3, /* May 12, 2009 */
48  COM_Text, 1, /* May 12, 2009 */
49  COM_NURBS, 4, /* Dec 2016 */
50  COM_CubeMapTexturing, 3, /* Sep 13, 2016 */
51  COM_EventUtilities, 1, /* May 12, 2009 */
52  COM_Interpolation, 5, /* Dec 2016 */
53  COM_Shaders, 1, /* May 12, 2009 */
54  COM_Navigation, 3, /* July 29 2010 */
55  COM_Grouping, 3, /* October 29, 2008 */
56  COM_Texturing, 3, /* May 12, 2009 */
57  COM_Geospatial, 2, /* May 12, 2009 */
58  COM_CADGeometry, 2, /* July 10 2013 */
59  COM_EnvironmentalEffects, 3, /* May 12, 2009 */
60  COM_Shape, 4, /* May 12, 2009 */
61  COM_Texturing3D, 2, /* Sept 4, 2016 */
62  COM_PointDeviceSensor, 1, /* May 12, 2009 */
63  COM_HAnim, 1, /* Nov 2016 */
64  COM_RigidBodyPhysics, 2, /* Nov 2016 */
65  COM_Core, 2, /* October 29, 2008 */
66  COM_Layout, 2, /* Jan 2016 */
67  COM_Time, 2, /* October 29, 2008 */
68  COM_Geometry3D, 4, /* May 12, 2009 */
69  COM_Followers, 1, /* 2016 */
70  COM_Scripting, 1, /* May 12, 2009 */
71  COM_Lighting, 3, /* May 12, 2009 */
72  COM_KeyDeviceSensor, 2, /* May 12, 2009 */
73  COM_Layering, 1, /* Jan 2016 */
74  COM_Networking, 3, /* May 12, 2009 */
75  COM_ParticleSystems, 3, /* Nov 2016 */
76  COM_Sound, 1, /* May 12, 2009 */
77  COM_VolumeRendering, 4, /* Oct 1, 2016 */
78  INT_ID_UNDEFINED, INT_ID_UNDEFINED,
79 };
80 
81 /* profiles... */
82 
83 /* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 H3 Component support */
84 static const int CADInterchangeProfile[] = {
85  COM_Core, 1,
86  COM_Networking, 1,
87  COM_Grouping, 1,
88  COM_Rendering, 4,
89  COM_Shape, 2,
90  COM_Lighting, 1,
91  COM_Texturing, 2,
92  COM_Navigation, 2,
93  COM_Shaders, 1,
94  COM_CADGeometry, 2,
95  INT_ID_UNDEFINED, INT_ID_UNDEFINED};
96 
97 
98 /* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 A3 Component support */
99 static const int CoreProfile[] = {
100  COM_Core, 1,
101  INT_ID_UNDEFINED, INT_ID_UNDEFINED};
102 
103 
104 /* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 F3 Component support */
105 static const int FullProfile[] = {
106  COM_Core, 2,
107  COM_Time, 2,
108  COM_Networking, 3,
109  COM_Grouping, 3,
110  COM_Rendering, 5,
111  COM_Shape, 4,
112  COM_Geometry3D, 4,
113  COM_Geometry2D, 2,
114  COM_Text, 1,
115  COM_Sound, 1,
116  COM_Lighting, 3,
117  COM_Texturing, 3,
118  COM_Interpolation, 5,
119  COM_Navigation, 3,
120  COM_PointDeviceSensor, 1,
121  COM_KeyDeviceSensor, 2,
122  COM_EnvironmentalSensor, 3,
123  COM_EnvironmentalEffects, 4,
124  COM_Geospatial, 2,
125  COM_HAnim, 1,
126  COM_NURBS, 4,
127  COM_DIS, 2,
128  COM_Scripting, 1,
129  COM_EventUtilities, 1,
130  COM_Shaders, 1,
131  COM_CADGeometry, 2,
132  COM_Texturing3D, 2,
133  COM_CubeMapTexturing, 3,
134  COM_Layering, 1,
135  COM_Layout, 2,
136  COM_RigidBodyPhysics, 2,
137  COM_Picking, 3,
138  COM_Followers, 1,
139  COM_ParticleSystems, 3,
140  INT_ID_UNDEFINED, INT_ID_UNDEFINED};
141 
142 
143 /* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 E3 Component support */
144 static const int ImmersiveProfile[] = {
145  COM_Core, 2,
146  COM_Time, 1,
147  COM_Networking, 3,
148  COM_Grouping, 2,
149  COM_Rendering, 3,
150  COM_Shape, 2,
151  COM_Geometry3D, 4,
152  COM_Geometry2D, 1,
153  COM_Text, 1,
154  COM_Sound, 1,
155  COM_Lighting, 2,
156  COM_Texturing, 3,
157  COM_Interpolation, 2,
158  COM_PointDeviceSensor, 1,
159  COM_KeyDeviceSensor, 2,
160  COM_EnvironmentalSensor, 2,
161  COM_EnvironmentalEffects, 2,
162  COM_Scripting, 1,
163  COM_EventUtilities, 1,
164  INT_ID_UNDEFINED, INT_ID_UNDEFINED};
165 
166 
167 /* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 C3 Component support */
168 static const int InteractiveProfile[] = {
169  COM_Core, 1,
170  COM_Time, 1,
171  COM_Networking, 2,
172  COM_Grouping, 2,
173  COM_Rendering, 3,
174  COM_Shape, 1,
175  COM_Geometry3D, 3,
176  COM_Lighting, 2,
177  COM_Texturing, 2,
178  COM_Interpolation, 2,
179  COM_Navigation, 1,
180  COM_PointDeviceSensor, 1,
181  COM_KeyDeviceSensor, 1,
182  COM_EnvironmentalSensor, 1,
183  COM_EnvironmentalEffects, 1,
184  COM_EventUtilities, 1,
185  COM_Layering, 1,
186  INT_ID_UNDEFINED, INT_ID_UNDEFINED};
187 
188 
189 /* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 B3 Component support */
190 static const int InterchangeProfile[] = {
191  COM_Core, 1,
192  COM_Time, 1,
193  COM_Networking, 1,
194  COM_Grouping, 1,
195  COM_Rendering, 3,
196  COM_Shape, 1,
197  COM_Geometry3D, 2,
198  COM_Lighting, 1,
199  COM_Texturing, 2,
200  COM_Interpolation, 2,
201  COM_Navigation, 1,
202  COM_EnvironmentalEffects, 1,
203  INT_ID_UNDEFINED, INT_ID_UNDEFINED};
204 
205 
206 /* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 D3 Component support */
207 static const int MPEG4Profile[] = {
208  COM_Core, 1,
209  COM_Time, 1,
210  COM_Networking, 2,
211  COM_Grouping, 2,
212  COM_Rendering, 1,
213  COM_Shape, 1,
214  COM_Geometry3D, 2,
215  COM_Lighting, 2,
216  COM_Texturing, 1,
217  COM_Interpolation, 2,
218  COM_Navigation, 1,
219  COM_PointDeviceSensor, 1,
220  COM_EnvironmentalSensor, 1,
221  COM_Navigation, 1,
222  COM_EnvironmentalEffects, 1,
223  INT_ID_UNDEFINED, INT_ID_UNDEFINED};
224 
225 
226 //dug9 Aug,2013 ecmascript interface V3 says a ProfileInfo has a name, level??, Title, providerUrl, componentInfoArray
227 //
228 //Q. how do you assign a Level to a Profile?
229 //H0: 1 if you have it, else 0
230 //H1: minimum of component levels in profile
231 //H2: maximum of component levels in profile
232 //H3: maximum nesting level - see diagram ie if you have Geospatial,Hanim,Nurbs you are at Full or Level=4
233 //http://www.web3d.org/realtime-3d/x3d/profiles
234 //I'll just make up and hardcode some values now
235 
237  int profileName;
238  const int *profileTable;
239  int level; //dug9
240 };
241 
242 static struct proftablestruct profTable[] = {
243  {PRO_Interchange, InterchangeProfile, 1},
244  {PRO_CADInterchange, CADInterchangeProfile, 1},
245  {PRO_MPEG4, MPEG4Profile, 1},
246  {PRO_Interactive, InteractiveProfile, 1},
247  {PRO_Full, FullProfile, 1},
248  {PRO_Immersive, ImmersiveProfile, 1},
249  {PRO_Core, CoreProfile, 1},
250  {INT_ID_UNDEFINED, (const int*) INT_ID_UNDEFINED, INT_ID_UNDEFINED}
251 };
252 
253 
254 void handleVersion(const char *versionString) {
255  int xa=0;
256  int xb=0;
257  int xc=0;
258  int rt;
259 
260  UNUSED(rt); // compiler warning mitigation
261 
262  /* printf ("handleVersion - x3d version :%s:\n", versionString); */
263  rt = sscanf (versionString,"%d.%d.%d",&xa, &xb,&xc);
264  /* printf ("rt %d xa %d xb %d xc %d\n",rt,xa,xb,xc); */
265 
266  /* we could (should?) do some more checking here, but for now... */
267  inputFileVersion[0] = xa, inputFileVersion[1] = xb; inputFileVersion[2] = xc;
268 }
269 
270 
271 
272 void handleMetaDataStringString(struct Uni_String *val1, struct Uni_String *val2) {
273  #ifdef CAPABILITIESVERBOSE
274  printf ("handleMetaDataStringString, :%s:, :%s:\n",val1->strptr, val2->strptr);
275  #endif
276 }
277 
278 // UNIT category unitname conversionfactor
279 // UNIT length micro 0.000001
280 // http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/core.html#UNITStatement
281 // http://www.web3d.org/documents/specifications/19776-2/V3.3/Part02/grammar.html#General
282 // http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/concepts.html#t-Standardunits
283 const char * unitcategories [] = {
284  "angle",
285  "force",
286  "length",
287  "mass",
288  "acceleration",
289  "angular_rate",
290  "area",
291  "speed",
292  "volume",
293 };
294 //#define UNITCATEGORIES_COUNT 9
295 const char * unitnames [] = {
296  "radian",
297  "newton",
298  "metre",
299  "kilogram",
300 };
301 //#define UNITNAMES_COUNT 4
302 void handleUnitDataStringString(char *categoryname, char *unitname, double conversionfactor) {
303  //int i1, i2;
304  //i1 = findFieldInARR(categoryname,unitcategories,UNITCATEGORIES_COUNT);
305  //i2 = findFieldInARR(unitname,unitnames,UNITNAMES_COUNT);
306  #ifdef CAPABILITIESVERBOSE
307  printf ("handleMetaDataStringString, :%s:, :%s:\n",val1->strptr, val2->strptr);
308  #endif
309 }
310 
311 void handleProfile (int myProfile) {
312  int *myTable = NULL;
313  int i;
314  /* myProfile is a valid profile number - bounds checked before entry */
315  #ifdef CAPABILITIESVERBOSE
316  printf ("handleProfile, my profile is %s (%d)\n",stringProfileType(myProfile), myProfile);
317  #endif
318 
319  i=0;
320  while ((profTable[i].profileName != INT_ID_UNDEFINED) && (profTable[i].profileName != myProfile)) i++;
321 
322  /* we really should have found this, unless we have a new profile that is not coded properly here */
323  if (profTable[i].profileName == INT_ID_UNDEFINED) {
324  ConsoleMessage ("Something wrong in handleProfile for profile %s\n",
325  stringProfileType(myProfile));
326  } else {
327  int comp;
328  int lev;
329  gglobal()->Mainloop.scene_profile = i;
330  myTable = (int *)profTable[i].profileTable;
331  /* go through the selected table, and see if each component is within range */
332  comp = *myTable; myTable++; lev = *myTable; myTable++;
333  while (comp != INT_ID_UNDEFINED) {
334  handleComponent(comp,lev);
335  comp = *myTable; myTable++; lev = *myTable; myTable++;
336  }
337  }
338 }
339 //>> exported to jsVRMLBrowser.c
340 int capabilitiesHandler_getComponentLevel(int *table, int comp)
341 {
342  return table[(comp*2) +1];
343 }
344 int capabilitiesHandler_getProfileLevel(int prof)
345 {
346  return profTable[prof].level;
347 }
348 const int *capabilitiesHandler_getProfileComponent(int prof)
349 {
350  return profTable[prof].profileTable;
351 }
352 const int *capabilitiesHandler_getCapabilitiesTable()
353 {
354  return capabilities;
355 }
356 int capabilitiesHandler_getTableLength(int* table){
357  int len = 0;
358  if(table == NULL) return 0;
359  while(table[2*len] != INT_ID_UNDEFINED)
360  len++;
361  return len;
362 }
363 //>>exported to jsVRMLBrowser_duk.c
364 struct proftablestruct *getProfTable(){
365  return profTable;
366 }
367 const int * getCapabilitiesTable(){
368  return capabilities;
369 }
370 
371 void scene_addComponent(int myComponent, int mylevel){
372  //besides the static tables for freewrl, we need a table for scene (desired) components
373  //generated during parsing
374  //we need an init to clear this
375  //and we need a Scene or ProtoInstance (ie broto) struct to store this in
376  int *scene_comps = gglobal()->Mainloop.scene_components;
377  int len = capabilitiesHandler_getTableLength(scene_comps);
378  scene_comps = realloc(scene_comps,sizeof(int)*2*(len+2));
379  scene_comps[len*2] = myComponent;
380  scene_comps[len*2 +1] = mylevel;
381  len++;
382  scene_comps[len*2] = INT_ID_UNDEFINED;
383  scene_comps[len*2 +1] = INT_ID_UNDEFINED;
384  gglobal()->Mainloop.scene_components = scene_comps;
385 }
386 void scene_clearComponents(){
387  FREE_IF_NZ(gglobal()->Mainloop.scene_components);
388 }
389 
390 //<<
391 
392 void handleComponent (int myComponent, int myLevel) {
393  int i;
394 
395  /* myComponent is a valid component number - bounds checked before entry */
396  #ifdef CAPABILITIESVERBOSE
397  printf ("handleComponent: my Component is %s, level %d\n",COMPONENTS[myComponent], myLevel);
398  #endif
399 
400  i=0;
401  while ((capabilities[i] != myComponent) && (capabilities[i] != INT_ID_UNDEFINED)) {
402  i+=2;
403  }
404 
405  /* did we find the component? */
406  if (capabilities[i] == myComponent) {
407  scene_addComponent(myComponent,myLevel);
408 
409  #ifdef CAPABILITIESVERBOSE
410  printf ("handleComponent, comparing requested level %d with supported level %d\n",myLevel, capabilities[i+1]);
411  #endif
412 
413  if (myLevel > capabilities[i+1]) {
414  ConsoleMessage ("Component %s support level %d, requested %d",
415  COMPONENTS[myComponent], capabilities[i+1], myLevel);
416  }
417  } else {
418  ConsoleMessage ("did not find component %s in capabilities table!",COMPONENTS[myComponent]);
419  }
420 }