Home | Changes | Index | Search | Go
Back to Documentation Page
Applications Development Tips
Table of Contents
Component3D?
Component3D? provide the following features
1) Animation of a itself and all it's children
2) setVisible controls
When writing LG3D? applications use Component3D? to group and animate portions of the scene graph.
If you don't need animation or the setVisible controls consider using other scene graph Nodes such
as BranchGroup?, TransformGroup? or Switch node to obtain the desired visual effect. This will improve performance.
Transparency
If you don't actually use Transparency in your application then don't add TransparencyAttributes? to the
Appearance bundles. If you are using Transparency try to share TransparencyAttributes? as much as possible.
Lg standards way of logging things :
looking glass redirects all logging in the lgserver.log file.
In order for your program to outputs some things in this file, you first need to declare a variable like this :
import static java.util.logging.Level.*;
import java.util.logging.Logger;
private static Logger logger = Logger.getLogger("lg.my_app_name");
(Where my_app_name must be replaced by the real application name)
And now if you wants to log something in the lgserver.log file just do this :
logger.log(Level.INFO,"Some infos");
or
logger.log(Level.SEVERE,"Some infos on a severe error");
the possible values of Level are :
- SEVERE (highest value)
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST (lowest value)
Including Java3D objects in a lg3d program
If you want to include java3D pieces in a lg3d application here is how to do it :
Frame3D frame = new Frame3D();
Java3DGraph j3dwrap = new Java3DGraph();
BranchGroup objRoot = new BranchGroup();
/*
Here you add Java3D objects to the BranchGroup
*/
j3dwrap.addJ3dChild(objRoot);
frame.addChild(j3dwrap);
Java3DGraph? is a class that extends Component3D? so you can use all the methods of Component3D? class on a Java3DGraph?
for example you could have done : j3dwrap.setTranslation(x,y,z); to move the Java3D object somewhere in the scene.
here is a link to the Javadoc of Java3DGraph?.
Dynamically showing/hiding objects in a scene based on a visiblity mask
First of all you need to Define the visibility mask :
int size = 10;
BitSet visibilityMask = new BitSet(size); //this initialise the mask to have a 10 values initilized to false
visibilityMask.set(3); //we set the 3rd entry to true (= visible in our case)
visibilityMask.set(5); //we set the 5th entry to true (= visible in our case)
Now we can build the scene that will use this BitSet? as mask :
Frame3D frame = new Frame3D(); // a common lg3d Frame3D object
SimpleAppearance itemApp = new SimpleAppearance(0.0f,0.5f,0.0f,0.5f); //a green transparent appearance
Java3DGraph j3dwrap = new Java3DGraph(); //a java3d graph wrapper (see other examples on this page)
BranchGroup objRoot = new BranchGroup(); //a common java3d branchGroup
Switch switchNode = new Switch(Switch.CHILD_MASK); //we declare the switch node so that it use a Mask to decide which of its childrens are visible or not
switchNode.setChildMask(visibilityMask); //we give the BitSet we declared before as the visibility mask
switchNode.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); //needed to say that we will modify the switchNode even after it has been included in the SceneGraph (see Java3D docs)
switchNode.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
for (int x=0;x<size;x++) {
TransformGroup tg = new TransformGroup(); //a new Java3D TransformGroup (see java3D tutorials)
Box b = new Box(width,height,depth,Box.GENERATE_NORMALS,itemApp); // a lg3d Shape.Box
tg.addChild((javax.media.j3d.Node) b.getWrapped().getWrapped()); //Here we add a lg3d object in the java3D sceneGraph Branch
Vector3f v = new Vector3f(((x * width),0.0f,0.0f);
Transform3D t3d = new Transform3D();
t3d.setTranslation(v);
tg.setTransform(t); //we move the box to a certain place
switchNode.addChild(a); //we add the TransformGroup to the switch node
}
objRoot.addChild(switchNode);
j3dwrap.addJ3dChild(objRoot);
j3dwrap.setTranslation(x1,y1,z1); //we move all the objects somewhere
frame.addChild(j3dwrap);
frame.changeEnabled(true);
frame.changeVisible(true);
This code will show 2 boxes (the 3rd and the 5th box).
If we now do
BitSet visibilityMask2 = new BitSet(size);
visibilityMask2.set(1);
visibilityMask2.set(3);
visibilityMask2.set(5);
visibilityMask2.set(7);
visibilityMask2.set(9);
switchNode.setChildMask(visibilityMask2);
We will now see 5 boxes on the screen (the 1st,3rd,5th,7th and 9th box)
Of course we can do this at runtime to fastly change which objects of our list are visible and which are not.
here is a link to the javadoc page of the BitSet? class
here is a link to the javadoc page of java3d Switch class
here is a page with good Java3d's tutorials
Using a xml file as configuration file for your application
First of all we need to define a class that will describe the content of the xml config file.
This class must implements the "Serializable" interface.
It must have a variable for each value you want to be in the config file as well as getters and setters for this variable,
An example would be :
import java.io.*;
import java.util.*;
public class MyConfig implements Serializable {
float configValue1;
String configValue2;
MyConfig() {} //empty constructor
public float getConfigValue1() {
return configValue1;
}
public void setConfigValue1(float x) {
configValue1 = x;
}
public String getConfigValue2() {
return configValue2;
}
public void setConfigValue2(String v) {
configValue2 = v.clone();
}
}
Now we must write a function that will reads the config file if it exists and create it with default value if it doesn't exist.
It could be done like this :
private void getMyConfig throws FileNotFoundException {
cfg = new Myconfig(); //an instance of the class defined just before
URL url = getClass().getClassLoader().getResource("org/jdesktop/lg3d/apps/your_application/your_config_file.xml"); // the path to the xml file (don't forget to replace your_application/your_config_file.xml by the real values)
File f = new File(url); //we try to open the file
if (f.exists()) { //if the file exists we just read it
XMLDecoder rdr = new XMLDecoder(
new BufferedInputStream(
new FileInputStream(f)));
cfg = (MyConfig)rdr.readObject(); //here we actually reads the xml file
rdr.close();
} else { //if the file doesn't exists we must create it with default values ...
cfg.setConfigValue1(1.0f); //some float value
cfg.setConfigValue2(new String("bla bla bla")); //some string value
//now we must write the default config file :
XMLEncoder wtr = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream(url)));
//here we try to modify the permissions on the file ( linux / unix related )
try {
Runtime.getRuntime().exec("/bin/chmod 666 "+ url.toString() );
} catch(Exception runtimeE) {
logger.warning("Unable to set permissions on MyConfig.xml");
}
wtr.writeObject(cfg); //here we actually write the file
wtr.close();
//And now we read it just to see if everything went Ok ..
XMLDecoder rdr = new XMLDecoder(
new BufferedInputStream(
new FileInputStream(url)));
gcfg = (MyConfig)rdr.readObject();
rdr.close();
}
}
In addition to this you will need this 2 variables declared in the class that contains the getMyConfig() function :
private MyConfig cfg;
private static Logger logger = Logger.getLogger("lg.myApplication");
And you will need theses imports in the file that contains the class :
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
In brief :
- declare a class that implements serializable interface
- make a function that read/write the files
- call this function from somewhere at the start of your program
- access the values in the config file like this : cfg.get_Value_Name();
Of course you can have other types than String and float in your config file.
The advantage of using a xml config file is that after it has been created (normally after the first launch of your program), the user will be able to modify the values in the config file to fit his preferences (so don't put any critical value in this file, or just do some checking on the values read from the config file)
here you can find the javadocs of the Serializable interface.
|