Interfacing FreeWRL/FreeX3D via ÒCÓ language
programs.
Document version 1.01 28 July 2009
Introduction
FreeWRL's C EAI interface allows you to write EAI code
to communicate with FreeWRL in C.
This document outlines how to create a C program that uses EAI to send
and receive information from a FreeWRL scenegraph.
Notes on compiling EAI programs
Code written in C must be linked against the FreeWRLEAI
library. This library should have
been created and installed during the installation of FreeWRL. Furthermore, you need to include the
"EAI_C.h" header file in order to access necessary function
definitions. The
"EAI_C.h" header file has been installed into /usr/local/include
during the FreeWRL installation process. (Note: as of 1.22.4, library is named ÒFreeWRLEAIÓ;
previously it was just ÒEAIÓ)
A simple EAI program
main.c:
#include <EAI_C.h>
#define SPHERE
"Sphere"
#define BLUE
"0.2 0.2 0.8"
X3DNode *myRoot;
X3DNode *shape1;
X3DEventIn *addChildren;
/* simple function to make shapes up */
X3DNode *makeSimpleShape (char * shape, char *colour, char
*posn) {
char myline[2000];
sprintf (myline,
"Transform{translation %s children Shape{" \
" appearance Appearance
{ \n" \
" material
Material {" \
"
diffuseColor %s" \
" }"
\
" }" \
" geometry %s {}"
\
"}}",posn,colour,shape);
return
X3D_createVrmlFromString(myline);
}
int main() {
/*
Initialization function. Connects
to FreeWRL EAI server. This
function must be called before any other EAI calls */
X3D_initialize("");
/*
Get a pointer to the node called "ROOT" in the current scenegraph */
myRoot =
X3D_getNode("ROOT");
if
(myRoot == 0) {
printf(ÒERROR:
node not found!\nÓ);
return;
}
/*
Get a pointer to the eventIn called "addChildren" of the ROOT node in
the current scenegraph */
addChildren
= X3D_getEventIn(myRoot, "addChildren");
if
(addChildren == 0) {
printf(ÒERROR:
event not found!\nÓ);
return;
}
/*
Utility function call which creates an X3D node - in this case a blue sphere */
shape1
= makeSimpleShape(SPHERE, BLUE, "-2.3 2.1 0");
/*
Set the value of the EventIn "addChildren" to a blue sphere. */
X3D_setValue(addChildren,
shape1);
/*
Wait so we can observe the results */
sleep(10);
/*
Free memory */
X3D_freeNode(myRoot);
X3D_freeNode(shape1);
X3D_freeEventIn(addChildren);
/*
Shutdown FreeWRL */
X3D_shutdown();
}
1.wrl:
#VRML V2.0 utf8
DEF ROOT Transform { }
To compile main.c on Linux; (might be subject to change)
gcc
-g -Wall -o EAITest -L/usr/lib -L/usr/lib/xulrunner-sdk-1.9pre/sdk/lib -lmozjs
-lpthread -lFreeWRLEAI -lfreetype -lGLU -lGL -lXxf86vm -lXext -lXmu -lXt -lXi
-ljpeg -lplds4 -lplc4 -lnspr4 -lpng12 -lXaw7 -lXmu -lXt -lX11 -lxml2 -lz -lm
-lSM -lICE -lexpat -lFreeWRL
To compile on OSX;
gcc
-o EAItest -lFreeWRLEAI main.c
To run the program:
freewrl --eai 1.wrl &
./EAITest
This test will add a blue sphere to the originally blank
1.wrl.
Note on the X3DNode structure
Many EAI functions take or return pointers to X3DNode
structures. The X3DNode structure
is actually a union that is used to contain all EAI data types, including - but
not limited to - nodes. Each X3DNode
structure has a type field which indicates the data type that the structure
holds. Field types are the same as
those used by FreeWRL and are defined as follows:
#define FIELDTYPE_SFFloat 0
#define FIELDTYPE_MFFloat 1
#define FIELDTYPE_SFRotation 2
#define FIELDTYPE_MFRotation 3
#define FIELDTYPE_SFVec3f 4
#define FIELDTYPE_MFVec3f 5
#define FIELDTYPE_SFBool 6
#define FIELDTYPE_MFBool 7
#define FIELDTYPE_SFInt32 8
#define FIELDTYPE_MFInt32 9
#define FIELDTYPE_SFNode 10
#define FIELDTYPE_MFNode 11
#define FIELDTYPE_SFColor 12
#define FIELDTYPE_MFColor 13
#define FIELDTYPE_SFColorRGBA 14
#define FIELDTYPE_MFColorRGBA 15
#define FIELDTYPE_SFTime 16
#define FIELDTYPE_MFTime 17
#define FIELDTYPE_SFString 18
#define FIELDTYPE_MFString 19
#define FIELDTYPE_SFVec2f 20
#define FIELDTYPE_MFVec2f 21
#define FIELDTYPE_SFImage 22
#define FIELDTYPE_FreeWRLPTR 23
#define FIELDTYPE_SFVec3d 24
#define FIELDTYPE_MFVec3d 25
#define FIELDTYPE_SFDouble 26
#define FIELDTYPE_MFDouble 27
#define FIELDTYPE_SFMatrix3f 28
#define FIELDTYPE_MFMatrix3f 29
#define FIELDTYPE_SFMatrix3d 30
#define FIELDTYPE_MFMatrix3d 31
#define FIELDTYPE_SFMatrix4f 32
#define FIELDTYPE_MFMatrix4f 33
#define FIELDTYPE_SFMatrix4d 34
#define FIELDTYPE_MFMatrix4d 35
#define FIELDTYPE_SFVec2d 36
#define FIELDTYPE_MFVec2d 37
#define FIELDTYPE_SFVec4f 38
#define FIELDTYPE_MFVec4f 39
#define FIELDTYPE_SFVec4d 40
#define FIELDTYPE_MFVec4d 41
The field type determines the data stored in the
node. For example, an SFVec2f
field will contain two floats, while an SFRotation field will contain three
floats. A series of utility
functions are provided to hide the internals of X3DNode from the user. These functions create new X3DNode
structures of the desired type initialized with the specified arguments. For example, the function
X3D_newSFInt32(int a) returns an X3DNode structure with a type field of
FIELDTYPE_SFInt32 and the data set to the value a. Similarly, utility functions
exist to extract the data from X3DNode structs and return them to the
user. For example, the function
X3D_getSFInt(X3DNode* node, int* value) copies the int stored in node into the variable value.
Establishing communication with a FreeWRL instance
Every program that wishes to use EAI to change a FreeWRL
scenegraph must first call X3D_initialize(hostname) in order to connect the EAI
program to the FreeWRL instance.
EAI programs communicate with FreeWRL using sockets on a known
port. The FreeWRL program acts as
the server and the EAI program as the client, meaning that FreeWRL listens for
incoming connections from EAI programs.
As a result, FreeWRL must be started before the EAI client is started. If the EAI client is started first it
will not find a FreeWRL instance to connect to and X3D_initialize will
(eventually) time out.
It is possible to specify the host on which the FreeWRL
instance is running as an argument to X3D_initialize. This allows an EAI client to communicate with a FreeWRL
server running on a different host.
If no destination host is specified as an argument to X3D_initialize the
localhost is used as the destination address.
Note that since FreeWRL and EAI communicate on a known
port it is currently not possible to run more than one EAI client or FreeWRL
server on the same host.
Furthermore, FreeWRL will only connect to a single EAI client at any one
time.
Once X3D_initialize has successfully returned it is
possible to use any of the provided interface functions to communicate with
FreeWRL. When the EAI program
wishes to terminate, it should call X3D_shutdown() to close the connection to
FreeWRL.
Getting information from the scenegraph
EAI allows you to query to current X3D scenegraph in
order to garner information about nodes and field values. In order to access nodes in the
scenegraph the function X3D_getNode(char* nodename) is used. This function searches the scenegraph
for a node that has been labelled with the specified nodename. For instance, should your world contain the following:
DEF ROOT Transform {
children
[
DEF
SQUARE Shape { }
]
}
X3D_getNode("ROOT") would return a pointer to
an X3DNode structure for the Transform node, while
X3D_getNode("SQUARE") would return a pointer to an X3DNode structure
for the Shape node. The X3DNode
structure returned contains little information about the requested node,
serving instead to provide a reference number for that node with which you can
make further queries.
It is best to think of X3D_getNode as returning an index
to the node in the scenegraph.
Using this index, you can query FreeWRL as to the specifics of the
eventIns and eventOuts of that node using X3D_getEventIn(X3DNode* node, char* eventname) and X3D_getEventOut(X3DNode* node, char* eventname). These two functions allow you to request pointers to the
fields, eventIns, and eventOuts. Note that if either X3D_getNode,
X3D_getEventIn or X3D_getEventOut are unable to find the requested node or
event, they will return 0. You
should always check the return values.
Using once again the above X3D code snippet:
/* Get a pointer to the ROOT node */
X3DNode* rootNode = X3D_getNode("ROOT");
if (myRoot == 0) {
printf(ÒERROR:
node not found!\nÓ);
return;
}
/* Get a pointer to the addChildren eventIn of the ROOT
node */
X3DEventIn* addChildren = X3D_getEventIn(rootNode,
"addChildren");
if (addChildren == 0) {
printf(ÒERROR:
event not found!\nÓ);
return;
}
/* Get a pointer to the translation eventOut of the ROOT
node */
X3DEventOut* translation = X3D_getEventOut(rootNode,
"translation");
if (translation == 0) {
printf(ÒERROR:
event not found!\nÓ);
return;
}
Now you have pointers to the addChildren eventIn and
translation eventOut of the ROOT node.
These pointers will allow you to obtain and modify the values of those
fields in the FreeWRL scenegraph.
We will address modifying values in the next section. Accessing field values can be done in
two different ways. Should you
want to obtain the value of a given field at an single instant in time the
X3D_getValue(X3DEventOut* src, X3DNode* value) will do what you require. This function is passed a pointer to
the EventOut for which you want a value, and returns the value in an X3DNode
structure. (See note on the
X3DNode structure above for more on how this value is stored). However, should you want to keep track
of the value of a field as it changes over time, you should register a listener
for that field. In order to
register a listener you use the X3DAdvise(X3DEventOut* event, void* callback) function. This will ensure that the function callback is called every time that the
EventOut event
changes. The function callback will be passed the updated
value of the EventOut field event whenever it is called.
Changing the scenegraph
EAI allows you to modify the FreeWRL scenegraph in real
time by changing the values of EventIns and by adding and removing ROUTEs
between fields.
Changing the value of an EventIn requires a pointer to
the EventIn that you wish to change.
This pointer can be obtained as outlined in the previous section. Once you have a pointer to the EventIn
that you wish to modify, you simply call the function X3D_setValue(X3DEventIn* dest, X3DNode* value). This changes the value of the EventIn dest to the value specified in value. In order to create the appropriate X3DNode structure it is
recommended that you use one of the utility functions (as outlined in the note
on the X3DNode structure section) or the function
X3D_createVrmlFromString(char* string).
X3D_createVrmlFromString(char* string) will take a string of X3D/VRML
code and ask FreeWRL to return a pointer to the nodes described within. Note that this function does not add nodes
to the scenegraph; it simply asks FreeWRL to parse the nodes and return a
pointer to the parsed nodes that can be used to add them to the graph.
Following on with our examples in the previous section,
but this time fetching the eventIn for the translation field:
/* Get a pointer to the ROOT node */
X3DNode* rootNode = X3D_getNode("ROOT");
if (myRoot == 0) {
printf(ÒERROR:
node not found!\nÓ);
return;
}
/* Get a pointer to the addChildren eventIn of the ROOT
node */
X3DEventIn* addChildren = X3D_getEventIn(rootNode,
"addChildren");
if (addChildren == 0) {
printf(ÒERROR:
event not found!\nÓ);
return;
}
/* Get a pointer to the translation eventOut of the ROOT
node */
X3DEventOut* translation = X3D_getEventOut(rootNode,
"translation");
if (translation == 0) {
printf(ÒERROR:
event not found!\nÓ);
return;
}
/* Create a simple sphere */
X3DNode* shape1 =
X3D_createVrmlFromString("Transform{children Shape { geometry Sphere {}
}}");
if (shape1 == 0) {
printf(ÒERROR:
unable to create vrml from string!\nÓ);
return;
}
/* Set the value of the addChildren field of the ROOT node
to the sphere we just created.
AddChildren is a special EventIn defined for Transform nodes. It will add the nodes given to it as
children of the transform node */
X3D_setValue(addChildren, shape1);
/* Create a new X3DNode structure containing an SFVec3f
value */
X3DNode* trans = X3D_newSFVec3f(1.0, 0.0, 0.0);
if (trans == 0) {
printf(ÒERROR:
node not found!\nÓ);
return;
}
/* Set the translation field of the ROOT node to the new
translation value just defined */
X3D_setValue(translation, trans);
The other way to modify the scenegraph provided by EAI
is by adding or removing ROUTEs.
ROUTE statements link an EventOut to an EventIn such that when the value
of the EventOut changes the value of the EventIn is modified to match. You can create a new ROUTE in EAI using
the X3D_addRoute(X3DEventOut* from, X3DEventIn* to) function.
This will link the specified EventIn to the specified EventOut. Similarly, you can delete an existing
route by calling X3D_deleteRoute(X3DEventOut* from, X3DEventIn* to). Note that ROUTE statements do not stack. If a ROUTE is defined multiple times
there is still only one ROUTE between any given field pair. Deleting a ROUTE will delete the
connection between a pair of fields no matter how many times the ROUTE had been
created in the past. Deleting a
ROUTE which does not exist has no effect.
Function Reference
void X3D_initialize(char* hostname)
Takes a pointer to a string containing the host name on
which FreeWRL is running as an argument.
If the length of the argument is 0 "localhost" is used as the
default.
This function attempts to connect to the EAI FreeWRL
server running on hostname on the default EAI port. You must call this function before calling any other EAI
functions.
void X3D_shutdown()
Takes no argument.
This function sends a command to FreeWRL telling it to
shutdown.
X3DNode* X3D_getNode(char* nodename)
Takes a pointer to a string containing the name of the
node requested.
Returns a pointer to an X3DNode structure containing the
address of the requested node. If
the node requested does not appear in the scenegraph, returns 0.
X3DEventIn* X3D_getEventIn(X3DNode* node, char* eventname)
Takes a pointer to the node for which the event is
requested and a pointer to a string containing the name of the event requested.
Returns a pointer to an X3DEventIn structure containing
the data for the requested eventIn.
If the eventIn requested does not exist for the given node, returns 0.
X3DEventOut* X3D_getEventOut(X3DNode* node, char* eventname)
Takes a pointer to the node for which the event is
requested and a pointer to a string containing the name of the event requested.
Returns a pointer to an X3DEventOut structure containing
the data for the requested eventOut.
If the eventOut requested does not exist for the given node, returns 0.
void X3D_addRoute(X3DEventOut* from, X3DEventIn* to)
Takes a pointer to the X3DEventOut to route from and a
pointer to the X3DEventIn to route to.
This function attempts to add a ROUTE between the two
specified events.
void X3D_deleteRoute(X3DEventOut* from, X3DEventIn* to)
Takes a pointer to the X3DEventOut that the route to be
deleted originated from and a pointer to the X3DEventIn at which the route to
be deleted ended.
This function attempts to remove the ROUTE between the
two specified events.
void X3D_setValue(X3DEventIn* dest, X3DNode* value)
Takes a pointer to the X3DEventIn who's value to change,
and a pointer to an X3DNode structure containing the value to set.
This function attempts to set the value of the eventIn
field dest to
the value contained in the X3DNode structure value.
void X3D_getValue(X3DEventOut* src, X3DNode* value)
Takes a pointer to the X3DEventOut who's value is
requested, and a pointer to an X3DNode structure in which to return the value.
This function attempts to fetch the value of the
eventOut field src and returns it in the X3DNode structure value.
X3DNode* X3D_createVrmlFromString(char* string)
Takes a pointer to a string containing the X3D code to
be used.
Returns a pointer to the nodes created by parsing the
passed X3D string.
This function attempts to parse the X3D code passed in string and return a pointer to the
node(s) created. If it was unable
to parse the passed string, it returns 0.
int X3DAdvise(X3DEventOut* event, void* function)
Takes a pointer to the event which you want to track and
a pointer to the function to call if the event value changes.
Returns 1 on success, and 0 otherwise.
This
function registers function as a listener for event. This means that whenever there is a change in the value of event the function function will be called. function must take a single void*
argument. When there is a change
to the value of event the new value will be passed in this argument when function is called. This function returns the index number
FreeWRL uses to identify this event.
If this
function is passed a zero as a function pointer (function == 0) changes in the value of event are instead written to a
socket. Programs can connect to
this socket in order to receive event information this way instead of via
callbacks. Event data is sent as
along with the index number associated with this event to allow client programs
to match the data to the appropriate event.
X3DNode
*X3D_newSFVec3f (float a, float b, float c)
Takes
as an argument three float values, and returns an X3DNode structure that
contains these values.
void
X3D_getSFVec3f(X3DNode* node, float* value);
Takes
as an argument an X3DNode structure that contains an SFVec3f and a pointer to a
float. This function allocates an
array of three floats and fills it with the values contained in the X3DNode.
X3DNode
*X3D_newSFColor (float a, float b, float c)
Takes
as an argument three float values, and returns an X3DNode structure that
contains these values.
void X3D_getSFColor(X3DNode*
node, float* value)
Takes
as an argument an X3DNode structure that contains an SFColor and a pointer to a
float. This function allocates an
array of three floats and fills it with the values contained in the X3DNode.
X3DNode
*X3D_newSFVec2f (float a, float b)
Takes
as an argument two float values, and returns an X3DNode structure that contains
these values.
void
X3D_getSFVec2f(X3DNode* node, float* value)
Takes
as an argument an X3DNode structure that contains an SFVec2f and a pointer to a
float. This function allocates an
array of two floats and fills it with the values contained in the X3DNode.
X3DNode
*X3D_newSFRotation (float a, float b, float c, float d)
Takes
as an argument four float values, and returns an X3DNode structure that
contains these values.
void
X3D_getSFRotation(X3DNode* node, float* value)
Takes
as an argument an X3DNode structure that contains an SFRotation and a pointer
to a float. This function
allocates an array of four floats and fills it with the values contained in the
X3DNode.
X3DNode
*X3D_newSFColorRGBA (float a, float b, float c, float d)
Takes
as an argument four float values, and returns an X3DNode structure that
contains these values.
void
X3D_getSFColorRGBA(X3DNode* node, float* value)
Takes
as an argument an X3DNode structure that contains an SFColorRGBA and a pointer
to a float. This function
allocates an array of four floats and fills it with the values contained in the
X3DNode.
X3DNode
*X3D_newSFBool (int a)
Takes
as an argument one int value, and returns an X3DNode structure that contains
this value.
void
X3D_getSFBool(X3DNode* node, int* value)
Takes
as an argument an X3DNode structure that contains an SFBool and a pointer to an
int. This function copies the int
value from the X3DNode into value.
X3DNode
*X3D_newSFFloat (float a)
Takes
as an argument one float value, and returns an X3DNode structure that contains
this value.
void
X3D_getSFFloat(X3DNode* node, float* value)
Takes
as an argument an X3DNode structure that contains an SFFloat and a pointer to a
float. This function copies the float value from the X3DNode into value
X3DNode
*X3D_newSFTime (double a)
Takes
as an argument one float value, and returns an X3DNode structure that contains
that value.
void
X3D_getSFTime(X3DNode* node, double* value)
Takes
as an argument an X3DNode structure that contains an SFTime and a pointer to a
float. This function copies the float value from the X3DNode into value.
X3DNode
*X3D_newSFInt32 (int a)
Takes
as an argument one int value, and returns an X3DNode structure that contains
that value.
void
X3D_getSFInt32(X3DNode* node, int* value)
Takes
as an argument an X3DNode structure that contains an SFInt32 and a pointer to
an int. This function copies the int value from the X3DNode into value.
X3DNode
*X3D_newSFString()
Takes
as an argument one string value, and returns an X3DNode structure that contains
that value.
char*
X3D_getSFString(X3DNode* node)
Takes
as an argument an X3DNode structure that contains an SFString value and returns
a pointer to the string value from that X3DNode.
X3DNode
*X3D_newMFColor(int num, float (*array)[3])
Takes
as an argument a pointer to an array of arrays of three floats, and the number
of such arrays. Returns an X3DNode structure that contains these values.
void
X3D_getMFColor(X3DNode* node, float ***array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to a
two-dimensional array of floats.
Allocates sufficient room for the floats contained in the X3DNode
structure and copies into it the values from that structure. Sets num to the number of three float
arrays.
X3DNode
*X3D_newMFFloat(int num, float* array)
Takes as
an argument a pointer to an array of floats, and the number of values. Returns
an X3DNode structure that contains these values.
void
X3D_getMFFloat(X3DNode* node, float** array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to an
array of floats. Allocates
sufficient room for the floats contained in the X3DNode structure and copies
into it the values from that structure.
Sets num
to the number of floats in the array.
X3DNode
*X3D_newMFInt32(int num, int* array)
Takes
as an argument a pointer to an array of ints, and the number of values. Returns
an X3DNode structure that contains these values.
void
X3D_getMFInt32(X3DNode* node, int** array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to an
array of ints. Allocates
sufficient room for the ints contained in the X3DNode structure and copies the
values from that structure. Sets num to the number of ints in the
array.
X3DNode
*X3D_newMFString(int num, char array[][256])
Takes
as an argument a pointer to an array of 256 char strings, and the number of
strings. Returns an X3DNode structure that contains these values.
void
X3D_getMFString(X3DNode* node, char*** array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to a
two-dimensional array of chars.
Allocates room for 256 character arrays to contain each string in the
X3DNode structure and copies in the values. Sets num to the number of strings.
X3DNode
*X3D_newMFRotation(int num, float (*array)[4])
Takes
as an argument a pointer to an array of arrays of four floats, and the number
of such arrays. Returns an X3DNode structure that contains these values.
void
X3D_getMFRotation(X3DNode* node, float ***array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to a
two-dimensional array of floats.
Allocates sufficient room for the floats contained in the X3DNode
structure and copies into it the values from that structure. Sets num to the number of four float
arrays.
X3DNode
*X3D_newMFVec2f(int num, float (*array)[2])
Takes
as an argument a pointer to an array of arrays of two floats, and the number of
such arrays. Returns an X3DNode structure that contains these values.
void
X3D_getMFVec2f(X3DNode* node, float ***array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to a
two-dimensional array of floats.
Allocates sufficient room for the floats contained in the X3DNode
structure and copies into it the values from that structure. Sets num to the number of two float
arrays.
X3DNode
*X3D_newMFVec3f(int num, float (*array)[3])
Takes
as an argument a pointer to an array of arrays of three floats, and the number
of such arrays. Returns an X3DNode structure that contains these values.
void
X3D_getMFVec3f(X3DNode* node, float ***array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to a
two-dimensional array of floats.
Allocates sufficient room for the floats contained in the X3DNode
structure and copies into it the values from that structure. Sets num to the number of three float
arrays.
X3DNode
*X3D_newMFColorRGBA(int num, float (*array)[4])
Takes
as an argument a pointer to an array of arrays of four floats, and the number
of such arrays. Returns an X3DNode structure that contains these values.
void
X3D_getMFColorRGBA(X3DNode* node, float ***array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to a
two-dimensional array of floats.
Allocates sufficient room for the floats contained in the X3DNode
structure and copies into it the values from that structure. Sets num to the number of four float
arrays.
X3DNode
*X3D_newMFBool(int num, int* array)
Takes
as an argument a pointer to an array of ints, and the number of values. Returns
an X3DNode structure that contains these values.
void
X3D_getMFBool(X3DNode* node, int** array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to an
array of ints. Allocates
sufficient room for the ints contained in the X3DNode structure and copies the
values from that structure. Sets num to the number of ints in the
array.
X3DNode
*X3D_newMFVec3d(int num, double (*array)[3])
Takes
as an argument a pointer to an array of arrays of three doubles, and the number
of such arrays. Returns an X3DNode structure that contains these values.
void
X3D_getMFVec3d(X3DNode* node, double ***array, int* num)
Takes
as an argument an X3DNode structure, a pointer to an int, and a pointer to a
two-dimensional array of doubles.
Allocates sufficient room for the doubles contained in the X3DNode
structure and copies into it the values from that structure. Sets num to the number of three double
arrays.
void
X3D_freeEventIn(X3DEventIn* ev)
Takes
as an argument a pointer to an X3DEventIn structure. Frees the memory used by this structure.
void
X3D_freeEventOut(X3DEventOut* ev)
Takes
as an argument a pointer to an X3DEventOut structure. Frees the memory used by this structure.
void
X3D_freeNode(X3DNode* node)
Takes
as an argument a pointer to an X3DNode structure. Frees the memory used by this structure.