SONY Community Place Developer FAQ v1.0
What tools do I
need to develop VRML/Java worlds?
What's a good
sample program to test my environment out?
Why do I get
errors about missing files when compiling my Java programs?
Can I use
Microsoft's Java SDK instead of Sun's?
I don't know the
first thing about 3D mathematics. Where
can I go for a reference?
Can I buy a book
about programming Java and VRML?
What's the best
way to debug my code?
TimeSensors are
giving me a headache. Any advice?
How can I
implement some simple Java-controlled animations?
How can I make my
worlds multi-user?
How can I share
events in my multi-user worlds?
Can I use the EAI
with Community Place?
Can I use
JavaScript with Community Place?
How can I read and
write files to the local hard drive?
How can I add my
own avatars to a multi-user world?
How can I
implement my own custom avatar behaviors to my multi-user world?
How can I have a
third-person perspective of my avatar?
How can I add
object persistence or database functionality to a world?
How can I traverse
the live scene graph from my Script?
I want to
implement my own custom navigation routine.
Can this be done?
How do I implement
user-object collision detection?
How do I implement
object-object collision detection?
Can I change the
pitch of a sound on-the-fly for Doppler-like effects?
Any support for
stereoscopic viewing?
Any 3DFX Voodoo
support?
I'm worried about
people decompiling my programs. What can
I do about this?
Can I use C
instead of Java?
Is Community Place
Y2K compliant?
Can I generate
textures on-the-fly?
What kinds of
other special effects can I use?
How can I optimize
my scene graph for faster rendering?
Can I use
joysticks, or any other special user input hardware?
How can I connect
to another server to retrieve some information?
Please tell me how
to use CreateVRMLFromX()!
How can I add
"bots" to my world?
How can I track
the movements of users in the world?
Can I send email
automatically from my Script node?
Can I use other
windows on the screen to display some information?
How can I
implement a "heads-up display"?
Why is it not a
good idea to have lots of Lights in my world?
How do I turn the
headlight off as a default for the world?
How can I
implement a guided tour?
I want to
accumulate several rotations, but there's no "multiply()" function in
the SFRotation JSAI spec. Help!
I want to
implement a particle system. Why
shouldn't I use Spheres?
Is there an easy
way to do particle flocking?
When using a
PlaneSensor I get a weird feedback problem.
Any advice?
What movie formats
can I use inside a MovieTexture?
What image formats
can I use inside an ImageTexture?
Why should I use
LODs? What's the best way to set up
LODs?
Fog isn't working
quite the way I wanted it to. Help!
I have hundreds of
ROUTEs in my main file. What can I do
about this?
I get a weird
flashing effect in CP when I'm playing MP3 audio files in the background.
I'm sick of typing
appearance Appearance material Material.
Please help!!
What tools do I need to develop VRML worlds?
At the very minimum you'll need some kind of text editor to
edit your VRML files. Programmers' File
Editor is a good choice for Windows users, and VIM is a good choice for people
used to a Unix-like environment. Both of
these products are freeware.
If you want to start coding Java worlds, you'll need the
Java Development Kit (JDK) from Sun.
(Note that this is different from the Java Runtime Environment (JRE),
which is intended only for end-users.)
Feel free to use Java IDEs if you want (Visual J++, Visual
Cafe, Kawa, etc.) but make sure to add the Community Place classes to your
compiler's CLASSPATH. (See below.)
What's a good sample program to test my environment out?
A simple toggle-switch is a good test case. Type the following programs in:
(toggle.wrl)
#VRML V2.0 utf8
NavigationInfo {
headlight FALSE
}
Transform {
children [
DEF TS TouchSensor {
}
Shape {
appearance
Appearance {
material
Material {
diffuseColor
1 0 0
}
}
geometry Box { }
}
]
}
DEF LIGHT PointLight {
on TRUE
location 5 5 5
}
DEF SCR Script {
url
"toggle.class"
eventIn SFBool click
eventOut SFBool lightActivated
}
ROUTE TS.isActive TO SCR.click
ROUTE SCR.lightActivated TO LIGHT.set_on
(toggle.java)
import vrml.*;
import vrml.node.*;
import vrml.field.*;
public class toggle extends Script {
SFBool
lightActivated;
boolean
my_lightActivated;
public void
initialize() {
lightActivated =
(SFBool)getEventOut("lightActivated");
my_lightActivated
= true;
}
public void
processEvent(Event ev) {
if
(((ConstSFBool)ev.getValue()).getValue() == true) { // filter out mouseUps
my_lightActivated = !my_lightActivated;
lightActivated.setValue(my_lightActivated);
System.out.println("I was clicked");
}
}
}
After you type these programs in, compile the Java program
by typing:
javac toggle.java
If you get no errors, great!
Run Community Place with the toggle.wrl file. When you click on the red box, the light
should turn on and off, toggling every time.
If you get Java-related errors, see the next question.
Why do I get errors about missing files when compiling my
Java programs?
The compiler is, most likely, not able to find the special
VRML-related Java classes. You need to
configure your environment to point to these classes. There are three ways of doing this:
1. (easiest) Add the VSCLASS.ZIP file to your
classpath. Note that the full file path
is C:\PROGRA~1\SONY\COMMUN~1\LIB\VSCLASS.ZIP by default. You do this by editing your C:\AUTOEXEC.BAT
file and adding the following at the bottom:
SET
CLASSPATH=%CLASSPATH%;C:\PROGRA~1\SONY\COMMUN~1\LIB\VSCLASS.ZIP
You should, of course, change these file directories to suit
your own particular installation.
2. Unzip the afore-mentioned VSCLASS.ZIP file somewhere in
your hard drive, and point the CLASSPATH to that directory. For example, I can unzip VSCLASS.ZIP into
C:\CLASSES and then add C:\CLASSES to my CLASSPATH variable (as above). Please make sure that your unzip tool
preserves the directories present in the ZIP file.
3. If you're using a Java IDE, please consult the user's
manual to learn how to add entries to the CLASSPATH variable, and choose one of
the methods listed above.
If you're getting non-VRML related Java compiler errors,
then you may have a separate problem.
Please check Sun's site for their developer info.
Can I use Microsoft's Java SDK instead of Sun's?
You sure can. Just make sure the CLASSPATH is set up
identically using Microsoft's Java compiler (see their release notes for more
information). However, remember that Community Place requires Sun's JRE to run.
But, you can use whatever compiler you want to generate the bytecode.
I don't know the first thing about 3D mathematics. Where can
I go for a reference?
We can recommend the following two books:
Computer Graphics
by Hearn and Baker for softcore mathematics.
Computer Graphics,
by Foley, Van Dam et al. for hardcore mathematics.
Can I buy a book about programming Java and VRML?
Yes, we can recommend two such books:
Java for 3D and VRML
Worlds, by Lea, Matsuda and Miyashita
Late Night VRML
with Java, by Roehl, Couch, et al.
In addition, there are several more we can recommend:
The Java Developers' Almanac
Java in a Nutshell
The Java Tutorial, 2nd Edition
The Java Application Programming Interface, vol 1
The Java Application Programming Interface, vol 2
The Annotated VRML 2.0 Reference Manual
The VRML 2.0 Sourcebook
The C Programming Language
What's the best way to debug my code?
The best way is to use the venerable "println"
statement. If you embed the following in your code:
System.out.println("Debug statement");
then the line "Debug statement" will appear in the
Java Console of Community Place (accessible via ??)
You can embed variables in this statement as well. For
example:
System.out.println("The value of my variable is " + myVariable
+ ".");
Will print out what a variable is. In the above example, if
myVariable was an integer, whose current contents is 52, the above statement
will print
The value of my
variable is 52.
Right now, the best approach to take is to use the println
paradigm.
TimeSensors are giving me a headache. Any advice?
There are generally three uses for TimeSensors. They are
presented below:
If you would like
to receive an event at every rendered frame, do the following:
Create an
infinite TimeSensor
DEF TS
TimeSensor {
cycleInterval 1 # number doesn't
matter
stopTime
-1
loop TRUE
}
Create a
Script with a SFFloat eventIn
DEF SCR
Script {
url
"......class"
...
eventIn
SFFloat tick
}
ROUTE the
"fraction_changed" event:
ROUTE
TS.fraction_changed TO SCR.tick
Now, in your
processEvent method, look for events of name "tick". These will be
events generated every frame.
If you would like
to receive an event continuously at some time interval, do the following:
Create an
infinite TimeSensor
DEF TS
TimeSensor {
cycleInterval 5 # this example
uses 5 seconds
stopTime
-1
loop TRUE
}
Create a
Script with a SFTime eventIn
DEF SCR
Script {
url
"......class"
...
eventIn
SFTime tick
}
ROUTE the
"cycleTime" event:
ROUTE
TS.cycleTime TO SCR.tick
Now, in your
processEvent method, look for events of name "tick". These will be
events generated at your time interval.
If you would like
to receive an event once after some time interval, do the following:
Create a
non-infinite TimeSensor
DEF TS
TimeSensor {
cycleInterval 5 # this example
uses 5 seconds
stopTime
-1
loop FALSE
}
Create a
Script with a SFTime eventOut and eventIn:
DEF SCR
Script {
url
"......class"
...
eventIn
SFTime tick
eventOut
SFTime startTimer
}
ROUTE the
following:
ROUTE
SCR.startTimer TO TS.set_startTime
ROUTE
TS.cycleTime TO SCR.tick
IMPORTANT: Be
sure to ignore EVERY OTHER "tick" event. This is because the
TimeSensor sends "tick" twice: once at the beginning of the interval,
and once at the end of the interval. An easy way to do this is to maintain a
boolean flag in your code that simply toggles everytime you receive a
"tick" event.
How can I implement some simple Java-controlled animations?
First, please make sure you have a firm knowledge of how
TimeSensors work before doing anything related to animation.
You can use a TimeSensor to send regular events to a Java
Script node. This Script node will then make some kind of calculation and
generate new translation and/or rotation values for an object. These new values
are then sent out to the object being moved. Here is a simple way to bounce a
ball up and down.
------here is ball.wrl-----------------------
#VRML V2.0 utf8
DEF BALL Transform {
translation 0 0 0
children [
Shape {
geometry Sphere
{
radius 0.1
}
}
]
}
DEF TS TimeSensor {
cycleInterval 1 #
period of 1 sec
loop TRUE
stopTime -1
}
DEF SCR Script {
url
"bounceBall.class"
eventIn SFFloat tick
eventOut SFVec3f
ballTrans
}
ROUTE TS.fraction_changed TO SCR.tick
ROUTE SCR.ballTrans TO BALL
------end of ball.wrl------------------------
------here is bounceBall.java----------------
import vrml.*;
import vrml.field.*;
import vrml.node.*;
public class bounceBall extends Script {
SFVec3f
ballTrans_ext;
float[]
ballTrans_int;
public void initialize()
{
ballTrans_int =
new float[3];
ballTrans_ext =
(SFVec3f)getEventOut("ballTrans");
}
public void
processEvent(Event ev) {
if
(ev.getName().equals("tick")) {
float frac =
((ConstSFFloat)ev.getValue()).getValue();
ballTrans_int[1]
= Math.abs((float)Math.sin(frac / 3.14159265f));
// we are using
an absolute sine wave to create a bounce effect
ballTrans_ext.setValue(ballTrans_int);
}
}
}
------end of bounceBall.java----------------
How can I make my worlds multi-user?
Simply add the following code at the top of your VRML code:
Sony_WorldInfo {
armLength 25
avatarRoom TRUE
###
### HERE! Bureau location is specified.
###
cpBureau "yourmachine.com:5126"
soundDeviceRate
11025
soundDeviceBits 16
}
In addition, please include the PROTO definition of
Sony_WorldInfo that is supplied with the Community Place documentation. In
addition, you need to create some avatar files.
For more information, see the docs that ship with Community
Place Browser or Bureau.
How can I share events in my multi-user worlds?
Community Place provides the ability to experience shared
behaviors in multi-user worlds. Community Place's Java library for remote
procedure calls which allows implementation of shared behaviors is similar to
that of RPC (remote procedure calls). That is, the computer on the other end of
the connection actually makes a procedure call on your local computer. This
means that now we need methods for both local operations and remote operations.
It is important to understand how the communication between
clients is set up. All clients are equal in the eyes of the server, except for
one which is designated as the "master". In general, if there is only
one client then that client is the master. Otherwise, the "master" is
a client chosen at random in the world. There can and must be only one master
in a particular world. If the master leaves the world, another master is chosen
at random.
To share a node, you must add some information to your VRML
file. First include the following PROTO at the top of your file:
PROTO Sony_BindSharedNode [
field SFNode
transformNode NULL
field SFNode
scriptNode NULL ] { }
This node is a Sony extension node which will be treated
appropriately by CP, but should be ignored by other browsers. Next, add a
script and a Sony_BindSharedNode for every "shared object" you want
to use. Here is an example:
DEF ScriptForSharedObj Script {
field SFNode
sharedobj USE SharedObj
eventIn SFBool
touched
eventIn SFString
rpc_touched
eventIn SFString
rpc_rotateBox
url
"shareclick.class"
}
Sony_BindSharedNode {
transformNode USE
SharedObj
scriptNode USE
ScriptForSharedObj
}
These nodes assume there is a Transform node called
"SharedObj" that we want to activate.
Now, here is a quick look at the functions most commonly
used from CP's RPC library:
public static Bool
amIMaster()
- returns true if
the client is master, false otherwise
public static void
sendApplSpecificMsgWithDist (SFNode obj, string methodName, string argument,
int distrMethod);
- sends a request
to other clients to call a method locally
Parameters :
SFNode obj :
the shared object
string
methodName : the name of the method which will be invoked locally on a client
receiving this call
string
"argument" : set of parameters encoded as a String. The receiver must
decode this.
int
distrMethod : a flag which specifies the clients who get this message
The common distribution methods are allClientsInAura,
allClientsInAuraExceptMe, responderOnly (which goes to the master), allClients
and allClientsExceptMe.
Now, here is a complete example. In this example, we have a
box which is shared. When any client clicks on it, the box rotates in all of
the clients' browsers.
The sequence of events is as follows :
A click is
received in one of the clients and routed to the client's local
"touched" method.
If the client is
master, then it makes a remote procedure call to other clients. This is done by
calling sendApplSpecificMsgWithDist with the distribution mode as
allClientsExceptMe. The methodName parameter in this call is rpc_rotateBox.
This is the name of the function which will be called locally at each client in
response to receiving the rpc call from the master. What it does (on the
recipient's side) is to locally rotate the box. Now the master calls
actualRotateBox for its own rotation.
If the client was
not the master then it calls the rpc_touched method on the master only using
the "responderOnly" distribution flag. In response to this the master
then executes the rpc_touched method. Remember that the client machine has not
executed the local rotate box command yet. In the rpc_touched method the master
now sends rpc's to all clients to invoke their respective local box commands.
This is very similar to the part in the original touched method. In fact, it
duplicates it! This mechanism ensures that no matter who clicked the object,
the master will execute this piece of code. This code acts as a "traffic
cop" the master takes control and sends messages to all of the clients to
rotate the box.
Note that if the client computer got the click and executed
the master's rpc_touched command, the master sends back a rotateBox message to
the original client as well. So we have a "ping-pong" effect which
finally results in everyone changing the color.
Be careful of circular loops in this scheme it is all too
easy to get in a circular loop where a client calls a master procedure which
calls the same client procedure, over and over again.
First, type (or paste) this code into a file called
"shareclick.wrl".
#VRML V2.0 utf8
PROTO Sony_BindSharedNode [
field SFNode
transformNode
field SFNode
scriptNode NULL
] {}
WorldInfo {
title
"VsServer"
info
["VsServer:spiw.com:7009"]
}
#create object to share
DEF SharedObj Transform {
children [
DEF CLICKME
TouchSensor {}
DEF ObjShape Shape
{
appearance
Appearance {
material
Material {diffuseColor 1 0 0}
}
geometry Box { }
}
]
}
#create script for the object
DEF ScriptForSharedObj Script {
field SFNode
sharedobj USE SharedObj
eventIn SFBool
touched
eventIn SFString
rpc_touched
eventIn SFString
rpc_rotateBox
url
"shareclick.class"
}
#route mouse click to "touched" method
ROUTE CLICKME.isActive TO ScriptForSharedObj.touched
Sony_BindSharedNode {
transformNode USE
SharedObj
scriptNode USE
ScriptForSharedObj
}
Second, here is the Java source code. Type or paste this
into a file called "shareclick.java".
import vs.*;
import vrml.*;
public class shareclick extends Script {
SFNode sharedObjNode
= (SFNode)getField("sharedobj");
Transform sharedObj
= (Transform)sharedObjNode.getValue();
// constructor
public shareclick ()
{}
// main class which
receives mouse click events
public void touched
(ConstSFBool flag, ConstSFTime time) {
if(flag.getValue()
== true)
return;
// if click was
received at the master, propagate to everyone
// else and make
local change as well
if(Vscp.amIMaster()) {
Vscp.sendApplSpecificMsgWithDist(sharedObjNode,
"rpc_rotateBox",
"", Vscp.allClientsExceptMe);
actualChangeBox();
}
else {
// click received
at a client - inform master about this and
// let master take
care of the rest
Vscp.sendApplSpecificMsgWithDist(sharedObjNode, "rpc_touched",
"",
Vscp.responderOnly);
}
}
// rpc_touched :
executed at master in response to a click at any
// other client.
Master now propagates to everyone else and also
// does local change
public void
rpc_touched(ConstSFString dum1, ConstSFTime dum2) {
Vscp.sendApplSpecificMsgWithDist(sharedObjNode,
"rpc_rotateBox",
"",
Vscp.allClientsExceptMe);
actualChangeBox();
}
// rpc_rotateBox :
executed at each client upon hearing from master
// that a click was
received at some client somewhere
public void
rpc_rotateBox(ConstSFString data, ConstSFTime time) {
actualChangeBox();
}
// actualChangeBox :
local change function whihc rotates the box about y axis
// by 10 degrees
public void
actualChangeBox() {
float [] axis =
{0, 1, 0, 10};
float [] center =
{0, 0, 0};
sharedObj.rotateAroundLineDegree(axis, center, sharedObj.modeRelative);
}
}
If you have questions about these examples, please feel free
to contact us.
Can I use the EAI with Community Place?
Not currently, though a future version of Community Place is
slated to include EAI support. However, the JSAI (Java Scripting Authoring
Interface) is fully supported.
Can I use JavaScript with Community Place?
Not currently.
How can I read and write files to the local hard drive?
There is an exhaustive example and discussion of this topic
in the book "Java for 3D and VRML worlds", starting on page 162.
How can I add my own avatars to a multi-user world?
If you do not "own" the multiuser world (i.e. if
you do not have control over the Community Place Bureau server), then you
cannot inject your own custom avatars into someone else's world. However, if
you own the world, you can specify a range of different avatars to add. This is
done as follows:
Create a
subdirectory called "avtimg" under your main directory (where your
main.wrl file is located).
In the avtimg
directory, place .bmp bitmaps of your avatars. These are the previews of the
avatars which will appear in the browser's Avatar selection menu.
Also in the avtimg
directory add a text file called imglist.txt. This file should contain the
names of .bmp files you want to include, one per line. The first on this list
will become the default avatar. In addition, the list of avatars on the
selection menu will appear in the order you enter them in this file.
Create another
subdirectory called "avtwrl" under the main directory.
In the avtwrl
directory place the avatars' .wrl files and their associated .wrl and texture
files
Also in the avtwrl
directory create a file called wrllist.txt, similar to imglist.txt above, but
with a list of the avatar .wrl files instead. The avatar files represented by
each line in these two .txt files must correspond.
A subtle but important point arises in avatar wrl files; if
they include references to other files such as Inline geometry or textures,
those files must be referred to by path name relative to the main directory. As
an example, let boy.wrl be an avatar file in the avtwrl directory. Suppose it
refers to a texture boy.jpg which is also in the same directory. Then boy.wrl
should refer to the texture as "avtwrl/boy.jpg" rather than just
"boy.jpg".
How can I implement my own custom avatar behaviors to my
multi-user world?
It's exciting to share your experiences with others,
especially when you can easily express yourself in a virtual world just as you
do in reality. This is one of the key features of Sony's Community Place
browser; the ability for multiple users to interact in the same VRML 2.0 world.
And one of the main ingredients that creates this interaction is body language.
The following tutorial is designed to help you create three
dimensional avatars which can be animated to express gestures using the Action
buttons in Community Place's multi-user Chat window. Example gestures are shown
below.
NORMAL HELLO
SMILE UMM...
WAO WOO!! BYE SLEEP
The frame labels listed down the left hand side of each
above image refer to INTERPOLATOR animation frame called by each Action button
in the Chat window. If you create animation at these frame values, your avatar
will be able to gesture in cyberspace.
Why are frames 00 through 03 the same? The buttons are hard
coded to the .class file which will call the appropriate keys of the
interpolators in your avatar's .wrl file.
To create avatar gestures, you will need animation
PositionInterpolators and OrientationInterpolators with fourteen (14) keys.
Each key is an expression of "hello", "Smile",
"Umm..", "Wow", "Woo!!", "Sad" or
"bye". There is also a key for "sleep" which is called when
the user selects the "sleep" Action button to let other users know
he/she is not paying attention to the world at the moment.
It is important to know which keys are for which actions.
Below is a table of frame (key) numbers and their corresponding actions.
FRAME 00:
Your avatar's normal stance FRAME
01:
Normal pose FRAME
02:
Normal pose FRAME
03:
Normal pose
FRAME 04:
Hello pose FRAME05:
Smile pose FRAME
06:
Umm...(thinking)pose FRAME
07:
Wow (surprised) pose
FRAME 08:
Woo!! (really surprised) pose FRAME 09:
Sad pose FRAME
10:
Normal pose FRAME
11:
Normal pose
FRAME 12:
Bye pose FRAME
13:
Sleep pose FRAME
14:
Normal pose
How can I have a third-person perspective of my avatar?
Community Place introduces two new nodes: Sony_Eyepoint, and
Sony_Renderingpoint. These nodes help you define a "pilot", or a
graphical representation for a user rendered by your own machine.
You can read all about pilots in a file called
"pilot-e.htm" in the directory "doc/tech" under your
Community Place install directory.
How can I add object persistence or database functionality
to a world?
There are two ways.
You can implement
your object as an Application Object (AO). Since these objects live in memory
on a server, they need never be unloaded from memory. Hence you can create
persistent objects, as long as the server is never shut down.
Alternatively you
can integrate your JSAI program with Java's JDBC functionality. This has been
tested and works well with Community Place. The description of JDBC is outside
the scope of this document, but you can learn more about it by looking at Sun's
JDBC page.
How can I traverse the live scene graph from my Script?
Since any node in your scene graph can be classified as a
SFNode, you can pass in a "root" of a scene graph to your Script
node, and use the Script node to manually "walk" through the scene
graph, peeking (and changing) its contents.
I want to implement my own custom navigation routine. Can
this be done?
Yes, but with costs.
If you want to implement your own navigation routine, you
will essentially be moving the camera around programmatically. This means that
you lose all of the built-in collision detection code. This means that you will
be able to walk/fly through walls. There is no way around this; the solution
involves writing your own collision detection code. Moreover, the only way you
can implement a custom navigation routine is via the keyboard.
If you've read all of that and still want to implement your
own navigation, do the following:
Set NavigationInfo
to be "NONE".
Add a
Sony_KeyboardSensor to your world. (See release notes.)
Add a Java Script
node to your world.
Add a Viewpoint
node to your world.
Connect the
Sony_KeyboardSensor's relevant events to the Script node, and connect the
Script node to the Viewpoint.
Write the Java
program to implement the kind of navigation you would like.
If you have consistency problems, try wrapping a Transform
node around the Viewpoint node, and route to that instead. Sometimes that works
better.
How do I implement user-object collision detection?
This is already done for you if you use one of the built-in
navigation modes to Community Place (e.g. WALK, EXAMINE). However, if you're
implementing a custom mode then you will need to implement your own collision
detection code. The description of this is outside the scope of this document,
although you may want to reference the books mentioned above.
How do I implement object-object collision detection?
This is an active research area. The University of North
Carolina, Chapel Hill has created a system called V-COLLIDE. Please check their
website for relevant software, papers, and technical reports.
Can I change the pitch of a sound on-the-fly for
Doppler-like effects?
The AudioClip node has a "pitch" field which
allows you to change the pitch of a sound. In theory, you could change this
"pitch" field while the sound is playing. This will allow you to
create a doppler-like effect. However, this functionality is not allowed by the
VRML specification.
You can achieve this "hack" in version 2.0 of
Community Place, but this undocumented feature will disappear in a future
version of the browser.
A better approach is to physically move the sound node
around your scene. Although the pitch attributes of your sound will no longer
have doppler effects, you will achieve a stereo sound effect, especially if the
sound is moving perpendicular to the user's Z axis.
Any support for stereoscopic viewing?
Not at this time.
Any 3DFX Voodoo support?
Not at this time.
I'm worried about people decompiling my programs. What can I
do about this?
Java programs, which your Script nodes are, can be
"decompiled" very easily. This means you can download a utility to
turn a .class file into its original .java file. This decompilation step is
very thorough. If you decompile one of your own programs you will be surprised
at how similar your source and its source turn out to be! This is because the
Java compiler saves extra information in the .class file.
You can download Java obfuscators like JMangle which
scramble the code in your .class files before distribution.
Can I use C instead of Java?
Currently no, but a future version of Community Place will
enable this functionality.
In the meantime, you can use the Java Native Interface (JNI)
which will allow you to call native C code from your Java code. See Sun's JNI
Page for more.
Is Community Place Y2K compliant?
Community Place uses a 32-bit integer to store the seconds
since January 1, 1970 for date calculations. Since this number will last well
into the 2030's, there is no danger of any failed software components after
January 1, 2000.
Can I generate textures on-the-fly?
In theory, you can use VRML's "PixelTexture" to
specify textures programmatically. However, the current version of Community
Place only partially supports this feature. Please stay tuned (and read the
next question)...
What kinds of other special effects can I use?
Here's a cool effect you can try. Believe it or not, you can
add mirrors to your VRML world, using a special Sony node called
Sony_Viewpoint. This node extends the original Viewpoint node by putting two
new fields:
snapshot: eventIn
whether to generate an image which is taken from Sony_Viewpoint or not.
snappedImage: a
generated image from Sony_Viewpoint, when a TRUE value is sent to the snapshot
eventIn.
The current
implementation only supports to route the snappedImage eventOut to an image
field of a PixelTexture.
The definition is as follows:
PROTO Sony_Viewpoint [
eventIn SFBool
snapshot
eventOut SFImage
snappedImage
eventIn SFBool
set_bind
exposedField
SFFloat fieldOfView 0.785398
exposedField
SFBool jump TRUE
exposedField
SFRotation orientation 0 0 1 0
exposedField
SFVec3f position 0 0 10
field SFString description ""
eventOut SFTime
bindTime
eventOut SFBool
isBound
] {
Viewpoint {
set_bind IS
set_bind
fieldOfView IS
fieldOfView
jump IS jump
orientation IS
orientation
position IS
position
description IS
description
bindTime IS
bindTime
isBound IS isBound
}
}
Here is an example:
Shape {
appearance
Appearance {
texture DEF
PICTURE PixelTexture {}
...
}
geometry ...
}
Transform {
children [
...
DEF CLICK
TouchSensor{}
DEF CAMERA
Sony_Viewpoint {}
]
}
ROUTE
CLICK.isActive TO CAMERA.snapshot
ROUTE
CAMERA.snappedImage TO PICTURE.set_image
How can I optimize my scene graph for faster rendering?
Do the following:
First and
foremost, reduce your poly counts!! Polygon bloat is the number one cause for
low frame rates in VRML browsing.
Try to spatially
organize your scene graph. For instance, if you have two objects far apart in
3D space, try not to group them together. Instead, put them in separate Group
nodes or Transform nodes. Keep objects close to one another in the same Group
or Transform node. This will allow the browser to more easily optimize the
rendering of your scene graph.
Use Sony_BSPGroup
instead of Group nodes for collections of objects that do not physically move.
If your users have
hardware acceleration boards, consider turning off all the lights in the world
and using textures instead.
Minimize the
number of active TimeSensors in your world. Each TimeSensor forces a cost on
your CPU for every frame.
Check to see that
your Java programs are not calculating too much, too frequently. Running a
complicated algorithm at every frame will certainly slow down the browser. If
you must (e.g. for custom collision detection), try porting your code to native
C and see if you get a speed boost. However, as Java implementations get faster
and faster, this will have less of an effect.
Can I use joysticks, or any other special user input hardware?
Types of hardware other than the keyboard and mouse are not
directly supported by Community Place. However, it may be possible to hook
alternative input devices to your machine for usage in Community Place. Such a
system is described in Chapter 16 of the book, "Late Night VRML 2.0 with
Java".
How can I connect to another server to retrieve some
information?
Since you have access to the entire Java core platform, you
may use any available Java mechanism for connecting to other servers in the
same way. This includes Sockets, RMI, CORBA, JDBC, and so on. Describing these
technologies is outside the scope of this document, but please refer to Sun's
Java site for more information.
Please note that if you intend to deploy your VRML world on
the web, there may be security restrictions that do not allow free-ranging
connections to other servers. See the Java documentation for more details.
Please tell me how to use CreateVRMLFromX()!
An excellent lesson on how to use createVRMLFromX can be
found here.
How can I add "bots" to my world?
Sony Application Objects (AOs) will allow you to
"inject" artificial personalities into your world. These AOs are
actually Java programs running on a server, but they look like regular clients
to your normal users. AOs run only with Community Place Bureau.
For more information on Application Objects, please see
TODO.
How can I track the movements of users in the world?
You can track users' movements in two ways:
If you are running
a version of Community Place Bureau, you can enable position logging. This will
print to a log the users' locations at some time interval.
The other
alternative is to create a very large ProximitySensor in your world. This
ProximitySensor will trigger the users' movements. You can route the events
from this ProximitySensor to a Java Script node, which can then send the
information to a server somewhere for you to process. This information
transferral can be done via typical Java connection mechanisms, or can be done
via Community Place Bureau.
Can I send email automatically from my Script node?
Sending mail via SMTP is very easy. First, you need to find
a SMTP host to use. (Most ISPs provide a SMTP host for you to use.) You can use
the following code:
Socket s = null;
DataInputStream sIn = null;
DataOutputStream sOut = null;
try {
s = new Socket(
"smtp.myisp.com",25 ); //
CHANGE THIS TO YOUR SMTP SERVER
sIn = new
DataInputStream( s.getInputStream() );
sOut = new
DataOutputStream( s.getOutputStream() );
} catch( UnknownHostException e ) {
System.out.println(
"Don't know the host." );
} catch( IOException e ) {
System.out.println(
e );
}
if( s != null && sIn != null && sOut != null
) {
try {
sOut.writeBytes(
"MAIL From: user@user.com\n" ); // CHANGE THIS TO SENDER
sOut.writeBytes(
"RCPT To: user@user.com\n" ); // CHANGE THIS TO RECEIPIENT
sOut.writeBytes(
"DATA\n" );
sOut.writeBytes(
"From: user@user.com\n" ); // CHANGE THIS TO SENDER
sOut.writeBytes(
"Subject: MySubject\n" ); // CHANGE THIS TO SUBJECT
sOut.writeBytes(
"BODY OF MESSAGE GOES HERE\n" );
sOut.writeBytes(
"THIS CAN OCCUPY SEVERAL LINES\n" );
sOut.writeBytes(
"\n.\n" );
String result;
while( ( result =
sIn.readLine() ) != null ) {
System.out.println( "Result: "+result );
if(
result.indexOf( "Ok" ) != -1 )
break;
}
sOut.close();
sIn.close();
s.close();
} catch(
UnknownHostException e ) {
System.out.println( "Can't connect: "+e );
} catch( IOException
e ) {
System.out.println(
e );
}
}
Can I use other windows on the screen to display some
information?
Yes, you can create "Frames" in Java and display
those. These are represented as additional windows in which you may display
Java AWT components.
How can I implement a "heads-up display"?
You can do this in VRML by positioning a plane just in front
of your camera. When the camera moves, you simply move the plane as well.
Here's an example. The world consists of a Sphere. A
partially- transparent blue polygon acts as the HUD in this example. Keep in
mind that you can place whatever geometry you want on the HUD, and it will
follow the user around.
#VRML V2.0 utf8
Transform {
children [
Shape {
geometry Sphere
{ }
}
]
}
DEF HUD Transform {
children [
Shape {
appearance
Appearance {
material
Material {
diffuseColor
0 0 1
transparency
0.5
}
}
geometry
IndexedFaceSet {
coord
Coordinate {
point [ -0.1
-0.1 -0.5, 0.1 -0.1 -0.5,
0.1
0.1 -0.5, -0.1 0.1 -0.5 ]
# note the
placement of the HUD on the Z axis
# If 0.5m is too coarse, shrink the HUD down
and place it
#
closer to the camera
}
coordIndex [
0, 1, 2, 3, -1 ]
}
}
]
}
DEF PS ProximitySensor {
size 1000 1000 1000
# this should
encompass your world
}
ROUTE PS.position_changed TO HUD.set_translation
ROUTE PS.orientation_changed TO HUD.set_rotation
# Look, ma, no Scripts!
Why is it not a good idea to have lots of Lights in my
world?
The colors of objects are rendered by a mathematical formula
that involve, among other things, the lights in your world. The more lights
there are in your world, the more complicated this formula becomes. As a
result, your frame rate suffers.
If your end-users are known to have hardware acceleration
boards, it's best to texture-map every single polygon in your world and remove
all Lights from your world. This will result in maximum rendering speed because
the board does not have to calculate any lighting calculations.
However, if your users have no hardware acceleration board,
rendering large amounts of textured objects may prove prohibitive. In this
case, it's best to use normal colors for your objects and try to have as few
lights as possible in your world.
How do I turn the headlight off as a default for the world?
Add:
NavigationInfo {
headlight FALSE
}
to the top of your VRML code. (If you already have a
NavigationInfo node, just add the "headlight FALSE" field to it.) How
can I implement a guided tour?
A live example can be found here (right-click to download).
Note that it uses JavaScript instead of Java, but it can be ported over to Java
pretty easily.
I want to accumulate several rotations, but there's no
"multiply()"
This is a disparity between the JSAI and EAI specifications.
The EAI provides an easy-to-use "multiply()" operator that allows you
to accumulate rotations. However the JSAI has no such command. You will need to
convert a VRML Rotation (x,y,z,angle) to a Quaternion. You can then multiply
these quaternions together to accumulate them. After that, you can convert the
final quaternion back into VRML Rotation format.
I want to implement a particle system. Why shouldn't I use
Spheres?
Although you may think that since you are using very small
objects, so you might as well use Spheres, this is a very bad idea because VRML
Spheres take up a large amount of polygons, and more polygons = lower frame
rate. Even though the polygons in the spheres are very tiny, the browser is
still forced to deal with each polygon individually. This wastes a lot of CPU
time.
Unfortunately Community Place does not support the PointSet
node yet. This would be the ideal way of creating particle systems.
However, better than Spheres is to create your particles out
of very small polygons -- either a triangle or rectangle will do. Place a
Billboard around this polygon and the speck will always face the camera. This
is generally the best way to implement particles in VRML, until the dev team
implements PointSet.
Is there an easy way to do particle flocking?
You can use Reynolds' Rules:
Keep maximum and
minimum distances to surrounding particles in order to stay close or not
collide.
Maintain the same
speed and direction as nearby particles.
Maintain position
near center of gravity of the flock.
These rules were formulated by Craig Reynolds, author of
these "boid" rules. For more information, please see Mr. Reynolds'
page here. When using a PlaneSensor I get a weird feedback problem. Any advice?
Your PlaneSensor is probably ROUTEing to itself. If the
PlaneSensor is being moved along with the object that you want to move, you
will experience feedback. This is similar to placing a microphone next to a
speaker.
The correct code fragment follows:
Group {
children [
DEF PS PlaneSensor
{ }
DEF TARGET
Transform {
children [
...
]
}
]
}
ROUTE PS.translation_changed TO TARGET.set_translation
Note that the "target" does not contain the
PlaneSensor, thus avoiding the feedback problem.
What movie formats can I use inside a MovieTexture?
The only format that CP supports right now is the Renderware
movie format. This format is defined as follows:
Use MovieTexture
node.
The file itself is
a JPEG or GIF.
Width must be 128
pixels.
Height must be
128XN pixels, where N is the number of frames.
Playback speed is
uncontrollable.
What image formats can I use inside an ImageTexture?
.GIF, .JPG, and .BMP formats are supported. Generally, .BMP
format works best if you have hardware acceleration. However, .BMP is usually
also the largest file format. Caveat emptor.
Why should I use LODs?
LODs are good to use because they can drastically reduce the
polygon load on the browser for objects that are far away. If a high-polygon
count object is far away from your camera, it makes little sense to maintain
the high number of polygons on that object because that object occupies a small
surface area of your browser. Better is to tell the browser to change that
model into another one via the LOD node.
If your objects generally don't wander far away from your
camera, there's no need to use the LOD node.
Fog isn't working quite the way I wanted it to. Help!
Software rendering, as well as some 3D boards, do not
support Fog correctly. You can use Fog if your users have the correct 3D board
that happens to support Fog.
I have hundreds of ROUTEs in my main file. What can I do
about this?
The ROUTE structure in VRML97 can tend to become obfuscated,
as your content becomes more and more complicated. The best solution is to
parcel out your VRML file into EXTERNPROTOs. This paradigm is similar to
procedural programming, where you split up complicated code into functions.
This will greatly ease the complexity of your applications.
I get a weird flashing effect in CP when I'm playing MP3
audio files in the background.
Both Community Place and MP3 players tend to consume a large
amount of CPU time. These applications can trample each other in their efforts
of getting some CPU time.
The best solution is to turn off all non-essential programs
before running Community Place.
I'm sick of typing appearance Appearance material Material.
Please help!!
There is a simple solution to your dilemma. Download
Community Place Conductor, a full-featured drag-and-drop VRML97 authoring tool!
Finally, we should mention the CP release notes, found in
doc/tech/contents-hints-e.htm in your package install directory. This can be
very useful for developers who have created contents with the previous version.
last updated 6 November 98