/* * Teapot4Canvas for Java 3D-enabled mobile phones supporting M3G (JSR-184) API. * Created by Mobilefish.com (http://www.mobilefish.com) * * File: Teapot4Canvas.java * Needs: Teapot4MIDlet.java * Resources: teapot4_background.m3g * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * If you have any questions, please contact contact@mobilefish.com */ package com.mobilefish.m3g; import javax.microedition.midlet.MIDletStateChangeException; import javax.microedition.m3g.*; import javax.microedition.lcdui.game.GameCanvas; import javax.microedition.lcdui.Graphics; import com.mobilefish.m3g.Teapot4MIDlet; // Teapot4Canvas creates the scenegraph, sets up the object // and draws the scene. public class Teapot4Canvas extends GameCanvas implements Runnable { // Teapot UserId. static final int TEAPOT_ID = 16; // Choose Camera ID 25, 26 or 27 static final int CAMERA_ID = 27; // The midlet Teapot4MIDlet midlet; // Contains the entire scene graph World world = null; // The camera private Camera camera = null; // Thread control boolean running = false; boolean done = true; // Global Graphics3D object Graphics3D g3d = null; // Rendering hints public static final int STRONG_RENDERING_HINTS = Graphics3D.ANTIALIAS | Graphics3D.TRUE_COLOR | Graphics3D.DITHER; public static final int WEAK_RENDERING_HINTS = 0; public static int RENDERING_HINTS = STRONG_RENDERING_HINTS; // Viewport dimensions int viewport_x; int viewport_y; int viewport_width; int viewport_height; // Key array boolean[] key = new boolean[5]; // Key constants public static final int FIRE = 0; public static final int UP = 1; public static final int DOWN = 2; public static final int LEFT = 3; public static final int RIGHT = 4; // Camera rotation float camRot = 0.0f; /** * Construct a new canvas */ Teapot4Canvas(Teapot4MIDlet mid) { super(true); midlet = mid; // Disable fullscreen canvas. // The correct aspect ratio must be maintained. //setFullScreenMode(true); // Load World loadWorld(); // Load Camera loadCamera(CAMERA_ID); // Disable load light. The scene has the correct light. //loadLight(); // Set viewport setupAspectRatio(); } /** * Draw the objects */ private void draw(Graphics g) { try { if (g.getClipWidth() != viewport_width || g.getClipHeight() != viewport_height || g.getClipX() != viewport_x || g.getClipY() != viewport_y) { g.setColor(0,0,0); g.fillRect(0, 0, getWidth(), getHeight()); } // Move the camera around moveCamera(); // Get the Graphics3D context g3d = Graphics3D.getInstance(); // Bind the graphics object. Use rendering hints. g3d.bindTarget(g, true, RENDERING_HINTS); g3d.setViewport(viewport_x, viewport_y, viewport_width, viewport_height); // Render the world. g3d.render(world); } catch(Exception e) { e.printStackTrace(); } finally { // release g3d.releaseTarget(); } } /** * Processes keys */ protected void process() { int keys = getKeyStates(); if((keys & GameCanvas.FIRE_PRESSED) != 0) key[FIRE] = true; else key[FIRE] = false; if((keys & GameCanvas.UP_PRESSED) != 0) key[UP] = true; else key[UP] = false; if((keys & GameCanvas.DOWN_PRESSED) != 0) key[DOWN] = true; else key[DOWN] = false; if((keys & GameCanvas.LEFT_PRESSED) != 0) key[LEFT] = true; else key[LEFT] = false; if((keys & GameCanvas.RIGHT_PRESSED) != 0) key[RIGHT] = true; else key[RIGHT] = false; } /** * Init. */ void init() { } /** * Cleanup and destroy. */ void destroy() { } /** * Load World from the m3g file */ private void loadWorld(){ try { String filename = "/teapot4_background.m3g"; world = (World) Loader.load(filename)[0]; if (world == null) { Object3D[] buffer = Loader.load(filename); for (int i = 0; i < buffer.length; i++ ) { if (buffer[i] instanceof World) { world = (World) buffer[i]; break; } } // Clean buffer; buffer = null; } } catch (Exception e) { e.printStackTrace(); } } /** * Load a camera */ private void loadCamera(int camId){ try { // Load a specific camera in the world camera = (Camera) world.find(CAMERA_ID); // Add camera to the world world.setActiveCamera(camera); } catch (Exception e) { e.printStackTrace(); } } /** * Load a light */ private void loadLight(){ try { Light light = new Light(); // Set light to Ambient light.setMode(Light.AMBIENT); // Set light intensity light.setIntensity(1.0f); // Add light to world world.addChild(light); } catch (Exception e) { e.printStackTrace(); } } /** * Start the thread. */ public void start(){ try { // Create thread Thread t = new Thread(this); running = true; done = false; // Start the thread t.start(); } catch (Exception e) { e.printStackTrace(); } } /** * Infinite loop until user stops. */ public void run() { while(running) { try { // Call the process method. process(); // Draw objects draw(getGraphics()); flushGraphics(); // Sleep try { Thread.sleep(30); } catch(Exception e) { e.printStackTrace(); } } catch(Exception e) { e.printStackTrace(); } } // Notify completion done = true; } /** * Make sure that the content is rendered with the correct aspect ratio. */ void setupAspectRatio() { viewport_x = 0; viewport_y = 0; viewport_width = getWidth(); viewport_height = getHeight(); float[] params = new float[4]; int type = camera.getProjection(params); if (type != Camera.GENERIC) { // Calculate the window aspect ratio float aspectratio = viewport_width / viewport_height; if (aspectratio < params[1]) { float height = viewport_width / params[1]; viewport_height = (int) height; viewport_y = (getHeight() - viewport_height) / 2; } else { float width = viewport_height * params[1]; viewport_width = (int) width; viewport_x = (getWidth() - viewport_width) / 2; } } } /** * Move camera. */ private void moveCamera() { if(key[RIGHT]) { // Rotate right camRot += 5.0f; } else if(key[LEFT]) { // Rotate left camRot -= 5.0f; } // Set the orientation camera.setOrientation(camRot, 0.0f, 0.0f, 1.0f); if(key[UP]) { // Move forward camera.translate(0.0f, 0.0f, -40.0f); } else if(key[DOWN]) { // Move backward camera.translate(0.0f, 0.0f, 40.0f); } // Quit if Fire key is pressed if(key[FIRE]) { try { midlet.destroyApp(true); } catch(MIDletStateChangeException mse) { mse.printStackTrace(); } } } /** * Check if the thread is running */ public boolean isRunning() { return running; } /** * Check if the thread is finished */ public boolean isDone() { return done; } }