/** * Copyright (c) 2003-2006, Xith3D Project Group * All rights reserved. * * Portions based on the Java3D interface, Copyright by Sun Microsystems. * Many thanks to the developers of Java3D and Sun Microsystems for their * innovation and design. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the 'Xith3D Project Group' nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE */ package org.xith3d.test.benchmark; import java.io.File; import java.io.IOException; import javax.vecmath.Vector3f; import net.jtank.input.KeyCode; import net.jtank.input.MouseDevice; import org.xith3d.loaders.bsp.BSPClusterManager; import org.xith3d.loaders.bsp.BSPLoader; import org.xith3d.loaders.bsp.BSPScene; import org.xith3d.render.base.ExtXith3DEnvironment; import org.xith3d.render.canvas.Canvas3DWrapper; import org.xith3d.render.canvas.Canvas3DWrapper.OpenGLLayer; import org.xith3d.render.loop.RenderLoop; import org.xith3d.test.Xith3DTest; import org.xith3d.test.util.Xith3DDemoFolder; import org.xith3d.util.input.EgoInputAdapter; import org.xith3d.util.view.CameraFlight; import org.xith3d.util.view.CameraFlightListener; import com.xith3d.loaders.texture.TextureLoader; import com.xith3d.loaders.texture.TextureStreamLoaderTGA; import com.xith3d.loaders.texture.TextureStreamLocatorFile; import com.xith3d.render.RenderPass; import com.xith3d.render.RenderPassConfig; import com.xith3d.render.RenderPassConfigProvider; import com.xith3d.render.Renderer; import com.xith3d.scenegraph.BranchGroup; import com.xith3d.scenegraph.View; /** * In this benchmark a CameraFlight through a Quake3 map is tested. * * @author David Yazel * @author Marvin Froehlich (aka Qudus) */ public class Q3FlightBenchmark extends RenderLoop implements Xith3DTest, CameraFlightListener { private static long start; private BSPClusterManager clusterManager; private View view; private EgoInputAdapter egoAdapter; private CameraFlight camFlight = null; protected void onKeyPressed(int key) { switch (key) { case 112: // F1 clusterManager.setPVSUsage( !clusterManager.isPVSUsed() ); System.out.println( "PVS: " + (clusterManager.isPVSUsed() ? "on" : "off") ); break; case KeyCode.VK_Y: // invert y-axis egoAdapter.setMouseSpeedY( -egoAdapter.getMouseSpeedY() ); break; } } protected void onKeyReleased(int key) { switch (key) { case KeyCode.VK_SPACE: if (camFlight == null) { try { camFlight = new CameraFlight( "data/pdmq3duel5/inter_engine_benchmark--2006-09-29.cflt" ); camFlight.addCameraFlightListener( this ); camFlight.start( getGameTime()); System.out.println( "CameraFlight started." ); canvas.setTitle("Xith3D Q3. Flight in progress..."); } catch (IOException e) { e.printStackTrace(); } } else { canvas.setTitle("Xith3D Q3. Hit space to run flight."); camFlight = null; } break; case KeyCode.VK_ESCAPE: System.exit(0); break; } } /** * This event is fired, when the CameraFlight ended. * * @param frames frames rendered during the flight * @param millis milliseconds needed for the flight * @param avgFPS average FPS for the flight * @return must return true, to proceed with the next flight round */ public void onCameraFlightEnded(long frames, long millis, double averageFPS) { double roundedFPS = ((double)((int)(averageFPS * 100.0)) / 100.0); canvas.setTitle("Xith3D Q3. Flight in progress... Last run - FPS: "+roundedFPS); System.out.println( "CameraFlight ended. (average FPS: " + roundedFPS + ")" + " frames: " + frames + " time: " + millis + "ms"); } private Vector3f camPos = new Vector3f(); private Canvas3DWrapper canvas; protected void loopIteration(long gameTime, long frameTime) { if (camFlight != null) camFlight.updateCamera( view, gameTime ); else egoAdapter.updateView(gameTime, frameTime); view.getPosition( camPos ); clusterManager.setVisibility( camPos ); super.loopIteration(gameTime, frameTime); } private BranchGroup createSceneGraph(ExtXith3DEnvironment env, RenderPassConfigProvider passConfig, Xith3DDemoFolder demoFolder) throws Exception { TextureLoader.getInstance().addTextureStreamLocator(new TextureStreamLocatorFile(new File("./data/pdmq3duel5"))); TextureLoader.getInstance().addTextureStreamLoader(new TextureStreamLoaderTGA()); BSPLoader loader = new BSPLoader(); BSPScene scene = loader.loadScene(new File("./data/pdmq3duel5/pdmq3duel5.bsp").getAbsolutePath()); this.clusterManager = scene.getClusterManager(); env.addBranchGraph( scene ); env.addRenderPass( new RenderPass(scene, passConfig) ); return( scene ); } public Q3FlightBenchmark(Canvas3DWrapper canvas, Xith3DDemoFolder demoFolder) throws Exception { super(); // don't limit FPS this.canvas = canvas; ExtXith3DEnvironment env = new ExtXith3DEnvironment(new Vector3f(2f, 2f, -4f), new Vector3f(0f, 2f, 0f), new Vector3f(0f, 1f, 0f), this); /* ExtXith3DEnvironment env = new ExtXith3DEnvironment(new Vector3f(-0.8549325f, 1.6671978f, -2.364439f), new Vector3f(-1.85440834f, 1.698608565f, -2.372288666f), new Vector3f(0f, 1f, 0f), this); */ this.view = env.getView(); canvas.enableLighting(); env.addCanvas(canvas); // initialize scene createSceneGraph(env, new RenderPassConfig(RenderPassConfig.PERSPECTIVE_PROJECTION), demoFolder); env.getRenderer().setOpaqueSortingPolicy( Renderer.OPAQUE_SORT_NONE ); // initialize input this.registerKeyboard(canvas); MouseDevice mouse = this.registerMouse(canvas); mouse.setExclusive(true); this.egoAdapter = new EgoInputAdapter(view, canvas, 1.0f, -1.0f, 1.0f); egoAdapter.createDefaultKeyBindings( true ); this.registerInputListener( this.egoAdapter ); System.out.println( "Hit \"Y\" to invert the mouse y-axis." ); System.out.println( "Hit \"SPACE\" to start the flight. Hit ESC to exit." ); canvas.setTitle("Xith3D Q3. Hit space to run flight."); // start the RenderLoop this.begin(); } @Override protected void onRenderLoopStarted() { System.err.println("init took: "+(System.currentTimeMillis()-start)+"ms"); } public static void main(String argv[]) throws Exception { start = System.currentTimeMillis(); Canvas3DWrapper canvas = Canvas3DWrapper.createStandalone(OpenGLLayer.JOGL, Xith3DTest.DEFAULT_RESOLUTION, "Q3FlightBenchmark"); new Q3FlightBenchmark(canvas, new Xith3DDemoFolder()); } }