diff --git a/engine/build.xml b/engine/build.xml index 539328660..8e6e2aaf3 100644 --- a/engine/build.xml +++ b/engine/build.xml @@ -5,6 +5,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/nbproject/project.properties b/engine/nbproject/project.properties index 96069ac85..e90693767 100644 --- a/engine/nbproject/project.properties +++ b/engine/nbproject/project.properties @@ -1,114 +1,114 @@ -annotation.processing.enabled=false -annotation.processing.enabled.in.editor=false -annotation.processing.run.all.processors=true -ant.customtasks.libs=JWSAntTasks -application.homepage=http://www.jmonkeyengine.com/ -application.title=jMonkeyEngine 3.0 -application.vendor=jMonkeyEngine -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/jMonkeyEngine3.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.src-test-data=src/test-data -includes=** -jar.archive.disabled=${jnlp.enabled} -jar.compress=true -jar.index=${jnlp.enabled} -javac.classpath=\ - ${libs.jogg.classpath}:\ - ${libs.jbullet.classpath}:\ - ${libs.bullet.classpath}:\ - ${libs.lwjgl.classpath}:\ - ${libs.jheora.classpath}:\ - ${libs.niftygui1.3.classpath}:\ - ${libs.jme3-test-data.classpath}:\ - ${libs.noise.classpath} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.5 -javac.target=1.5 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir}:\ - ${libs.junit_4.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle=jMonkeyEngine3 -jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" -jnlp.applet.class=jme3test.awt.AppHarness -jnlp.applet.height=300 -jnlp.applet.width=300 -jnlp.codebase.type=user -jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/ -jnlp.descriptor=application -jnlp.enabled=false -jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png -jnlp.mixed.code=default -jnlp.offline-allowed=true -jnlp.signed=true -jnlp.signing=generated -jnlp.signing.alias= -jnlp.signing.keystore= -main.class=jme3test.TestChooser -manifest.file=MANIFEST.MF -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -run.jvmargs=-Xms40m -Xmx40m -XX:MaxDirectMemorySize=256M -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.blender.dir=src/blender -src.core-data.dir=src/core-data -src.core-plugins.dir=src/core-plugins -src.core.dir=src/core -src.desktop-fx.dir=src/desktop-fx -src.desktop.dir=src/desktop -src.games.dir=src/games -src.jbullet.dir=src/jbullet -src.jheora.dir=src/jheora -src.jogg.dir=src/jogg -src.lwjgl-oal.dir=src/lwjgl-oal -src.lwjgl-ogl.dir=src/lwjgl-ogl -src.networking.dir=src\\networking -src.niftygui.dir=src/niftygui -src.ogre.dir=src/ogre -src.pack.dir=src/pack -src.terrain.dir=src/terrain -src.test.dir=src/test -src.tools.dir=src/tools -src.xml.dir=src/xml -test.test.dir=test +annotation.processing.enabled=false +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +ant.customtasks.libs=JWSAntTasks +application.homepage=http://www.jmonkeyengine.com/ +application.title=jMonkeyEngine 3.0 +application.vendor=jMonkeyEngine +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/jMonkeyEngine3.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.src-test-data=src/test-data +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=true +jar.index=${jnlp.enabled} +javac.classpath=\ + ${libs.jogg.classpath}:\ + ${libs.jbullet.classpath}:\ + ${libs.bullet.classpath}:\ + ${libs.lwjgl.classpath}:\ + ${libs.jheora.classpath}:\ + ${libs.niftygui1.3.classpath}:\ + ${libs.jme3-test-data.classpath}:\ + ${libs.noise.classpath} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle=jMonkeyEngine3 +jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" +jnlp.applet.class=jme3test.awt.AppHarness +jnlp.applet.height=300 +jnlp.applet.width=300 +jnlp.codebase.type=user +jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/ +jnlp.descriptor=application +jnlp.enabled=false +jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png +jnlp.mixed.code=default +jnlp.offline-allowed=true +jnlp.signed=true +jnlp.signing=generated +jnlp.signing.alias= +jnlp.signing.keystore= +main.class=jme3test.export.TestOgreConvert +manifest.file=MANIFEST.MF +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +run.jvmargs=-Xms30m -Xmx30m -XX:MaxDirectMemorySize=256M +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.blender.dir=src/blender +src.core-data.dir=src/core-data +src.core-plugins.dir=src/core-plugins +src.core.dir=src/core +src.desktop-fx.dir=src/desktop-fx +src.desktop.dir=src/desktop +src.games.dir=src/games +src.jbullet.dir=src/jbullet +src.jheora.dir=src/jheora +src.jogg.dir=src/jogg +src.lwjgl-oal.dir=src/lwjgl-oal +src.lwjgl-ogl.dir=src/lwjgl-ogl +src.networking.dir=src\\networking +src.niftygui.dir=src/niftygui +src.ogre.dir=src/ogre +src.pack.dir=src/pack +src.terrain.dir=src/terrain +src.test.dir=src/test +src.tools.dir=src/tools +src.xml.dir=src/xml +test.test.dir=test diff --git a/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md b/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md index 7114be00b..afb721e64 100644 --- a/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md +++ b/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md @@ -38,16 +38,16 @@ MaterialDef Phong Lighting { Boolean UseVertexColor // Ambient color - Color Ambient + Color Ambient : MaterialAmbient // Diffuse color - Color Diffuse : Color + Color Diffuse : MaterialDiffuse // Specular color - Color Specular + Color Specular : MaterialSpecular // Specular power/shininess - Float Shininess + Float Shininess : MaterialShininess // Diffuse map Texture2D DiffuseMap diff --git a/engine/src/core-data/Common/MatDefs/Misc/Unshaded.frag b/engine/src/core-data/Common/MatDefs/Misc/Unshaded.frag index a5f1904da..ab28778e6 100644 --- a/engine/src/core-data/Common/MatDefs/Misc/Unshaded.frag +++ b/engine/src/core-data/Common/MatDefs/Misc/Unshaded.frag @@ -14,7 +14,7 @@ uniform vec4 m_Color; #ifdef HAS_LIGHTMAP uniform sampler2D m_LightMap; - #ifdef SEPERATE_TEXCOORD + #ifdef SEPARATE_TEXCOORD varying vec2 texCoord2; #endif #endif diff --git a/engine/src/core/com/jme3/app/AppTask.java b/engine/src/core/com/jme3/app/AppTask.java index efda06c46..4eeb6223d 100644 --- a/engine/src/core/com/jme3/app/AppTask.java +++ b/engine/src/core/com/jme3/app/AppTask.java @@ -60,6 +60,12 @@ public class AppTask implements Future { private final ReentrantLock stateLock = new ReentrantLock(); private final Condition finishedCondition = stateLock.newCondition(); + /** + * Create an AppTask that will execute the given + * {@link Callable}. + * + * @param callable The callable to be executed + */ public AppTask(Callable callable) { this.callable = callable; } diff --git a/engine/src/core/com/jme3/app/Application.java b/engine/src/core/com/jme3/app/Application.java index e387dcb48..2c65ae18f 100644 --- a/engine/src/core/com/jme3/app/Application.java +++ b/engine/src/core/com/jme3/app/Application.java @@ -37,7 +37,6 @@ import com.jme3.input.JoyInput; import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; import com.jme3.input.TouchInput; -import com.jme3.system.*; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import com.jme3.renderer.Renderer; @@ -47,6 +46,9 @@ import com.jme3.audio.Listener; import com.jme3.input.InputManager; import com.jme3.renderer.RenderManager; import com.jme3.renderer.ViewPort; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeCanvasContext; +import com.jme3.system.JmeContext; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.Callable; @@ -54,6 +56,10 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Future; import java.util.logging.Level; import java.util.logging.Logger; +import com.jme3.system.JmeContext.Type; +import com.jme3.system.JmeSystem; +import com.jme3.system.SystemListener; +import com.jme3.system.Timer; /** * The Application class represents an instance of a @@ -103,14 +109,36 @@ public class Application implements SystemListener { public Application(){ } + /** + * Returns true if pause on lost focus is enabled, false otherwise. + * + * @return true if pause on lost focus is enabled + * + * @see #setPauseOnLostFocus(boolean) + */ public boolean isPauseOnLostFocus() { return pauseOnFocus; } + /** + * Enable or disable pause on lost focus. + *

+ * By default, pause on lost focus is enabled. + * If enabled, the application will stop updating + * when it loses focus or becomes inactive (e.g. alt-tab). + * For online or real-time applications, this might not be preferable, + * so this feature should be set to disabled. For other applications, + * it is best to keep it on so that CPU usage is not used when + * not necessary. + * + * @param pauseOnLostFocus True to enable pause on lost focus, false + * otherwise. + */ public void setPauseOnLostFocus(boolean pauseOnLostFocus) { this.pauseOnFocus = pauseOnLostFocus; } + @Deprecated public void setAssetManager(AssetManager assetManager){ if (this.assetManager != null) throw new IllegalStateException("Can only set asset manager" @@ -243,78 +271,80 @@ public class Application implements SystemListener { } /** - * @return The asset manager for this application. + * @return The {@link AssetManager asset manager} for this application. */ public AssetManager getAssetManager(){ return assetManager; } /** - * @return the input manager. + * @return the {@link InputManager input manager}. */ public InputManager getInputManager(){ return inputManager; } /** - * @return the app state manager + * @return the {@link AppStateManager app state manager} */ public AppStateManager getStateManager() { return stateManager; } /** - * @return the render manager + * @return the {@link RenderManager render manager} */ public RenderManager getRenderManager() { return renderManager; } /** - * @return The renderer for the application, or null if was not started yet. + * @return The {@link Renderer renderer} for the application */ public Renderer getRenderer(){ return renderer; } /** - * @return The audio renderer for the application, or null if was not started yet. + * @return The {@link AudioRenderer audio renderer} for the application */ public AudioRenderer getAudioRenderer() { return audioRenderer; } /** - * @return The listener object for audio + * @return The {@link Listener listener} object for audio */ public Listener getListener() { return listener; } /** - * @return The display context for the application, or null if was not - * started yet. + * @return The {@link JmeContext display context} for the application */ public JmeContext getContext(){ return context; } /** - * @return The camera for the application, or null if was not started yet. + * @return The {@link Camera camera} for the application */ public Camera getCamera(){ return cam; } /** - * Starts the application as a display. + * Starts the application in {@link Type#Display display} mode. + * + * @see #start(com.jme3.system.JmeContext.Type) */ public void start(){ start(JmeContext.Type.Display); } /** - * Starts the application. Creating a rendering context and executing + * Starts the application. + * Creating a rendering context and executing * the main loop in a separate thread. */ public void start(JmeContext.Type contextType){ @@ -333,6 +363,21 @@ public class Application implements SystemListener { context.create(false); } + /** + * Initializes the application's canvas for use. + *

+ * After calling this method, cast the {@link #getContext() context} to + * {@link JmeCanvasContext}, + * then acquire the canvas with {@link JmeCanvasContext#getCanvas() } + * and attach it to an AWT/Swing Frame. + * The rendering thread will start when the canvas becomes visible on + * screen, however if you wish to start the context immediately you + * may call {@link #startCanvas() } to force the rendering thread + * to start. + * + * @see JmeCanvasContext + * @see Type#Canvas + */ public void createCanvas(){ if (context != null && context.isCreated()){ logger.warning("createCanvas() called when application already created!"); @@ -348,30 +393,66 @@ public class Application implements SystemListener { context.setSystemListener(this); } + /** + * Starts the rendering thread after createCanvas() has been called. + *

+ * Same as calling startCanvas(false) + * + * @see #startCanvas(boolean) + */ public void startCanvas(){ startCanvas(false); } + /** + * Starts the rendering thread after createCanvas() has been called. + *

+ * Calling this method is optional, the canvas will start automatically + * when it becomes visible. + * + * @param waitFor If true, the current thread will block until the + * rendering thread is running + */ public void startCanvas(boolean waitFor){ context.create(waitFor); } + /** + * Internal use only. + */ public void reshape(int w, int h){ renderManager.notifyReshape(w, h); } + /** + * Restarts the context, applying any changed settings. + *

+ * Changes to the {@link AppSettings} of this Application are not + * applied immediately; calling this method forces the context + * to restart, applying the new settings. + */ public void restart(){ context.setSettings(settings); context.restart(); } + /** + * + * Requests the context to close, shutting down the main loop + * and making necessary cleanup operations. + * + * Same as calling stop(false) + * + * @see #stop(boolean) + */ public void stop(){ stop(false); } /** - * Requests the display to close, shutting down the main loop - * and making neccessary cleanup operations. + * Requests the context to close, shutting down the main loop + * and making necessary cleanup operations. + * After the application has stopped, it cannot be used anymore. */ public void stop(boolean waitFor){ logger.log(Level.FINE, "Closing application: {0}", getClass().getName()); @@ -381,7 +462,7 @@ public class Application implements SystemListener { /** * Do not call manually. * Callback from ContextListener. - * + *

* Initializes the Application, by creating a display and * default camera. If display settings are not specified, a default * 640x480 display is created. Default values are used for the camera; @@ -409,12 +490,18 @@ public class Application implements SystemListener { // user code here.. } + /** + * Internal use only. + */ public void handleError(String errMsg, Throwable t){ logger.log(Level.SEVERE, errMsg, t); // user should add additional code to handle the error. stop(); // stop the application } + /** + * Internal use only. + */ public void gainFocus(){ if (pauseOnFocus){ paused = false; @@ -424,6 +511,9 @@ public class Application implements SystemListener { } } + /** + * Internal use only. + */ public void loseFocus(){ if (pauseOnFocus){ paused = true; @@ -431,6 +521,9 @@ public class Application implements SystemListener { } } + /** + * Internal use only. + */ public void requestClose(boolean esc){ context.destroy(false); } diff --git a/engine/src/core/com/jme3/material/Material.java b/engine/src/core/com/jme3/material/Material.java index 2e14055fe..4a34424e8 100644 --- a/engine/src/core/com/jme3/material/Material.java +++ b/engine/src/core/com/jme3/material/Material.java @@ -56,7 +56,6 @@ import com.jme3.renderer.Renderer; import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; import com.jme3.shader.Shader; import com.jme3.shader.Uniform; import com.jme3.shader.VarType; @@ -1009,13 +1008,42 @@ public class Material implements Cloneable, Savable, Comparable { public void read(JmeImporter im) throws IOException { InputCapsule ic = im.getCapsule(this); - String defName = ic.readString("material_def", null); - def = (MaterialDef) im.getAssetManager().loadAsset(new AssetKey(defName)); + additionalState = (RenderState) ic.readSavable("render_state", null); transparent = ic.readBoolean("is_transparent", false); + // Load the material def + String defName = ic.readString("material_def", null); HashMap params = (HashMap) ic.readStringSavableMap("parameters", null); -// paramValues.putAll(params); + + boolean enableVcolor = false; + boolean separateTexCoord = false; + + if (im.getFormatVersion() == 0){ + // Enable compatibility with old models + if (defName.equalsIgnoreCase("Common/MatDefs/Misc/VertexColor.j3md")){ + // Using VertexColor, switch to Unshaded and set VertexColor=true + enableVcolor = true; + defName = "Common/MatDefs/Misc/Unshaded.j3md"; + }else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/SimpleTextured.j3md") + || defName.equalsIgnoreCase("Common/MatDefs/Misc/SolidColor.j3md")){ + // Using SimpleTextured/SolidColor, just switch to Unshaded + defName = "Common/MatDefs/Misc/Unshaded.j3md"; + }else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/WireColor.j3md")){ + // Using WireColor, set wireframe renderstate = true and use Unshaded + additionalState.setWireframe(true); + defName = "Common/MatDefs/Misc/Unshaded.j3md"; + }else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/Unshaded.j3md")){ + // Uses unshaded, ensure that the proper param is set + MatParam value = params.get("SeperateTexCoord"); + if (value != null && ((Boolean)value.getValue()) == true){ + params.remove("SeperateTexCoord"); + separateTexCoord = true; + } + } + } + + def = (MaterialDef) im.getAssetManager().loadAsset(new AssetKey(defName)); paramValues = new ListMap(); // load the textures and update nextTexUnit @@ -1037,5 +1065,12 @@ public class Material implements Cloneable, Savable, Comparable { param.setName(checkSetParam(param.getVarType(), param.getName())); paramValues.put(param.getName(), param); } + + if (enableVcolor){ + setBoolean("VertexColor", true); + } + if (separateTexCoord){ + setBoolean("SeparateTexCoord", true); + } } } diff --git a/engine/src/core/com/jme3/scene/Node.java b/engine/src/core/com/jme3/scene/Node.java index d9a7dd531..e43a25a0f 100644 --- a/engine/src/core/com/jme3/scene/Node.java +++ b/engine/src/core/com/jme3/scene/Node.java @@ -592,7 +592,10 @@ public class Node extends Spatial implements Savable { @Override public void read(JmeImporter e) throws IOException { - super.read(e); + // XXX: Load children before loading itself!! + // This prevents empty children list if controls query + // it in Control.setSpatial(). + children = e.getCapsule(this).readSavableArrayList("children", null); // go through children and set parent to this node @@ -602,6 +605,8 @@ public class Node extends Spatial implements Savable { child.parent = this; } } + + super.read(e); } @Override diff --git a/engine/src/core/com/jme3/scene/shape/StripBox.java b/engine/src/core/com/jme3/scene/shape/StripBox.java new file mode 100644 index 000000000..dc60b303b --- /dev/null +++ b/engine/src/core/com/jme3/scene/shape/StripBox.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * 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 'jMonkeyEngine' 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) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// $Id: Box.java 4131 2009-03-19 20:15:28Z blaine.dev $ +package com.jme3.scene.shape; + +import com.jme3.math.Vector3f; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.util.BufferUtils; +import java.nio.FloatBuffer; + +/** + * A box with solid (filled) faces. + * + * @author Mark Powell + * @version $Revision: 4131 $, $Date: 2009-03-19 16:15:28 -0400 (Thu, 19 Mar 2009) $ + */ +public class StripBox extends AbstractBox { + + private static final short[] GEOMETRY_INDICES_DATA = + { 1, 0, 4, + 5, + 7, + 0, + 3, + 1, + 2, + 4, + 6, + 7, + 2, + 3 }; + + private static final float[] GEOMETRY_TEXTURE_DATA = { + 1, 0, + 0, 0, + 0, 1, + 1, 1, + + 1, 0, + 0, 0, + 1, 1, + 0, 1 + }; + + /** + * Creates a new box. + *

+ * The box has a center of 0,0,0 and extends in the out from the center by + * the given amount in each direction. So, for example, a box + * with extent of 0.5 would be the unit cube. + * + * @param name the name of the box. + * @param x the size of the box along the x axis, in both directions. + * @param y the size of the box along the y axis, in both directions. + * @param z the size of the box along the z axis, in both directions. + */ + public StripBox(float x, float y, float z) { + super(); + updateGeometry(Vector3f.ZERO, x, y, z); + } + + /** + * Creates a new box. + *

+ * The box has the given center and extends in the out from the center by + * the given amount in each direction. So, for example, a box + * with extent of 0.5 would be the unit cube. + * + * @param name the name of the box. + * @param center the center of the box. + * @param x the size of the box along the x axis, in both directions. + * @param y the size of the box along the y axis, in both directions. + * @param z the size of the box along the z axis, in both directions. + */ + public StripBox(Vector3f center, float x, float y, float z) { + super(); + updateGeometry(center, x, y, z); + } + + /** + * Constructor instantiates a new Box object. + *

+ * The minimum and maximum point are provided, these two points define the + * shape and size of the box but not it’s orientation or position. You should + * use the {@link #setLocalTranslation()} and {@link #setLocalRotation()} + * methods to define those properties. + * + * @param name the name of the box. + * @param min the minimum point that defines the box. + * @param max the maximum point that defines the box. + */ + public StripBox(Vector3f min, Vector3f max) { + super(); + updateGeometry(min, max); + } + + /** + * Empty constructor for serialization only. Do not use. + */ + public StripBox(){ + super(); + } + + /** + * Creates a clone of this box. + *

+ * The cloned box will have ‘_clone’ appended to it’s name, but all other + * properties will be the same as this box. + */ + @Override + public StripBox clone() { + return new StripBox(center.clone(), xExtent, yExtent, zExtent); + } + + protected void duUpdateGeometryIndices() { + if (getBuffer(Type.Index) == null){ + setBuffer(Type.Index, 3, BufferUtils.createShortBuffer(GEOMETRY_INDICES_DATA)); + } + } + + protected void duUpdateGeometryNormals() { + if (getBuffer(Type.Normal) == null){ + float[] normals = new float[8 * 3]; + + Vector3f[] vert = computeVertices(); + Vector3f norm = new Vector3f(); + + for (int i = 0; i < 8; i++) { + norm.set(vert[i]).normalizeLocal(); + + normals[i * 3 + 0] = norm.x; + normals[i * 3 + 1] = norm.x; + normals[i * 3 + 2] = norm.x; + } + + setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(normals)); + } + } + + protected void duUpdateGeometryTextures() { + if (getBuffer(Type.TexCoord) == null){ + setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(GEOMETRY_TEXTURE_DATA)); + } + } + + protected void duUpdateGeometryVertices() { + FloatBuffer fpb = BufferUtils.createVector3Buffer(8 * 3); + Vector3f[] v = computeVertices(); + fpb.put(new float[] { + v[0].x, v[0].y, v[0].z, + v[1].x, v[1].y, v[1].z, + v[2].x, v[2].y, v[2].z, + v[3].x, v[3].y, v[3].z, + v[4].x, v[4].y, v[4].z, + v[5].x, v[5].y, v[5].z, + v[6].x, v[6].y, v[6].z, + v[7].x, v[7].y, v[7].z, + }); + setBuffer(Type.Position, 3, fpb); + setMode(Mode.TriangleStrip); + updateBound(); + } + +} \ No newline at end of file diff --git a/engine/src/core/com/jme3/util/BufferUtils.java b/engine/src/core/com/jme3/util/BufferUtils.java index a9cea5eca..ce6f298dd 100644 --- a/engine/src/core/com/jme3/util/BufferUtils.java +++ b/engine/src/core/com/jme3/util/BufferUtils.java @@ -56,16 +56,10 @@ import java.util.WeakHashMap; */ public final class BufferUtils { - //// -- TEMP DATA OBJECTS -- //// -// private static final Vector2f _tempVec2 = new Vector2f(); -// private static final Vector3f _tempVec3 = new Vector3f(); -// private static final ColorRGBA _tempColor = new ColorRGBA(); - //// -- TRACKER HASH -- //// private static final Map trackingHash = Collections.synchronizedMap(new WeakHashMap()); private static final Object ref = new Object(); - private static final boolean trackDirectMemory = false; + private static final boolean trackDirectMemory = true; - //// -- GENERIC CLONE -- //// /** * Creates a clone of the given buffer. The clone's capacity is * equal to the given buffer's limit. @@ -88,8 +82,58 @@ public final class BufferUtils { throw new UnsupportedOperationException(); } } + + private static void onBufferAllocated(Buffer buffer){ + /* + StackTraceElement[] stackTrace = new Throwable().getStackTrace(); + int initialIndex = 0; + + for (int i = 0; i < stackTrace.length; i++){ + if (!stackTrace[i].getClassName().equals(BufferUtils.class.getName())){ + initialIndex = i; + break; + } + } + + int allocated = buffer.capacity(); + int size = 0; + + if (buffer instanceof FloatBuffer){ + size = 4; + }else if (buffer instanceof ShortBuffer){ + size = 2; + }else if (buffer instanceof ByteBuffer){ + size = 1; + }else if (buffer instanceof IntBuffer){ + size = 4; + }else if (buffer instanceof DoubleBuffer){ + size = 8; + } + + allocated *= size; + + for (int i = initialIndex; i < stackTrace.length; i++){ + StackTraceElement element = stackTrace[i]; + if (element.getClassName().startsWith("java")){ + break; + } + + try { + Class clazz = Class.forName(element.getClassName()); + if (i == initialIndex){ + System.out.println(clazz.getSimpleName()+"."+element.getMethodName()+"():" + element.getLineNumber() + " allocated " + allocated); + }else{ + System.out.println(" at " + clazz.getSimpleName()+"."+element.getMethodName()+"()"); + } + } catch (ClassNotFoundException ex) { + } + }*/ + + if (trackDirectMemory){ + trackingHash.put(buffer, ref); + } + } - //// -- VECTOR3F METHODS -- //// /** * Generate a new FloatBuffer using the given array of Vector3f objects. * The FloatBuffer will be 3 * data.length long and contain the vector data @@ -658,9 +702,7 @@ public final class BufferUtils { public static DoubleBuffer createDoubleBuffer(int size) { DoubleBuffer buf = ByteBuffer.allocateDirect(8 * size).order(ByteOrder.nativeOrder()).asDoubleBuffer(); buf.clear(); - if (trackDirectMemory) { - trackingHash.put(buf, ref); - } + onBufferAllocated(buf); return buf; } @@ -723,9 +765,7 @@ public final class BufferUtils { public static FloatBuffer createFloatBuffer(int size) { FloatBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer(); buf.clear(); - if (trackDirectMemory) { - trackingHash.put(buf, ref); - } + onBufferAllocated(buf); return buf; } @@ -787,9 +827,7 @@ public final class BufferUtils { public static IntBuffer createIntBuffer(int size) { IntBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer(); buf.clear(); - if (trackDirectMemory) { - trackingHash.put(buf, ref); - } + onBufferAllocated(buf); return buf; } @@ -852,9 +890,7 @@ public final class BufferUtils { public static ByteBuffer createByteBuffer(int size) { ByteBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()); buf.clear(); - if (trackDirectMemory) { - trackingHash.put(buf, ref); - } + onBufferAllocated(buf); return buf; } @@ -932,9 +968,7 @@ public final class BufferUtils { public static ShortBuffer createShortBuffer(int size) { ShortBuffer buf = ByteBuffer.allocateDirect(2 * size).order(ByteOrder.nativeOrder()).asShortBuffer(); buf.clear(); - if (trackDirectMemory) { - trackingHash.put(buf, ref); - } + onBufferAllocated(buf); return buf; } diff --git a/engine/src/test/jme3test/audio/TestDoppler.java b/engine/src/test/jme3test/audio/TestDoppler.java index a2b8ccf81..0722c6aa2 100644 --- a/engine/src/test/jme3test/audio/TestDoppler.java +++ b/engine/src/test/jme3test/audio/TestDoppler.java @@ -32,8 +32,15 @@ package jme3test.audio; +import com.jme3.asset.plugins.FileLocator; import com.jme3.audio.AudioNode; +import com.jme3.audio.Environment; +import com.jme3.audio.LowPassFilter; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; +import org.lwjgl.openal.AL10; +import org.lwjgl.openal.AL11; /** * Test Doppler Effect @@ -42,8 +49,15 @@ public class TestDoppler extends AudioApp { private AudioNode ufo; - private float location = 0; - private float rate = 1; + private float x = 20, z = 0; + + private float rate = -0.05f; + private float xDist = 20; + private float zDist = 5; + + private float angle = FastMath.TWO_PI; + + private LowPassFilter filter = new LowPassFilter(1, 1); public static void main(String[] args){ TestDoppler test = new TestDoppler(); @@ -52,28 +66,50 @@ public class TestDoppler extends AudioApp { @Override public void initAudioApp(){ - ufo = new AudioNode(audioRenderer, assetManager, "Sound/Effects/Beep.ogg", false); + assetManager.registerLocator("C:\\", FileLocator.class); + + Quaternion q = new Quaternion(); + q.lookAt(new Vector3f(0, 0, -1f), Vector3f.UNIT_Y); + listener.setRotation(q); + + audioRenderer.setEnvironment(Environment.Dungeon); + AL10.alDistanceModel(AL11.AL_EXPONENT_DISTANCE); + + ufo = new AudioNode(audioRenderer, assetManager, "test.ogg", false); ufo.setPositional(true); ufo.setLooping(true); + ufo.setReverbEnabled(true); + ufo.setRefDistance(100000000); + ufo.setMaxDistance(100000000); audioRenderer.playSource(ufo); } @Override public void updateAudioApp(float tpf){ - // move the location variable left and right - if (location > 10){ - location = 10; + //float x = (float) (Math.cos(angle) * xDist); + float dx = (float) Math.sin(angle) * xDist; + + //float z = (float) (Math.sin(angle) * zDist); + float dz = (float)(-Math.cos(angle) * zDist); + + x += dx * tpf * 0.05f; + z += dz * tpf * 0.05f; + + angle += tpf * rate; + + if (angle > FastMath.TWO_PI){ + angle = FastMath.TWO_PI; rate = -rate; - ufo.setVelocity(new Vector3f(rate*10, 0, 0)); - }else if (location < -10){ - location = -10; + }else if (angle < -0){ + angle = -0; rate = -rate; - ufo.setVelocity(new Vector3f(rate*10, 0, 0)); - }else{ - location += rate * tpf * 10; } - ufo.setLocalTranslation(location, 0, 2); + + ufo.setVelocity(new Vector3f(dx, 0, dz)); + ufo.setLocalTranslation(x, 0, z); ufo.updateGeometricState(); + + System.out.println("LOC: " + (int)x +", " + (int)z + ", VEL: " + (int)dx + ", " + (int)dz); } } diff --git a/engine/src/test/jme3test/awt/TestCanvas.java b/engine/src/test/jme3test/awt/TestCanvas.java index 3eda38a7f..811752068 100644 --- a/engine/src/test/jme3test/awt/TestCanvas.java +++ b/engine/src/test/jme3test/awt/TestCanvas.java @@ -36,7 +36,6 @@ import com.jme3.app.Application; import com.jme3.app.SimpleApplication; import com.jme3.system.AppSettings; import com.jme3.system.JmeCanvasContext; -import com.jme3.system.JmeSystem; import com.jme3.util.JmeFormatter; import java.awt.Canvas; import java.awt.event.ActionEvent; @@ -60,7 +59,7 @@ public class TestCanvas { private static Canvas canvas; private static Application app; private static JFrame frame; - private static final String appClass = "jme3test.model.shape.TestBox"; + private static final String appClass = "jme3test.post.TestMultiplesFilters"; private static void createFrame(){ frame = new JFrame("Test"); diff --git a/engine/src/test/jme3test/export/TestOgreConvert.java b/engine/src/test/jme3test/export/TestOgreConvert.java index fb52e100d..0b00a7303 100644 --- a/engine/src/test/jme3test/export/TestOgreConvert.java +++ b/engine/src/test/jme3test/export/TestOgreConvert.java @@ -75,7 +75,6 @@ public class TestOgreConvert extends SimpleApplication { AnimControl control = ogreModelReloaded.getControl(AnimControl.class); AnimChannel chan = control.createChannel(); chan.setAnim("Walk"); -// fis.close(); rootNode.attachChild(ogreModelReloaded); } catch (IOException ex){ diff --git a/engine/src/test/jme3test/stress/TestLodStress.java b/engine/src/test/jme3test/stress/TestLodStress.java index abe78e077..de8a53ccd 100644 --- a/engine/src/test/jme3test/stress/TestLodStress.java +++ b/engine/src/test/jme3test/stress/TestLodStress.java @@ -33,7 +33,6 @@ package jme3test.stress; import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; import com.jme3.light.DirectionalLight; import com.jme3.material.Material; import com.jme3.math.Quaternion; @@ -41,32 +40,34 @@ import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.control.LodControl; +import com.jme3.scene.shape.Sphere; public class TestLodStress extends SimpleApplication { - private boolean lod = false; - public static void main(String[] args){ TestLodStress app = new TestLodStress(); + app.setShowSettings(false); + app.setPauseOnLostFocus(false); app.start(); } public void simpleInitApp() { -// inputManager.registerKeyBinding("USELOD", KeyInput.KEY_L); - DirectionalLight dl = new DirectionalLight(); dl.setDirection(new Vector3f(-1,-1,-1).normalizeLocal()); rootNode.addLight(dl); - Node teapotNode = (Node) assetManager.loadModel("Models/Teapot/Teapot.mesh.xml"); - Geometry teapot = (Geometry) teapotNode.getChild(0); +// Node teapotNode = (Node) assetManager.loadModel("Models/Teapot/Teapot.mesh.xml"); +// Geometry teapot = (Geometry) teapotNode.getChild(0); + + Sphere sph = new Sphere(16, 16, 4); + Geometry teapot = new Geometry("teapot", sph); Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); mat.setFloat("Shininess", 16f); - mat.setBoolean("VertexLighting", true); +// mat.setBoolean("VertexLighting", true); teapot.setMaterial(mat); - - // show normals as material + + // show normals as material //Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); for (int y = -10; y < 10; y++){ @@ -77,9 +78,9 @@ public class TestLodStress extends SimpleApplication { clonePot.setLocalTranslation(x * .5f, 0, y * .5f); clonePot.setLocalScale(.15f); - LodControl control = new LodControl(); - clonePot.addControl(control); - rootNode.attachChild(clonePot); +// LodControl control = new LodControl(); +// clonePot.addControl(control); +// rootNode.attachChild(clonePot); } } diff --git a/engine/src/tools/jme3tools/converters/ImageToAwt.java b/engine/src/tools/jme3tools/converters/ImageToAwt.java index 3e034518f..995dedfa2 100644 --- a/engine/src/tools/jme3tools/converters/ImageToAwt.java +++ b/engine/src/tools/jme3tools/converters/ImageToAwt.java @@ -46,11 +46,12 @@ import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.HashMap; +import java.util.EnumMap; public class ImageToAwt { - private static final HashMap params = new HashMap(); + private static final EnumMap params + = new EnumMap(Format.class); private static class DecodeParams { @@ -294,6 +295,80 @@ public class ImageToAwt { image.setData(BufferUtils.createByteBuffer(total)); } + /** + * Convert the image from the given format to the output format. + * It is assumed that both images have buffers with the appropriate + * number of elements and that both have the same dimensions. + * + * @param input + * @param output + */ + public static void convert(Image input, Image output){ + DecodeParams inParams = params.get(input.getFormat()); + DecodeParams outParams = params.get(output.getFormat()); + + if (inParams == null || outParams == null) + throw new UnsupportedOperationException(); + + int width = input.getWidth(); + int height = input.getHeight(); + + if (width != output.getWidth() || height != output.getHeight()) + throw new IllegalArgumentException(); + + ByteBuffer inData = input.getData(0); + + boolean inAlpha = false; + boolean inLum = false; + boolean inRGB = false; + if (inParams.am != 0) { + inAlpha = true; + } + + if (inParams.rm != 0 && inParams.gm == 0 && inParams.bm == 0) { + inLum = true; + } else if (inParams.rm != 0 && inParams.gm != 0 && inParams.bm != 0) { + inRGB = true; + } + + int expansionA = 8 - Integer.bitCount(inParams.am); + int expansionR = 8 - Integer.bitCount(inParams.rm); + int expansionG = 8 - Integer.bitCount(inParams.gm); + int expansionB = 8 - Integer.bitCount(inParams.bm); + + int inputPixel; + for (int y = 0; y < height; y++){ + for (int x = 0; x < width; x++){ + int i = Ix(x, y, width) * inParams.bpp; + inputPixel = (readPixel(inData, i, inParams.bpp) & inParams.im) >> inParams.is; + + int a = (inputPixel & inParams.am) >> inParams.as; + int r = (inputPixel & inParams.rm) >> inParams.rs; + int g = (inputPixel & inParams.gm) >> inParams.gs; + int b = (inputPixel & inParams.bm) >> inParams.bs; + + r = r & 0xff; + g = g & 0xff; + b = b & 0xff; + a = a & 0xff; + + a = a << expansionA; + r = r << expansionR; + g = g << expansionG; + b = b << expansionB; + + if (inLum) + b = g = r; + + if (!inAlpha) + a = 0xff; + +// int argb = (a << 24) | (r << 16) | (g << 8) | b; +// out.setRGB(x, y, argb); + } + } + } + public static BufferedImage convert(Image image, boolean do16bit, boolean fullalpha, int mipLevel){ Format format = image.getFormat(); DecodeParams p = params.get(image.getFormat());