FreeWRL / FreeX3D 4.3.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 */
42static 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, 4, /* 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, 3, /* Nov 2020 */
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 COM_TextureProjection, 2, //ProjectiveTextureMapping, 2, /* Feb 9, 2020 */
79 COM_MIDI, 3, /*July 2023*/
80 INT_ID_UNDEFINED, INT_ID_UNDEFINED,
81};
82
83/* profiles... */
84
85/* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 H3 Component support */
86static const int CADInterchangeProfile[] = {
87 COM_Core, 1,
88 COM_Networking, 1,
89 COM_Grouping, 1,
90 COM_Rendering, 4,
91 COM_Shape, 2,
92 COM_Lighting, 1,
93 COM_Texturing, 2,
94 COM_Navigation, 2,
95 COM_Shaders, 1,
96 COM_CADGeometry, 2,
97 COM_MIDI, 3,
98 INT_ID_UNDEFINED, INT_ID_UNDEFINED};
99
100
101/* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 A3 Component support */
102static const int CoreProfile[] = {
103 COM_Core, 1,
104 INT_ID_UNDEFINED, INT_ID_UNDEFINED};
105
106
107/* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 F3 Component support */
108static const int FullProfile[] = {
109 COM_Core, 2,
110 COM_Time, 2,
111 COM_Networking, 3,
112 COM_Grouping, 3,
113 COM_Rendering, 5,
114 COM_Shape, 4,
115 COM_Geometry3D, 4,
116 COM_Geometry2D, 2,
117 COM_Text, 1,
118 COM_Sound, 1,
119 COM_Lighting, 3,
120 COM_Texturing, 3,
121 COM_Interpolation, 5,
122 COM_Navigation, 3,
123 COM_PointDeviceSensor, 1,
124 COM_KeyDeviceSensor, 2,
125 COM_EnvironmentalSensor, 3,
126 COM_EnvironmentalEffects, 4,
127 COM_Geospatial, 2,
128 COM_HAnim, 3,
129 COM_NURBS, 4,
130 COM_DIS, 2,
131 COM_Scripting, 1,
132 COM_EventUtilities, 1,
133 COM_Shaders, 1,
134 COM_CADGeometry, 2,
135 COM_Texturing3D, 2,
136 COM_CubeMapTexturing, 3,
137 COM_Layering, 1,
138 COM_Layout, 2,
139 COM_RigidBodyPhysics, 2,
140 COM_Picking, 3,
141 COM_Followers, 1,
142 COM_ParticleSystems, 3,
143 COM_TextureProjection, 2, //ProjectiveTextureMapping, 2,
144 COM_MIDI, 3,
145 INT_ID_UNDEFINED, INT_ID_UNDEFINED};
146
147
148/* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 E3 Component support */
149static const int ImmersiveProfile[] = {
150 COM_Core, 2,
151 COM_Time, 1,
152 COM_Networking, 3,
153 COM_Grouping, 2,
154 COM_Rendering, 3,
155 COM_Shape, 2,
156 COM_Geometry3D, 4,
157 COM_Geometry2D, 1,
158 COM_Text, 1,
159 COM_Sound, 1,
160 COM_Lighting, 2,
161 COM_Texturing, 3,
162 COM_Interpolation, 2,
163 COM_PointDeviceSensor, 1,
164 COM_KeyDeviceSensor, 2,
165 COM_EnvironmentalSensor, 2,
166 COM_EnvironmentalEffects, 2,
167 COM_Scripting, 1,
168 COM_EventUtilities, 1,
169 COM_ParticleSystems, 3,
170 COM_TextureProjection, 2, //ProjectiveTextureMapping, 2,
171 COM_MIDI, 3,
172 INT_ID_UNDEFINED, INT_ID_UNDEFINED};
173
174
175/* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 C3 Component support */
176static const int InteractiveProfile[] = {
177 COM_Core, 1,
178 COM_Time, 1,
179 COM_Networking, 2,
180 COM_Grouping, 2,
181 COM_Rendering, 3,
182 COM_Shape, 1,
183 COM_Geometry3D, 3,
184 COM_Lighting, 2,
185 COM_Texturing, 2,
186 COM_Interpolation, 2,
187 COM_Navigation, 1,
188 COM_PointDeviceSensor, 1,
189 COM_KeyDeviceSensor, 1,
190 COM_EnvironmentalSensor, 1,
191 COM_EnvironmentalEffects, 1,
192 COM_EventUtilities, 1,
193 INT_ID_UNDEFINED, INT_ID_UNDEFINED};
194
195
196/* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 B3 Component support */
197static const int InterchangeProfile[] = {
198 COM_Core, 1,
199 COM_Time, 1,
200 COM_Networking, 1,
201 COM_Grouping, 1,
202 COM_Rendering, 3,
203 COM_Shape, 1,
204 COM_Geometry3D, 2,
205 COM_Lighting, 1,
206 COM_Texturing, 2,
207 COM_Interpolation, 2,
208 COM_Navigation, 1,
209 COM_EnvironmentalEffects, 1,
210 INT_ID_UNDEFINED, INT_ID_UNDEFINED};
211
212
213/* ISO-IEC-FDISINT_ID_UNDEFINED9775:1.2 D3 Component support */
214static const int MPEG4Profile[] = {
215 COM_Core, 1,
216 COM_Time, 1,
217 COM_Networking, 2,
218 COM_Grouping, 2,
219 COM_Rendering, 1,
220 COM_Shape, 1,
221 COM_Geometry3D, 2,
222 COM_Lighting, 2,
223 COM_Texturing, 1,
224 COM_Interpolation, 2,
225 COM_Navigation, 1,
226 COM_PointDeviceSensor, 1,
227 COM_EnvironmentalSensor, 1,
228 COM_Navigation, 1,
229 COM_EnvironmentalEffects, 1,
230 INT_ID_UNDEFINED, INT_ID_UNDEFINED};
231
232
233//dug9 Aug,2013 ecmascript interface V3 says a ProfileInfo has a name, level??, Title, providerUrl, componentInfoArray
234//
235//Q. how do you assign a Level to a Profile?
236//H0: 1 if you have it, else 0
237//H1: minimum of component levels in profile
238//H2: maximum of component levels in profile
239//H3: maximum nesting level - see diagram ie if you have Geospatial,Hanim,Nurbs you are at Full or Level=4
240//http://www.web3d.org/realtime-3d/x3d/profiles
241//I'll just make up and hardcode some values now
242
244 int profileName;
245 const int *profileTable;
246 int level; //dug9
247};
248
249static struct proftablestruct profTable[] = {
250 {PRO_Interchange, InterchangeProfile, 1},
251 {PRO_CADInterchange, CADInterchangeProfile, 1},
252 {PRO_MPEG4, MPEG4Profile, 1},
253 {PRO_Interactive, InteractiveProfile, 1},
254 {PRO_Full, FullProfile, 1},
255 {PRO_Immersive, ImmersiveProfile, 1},
256 {PRO_Core, CoreProfile, 1},
257 {INT_ID_UNDEFINED, (const int*) INT_ID_UNDEFINED, INT_ID_UNDEFINED}
258};
259
260
261void handleVersion(const char *versionString) {
262 int xa=0;
263 int xb=0;
264 int xc=0;
265 int rt;
266
267 UNUSED(rt); // compiler warning mitigation
268
269 /* printf ("handleVersion - x3d version :%s:\n", versionString); */
270 rt = sscanf (versionString,"%d.%d.%d",&xa, &xb,&xc);
271 /* printf ("rt %d xa %d xb %d xc %d\n",rt,xa,xb,xc); */
272
273 /* we could (should?) do some more checking here, but for now... */
274 inputFileVersion[0] = xa, inputFileVersion[1] = xb; inputFileVersion[2] = xc;
275}
276
277
278
279void handleMetaDataStringString(void *ectx, char *name, char *content) {
280 #ifdef CAPABILITIESVERBOSE
281 printf ("handleMetaDataStringString, :%s:, :%s:\n",val1->strptr, val2->strptr);
282 #endif
283 if (ectx) {
284 int nodetype = X3D_NODE(ectx)->_nodeType;
285 if (nodetype == NODE_Proto || nodetype == NODE_Inline) {
286 struct X3D_Proto* ec = (struct X3D_Proto*)ectx;
287 //add to __META section.
288 if (!ec->__META)
289 ec->__META = newVector(struct metarecord, 10);
290
291 struct Vector* metalist = (struct Vector*)ec->__META;
292 struct metarecord mr;
293 mr.name = strdup(name);
294 mr.content = strdup(content);
295 vector_pushBack(struct metarecord, metalist, mr);
296 }
297 }
298}
299
300// UNIT category unitname conversionfactor
301// UNIT length micro 0.000001
302// http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/core.html#UNITStatement
303// http://www.web3d.org/documents/specifications/19776-2/V3.3/Part02/grammar.html#General
304// http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/concepts.html#t-Standardunits
305void addUnits(void *ec, char *category, char *unit, double factor);
306void handleUnitDataStringString(void *ec, char *categoryname, char *unitname, double conversionfactor) {
307 addUnits(ec, categoryname,unitname,conversionfactor);
308 //printf ("handleUnitDataStringString, :%s:, :%s: :%lf:\n",categoryname,unitname,conversionfactor);
309}
310
311void 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
340int capabilitiesHandler_getComponentLevel(int *table, int comp)
341{
342 return table[(comp*2) +1];
343}
344int capabilitiesHandler_getProfileLevel(int prof)
345{
346 return profTable[prof].level;
347}
348const int *capabilitiesHandler_getProfileComponent(int prof)
349{
350 return profTable[prof].profileTable;
351}
352const int *capabilitiesHandler_getCapabilitiesTable()
353{
354 return capabilities;
355}
356int 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
364struct proftablestruct *getProfTable(){
365 return profTable;
366}
367const int * getCapabilitiesTable(){
368 return capabilities;
369}
370
371void 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}
386void scene_clearComponents(){
387 FREE_IF_NZ(gglobal()->Mainloop.scene_components);
388}
389
390//<<
391
392void 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}