A multipurpose, sample JApplet of mine while we're at it (and while I can still disclose some of my sources).
It does all the contrived url resolution job to be compliant with both Java Applet and Java Application formats, I'll post some app
code as well.
It also does some simple centering, and contains explicit "Config" items.
It does all the contrived url resolution job to be compliant with both Java Applet and Java Application formats, I'll post some app
code as well.
It also does some simple centering, and contains explicit "Config" items.
Code Select
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JApplet;
import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Lights;
import com.threed.jpct.Loader;
import com.threed.jpct.Matrix;
import com.threed.jpct.O3D;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
public class WebPlayer extends JApplet implements Runnable, MouseListener, MouseMotionListener
{
/**
*
*/
private static final long serialVersionUID = -2551994533836965764L;
private O3D redGear;
private FrameBuffer buffer = null;
private World world = null;
private Camera camera = null;
private int width = 0;
private int height = 0;
private float gear_rotation = 0.02f;
private float delta = 0.0f;
private int prevMouseX, prevMouseY;
private Thread t;
private Graphics g;
private boolean flag = false;
// Initialize all components of the applet
public void setFrameBufferSize(int width, int height){
flag = true;
this.width = width;
this.height = height;
if(buffer!=null){
buffer.dispose();
System.gc();
}
buffer = new FrameBuffer( this.width, this.height, FrameBuffer.SAMPLINGMODE_NORMAL );
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
//g = this.getGraphics();
//java.awt.Color bg = getBackground();
buffer.optimizeBufferAccess();
this.resize(width,height);
flag = false;
}
public void init()
{
// sign the applet up to receive mouse messages:
addMouseListener( this );
addMouseMotionListener( this );
this.setBackground(new java.awt.Color(100,144,255));
world = new World(); // create a new world
// create a new buffer to render the world on:
this.width = this.getSize().width;
this.height = this.getSize().height;
/*buffer = new FB( this.width, this.height, FB.SAMPLINGMODE_NORMAL );
buffer.enableRenderer( IRenderer.RENDERER_SOFTWARE );
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);*/
this.setForeground(java.awt.Color.WHITE);
// load some 3D objects and make sure they have the correct orientation:
redGear = loadMeshFile( "head.3ds" );
redGear.rotateY( (float)Math.PI / 2.0f );
redGear.rotateMesh();
redGear.setRotationMatrix( new Matrix() );
redGear.setOrigin( new SimpleVector( 0, 0, 0 ) );
//redGear.setEnvmapped(true);
redGear.setScale(1.0f);
com.threed.jpct.OcTree tree = new com.threed.jpct.OcTree(redGear,95,com.threed.jpct.OcTree.MODE_OPTIMIZED);
redGear.setOcTree(tree);
com.threed.jpct.Config.doPortalHsr = false;
com.threed.jpct.Config.optiZ = true;
com.threed.jpct.Config.useBB = true;
com.threed.jpct.Config.useFastCollisionDetection = true;
com.threed.jpct.Config.useFastSpecular = true;
com.threed.jpct.Config.useFrustumCulling = true;
com.threed.jpct.Config.spanBasedHsr = true;
com.threed.jpct.Config.doSorting = true;
com.threed.jpct.Config.texelFilter = true;
com.threed.jpct.Config.optimizeNormalCalcTH = 2;
//com.threed.jpct.Config.useFrustumCulling = true;
//com.threed.jpct.Config.useBB = false;
// add the objects our world:
world.addObject( redGear );
//world.(new com.threed.jpct.OcTree(redGear,20,20));
world.buildAllObjects();
lookAt( redGear ); // make sure the camera is facing towards the object
letThereBeLight(); // create light sources for the scene
System.gc();
System.runFinalization();
this.t = new Thread(this);
if(!t.isAlive()){
t.start();
}
}
public void run(){
Float fps;
long time;
this.setFrameBufferSize(this.width,this.height);
//this.buffer = new FrameBuffer( this.width, this.height, FrameBuffer.SAMPLINGMODE_NORMAL );
//this.buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
g = this.getGraphics();
java.awt.Color bg = getBackground();
//this.buffer.optimizeBufferAccess();
//redGear.enableLazyTransformations();
//redGear.
while(Thread.currentThread().isAlive()){
// rotate the gear:
time = System.nanoTime();
//buffer.enableRenderer( IRenderer.RENDERER_SOFTWARE );
redGear.rotateAxis( redGear.getZAxis(), -gear_rotation );
this.buffer.clear(bg); // erase the previous frame
// render the world onto the buffer:
world.renderScene( this.buffer );
world.draw( this.buffer );
this.buffer.update();
if(g!=null){
if(!flag){
this.buffer.display(g); // draw the buffer onto the applet frame
time = System.nanoTime()-time;
fps = 1000000000.0f/time;
try{
g.drawString("fps : " + fps.toString(),10,20);
Thread.sleep(5);
}
catch(Exception e){
System.exit(1);
}
}
else{
g.drawString("Please wait, resetting buffers",10,35);
}
}
//System.out.println(1.0f/(0.000000001*time));
}
}
// Draw the scene
@Override
public void paint( Graphics g )
{
//repaint( 200, 0, 0, width, height ); // keep the graphics auto-refreshing
}
public void update( Graphics g )
{
//repaint( 200, 0, 0, width, height ); // keep the graphics auto-refreshing
}
// Load a 3Ds file, and return its Object3D handle
private O3D loadMeshFile( String filename )
{
O3D newObject;
String modelName = "";
String url = "";
java.net.URL locator = null;
try{
modelName = this.getParameter("model");
url = this.getDocumentBase().toString();
url = url.substring(0,url.lastIndexOf("/"));
//locator = Toolkit.getDefaultToolkit().getClass().getClassLoader().getResource(modelName);
}
catch(Exception e){
modelName = filename;
//String currentDir = System.getProperty("user.dir");
//System.out.println(WebPlayer.class.getResource("").getPath());
url = "file:" + WebPlayer.class.getResource("").getPath();
//url = url.substring(0,url.length()-1);
}
url += "/models/" + modelName;
try{
//System.out.println(url);
locator = new java.net.URL(url);
}
catch(Exception ex){
}
//String fileType = modelName.substring(modelName.lastIndexOf(".")+1, modelName.length()).toLowerCase();
//System.out.println(fileType);
O3D[] objs;
try{
System.out.println(url);
//if(fileType.trim()=="3ds"){
//System.out.println("3DS format detected");
objs = Loader.load3DS( locator,/* "models" + File.separatorChar +*/ modelName, 1.0f );
//}
//else if(fileType.trim() == "obj"){
//objs = Loader.loadOBJ( new java.net.URL(url),/* "models" + File.separatorChar +*/ modelName, null, 1.0f );
//}
//else{
//throw(new Exception());
//}
}
catch(Exception e){
objs = Loader.load3DS( this.getDocumentBase(), modelName, /*"models" + File.separatorChar +*/ 1.0f );
}
if( objs.length==1 )
{
// The object loaded fine, just need to initialize it
newObject=objs[0];
newObject.setCulling( O3D.CULLING_ENABLED );
newObject.build();
}
else
{
// Didn't load anything, or loaded
// more than 1 object (not supposed to happen)
System.out.println( "Unknown file format: " + filename );
newObject = null;
}
return newObject;
}
// point the camera toward the given object
private void lookAt( O3D obj )
{
//obj.calcBoundingBox();
com.threed.jpct.Mesh tmp = obj.getMesh();
float[] bBox = tmp.getBoundingBox();
float mx = bBox[1]-bBox[0];
float my = bBox[3]-bBox[2];
float mz = bBox[5]-bBox[4];
float m = Math.max(mx,Math.max(my, mz));
com.threed.jpct.Config.farPlane = m*2;
this.delta = m;
camera = world.getCamera(); // grab a handle to the camera
camera.setPosition( 0, 0, m*0.9f ); // set its *relative* position
camera.increaseFOV(4.0f);
camera.lookAt( obj.getTransformedCenter() ); // look toward the object
obj.align(camera);
}
// create light sources for the scene
private void letThereBeLight()
{
world.getLights().setOverbrightLighting (
Lights.OVERBRIGHT_LIGHTING_DISABLED );
world.getLights().setRGBScale( Lights.RGB_SCALE_2X );
// Set the overall brightness of the world:
world.setAmbientLight( 50, 50, 50 );
// Create a main light-source:
world.addLight( new SimpleVector( -this.delta*0.1, -this.delta*0.1, this.delta*0.45 ), 30.0f, 30.0f, 36.0f );
world.addLight( new SimpleVector( this.delta*0.1, -this.delta*0.1, this.delta*0.45 ), 30.0f, 30.0f, 36.0f );
//world.addLight( new SimpleVector( 0, this.delta*0.3, -this.delta*0.4 ), 30.0f, 30.0f, 20.0f );
world.setLightDiscardDistance(0, this.delta*2);
world.setLightDiscardDistance(1, this.delta*2);
}
// Mouse events:
public void mouseDragged( MouseEvent e )
{
// here we want to rotate the gear based on the mouse dragging
int x = e.getX();
int y = e.getY();
Dimension size = e.getComponent().getSize();
float thetaY = (float)Math.PI * ( (float)(x-prevMouseX)/(float)size.width );
float thetaX = (float)Math.PI * ( (float)(prevMouseY-y)/(float)size.height );
prevMouseX = x;
prevMouseY = y;
redGear.rotateX( thetaX );
redGear.rotateY( thetaY );
}
public void mousePressed( MouseEvent e )
{
// set the "previous" mouse location
// this prevent the gear from jerking to the new angle
// whenever mouseDragged gets called
prevMouseX = e.getX();
prevMouseY = e.getY();
}
public void mouseReleased( MouseEvent e ){}
public void mouseEntered( MouseEvent e ) {}
public void mouseExited( MouseEvent e ) {}
public void mouseClicked( MouseEvent e ) {}
public void mouseMoved( MouseEvent e ) {}
}