Saturday 24 June 2017

SONY Community Place Developer FAQ v1.0




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