VRML JavasScript Conversion to Seamless3d C++

I have designed the Seamless3d library so that it should be very simular in how it looks and feels to JavaScript for VRML.

Declaring Variables

The main difference between JavaScript and Seamless3d, is variables must be declared stating what type of variable they are.

For example in JavaScript we can declare a number variable named "i" to the value of 5:

i = 5;

for C++ we must insert an int, float or double in the beginning:

int i = 5;

float i = 5;

double i = 5;

If we wanted we could always use a double when converting from JavaScript for number variables and it would still be more efficient than JavaScript. However floats are more efficient than doubles (but not as accurate) and ints are more efficinet again but can not represent fractions.

For functions we drop the keyword "function" but we must define the types for both the return and parameter variables.
For example:

int myFunction(int myInt, float myFloat){
    return myInt + myFloat * .5;
}

If we don't return anything with the function we must use the keyword void for the return type as shown in the following example:

void myFunction(int myInt, float myFloat){
   g_myGlobalInt = myInt + myFloat * .5;
}

Global and Local Variables

A global variable is declared outside a function and can be treated much the same as declaring a field in a VRML Script node but are declared exactly the same way a local variable is except they must Not be declared inside a function.

A local variable is declared within a function which is the same for JavaScript. It's value is only relevant for the time the CPU is running through the function and so it's value will be lost soon as the function has exited and therefore will not last to see the next animated frame.

Global variables unlike local variables can be used to store values from frame to frame.

Type Conversion:

Seamless3d types are much the same but should be thought of as just plain variables not fields when writing scripts. Field types in Seamless3d always belong to a node type and therefore can not be declared in a script by them selves the way they are in JavaScript. When we want a SFVec3f type declared in a script we use the variable Vec3f which is the value type for a SFVec3f.

The following table shows the equivalent JavaScript types to C++:


VRML Seamless3d
SFColor Color3f
SFFloat float
SFInt32 int
SFNode NodePtr, Node*
SFImage Not yet suported
SFRotation Rotation
SFString String
SFTime double
SFVec2f Vec2f
SFVec3f Vec3f
MFColor M_Color3f
MFFloat M_Float
MFInt32 M_Int
MFNode M_Node
MFRotation M_Rotation
MFString M_String
MFTime M_Double
MFVec2f M_Vec2f
MFVec3f M_Vec3f
VrmlMatrix Matrix


In JavaScript when a specific VRML type is declared such as a SFVec3f it is declared with a "new". For example:

myVecf3 = new SFVec3f(0,1,1);

For C++ we declare all of the VRML types except for a Node type with NO "new":

Vec3f myVecf3 = Vec3f(0,1,1);

This is more efficient than using a new because we utilize the stack memory instead of using memory from the heap.

Operators that Replace Some Functions

Some of the JavaScript functions have been replced with operators to make coding read better:
To multiply a SFRotation type with another SFRotation type in javascript we do this:

rotA = rotA.Multiply(rotB);

in C++ its:

rotA = rotA * rotB;

For multVec we do the same for C++ using the exact same operator:

vec3fA = rotA * vec3fB;

The following table shows the operators to use instead of the javaScript functions:

In the example colum: rot = a Rotation type, vec = Vec2f or Vec3f, mtrx = Matrix

Type Function Operator Example
Rotationmultiply* rot = rot * rot
RotationmultVec* vec = rot * vec
Rotationinverse- rot = -rot
Vec2fadd+ vec = vec + vec
Vec2fdivide/ vec = vec / 2
Vec2fnegate- vec = -vec
Vec3fadd+ vec = vec + vec
Vec3fsubtract- vec = vec - vec
Vec3fdivide/ vec = vec / 2
Vec3fnegate- vec = -vec
Vec3fsubtract- vec = vec - vec
MatrixmultLeft* mtrx = mtrx * mtrx
MatrixmultRight* mtrx = mtrx * mtrx
MatrixmultVecMatrix* vec = vec * mtrx
MatrixmultMatrixVec* vec = mtrx * vec


Multiple Field (MF) Types

In C++ MF fields types are known as container types. In most C++ libraries to change the size of a container type a function is typically used but for Seamless3d this is done exactly the same way as in JavaScript or any other language that uses properties.

For example to set myM_Int to the length of 5 elements:

myM_Int.length = 5;

to read the value of how many elements myInt contains:

int i = myM_Int.length;

For Seamless3d container types do not automatically adjust their length when an element is indexed by an index greater or equal to the length of the container. When this is done an exception occurs. This is designed like this not only to keep things more efficint but to also aid debugging by helping  keep the programmer in touch with what is going on.

The += operator can be used to automaticaly add a value to the end of the list of element in the container. 
So to do this in javascript:

myM_Int[myM_Int.length = 5;

we do it liked this for Seamless3d:

myM_Int += 5;

which reads nicer :)



Long Lists of Elements

With vrml we can easily define a long list of Vec3f types using a MFVec3f field in a Script node (outside of the javascript) which containes simply a list of floats.

Unfortunaly C++ does not currently have an equivlent that is this convient.
However bjarne stroustrup is addressing this deficinecy for the next C++ standard. Because of this I have made the Seamless C++ compiler let the user declare a long list of Vec3f types for a M_Vec3f using a FloatList constructor.
For example:

M_Vec3f myMv = FloatList(4.5 ,0 , 4.5 , 78 ,5, 0);
So long as the number of elements inside the FloatList divides cleanly by 3 it is leagal.

A FloatList constructor can also be used for M_Vec2f (must divide by 2) and M_Rotation types (must divide by 4).

For a M_Float just use a long list in a M_Float and do the equivlent for for M_Int, M_Double and M_Bool types.


When using a current standard C++ compiler we can use arrays and the FLOAT_LIST or INT_LIST macros to initialize a long list for a container.

for example:

float myFloatArray[]={4.5 ,0 , 4.5 , 78 ,5, 0};
M_Vec3f myMv = FLOAT_LIST(myFloatArray);

For a list of floats less than 20 elements for a M_Float type use a M_Float constructor.
for over use the FLOAT_LIST macro too
For a list of ints less than 20 elements for a M_Int type use a M_Int constructor.
for over use the FLOAT_INT macro too

These macros are not as nice as constructores but are a workable way for the current  standard.


Strings
Seamless3d Strings behave the same as JavaScript strings except when using C++ it is impossible to concatenate 2 or more literal strings in a row using the + operator (something that is not really needed)

for example this is illegal:

String str = "ab" + "cd";

which should be converted to:

String str = "abcd";

The + operator works fine for any number of String variables.
for example:

String strA = strB + strC + strD;

and it is fine to insert a literal string any where so long as we do not have 2 literal strings concatenated together using the + operator:

therefore this is fine:

String strA = "ab" + strC + "cd";


 

Copyright © 2000-2006 Graham Perrett thyme@seamless3d.com