The Seamless3d
Modelling Language
Most of the effort so far has focused on developing a WYSIWYG editor for creating
VRML/X3D and POV-Ray content but it is inevitable that a specialized 3d viewer that
can take advantage of seamless3d's powerful built in compiler will emerge.
Why Seamless3d is designed to be more script friendly
than VRML/X3D
Although seamless3d is influenced by VRML97, Seamless3d is designed to be a more
script friendly and a more powerful modelling language than VRML/X3D by making scripts integrated
into the design and by not having all events deferred.
In Example 1, we have VRML97 code for a spinning box using 2 ROUTEs and an OrienationInterpolator.
Example 1:
#VRML V2.0 utf8
DEF transform Transform{
children Shape{
appearance Appearance{
material Material{}
}
geometry Box{}
}
}
DEF orientationInterpolator OrientationInterpolator{
key [0 .333333 .666666 1]
keyValue [0 1 0 0 0 1 0 2.094395 0 1 0 4.18879 0 1 0 0]
}
DEF timeSensor TimeSensor{
cycleInterval 4
loop TRUE
}
ROUTE timeSensor.fraction_changed TO orientationInterpolator.set_fraction
ROUTE orientationInterpolator.value_changed TO transform.rotation
In Example 2, ROUTEs are replaced with script but a ROUTE is also added
from the TimeSensor to the Script node because there is no other way to call a script from
a Sensor node in VRML/X3D.
Example 2:
#VRML V2.0 utf8
DEF transform Transform{
children Shape{
appearance Appearance{
material Material{}
}
geometry Box{}
}
}
DEF orientationInterpolator OrientationInterpolator{
key [0 .333333 .666666 1]
keyValue [0 1 0 0 0 1 0 2.094395 0 1 0 4.18879 0 1 0 0]
}
DEF timeSensor TimeSensor{
cycleInterval 4
loop TRUE
}
DEF script Script{
directOutput TRUE
field SFNode transform USE transform
field SFNode orientationInterpolator USE orientationInterpolator
eventIn SFFloat onFrame
url "javascript:
function onFrame(v){
orientationInterpolator.set_fraction = v;
transform.rotation = orientationInterpolator.value_changed;
}
"
}
ROUTE timeSensor.fraction_changed TO script.onFrame
Example 2 is not as clean as example 1 because it is only one ROUTE less and
the Script node added adds 12 lines!
Although the actual function contains only 2 lines of script, the extra lines around
the function are needed because:
- All script functions must be contained in a Script node (but unlimited functions
can be contained in a single Script node).
- VRML/X3D requires that in order to reference a node external to the Script node,
a SFNode field be added to the Script node with it USEing the external node.
- An eventIn field must be added to the Script node with the same name as the
function so that a ROUTE can call the function by sending values to the eventIn field.
-
The directOutput field must be set to TRUE to allow for nodes to be referenced.
- VRML/X3D is a ROUTE oriented design.
In Example 3, script is utilised more neatly by replacing the OrientationInterpolator
node with a single line of script:
Example 3
#VRML V2.0 utf8
DEF transform Transform{
children Shape{
appearance Appearance{
material Material{}
}
geometry Box{}
}
}
DEF timeSensor TimeSensor{
cycleInterval 4
loop TRUE
}
DEF script Script{
directOutput TRUE
field SFNode transform USE transform
eventIn SFFloat onFrame
url "javascript:
function onFrame(v){
transform.rotation = new SFRotation(0, 1, 0, Math.PI * 2 * v);
}
"
}
ROUTE timeSensor.fraction_changed TO script.onFrame
This is significalty cleaner than the previous example but this still has more lines
of code than the first example.
Some advise not to reference nodes from a script
node and instead use the approach
shown in example 4 because of problems that can arise when events are deferred for
VRML/X3D.
Example 4
#VRML V2.0 utf8
DEF transform Transform{
children Shape{
appearance Appearance{
material Material{}
}
geometry Box{}
}
}
DEF timeSensor TimeSensor{
cycleInterval 4
loop TRUE
}
DEF script Script{
eventOut SFRotation spin_changed
eventIn SFFloat onFrame
url "javascript:
function onFrame(v){
spin_changed = new SFRotation(0, 1, 0, Math.PI * 2 * v);
}
"
}
ROUTE timeSensor.fraction_changed TO script.onFrame
ROUTE script.spin_changed TO transform.rotation
This may simplify some of the lines in the script node and the directOutput field
no longer
has to be specified but because of the extra ROUTE, it is not any cleaner and feels more like spaghetti logic than example
3.
Although in the last 2 examples the OrientationInterpolator is replaced with a single
line of script, it is debatable if the last 2 examples look any more elegant than
the first example.
I think this is because ROUTEs feel like they are part of the language the way they
are more integrated into the design (a ROUTE oriented design). This is why it often feels good if scripts can be avoided for VRML/X3D but scripts offer greater creative
freedom so typically a combination of ROUTEs and scripts are used but this can be
messy.
Often one hopes one can avoid using script for some minor task and so ROUTEs are first
applied and then later while debugging, scripts may be tried if they look like they
may offer a solution and then later again one may come up with another
idea that might utilize ROUTEs better but alternating
back and forth between what feels like 2 different languages can be time consuming.
When scripts are required for VRML/X3D I prefer to do as much as I can using scripts
and use ROUTEs only when there is no alterative way offered (such as for capturing
events from Sensor nodes).
The
next example which uses Seamless3d code offers a solution as clean as using
ROUTEs (free of script) using script (free of ROUTEs).
Example 5
#SMLS V2.123 utf8
Seamless{
effect ColorEffect{}
skeleton DEF part Part{}
build BoxBuild{
part USE part
}
}
Anim{
play TRUE
pause FALSE
loop TRUE
period 4
void onFrame(float v){
part.rotation = Rotation(0, 1, 0, PI * 2 * v);
}
}
With this script friendly design, scripts can accomplish the same trivial tasks that can be done using ROUTEs just as easily.
The following VRML/X3D ROUTE:
ROUTE nodeA.field TO nodeB.field
translates to the following line of seamless script:
nodeB.feild = nodeA.feild
and scripting options not available to ROUTEs can be so much more easily taken advantage
of:
nodeB.field = nodeA.field * .5
Firing Events Immediatly as Opposed to Defering Events
In Seamless3d events fire immediately by default the same way they do for other modern procedural oriented languages. This keeps the language both simple and flexible and avoids exposing the beginner to a non intuitive scripting environment.
For example most would intuitively expect the following code to display 2 on the screen:
Deferred Event Example:
#VRML V2.0 utf8
Shape{
appearance Appearance{
material Material{}
}
geometry DEF text Text{}
}
PROTO MyNode[
exposedField SFInt32 myField 0
]{
Group{}
}
DEF myNode MyNode{}
Script{
directOutput TRUE
field SFNode myNode USE myNode
field SFNode text USE text
field MFString str []
url "javascript:
function initialize(){
myNode.myField = 1;
myNode.myField = myNode.myField + 1;
str[0] = myNode.myField;
text.string = str;
}
"
}
But if the events are deferred for VRML/X3D, 0 will be displayed. The Xj3D browser gives an answer of 0 which is consistent with this but four of the most popular
VRML browsers, Cosmo, Contact, Cortona and Octaga will display the intuitive
answer of 2 which suggests they fire events
immediately the same as Seamless3d. Are these browsers not conforming to
the VRML standard? It does not seem clear to me that VRML must defer events because
the VRML specs state under
4.12.5 Scripts with direct outputs:
When setting a value in another node, implementations
are free to either immediately set the value or to defer setting the value until
the Script is finished.
This to me seems to be saying it is ok to either defer or not defer events for VRML (not to be confused with X3D), if so the answer can be either 0 or 2 allowing for inconsistent behaviour from different browsers.
Order of instructions
It is said by some that ROUTEs have the advantage of it not mattering what order they are placed in your code because the same behaviour will always result but if the user expects their instructions to follow through in the order they specify as most would intuitively expect, the user will experience frustration.
Avoiding self modifying code
It is said by some that ROUTEs offer the advantage of being able to be displayed
as a map to show all of the event ins and event outs and that ROUTEs can be added
and removed on the fly.
But if ROUTEs can be added or deleted at run time you are not guaranteed of seeing
all your ROUTEs mapped in your source code.
Self modifying code is a common request by beginner programmers and it can have
it's uses but because self modifying code can make code very difficult to read,
debug and document, most programmers use more practical means.
Avoiding browser bloat
By avoiding the extra overhead required for ROUTEs and a deferred event mechanism the browser is freed from a lot of unnecessary baggage.
Compatibility with other procedral languages
Seamless script offers a standard way to process
logic that does not get in the way of the novice advancing on to more advanced
tasks.
Using a more standard approach
for processing logic makes it much easier to convert scripts from and
to other procedral languages.
Compatibility with VRML/X3D
When seamless scripts are exported to VRML/X3D the necessary ROUTEs are created
but if one wants to write strict legal code for VRML/X3D it must be realized not
all of the powerful scripting capabilities from the Seamless3d modelling language apply, largely
due to VRML/X3D being a ROUTE oriented language. Therefore when targeting VRML/X3D,
scripts have to be written for the language but seamless can still make scripting
easier when targeting VRML/X3D because there is no need to set up a USE to reference
a node and there is no need to add a Script node nor is there any need to explicitly
add ROUTEs and one can take advantage of using operators for SFRotation and SFVec3f
types. For more information on how seamless utilises operators better than JavaScript
see
VRML JavasScript Conversion to Seamless3d C++
Why Seamless3d is not yet another incompatible
3d modelling language
It is fair to say Seamless3d is not a new 3d modelling language but rather it is a C++
library for creating and displaying 3d content and that this library is influenced
by VRML and is designed to be able to interpret most VRML content. However to allow
content for this library to be viewed on-line by a Seamless3d player (currently
the only Seamless3d player is the Seamless3d editor), a specialized on-line script
compiler is required to ensure scripts do not pose any more security issues than
would arise from any other web friendly scripting language.
C++ is highly suitable for writing complex applications and because it is a versitile
language by design it is also highly suitable for writing the most trivial of scripts
but seamless3d format does not have to be strictly C++ code for it to run in the
player, it just has to be be designed so that it relates 100% to the C++ standard
so that the content is guaranteed of being able to be compiled by any standard C++
compiler after it has been passed through a converter. This gives more than enough
elbow room in order to keep the standard both novice and expert friendly. I feel
it is very important to keep the modelling language compatible with C++ because:
- C++ enjoys an enormous amount of support and is the most popular language used for
writing 3d applications.
- C++ is an already well established ISO non proprietary standard.
- Scripts for on-line content can be interchanged with offline content.
- C++ offers a great level of creative freedom.
- Through custom built libraries C++ comes closest to satisfying everyone's needs.
- Scripts can be single stepped through and examined frozen in time using standard
C++ debugging aids.
- Standard C++ compilers can be used to verify script behavior.
- Very fast Scripts can be written for simulating physics in real time.
- It does not hold the novice back from advancing.
- C++ is not a trade mark of any organization and is free of lawsuit threats if one
finds the need to innovate on the standard.
Same as C++, the Seamless3d modelling language is not intended to be owned by any individual
including my self (thyme) or become a trademark of any organisation.
[3d Modelling Software]
[Tutorials]
[Forum]
[Features]
[Download]
[Gallery]
[FAQ]
[Worlds]
[Avatars]
[Links]
[Thyme]
Copyright © 2000-2009 Graham Perrett thyme@seamless3d.com