From acd2cb304de2fa7490e9393940700f8de22038ea Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Sun, 4 Jun 2023 22:21:33 -0500 Subject: [PATCH 01/18] Add support for Multiple Monitors in jme-LWJGL3 #2030 Add support for multiple monitors. Add a feature so that when a "Full Screen" window is created, that you can tell it which monitor to create the window on. Add a feature so that the application can call context to get a list of monitors that OPENGL found. It returns them in an ArrayList so that the programmers can select a monitor from the list. JME will take the pos of the monitor from the arraylist to get its handle. So if you have 2 monitors, you will have 2 in the list. So to tell JME which monitor to create the window on it would be 0 or 1. The array position in the list. The thought behind this is the program gets a list of monitors and then they can use that list in their settings for the user to select which monitor to us. Since the ID of the monitor changes between each launch, I went with the position from the arraylist that it returned. So many if user changes the order of the monitors then the program will launch on a different screen. Minor. Added in AppSettings a way to get/set Monitor. Monitor value is used only when creating a Full Screen. --- .../com/jme3/system/android/OGLESContext.java | 14 +++ .../java/com/jme3/system/AppSettings.java | 29 +++++ .../main/java/com/jme3/system/JmeContext.java | 18 +++ .../java/com/jme3/system/MonitorInfo.java | 73 +++++++++++ .../main/java/com/jme3/system/Monitors.java | 119 ++++++++++++++++++ .../java/com/jme3/system/NullContext.java | 12 ++ .../main/java/com/jme3/system/AWTContext.java | 12 ++ .../com/jme3/system/awt/AwtPanelsContext.java | 12 ++ .../com/jme3/system/ios/IGLESContext.java | 14 +++ .../com/jme3/system/lwjgl/LwjglCanvas.java | 15 +++ .../com/jme3/system/lwjgl/LwjglDisplay.java | 16 +++ .../system/lwjgl/LwjglOffscreenBuffer.java | 16 +++ .../com/jme3/system/lwjgl/LwjglWindow.java | 101 ++++++++++++++- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 15 +++ 14 files changed, 461 insertions(+), 5 deletions(-) create mode 100644 jme3-core/src/main/java/com/jme3/system/MonitorInfo.java create mode 100644 jme3-core/src/main/java/com/jme3/system/Monitors.java diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index 5757368ef8..52f2e41479 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -554,4 +554,18 @@ private Rect getSurfaceFrame() { Rect result = holder.getSurfaceFrame(); return result; } + + @Override + public Monitors getMonitors() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() + { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java index f3fb5a158f..ccb3027395 100644 --- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java +++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java @@ -266,6 +266,7 @@ public final class AppSettings extends HashMap { public static final String JOAL = "JOAL"; static { + defaults.put("Monitor", 0); defaults.put("CenterWindow", true); defaults.put("Width", 640); defaults.put("Height", 480); @@ -1479,4 +1480,32 @@ public int getWindowYPosition() { public void setWindowYPosition(int pos) { putInteger("WindowYPosition", pos); } + + + /** + * Gets the monitor number used when creating a window. + * + *

This setting is used only with LWJGL3, it defines which monitor + * to use when creating a OpenGL window. + * + * @return the desired monitor used when creating a OpenGL window + * @see #setMonitor(long) + */ + public int getMonitor() { + return getInteger("Monitor"); + } + + /** + * Sets the monitor number used when creating a window. The position + * number is the number in the list of monitors GlfwGetMonitors returns. + * + *

This setting is used only with LWJGL3, it defines which monitor + * to use when creating a OpenGL window. its default value is -1. + * + * @param mon the desired monitor used when creating a OpenGL window + * + */ + public void setMonitor(int mon) { + putInteger("Monitor", mon); + } } diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index 8d83e0960e..59d7cdbb05 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -225,4 +225,22 @@ public enum Type { * @throws IllegalStateException for a headless or null context */ public int getWindowYPosition(); + + /** + * This call will return a list of Monitors that glfwGetMonitors() + * returns and information about the monitor, like width, height, + * and refresh rate. + * + * @return returns a list of monitors and their information. + */ + public Monitors getMonitors(); + + /** + * Use this to get the positional number of the primary + * monitor from the glfwGetMonitors() function call. + * + * @return the position of the value in the arraylist of + * the primary monitor. + */ + public int getPrimaryMonitor(); } diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java new file mode 100644 index 0000000000..272a30ce43 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009-2022 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. + */ +package com.jme3.system; + +/** + * This class holds information about the monitor that was + * returned by glfwGetMonitors() calls in the context + * class + * + * @author Kevin Bales + */ +public class MonitorInfo { + + /** + * monitorID - monitor id that was return from Lwjgl3. + */ + public long monitorID = 0; + + /** + * width - width that was return from Lwjgl3. + */ + public int width = 1080; + + /** + * height - height that was return from Lwjgl3. + */ + public int height = 1920; + + /** + * rate - refresh rate that was return from Lwjgl3. + */ + public int rate = 60; + + /** + * primary - indicates if the monitor is the primary monitor. + */ + public boolean primary = false; + + /** + * name - monitor name that was return from Lwjgl3. + */ + public String name = "Generic Monitor"; + +} diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java new file mode 100644 index 0000000000..998ff869f5 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/system/Monitors.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2009-2022 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. + */ +package com.jme3.system; + +import java.util.ArrayList; + +/** + * This class holds all information about all monitors that where + * return from the glfwGetMonitors() call. It stores them into + * an + * + * @author Kevin Bales + */ +public class Monitors { + + private ArrayList monitors = new ArrayList(); + + public int addNewMonitor(long monitorID) + { + MonitorInfo info = new MonitorInfo(); + info.monitorID = monitorID; + monitors.add(info); + return monitors.size() - 1; + } + + /** + * This function returns the size of the monitor ArrayList + * @return the + */ + public int size() + { + return monitors.size(); + } + + /** + * Call to get monitor information on a certain monitor. + * + * @param pos the position in the arraylist of the monitor + * information that you want to get. + * @return returns the MonitorInfo data for the monitor + * called for. + */ + public MonitorInfo get(int pos) + { + if (pos < monitors.size()) + return monitors.get(pos); + + return null; + } + + /** + * Set information about this monitor stored in monPos position + * in the array list. + * + * @param monPos arraylist position of monitor to update + * @param width the current width the monitor is displaying + * @param height the current height the monitor is displaying + * @param rate the current refresh rate the monitor is set to + */ + public void setInfo(int monPos, String name, int width, int height, int rate) { + if (monPos < monitors.size() ) { + MonitorInfo info = monitors.get(monPos); + if (info != null) { + info.width = width; + info.height = height; + info.rate = rate; + info.name = name; + } + } + } + + /** + * This function will mark a certain monitor as the + * primary monitor. + * + * @param monPos the position in the arraylist of which + * monitor is the primary monitor + */ + public void setPrimaryMonitor(int monPos) { + if (monPos < monitors.size() ) { + MonitorInfo info = monitors.get(monPos); + if (info != null) + info.primary = true; + } + + } + + + +} diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index fd43d8d761..f0eccdc112 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -306,4 +306,16 @@ public int getWindowXPosition() { public int getWindowYPosition() { throw new UnsupportedOperationException("null context"); } + + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java index 1232f04809..c58b2c44af 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java @@ -275,4 +275,16 @@ public int getWindowXPosition() { public int getWindowYPosition() { throw new UnsupportedOperationException("not implemented yet"); } + + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index 032c8457eb..23a46c8930 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -328,4 +328,16 @@ public int getWindowXPosition() { public int getWindowYPosition() { return inputSource.getY(); } + + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index 009195c776..d19a18c44a 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -267,4 +267,18 @@ public int getWindowXPosition() { public int getWindowYPosition() { throw new UnsupportedOperationException("not implemented yet"); } + + @Override + public Monitors getMonitors() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() + { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 0bfb63976e..17d0b9bd6c 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -36,6 +36,7 @@ import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystem; +import com.jme3.system.Monitors; import com.jme3.system.Platform; import java.awt.Canvas; import java.util.logging.Level; @@ -502,4 +503,18 @@ protected void createContext(AppSettings settings) { // TODO: Fix deadlock that happens after the error (throw runtime exception?) } } + + @Override + public Monitors getMonitors() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() + { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 1db33942e8..bf7eef3aa0 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -34,6 +34,8 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext.Type; +import com.jme3.system.Monitors; + import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; @@ -282,4 +284,18 @@ private ByteBuffer imageToByteBuffer(BufferedImage image) { return ByteBuffer.wrap(imageBuffer); } + @Override + public Monitors getMonitors() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() + { + // TODO Auto-generated method stub + return 0; + } + } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 5484d13cf6..1965d19ec0 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -38,6 +38,8 @@ import com.jme3.input.TouchInput; import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; +import com.jme3.system.Monitors; + import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -218,4 +220,18 @@ public TouchInput getTouchInput() { public void setTitle(String title) { } + @Override + public Monitors getMonitors() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() + { + // TODO Auto-generated method stub + return 0; + } + } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index c2b5e47402..74446fd8fc 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine +* Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,9 +43,12 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; +import com.jme3.system.Monitors; import com.jme3.system.NanoTimer; import com.jme3.util.BufferUtils; import com.jme3.util.SafeArrayList; + +import org.lwjgl.PointerBuffer; import org.lwjgl.Version; import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWFramebufferSizeCallback; @@ -58,9 +61,11 @@ import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; +import java.nio.IntBuffer; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -283,21 +288,34 @@ public void invoke(int error, long description) { glfwWindowHint(GLFW_ALPHA_BITS, settings.getAlphaBits()); - // TODO: Add support for monitor selection long monitor = NULL; + /** + * Let's grab the monitor selected, if not found it will return primaryMonitor. + * if not full screen just use primary monitor data. + */ if (settings.isFullscreen()) { - monitor = glfwGetPrimaryMonitor(); + monitor = getMonitor(settings.getMonitor()); + } else { + monitor = glfwGetPrimaryMonitor(); } - final GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + final GLFWVidMode videoMode = glfwGetVideoMode(monitor); int requestWidth = settings.getWindowWidth(); int requestHeight = settings.getWindowHeight(); if (requestWidth <= 0 || requestHeight <= 0) { requestWidth = videoMode.width(); requestHeight = videoMode.height(); } - window = glfwCreateWindow(requestWidth, requestHeight, settings.getTitle(), monitor, NULL); + + //Lets use the monitor selected from AppSettings if FullScreen is + //set. + if (settings.isFullscreen()) + window = glfwCreateWindow(requestWidth, requestHeight, settings.getTitle(), monitor, NULL); + else + window = glfwCreateWindow(requestWidth, requestHeight, settings.getTitle(), NULL, NULL); + + if (window == NULL) { throw new RuntimeException("Failed to create the GLFW window"); } @@ -853,4 +871,77 @@ public int getWindowYPosition() { int result = height[0]; return result; } + + /** + * Returns the Primary Monitor position number from the list of monitors + * returned by glfwGetPrimaryMonitor(). If primary monitor not found + * it will return -1 and report the error. + * + * @return returns the Primary Monitor Position. + */ + @Override + public int getPrimaryMonitor() + { + long prim = glfwGetPrimaryMonitor(); + Monitors monitors = getMonitors(); + for ( int i = 0; i < monitors.size(); i++ ) { + long monitorI = monitors.get(i).monitorID; + if (monitorI == prim) + return i; + } + + LOGGER.log(Level.SEVERE,"Couldn't locate Primary Monitor in the list of Monitors."); + return -1; + } + + + /** + * This routines return the monitor ID by position in an array of monitors returned + * by glfwGetMonitors(). + * + * @param pos the position of the monitor in the list of monitors returned. + * @return return the monitorID if found otherwise return Primary Monitor + */ + private long getMonitor(int pos) { + Monitors monitors = getMonitors(); + if (pos < monitors.size()) + return monitors.get(pos).monitorID; + + LOGGER.log(Level.SEVERE,"Couldn't locate Monitor requested in the list of Monitors. pos:"+pos+" size: "+ monitors.size()); + return glfwGetPrimaryMonitor(); + } + + /** + * This returns an arraylist of all the monitors returned by OpenGL get Monitor + * call. It will also has some limited information about each monitor, like: + * width, height and refresh rate. + * + * @return returns an ArrayList of all Monitors returned by glfwGetMonitors() + */ + + @Override + public Monitors getMonitors() + { + PointerBuffer monitors = glfwGetMonitors(); + long primary = glfwGetPrimaryMonitor(); + Monitors monitorList = new Monitors(); + + for ( int i = 0; i < monitors.limit(); i++ ) { + long monitorI = monitors.get(i); + int monPos = monitorList.addNewMonitor(monitorI); + //lets check if this monitor is the primary monitor. If use mark it as such. + if (primary == monitorI) + monitorList.setPrimaryMonitor(monPos); + + final GLFWVidMode modes = glfwGetVideoMode(monitorI); + String name = glfwGetMonitorName(monitorI); + + int width = modes.width(); + int height = modes.height(); + int rate = modes.refreshRate(); + monitorList.setInfo(monPos, name, width, height, rate); + LOGGER.log(Level.INFO, "Monitor id: "+monitorI+" Resolution: " + width + " x " + height + " @ " + rate); + } + return monitorList; + } } diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index 5df00bf08f..888c8b879d 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -32,6 +32,7 @@ package com.jme3.system.lwjgl; import com.jme3.opencl.Context; +import com.jme3.system.Monitors; /** * A VR oriented LWJGL display. @@ -51,4 +52,18 @@ public LwjglDisplayVR() { public Context getOpenCLContext() { return null; } + + @Override + public Monitors getMonitors() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() + { + // TODO Auto-generated method stub + return 0; + } } From 94fb53bd05153f9337bb02b297c9c0e780929c24 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Sun, 4 Jun 2023 22:29:14 -0500 Subject: [PATCH 02/18] Add support for Multiple Monitors in jme-LWJGL3 #2030 Add support for multiple monitors. Add a feature so that when a "Full Screen" window is created, that you can tell it which monitor to create the window on. Add a feature so that the application can call context to get a list of monitors that OPENGL found. It returns them in an ArrayList so that the programmers can select a monitor from the list. JME will take the pos of the monitor from the arraylist to get its handle. So if you have 2 monitors, you will have 2 in the list. So to tell JME which monitor to create the window on it would be 0 or 1. The array position in the list. The thought behind this is the program gets a list of monitors and then they can use that list in their settings for the user to select which monitor to us. Since the ID of the monitor changes between each launch, I went with the position from the arraylist that it returned. So many if user changes the order of the monitors then the program will launch on a different screen. Minor. Added in AppSettings a way to get/set Monitor. Monitor value is used only when creating a Full Screen. --- .../java/jme3test/app/TestMonitorApp.java | 251 ++++++++++++++++++ .../java/jme3test/app/TestResizableApp.java | 8 +- 2 files changed, 256 insertions(+), 3 deletions(-) create mode 100644 jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java new file mode 100644 index 0000000000..e6b59d56ce --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.app; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; +import com.jme3.system.MonitorInfo; +import com.jme3.system.Monitors; + +/** + * Tests the capability to change which monitor the window + * will be created on. Also, shows that you can force + * JME to center the window. Also, it shows to to force JME to + * set the window to x,y coords. Center window and window + * position doesn't apply if in fullscreen. + * + * @author Kevin Bales + */ +public class TestMonitorApp extends SimpleApplication implements ActionListener { + + private BitmapText txt; + private BitmapText selectedMonitorTxt; + private BitmapText fullScreenTxt; + private int monitorSelected = 0; + private Monitors monitors = null; + + public static void main(String[] args){ + TestMonitorApp app = new TestMonitorApp(); + AppSettings settings = new AppSettings(true); + settings.setResizable(false); + app.setShowSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL33); + settings.setMonitor(0); + settings.setResolution(800, 600); + + settings.setFullscreen(true); + + //Force JME to center the window, this only applies if it is + //not fullscreen. + settings.setCenterWindow(true); + + //If center window is not turned on, you can force JME to + //open the window at certain x,y coords. These are ignored + //if the screen is set to "fullscreen". + settings.setWindowXPosition(0); + settings.setWindowYPosition(0); + + try + { + //Let's try and load the AppSetting parameters back into memory + InputStream out = new FileInputStream("TestMonitorApp.prefs"); + settings.load(out); + } + catch (IOException e) + { + System.out.println("failed to load settings, reverting to defaults"); + } + app.setSettings(settings); + + app.start(); + } + + + @Override + public void simpleInitApp() { + flyCam.setDragToRotate(true); + int numMonitors = 1; + + //If monitor is define, Jme supports multiple monitors. Setup to keys + if (monitors == null) { + inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("fullscreen", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addListener(this, "down", "fullscreen"); + } + + //Get the selected monitor + monitorSelected = settings.getMonitor(); + monitors = context.getMonitors(); + if (monitors != null) + numMonitors = monitors.size(); + + + + //Let's define the labels for users to see what is going on with Multiple Monitor + String labelValue = ""; + labelValue = "There are "+numMonitors+" monitor(s) hooked up to this computer."; + txt = new BitmapText(loadGuiFont()); + txt.setText(labelValue); + txt.setLocalTranslation(0, settings.getHeight(), 0); + guiNode.attachChild(txt); + + txt = new BitmapText(loadGuiFont()); + if (!settings.isFullscreen()) + txt.setText("Window is on Monitor N/A (fullscreen only feature)"); + else + txt.setText("Window is on Monitor "+settings.getMonitor()); + + txt.setLocalTranslation(0, settings.getHeight() - 40, 0); + guiNode.attachChild(txt); + + if (monitors != null) { + selectedMonitorTxt = new BitmapText(loadGuiFont()); + //Lets display information about selected monitor + String label = "Selected Monitor "+ + "Name: "+monitors.get(settings.getMonitor()).name+" "+ + monitorSelected+ " Res: " + + monitors.get(settings.getMonitor()).width+","+ + monitors.get(settings.getMonitor()).height + + " refresh: "+monitors.get(settings.getMonitor()).rate; + selectedMonitorTxt.setText(label); + selectedMonitorTxt.setLocalTranslation(0, settings.getHeight() - 80, 0); + guiNode.attachChild(selectedMonitorTxt); + + //Let's loop through all the monitors and display on the screen + for(int i = 0; i < monitors.size(); i++) { + MonitorInfo monitor = monitors.get(i); + labelValue = "Mon : "+i+" "+monitor.name+" " + monitor.width +","+ monitor.height +" refresh: "+ monitor.rate; + txt = new BitmapText(loadGuiFont()); + txt.setText(labelValue); + txt.setLocalTranslation(0, settings.getHeight() - 160 - (40*i), 0); + guiNode.attachChild(txt); + } + } + + //Lets put a label up there for FullScreen/Window toggle + fullScreenTxt = new BitmapText(loadGuiFont()); + if (!settings.isFullscreen()) + fullScreenTxt.setText("(f) Window Screen"); + else + fullScreenTxt.setText("(f) Fullscreen"); + + fullScreenTxt.setLocalTranslation(00, settings.getHeight() - 240, 0); + guiNode.attachChild(fullScreenTxt); + + BitmapText infoTxt = new BitmapText(loadGuiFont()); + infoTxt.setText("Restart is required to activate changes in settings."); + infoTxt.setLocalTranslation(0, settings.getHeight() - 300, 0); + guiNode.attachChild(infoTxt); + + + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + + if (monitors == null) + return; + + if (name.equals("down") && isPressed) { + monitorSelected++; + if (monitorSelected >= monitors.size()) + monitorSelected = 0; + saveSettings(); + } + else if (name.equals("up") && isPressed) { + monitorSelected--; + if (monitorSelected < 0) + monitorSelected = monitors.size()-1; + saveSettings(); + } + else if (name.equals("fullscreen") && isPressed) { + settings.setFullscreen(!settings.isFullscreen()); + saveSettings(); + } + } + + /** + * This function saves out the AppSettings into a file to be loaded back in + * on start of application. + */ + public void saveSettings() + { + + try + { + settings.setMonitor(monitorSelected); + OutputStream out = new FileOutputStream("TestMonitorApp.prefs"); + settings.save(out); + + int monitorSelected = settings.getMonitor(); + String label = "Selected Monitor "+ monitorSelected+ + " "+ monitors.get(monitorSelected).name+ + " Res: " +monitors.get(monitorSelected).width+","+ + monitors.get(monitorSelected).height + + "refresh: "+monitors.get(monitorSelected).rate; + selectedMonitorTxt.setText(label); + if (!settings.isFullscreen()) + fullScreenTxt.setText("(f) Window Screen"); + else + fullScreenTxt.setText("(f) Fullscreen"); + } + catch (FileNotFoundException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + +} diff --git a/jme3-examples/src/main/java/jme3test/app/TestResizableApp.java b/jme3-examples/src/main/java/jme3test/app/TestResizableApp.java index 09d034581d..da88af4ff1 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestResizableApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestResizableApp.java @@ -61,9 +61,11 @@ public void reshape(int width, int height) { super.reshape(width, height); // Need to move text relative to app height - txt.setLocalTranslation(0, settings.getHeight(), 0); - txt.setText("Drag the corners of the application to resize it.\n" + - "Current Size: " + settings.getWidth() + "x" + settings.getHeight()); + if (txt != null) { + txt.setLocalTranslation(0, settings.getHeight(), 0); + txt.setText("Drag the corners of the application to resize it.\n" + + "Current Size: " + settings.getWidth() + "x" + settings.getHeight()); + } } @Override From 2251e2e37bdb3e597921fd4132bf1b2a3707f1a1 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Wed, 7 Jun 2023 21:27:46 -0500 Subject: [PATCH 03/18] updated comment and change comment on default value to 0. --- jme3-core/src/main/java/com/jme3/system/AppSettings.java | 2 +- jme3-core/src/main/java/com/jme3/system/MonitorInfo.java | 2 +- jme3-core/src/main/java/com/jme3/system/Monitors.java | 2 +- .../src/main/java/jme3test/app/TestMonitorApp.java | 2 +- .../src/main/java/com/jme3/system/lwjgl/LwjglWindow.java | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java index ccb3027395..c5509301ac 100644 --- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java +++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java @@ -1500,7 +1500,7 @@ public int getMonitor() { * number is the number in the list of monitors GlfwGetMonitors returns. * *

This setting is used only with LWJGL3, it defines which monitor - * to use when creating a OpenGL window. its default value is -1. + * to use when creating a OpenGL window. its default value is 0. * * @param mon the desired monitor used when creating a OpenGL window * diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java index 272a30ce43..64864fb70e 100644 --- a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022 jMonkeyEngine + * Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java index 998ff869f5..61a874d201 100644 --- a/jme3-core/src/main/java/com/jme3/system/Monitors.java +++ b/jme3-core/src/main/java/com/jme3/system/Monitors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022 jMonkeyEngine + * Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index e6b59d56ce..f673c22afc 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2021 jMonkeyEngine + * Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index 74446fd8fc..e0002d6424 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -152,6 +152,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { private Thread mainThread; + private long monitor = NULL; private long window = NULL; private int frameRateLimit = -1; @@ -288,7 +289,7 @@ public void invoke(int error, long description) { glfwWindowHint(GLFW_ALPHA_BITS, settings.getAlphaBits()); - long monitor = NULL; +// long monitor = NULL; /** * Let's grab the monitor selected, if not found it will return primaryMonitor. @@ -920,8 +921,7 @@ private long getMonitor(int pos) { */ @Override - public Monitors getMonitors() - { + public Monitors getMonitors() { PointerBuffer monitors = glfwGetMonitors(); long primary = glfwGetPrimaryMonitor(); Monitors monitorList = new Monitors(); From 75f6d6635f603661f0993d06628162b95641c06c Mon Sep 17 00:00:00 2001 From: bob0bob <30982580+bob0bob@users.noreply.github.com> Date: Wed, 7 Jun 2023 22:00:51 -0500 Subject: [PATCH 04/18] By default use PrimitiveAllocator on Android (#2029) (#6) Co-authored-by: Ali-RS --- .../src/main/java/com/jme3/system/android/OGLESContext.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index 52f2e41479..8d3d28f89c 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -58,7 +58,8 @@ import com.jme3.renderer.opengl.*; import com.jme3.system.*; import com.jme3.util.BufferAllocatorFactory; -import com.jme3.util.AndroidNativeBufferAllocator; +import com.jme3.util.PrimitiveAllocator; + import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -85,7 +86,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex final String implementation = BufferAllocatorFactory.PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION; if (System.getProperty(implementation) == null) { - System.setProperty(implementation, AndroidNativeBufferAllocator.class.getName()); + System.setProperty(implementation, PrimitiveAllocator.class.getName()); } } From 8ef3c5e901bbf02c714e4ee87329d4aefd139a7a Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Wed, 7 Jun 2023 22:56:12 -0500 Subject: [PATCH 05/18] Missed a file during check in for multiple monitor selection. --- .../java/com/jme3/app/LegacyApplication.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index 626dec4bfd..0f172d37f2 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -852,4 +852,28 @@ public Object call() { return null; } } + + /** + * This call will return a list of Monitors that glfwGetMonitors() + * returns and information about the monitor, like width, height, + * and refresh rate. + * + * @return returns a list of monitors and their information. + */ + public Monitors getMonitors() + { + return context.getMonitors(); + } + + /** + * Use this to get the positional number of the primary + * monitor from the glfwGetMonitors() function call. + * + * @return the position of the value in the arraylist of + * the primary monitor. + */ + public int getPrimaryMonitor() + { + return context.getPrimaryMonitor(); + } } From 6a590dbc99ee16cb415acab5662e356d2ea6b169 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Tue, 13 Jun 2023 20:44:01 -0500 Subject: [PATCH 06/18] Changing formatting to be google format style for the JME standard. --- .../com/jme3/system/android/OGLESContext.java | 26 +- .../java/com/jme3/app/LegacyApplication.java | 1608 ++++++++--------- .../java/com/jme3/system/AppSettings.java | 20 +- .../main/java/com/jme3/system/JmeContext.java | 16 +- .../java/com/jme3/system/MonitorInfo.java | 101 +- .../main/java/com/jme3/system/Monitors.java | 180 +- .../java/com/jme3/system/NullContext.java | 12 +- .../com/jme3/system/awt/AwtPanelsContext.java | 22 +- .../java/jme3test/app/TestMonitorApp.java | 339 ++-- .../com/jme3/system/ios/IGLESContext.java | 24 +- .../com/jme3/system/lwjgl/LwjglCanvas.java | 881 +++++---- .../com/jme3/system/lwjgl/LwjglDisplay.java | 22 +- .../system/lwjgl/LwjglOffscreenBuffer.java | 24 +- .../com/jme3/system/lwjgl/LwjglWindow.java | 23 +- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 22 +- 15 files changed, 1609 insertions(+), 1711 deletions(-) diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index 8d3d28f89c..005a579b7e 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -556,17 +556,15 @@ private Rect getSurfaceFrame() { return result; } - @Override - public Monitors getMonitors() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryMonitor() - { - // TODO Auto-generated method stub - return 0; - } -} + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } + } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index 0f172d37f2..e74874b095 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -1,33 +1,27 @@ /* - * Copyright (c) 2009-2022 jMonkeyEngine - * All rights reserved. + * Copyright (c) 2009-2022 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: + * 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 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. + * * 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. + * * 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. + * 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. */ package com.jme3.app; @@ -56,824 +50,792 @@ import java.util.logging.Logger; /** - * The LegacyApplication class represents an instance of a - * real-time 3D rendering jME application. + * The LegacyApplication class represents an instance of a real-time 3D rendering jME + * application. * * An LegacyApplication provides all the tools that are commonly used in jME3 * applications. * - * jME3 applications *SHOULD NOT EXTEND* this class but extend {@link com.jme3.app.SimpleApplication} instead. + * jME3 applications *SHOULD NOT EXTEND* this class but extend + * {@link com.jme3.app.SimpleApplication} instead. * */ public class LegacyApplication implements Application, SystemListener { - private static final Logger logger = Logger.getLogger(LegacyApplication.class.getName()); - - protected AssetManager assetManager; - - protected AudioRenderer audioRenderer; - protected Renderer renderer; - protected RenderManager renderManager; - protected ViewPort viewPort; - protected ViewPort guiViewPort; - - protected JmeContext context; - protected AppSettings settings; - protected Timer timer = new NanoTimer(); - protected Camera cam; - protected Listener listener; - - protected boolean inputEnabled = true; - protected LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus; - protected float speed = 1f; - protected boolean paused = false; - protected MouseInput mouseInput; - protected KeyInput keyInput; - protected JoyInput joyInput; - protected TouchInput touchInput; - protected InputManager inputManager; - protected AppStateManager stateManager; - - protected AppProfiler prof; - - private final ConcurrentLinkedQueue> taskQueue = new ConcurrentLinkedQueue<>(); - - /** - * Create a new instance of LegacyApplication. - */ - public LegacyApplication() { - this((AppState[]) null); - } - - /** - * Create a new instance of LegacyApplication, preinitialized - * with the specified set of app states. - * - * @param initialStates app states to pre-attach, or null for none - */ - public LegacyApplication(AppState... initialStates) { - initStateManager(); - - if (initialStates != null) { - for (AppState a : initialStates) { - if (a != null) { - stateManager.attach(a); - } - } - } - } - - /** - * Determine the application's behavior when unfocused. - * - * @return The lost focus behavior of the application. - */ - @Override - public LostFocusBehavior getLostFocusBehavior() { - return lostFocusBehavior; - } - - /** - * Changes the application's behavior when unfocused. - * - * By default, the application will - * {@link LostFocusBehavior#ThrottleOnLostFocus throttle the update loop} - * so as not to use 100% of the CPU when out of focus, e.g. - * alt-tabbed, minimized, or hidden by another window. - * - * @param lostFocusBehavior The new lost focus behavior to use. - * - * @see LostFocusBehavior - */ - @Override - public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) { - this.lostFocusBehavior = lostFocusBehavior; - } - - /** - * Returns true if pause on lost focus is enabled, false otherwise. - * - * @return true if pause on lost focus is enabled - * - * @see #getLostFocusBehavior() - */ - @Override - public boolean isPauseOnLostFocus() { - return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus; - } - - /** - * 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 be undesirable, - * so this feature should be disabled. For other applications, - * it is best to keep it enabled so the CPU is not used unnecessarily. - * - * @param pauseOnLostFocus True to enable pause on lost focus, false - * otherwise. - * - * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior) - */ - @Override - public void setPauseOnLostFocus(boolean pauseOnLostFocus) { - if (pauseOnLostFocus) { - setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus); - } else { - setLostFocusBehavior(LostFocusBehavior.Disabled); + private static final Logger logger = Logger.getLogger(LegacyApplication.class.getName()); + + protected AssetManager assetManager; + + protected AudioRenderer audioRenderer; + protected Renderer renderer; + protected RenderManager renderManager; + protected ViewPort viewPort; + protected ViewPort guiViewPort; + + protected JmeContext context; + protected AppSettings settings; + protected Timer timer = new NanoTimer(); + protected Camera cam; + protected Listener listener; + + protected boolean inputEnabled = true; + protected LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus; + protected float speed = 1f; + protected boolean paused = false; + protected MouseInput mouseInput; + protected KeyInput keyInput; + protected JoyInput joyInput; + protected TouchInput touchInput; + protected InputManager inputManager; + protected AppStateManager stateManager; + + protected AppProfiler prof; + + private final ConcurrentLinkedQueue> taskQueue = new ConcurrentLinkedQueue<>(); + + /** + * Create a new instance of LegacyApplication. + */ + public LegacyApplication() { + this((AppState[]) null); + } + + /** + * Create a new instance of LegacyApplication, preinitialized with the specified set + * of app states. + * + * @param initialStates app states to pre-attach, or null for none + */ + public LegacyApplication(AppState... initialStates) { + initStateManager(); + + if (initialStates != null) { + for (AppState a : initialStates) { + if (a != null) { + stateManager.attach(a); } - } - - @Deprecated - public void setAssetManager(AssetManager assetManager) { - if (this.assetManager != null) - throw new IllegalStateException("Can only set asset manager" - + " before initialization."); - - this.assetManager = assetManager; - } - - private void initAssetManager() { - URL assetCfgUrl = null; - - if (settings != null) { - String assetCfg = settings.getString("AssetConfigURL"); - if (assetCfg != null) { - try { - assetCfgUrl = new URL(assetCfg); - } catch (MalformedURLException ex) { - } - if (assetCfgUrl == null) { - assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg); - if (assetCfgUrl == null) { - logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg); - return; - } - } - } + } + } + } + + /** + * Determine the application's behavior when unfocused. + * + * @return The lost focus behavior of the application. + */ + @Override + public LostFocusBehavior getLostFocusBehavior() { + return lostFocusBehavior; + } + + /** + * Changes the application's behavior when unfocused. + * + * By default, the application will {@link LostFocusBehavior#ThrottleOnLostFocus throttle the + * update loop} so as not to use 100% of the CPU when out of focus, e.g. alt-tabbed, minimized, or + * hidden by another window. + * + * @param lostFocusBehavior The new lost focus behavior to use. + * + * @see LostFocusBehavior + */ + @Override + public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) { + this.lostFocusBehavior = lostFocusBehavior; + } + + /** + * Returns true if pause on lost focus is enabled, false otherwise. + * + * @return true if pause on lost focus is enabled + * + * @see #getLostFocusBehavior() + */ + @Override + public boolean isPauseOnLostFocus() { + return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus; + } + + /** + * 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 be undesirable, so this feature should be disabled. For other applications, it is best to + * keep it enabled so the CPU is not used unnecessarily. + * + * @param pauseOnLostFocus True to enable pause on lost focus, false otherwise. + * + * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior) + */ + @Override + public void setPauseOnLostFocus(boolean pauseOnLostFocus) { + if (pauseOnLostFocus) { + setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus); + } else { + setLostFocusBehavior(LostFocusBehavior.Disabled); + } + } + + @Deprecated + public void setAssetManager(AssetManager assetManager) { + if (this.assetManager != null) + throw new IllegalStateException("Can only set asset manager" + " before initialization."); + + this.assetManager = assetManager; + } + + private void initAssetManager() { + URL assetCfgUrl = null; + + if (settings != null) { + String assetCfg = settings.getString("AssetConfigURL"); + if (assetCfg != null) { + try { + assetCfgUrl = new URL(assetCfg); + } catch (MalformedURLException ex) { } if (assetCfgUrl == null) { - assetCfgUrl = JmeSystem.getPlatformAssetConfigURL(); - } - if (assetManager == null) { - assetManager = JmeSystem.newAssetManager(assetCfgUrl); - } - } - - /** - * Set the display settings to define the display created. - *

- * Examples of display parameters include display pixel width and height, - * color bit depth, z-buffer bits, anti-aliasing samples, and update frequency. - * If this method is called while the application is already running, then - * {@link #restart() } must be called to apply the settings to the display. - * - * @param settings The settings to set. - */ - @Override - public void setSettings(AppSettings settings) { - this.settings = settings; - if (context != null && settings.useInput() != inputEnabled) { - // may need to create or destroy input based - // on settings change - inputEnabled = !inputEnabled; - if (inputEnabled) { - initInput(); - } else { - destroyInput(); - } - } else { - inputEnabled = settings.useInput(); - } - } - - /** - * Sets the Timer implementation that will be used for calculating - * frame times. By default, Application will use the Timer as returned - * by the current JmeContext implementation. - */ - @Override - public void setTimer(Timer timer) { - this.timer = timer; - - if (timer != null) { - timer.reset(); - } - - if (renderManager != null) { - renderManager.setTimer(timer); - } - } - - @Override - public Timer getTimer() { - return timer; - } - - private void initDisplay() { - // acquire important objects - // from the context - settings = context.getSettings(); - - // Only reset the timer if a user has not already provided one - if (timer == null) { - timer = context.getTimer(); - } - - renderer = context.getRenderer(); - } - - private void initAudio() { - if (settings.getAudioRenderer() != null && context.getType() != Type.Headless) { - audioRenderer = JmeSystem.newAudioRenderer(settings); - audioRenderer.initialize(); - AudioContext.setAudioRenderer(audioRenderer); - - listener = new Listener(); - audioRenderer.setListener(listener); - } - } - - /** - * Creates the camera to use for rendering. Default values are perspective - * projection with 45° field of view, with near and far values 1 and 1000 - * units respectively. - */ - private void initCamera() { - cam = new Camera(settings.getWidth(), settings.getHeight()); - - cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 1f, 1000f); - cam.setLocation(new Vector3f(0f, 0f, 10f)); - cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); - - renderManager = new RenderManager(renderer); - //Remy - 09/14/2010 set the timer in the renderManager - renderManager.setTimer(timer); - - if (prof != null) { - renderManager.setAppProfiler(prof); - } - - viewPort = renderManager.createMainView("Default", cam); - viewPort.setClearFlags(true, true, true); - - // Create a new cam for the gui - Camera guiCam = new Camera(settings.getWidth(), settings.getHeight()); - guiViewPort = renderManager.createPostView("Gui Default", guiCam); - guiViewPort.setClearFlags(false, false, false); - } - - /** - * Initializes mouse and keyboard input. Also - * initializes joystick input if joysticks are enabled in the - * AppSettings. - */ - private void initInput() { - mouseInput = context.getMouseInput(); - if (mouseInput != null) - mouseInput.initialize(); - - keyInput = context.getKeyInput(); - if (keyInput != null) - keyInput.initialize(); - - touchInput = context.getTouchInput(); - if (touchInput != null) - touchInput.initialize(); - - if (settings.useJoysticks()) { - joyInput = context.getJoyInput(); - if (joyInput != null) - joyInput.initialize(); - } - - inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput); - } - - private void initStateManager() { - stateManager = new AppStateManager(this); - - // Always register a ResetStatsState to make sure - // that the stats are cleared every frame - stateManager.attach(new ResetStatsState()); - } - - /** - * @return The {@link AssetManager asset manager} for this application. - */ - @Override - public AssetManager getAssetManager() { - return assetManager; - } - - /** - * @return the {@link InputManager input manager}. - */ - @Override - public InputManager getInputManager() { - return inputManager; - } - - /** - * @return the {@link AppStateManager app state manager} - */ - @Override - public AppStateManager getStateManager() { - return stateManager; - } - - /** - * @return the {@link RenderManager render manager} - */ - @Override - public RenderManager getRenderManager() { - return renderManager; - } - - /** - * @return The {@link Renderer renderer} for the application - */ - @Override - public Renderer getRenderer() { - return renderer; - } - - /** - * @return The {@link AudioRenderer audio renderer} for the application - */ - @Override - public AudioRenderer getAudioRenderer() { - return audioRenderer; - } - - /** - * @return The {@link Listener listener} object for audio - */ - @Override - public Listener getListener() { - return listener; - } - - /** - * @return The {@link JmeContext display context} for the application - */ - @Override - public JmeContext getContext() { - return context; - } - - /** - * @return The {@link Camera camera} for the application - */ - @Override - public Camera getCamera() { - return cam; - } - - /** - * Starts the application in {@link Type#Display display} mode. - * - * @see #start(com.jme3.system.JmeContext.Type) - */ - @Override - public void start() { - start(JmeContext.Type.Display, false); - } - - /** - * Starts the application in {@link Type#Display display} mode. - * - * @param waitFor true→wait for the context to be initialized, - * false→don't wait - * @see #start(com.jme3.system.JmeContext.Type) - */ - @Override - public void start(boolean waitFor) { - start(JmeContext.Type.Display, waitFor); - } - - /** - * Starts the application. - * Creating a rendering context and executing - * the main loop in a separate thread. - * - * @param contextType the type of context to create - */ - public void start(JmeContext.Type contextType) { - start(contextType, false); - } - - /** - * Starts the application. - * Creating a rendering context and executing - * the main loop in a separate thread. - * - * @param contextType the type of context to create - * @param waitFor true→wait for the context to be initialized, - * false→don't wait - */ - public void start(JmeContext.Type contextType, boolean waitFor) { - if (context != null && context.isCreated()) { - logger.warning("start() called when application already created!"); + assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg); + if (assetCfgUrl == null) { + logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", + assetCfg); return; + } } - - if (settings == null) { - settings = new AppSettings(true); - } - - logger.log(Level.FINE, "Starting application: {0}", getClass().getName()); - context = JmeSystem.newContext(settings, contextType); - context.setSystemListener(this); - context.create(waitFor); - } - - /** - * Sets an AppProfiler hook that will be called back for - * specific steps within a single update frame. Value defaults - * to null. - * - * @param prof the profiler to use (alias created) or null for none - */ - @Override - public void setAppProfiler(AppProfiler prof) { - this.prof = prof; - if (renderManager != null) { - renderManager.setAppProfiler(prof); - } - } - - /** - * Returns the current AppProfiler hook, or null if none is set. - */ - @Override - public AppProfiler getAppProfiler() { - return prof; - } - - /** - * Initializes the application's canvas for use. - *

- * After calling this method, cast the {@link #getContext()} context to - * JmeCanvasContext, - * then acquire the canvas with 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 Type#Canvas - */ - public void createCanvas() { - if (context != null && context.isCreated()) { - logger.warning("createCanvas() called when application already created!"); - return; - } - - if (settings == null) { - settings = new AppSettings(true); - } - - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "Starting application: {0}", getClass().getName()); - } - context = JmeSystem.newContext(settings, JmeContext.Type.Canvas); - 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. - */ - @Override - public void reshape(int w, int h) { - if (renderManager != null) { - renderManager.notifyReshape(w, h); - } - } - - - @Override - public void rescale(float x, float y){ - if (renderManager != null) { - renderManager.notifyRescale(x, y); - } - } - - /** - * 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. - */ - @Override - 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) - */ - @Override - public void stop() { - stop(false); - } - - /** - * 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. - * - * @param waitFor true→wait for the context to be fully destroyed, - * true→don't wait - */ - @Override - public void stop(boolean waitFor) { - logger.log(Level.FINE, "Closing application: {0}", getClass().getName()); - context.destroy(waitFor); - } - - /** - * 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; - * perspective projection with 45° field of view, with near - * and far values 1 and 1000 units respectively. - */ - @Override - public void initialize() { - if (assetManager == null) { - initAssetManager(); - } - - initDisplay(); - initCamera(); - - if (inputEnabled) { - initInput(); - } - initAudio(); - - // update timer so that the next delta is not too large -// timer.update(); - timer.reset(); - - // user code here - } - - /** - * Internal use only. - */ - @Override - public void handleError(String errMsg, Throwable t) { - // Print error to log. - logger.log(Level.SEVERE, errMsg, t); - // Display error message on screen if not in headless mode - if (context.getType() != JmeContext.Type.Headless) { - if (t != null) { - JmeSystem.handleErrorMessage(errMsg + "\n" + t.getClass().getSimpleName() - + (t.getMessage() != null ? ": " + t.getMessage() : "")); - } else { - JmeSystem.handleErrorMessage(errMsg); - } - } - - stop(); // stop the application - } - - /** - * Internal use only. - */ - @Override - public void gainFocus() { - if (lostFocusBehavior != LostFocusBehavior.Disabled) { - if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { - paused = false; - } - context.setAutoFlushFrames(true); - if (inputManager != null) { - inputManager.reset(); - } - } - } - - /** - * Internal use only. - */ - @Override - public void loseFocus() { - if (lostFocusBehavior != LostFocusBehavior.Disabled) { - if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { - paused = true; - } - context.setAutoFlushFrames(false); - } - } - - /** - * Internal use only. - */ - @Override - public void requestClose(boolean esc) { - context.destroy(false); - } - - /** - * Enqueues a task/callable object to execute in the jME3 - * rendering thread. - *

- * Callables are executed right at the beginning of the main loop. - * They are executed even if the application is currently paused - * or out of focus. - * - * @param type of result returned by the Callable - * @param callable The callable to run in the main jME3 thread - * @return a new instance - */ - @Override - public Future enqueue(Callable callable) { - AppTask task = new AppTask<>(callable); - taskQueue.add(task); - return task; - } - - /** - * Enqueues a runnable object to execute in the jME3 - * rendering thread. - *

- * Runnables are executed right at the beginning of the main loop. - * They are executed even if the application is currently paused - * or out of focus. - * - * @param runnable The runnable to run in the main jME3 thread - */ - @Override - @SuppressWarnings("unchecked") - public void enqueue(Runnable runnable) { - enqueue(new RunnableWrapper(runnable)); - } - - /** - * Runs tasks enqueued via {@link #enqueue(Callable)} - */ - protected void runQueuedTasks() { - AppTask task; - while ((task = taskQueue.poll()) != null) { - if (!task.isCancelled()) { - task.invoke(); - } - } - } - - /** - * Do not call manually. - * Callback from ContextListener. - */ - @Override - public void update() { - // Make sure the audio renderer is available to callables - AudioContext.setAudioRenderer(audioRenderer); - - if (prof != null) - prof.appStep(AppStep.QueuedTasks); - runQueuedTasks(); - - if (speed == 0 || paused) - return; - - timer.update(); - - if (inputEnabled) { - if (prof != null) - prof.appStep(AppStep.ProcessInput); - inputManager.update(timer.getTimePerFrame()); - } - - if (audioRenderer != null) { - if (prof != null) - prof.appStep(AppStep.ProcessAudio); - audioRenderer.update(timer.getTimePerFrame()); - } - - // user code here - } - - protected void destroyInput() { - if (mouseInput != null) - mouseInput.destroy(); - - if (keyInput != null) - keyInput.destroy(); - - if (joyInput != null) - joyInput.destroy(); - - if (touchInput != null) - touchInput.destroy(); - - inputManager = null; - } - - /** - * Do not call manually. - * Callback from ContextListener. - */ - @Override - public void destroy() { - stateManager.cleanup(); - + } + } + if (assetCfgUrl == null) { + assetCfgUrl = JmeSystem.getPlatformAssetConfigURL(); + } + if (assetManager == null) { + assetManager = JmeSystem.newAssetManager(assetCfgUrl); + } + } + + /** + * Set the display settings to define the display created. + *

+ * Examples of display parameters include display pixel width and height, color bit depth, + * z-buffer bits, anti-aliasing samples, and update frequency. If this method is called while the + * application is already running, then {@link #restart() } must be called to apply the settings + * to the display. + * + * @param settings The settings to set. + */ + @Override + public void setSettings(AppSettings settings) { + this.settings = settings; + if (context != null && settings.useInput() != inputEnabled) { + // may need to create or destroy input based + // on settings change + inputEnabled = !inputEnabled; + if (inputEnabled) { + initInput(); + } else { destroyInput(); - if (audioRenderer != null) - audioRenderer.cleanup(); - - timer.reset(); + } + } else { + inputEnabled = settings.useInput(); } + } - /** - * @return The GUI viewport. Which is used for the on screen - * statistics and FPS. - */ - @Override - public ViewPort getGuiViewPort() { - return guiViewPort; - } + /** + * Sets the Timer implementation that will be used for calculating frame times. By default, + * Application will use the Timer as returned by the current JmeContext implementation. + */ + @Override + public void setTimer(Timer timer) { + this.timer = timer; - @Override - public ViewPort getViewPort() { - return viewPort; + if (timer != null) { + timer.reset(); } - private class RunnableWrapper implements Callable { - private final Runnable runnable; + if (renderManager != null) { + renderManager.setTimer(timer); + } + } - public RunnableWrapper(Runnable runnable) { - this.runnable = runnable; - } + @Override + public Timer getTimer() { + return timer; + } + + private void initDisplay() { + // acquire important objects + // from the context + settings = context.getSettings(); + + // Only reset the timer if a user has not already provided one + if (timer == null) { + timer = context.getTimer(); + } + + renderer = context.getRenderer(); + } + + private void initAudio() { + if (settings.getAudioRenderer() != null && context.getType() != Type.Headless) { + audioRenderer = JmeSystem.newAudioRenderer(settings); + audioRenderer.initialize(); + AudioContext.setAudioRenderer(audioRenderer); + + listener = new Listener(); + audioRenderer.setListener(listener); + } + } + + /** + * Creates the camera to use for rendering. Default values are perspective projection with 45° + * field of view, with near and far values 1 and 1000 units respectively. + */ + private void initCamera() { + cam = new Camera(settings.getWidth(), settings.getHeight()); + + cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 1f, 1000f); + cam.setLocation(new Vector3f(0f, 0f, 10f)); + cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); + + renderManager = new RenderManager(renderer); + // Remy - 09/14/2010 set the timer in the renderManager + renderManager.setTimer(timer); + + if (prof != null) { + renderManager.setAppProfiler(prof); + } + + viewPort = renderManager.createMainView("Default", cam); + viewPort.setClearFlags(true, true, true); + + // Create a new cam for the gui + Camera guiCam = new Camera(settings.getWidth(), settings.getHeight()); + guiViewPort = renderManager.createPostView("Gui Default", guiCam); + guiViewPort.setClearFlags(false, false, false); + } + + /** + * Initializes mouse and keyboard input. Also initializes joystick input if joysticks are enabled + * in the AppSettings. + */ + private void initInput() { + mouseInput = context.getMouseInput(); + if (mouseInput != null) + mouseInput.initialize(); + + keyInput = context.getKeyInput(); + if (keyInput != null) + keyInput.initialize(); + + touchInput = context.getTouchInput(); + if (touchInput != null) + touchInput.initialize(); + + if (settings.useJoysticks()) { + joyInput = context.getJoyInput(); + if (joyInput != null) + joyInput.initialize(); + } + + inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput); + } + + private void initStateManager() { + stateManager = new AppStateManager(this); + + // Always register a ResetStatsState to make sure + // that the stats are cleared every frame + stateManager.attach(new ResetStatsState()); + } + + /** + * @return The {@link AssetManager asset manager} for this application. + */ + @Override + public AssetManager getAssetManager() { + return assetManager; + } + + /** + * @return the {@link InputManager input manager}. + */ + @Override + public InputManager getInputManager() { + return inputManager; + } + + /** + * @return the {@link AppStateManager app state manager} + */ + @Override + public AppStateManager getStateManager() { + return stateManager; + } + + /** + * @return the {@link RenderManager render manager} + */ + @Override + public RenderManager getRenderManager() { + return renderManager; + } + + /** + * @return The {@link Renderer renderer} for the application + */ + @Override + public Renderer getRenderer() { + return renderer; + } + + /** + * @return The {@link AudioRenderer audio renderer} for the application + */ + @Override + public AudioRenderer getAudioRenderer() { + return audioRenderer; + } + + /** + * @return The {@link Listener listener} object for audio + */ + @Override + public Listener getListener() { + return listener; + } + + /** + * @return The {@link JmeContext display context} for the application + */ + @Override + public JmeContext getContext() { + return context; + } + + /** + * @return The {@link Camera camera} for the application + */ + @Override + public Camera getCamera() { + return cam; + } + + /** + * Starts the application in {@link Type#Display display} mode. + * + * @see #start(com.jme3.system.JmeContext.Type) + */ + @Override + public void start() { + start(JmeContext.Type.Display, false); + } + + /** + * Starts the application in {@link Type#Display display} mode. + * + * @param waitFor true→wait for the context to be initialized, false→don't wait + * @see #start(com.jme3.system.JmeContext.Type) + */ + @Override + public void start(boolean waitFor) { + start(JmeContext.Type.Display, waitFor); + } + + /** + * Starts the application. Creating a rendering context and executing the main loop in a separate + * thread. + * + * @param contextType the type of context to create + */ + public void start(JmeContext.Type contextType) { + start(contextType, false); + } + + /** + * Starts the application. Creating a rendering context and executing the main loop in a separate + * thread. + * + * @param contextType the type of context to create + * @param waitFor true→wait for the context to be initialized, false→don't wait + */ + public void start(JmeContext.Type contextType, boolean waitFor) { + if (context != null && context.isCreated()) { + logger.warning("start() called when application already created!"); + return; + } + + if (settings == null) { + settings = new AppSettings(true); + } + + logger.log(Level.FINE, "Starting application: {0}", getClass().getName()); + context = JmeSystem.newContext(settings, contextType); + context.setSystemListener(this); + context.create(waitFor); + } + + /** + * Sets an AppProfiler hook that will be called back for specific steps within a single update + * frame. Value defaults to null. + * + * @param prof the profiler to use (alias created) or null for none + */ + @Override + public void setAppProfiler(AppProfiler prof) { + this.prof = prof; + if (renderManager != null) { + renderManager.setAppProfiler(prof); + } + } + + /** + * Returns the current AppProfiler hook, or null if none is set. + */ + @Override + public AppProfiler getAppProfiler() { + return prof; + } + + /** + * Initializes the application's canvas for use. + *

+ * After calling this method, cast the {@link #getContext()} context to JmeCanvasContext, then + * acquire the canvas with 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 Type#Canvas + */ + public void createCanvas() { + if (context != null && context.isCreated()) { + logger.warning("createCanvas() called when application already created!"); + return; + } + + if (settings == null) { + settings = new AppSettings(true); + } + + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, "Starting application: {0}", getClass().getName()); + } + context = JmeSystem.newContext(settings, JmeContext.Type.Canvas); + 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. + */ + @Override + public void reshape(int w, int h) { + if (renderManager != null) { + renderManager.notifyReshape(w, h); + } + } + + + @Override + public void rescale(float x, float y) { + if (renderManager != null) { + renderManager.notifyRescale(x, y); + } + } + + /** + * 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. + */ + @Override + 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) + */ + @Override + public void stop() { + stop(false); + } + + /** + * 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. + * + * @param waitFor true→wait for the context to be fully destroyed, true→don't wait + */ + @Override + public void stop(boolean waitFor) { + logger.log(Level.FINE, "Closing application: {0}", getClass().getName()); + context.destroy(waitFor); + } + + /** + * 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; perspective projection with 45° field of view, with near and far values 1 and 1000 + * units respectively. + */ + @Override + public void initialize() { + if (assetManager == null) { + initAssetManager(); + } + + initDisplay(); + initCamera(); + + if (inputEnabled) { + initInput(); + } + initAudio(); + + // update timer so that the next delta is not too large + // timer.update(); + timer.reset(); + + // user code here + } + + /** + * Internal use only. + */ + @Override + public void handleError(String errMsg, Throwable t) { + // Print error to log. + logger.log(Level.SEVERE, errMsg, t); + // Display error message on screen if not in headless mode + if (context.getType() != JmeContext.Type.Headless) { + if (t != null) { + JmeSystem.handleErrorMessage(errMsg + "\n" + t.getClass().getSimpleName() + + (t.getMessage() != null ? ": " + t.getMessage() : "")); + } else { + JmeSystem.handleErrorMessage(errMsg); + } + } + + stop(); // stop the application + } + + /** + * Internal use only. + */ + @Override + public void gainFocus() { + if (lostFocusBehavior != LostFocusBehavior.Disabled) { + if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { + paused = false; + } + context.setAutoFlushFrames(true); + if (inputManager != null) { + inputManager.reset(); + } + } + } + + /** + * Internal use only. + */ + @Override + public void loseFocus() { + if (lostFocusBehavior != LostFocusBehavior.Disabled) { + if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { + paused = true; + } + context.setAutoFlushFrames(false); + } + } + + /** + * Internal use only. + */ + @Override + public void requestClose(boolean esc) { + context.destroy(false); + } + + /** + * Enqueues a task/callable object to execute in the jME3 rendering thread. + *

+ * Callables are executed right at the beginning of the main loop. They are executed even if the + * application is currently paused or out of focus. + * + * @param type of result returned by the Callable + * @param callable The callable to run in the main jME3 thread + * @return a new instance + */ + @Override + public Future enqueue(Callable callable) { + AppTask task = new AppTask<>(callable); + taskQueue.add(task); + return task; + } + + /** + * Enqueues a runnable object to execute in the jME3 rendering thread. + *

+ * Runnables are executed right at the beginning of the main loop. They are executed even if the + * application is currently paused or out of focus. + * + * @param runnable The runnable to run in the main jME3 thread + */ + @Override + @SuppressWarnings("unchecked") + public void enqueue(Runnable runnable) { + enqueue(new RunnableWrapper(runnable)); + } + + /** + * Runs tasks enqueued via {@link #enqueue(Callable)} + */ + protected void runQueuedTasks() { + AppTask task; + while ((task = taskQueue.poll()) != null) { + if (!task.isCancelled()) { + task.invoke(); + } + } + } + + /** + * Do not call manually. Callback from ContextListener. + */ + @Override + public void update() { + // Make sure the audio renderer is available to callables + AudioContext.setAudioRenderer(audioRenderer); + + if (prof != null) + prof.appStep(AppStep.QueuedTasks); + runQueuedTasks(); + + if (speed == 0 || paused) + return; + + timer.update(); + + if (inputEnabled) { + if (prof != null) + prof.appStep(AppStep.ProcessInput); + inputManager.update(timer.getTimePerFrame()); + } + + if (audioRenderer != null) { + if (prof != null) + prof.appStep(AppStep.ProcessAudio); + audioRenderer.update(timer.getTimePerFrame()); + } + + // user code here + } + + protected void destroyInput() { + if (mouseInput != null) + mouseInput.destroy(); + + if (keyInput != null) + keyInput.destroy(); + + if (joyInput != null) + joyInput.destroy(); + + if (touchInput != null) + touchInput.destroy(); + + inputManager = null; + } + + /** + * Do not call manually. Callback from ContextListener. + */ + @Override + public void destroy() { + stateManager.cleanup(); + + destroyInput(); + if (audioRenderer != null) + audioRenderer.cleanup(); + + timer.reset(); + } + + /** + * @return The GUI viewport. Which is used for the on screen statistics and FPS. + */ + @Override + public ViewPort getGuiViewPort() { + return guiViewPort; + } + + @Override + public ViewPort getViewPort() { + return viewPort; + } + + private class RunnableWrapper implements Callable { + private final Runnable runnable; + + public RunnableWrapper(Runnable runnable) { + this.runnable = runnable; + } + + @Override + public Object call() { + runnable.run(); + return null; + } + } + + /** + * This call will return a list of Monitors that glfwGetMonitors() returns and information about + * the monitor, like width, height, and refresh rate. + * + * @return returns a list of monitors and their information. + */ + public Monitors getMonitors() { + return context.getMonitors(); + } - @Override - public Object call() { - runnable.run(); - return null; - } - } - - /** - * This call will return a list of Monitors that glfwGetMonitors() - * returns and information about the monitor, like width, height, - * and refresh rate. - * - * @return returns a list of monitors and their information. - */ - public Monitors getMonitors() - { - return context.getMonitors(); - } - - /** - * Use this to get the positional number of the primary - * monitor from the glfwGetMonitors() function call. - * - * @return the position of the value in the arraylist of - * the primary monitor. - */ - public int getPrimaryMonitor() - { - return context.getPrimaryMonitor(); - } + /** + * Use this to get the positional number of the primary monitor from the glfwGetMonitors() + * function call. + * + * @return the position of the value in the arraylist of the primary monitor. + */ + public int getPrimaryMonitor() { + return context.getPrimaryMonitor(); + } } diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java index c5509301ac..cfa98ec41e 100644 --- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java +++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java @@ -1485,27 +1485,29 @@ public void setWindowYPosition(int pos) { /** * Gets the monitor number used when creating a window. * - *

This setting is used only with LWJGL3, it defines which monitor - * to use when creating a OpenGL window. + *

+ * This setting is used only with LWJGL3, it defines which monitor to use when creating a OpenGL + * window. * * @return the desired monitor used when creating a OpenGL window * @see #setMonitor(long) */ public int getMonitor() { - return getInteger("Monitor"); + return getInteger("Monitor"); } /** - * Sets the monitor number used when creating a window. The position - * number is the number in the list of monitors GlfwGetMonitors returns. + * Sets the monitor number used when creating a window. The position number is the number in the + * list of monitors GlfwGetMonitors returns. * - *

This setting is used only with LWJGL3, it defines which monitor - * to use when creating a OpenGL window. its default value is 0. + *

+ * This setting is used only with LWJGL3, it defines which monitor to use when creating a OpenGL + * window. its default value is 0. * * @param mon the desired monitor used when creating a OpenGL window * */ public void setMonitor(int mon) { - putInteger("Monitor", mon); + putInteger("Monitor", mon); } -} + } diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index 59d7cdbb05..258639634f 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -227,20 +227,18 @@ public enum Type { public int getWindowYPosition(); /** - * This call will return a list of Monitors that glfwGetMonitors() - * returns and information about the monitor, like width, height, - * and refresh rate. + * This call will return a list of Monitors that glfwGetMonitors() returns and information about + * the monitor, like width, height, and refresh rate. * * @return returns a list of monitors and their information. */ public Monitors getMonitors(); /** - * Use this to get the positional number of the primary - * monitor from the glfwGetMonitors() function call. + * Use this to get the positional number of the primary monitor from the glfwGetMonitors() + * function call. * - * @return the position of the value in the arraylist of - * the primary monitor. - */ + * @return the position of the value in the arraylist of the primary monitor. + */ public int getPrimaryMonitor(); -} + } diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java index 64864fb70e..a7791d37b2 100644 --- a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java @@ -1,73 +1,66 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine - * All rights reserved. + * Copyright (c) 2009-2023 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: + * 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 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. + * * 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. + * * 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. + * 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. */ package com.jme3.system; /** - * This class holds information about the monitor that was - * returned by glfwGetMonitors() calls in the context - * class + * This class holds information about the monitor that was returned by glfwGetMonitors() calls in + * the context class * * @author Kevin Bales */ public class MonitorInfo { - - /** - * monitorID - monitor id that was return from Lwjgl3. - */ - public long monitorID = 0; - /** - * width - width that was return from Lwjgl3. - */ - public int width = 1080; + /** + * monitorID - monitor id that was return from Lwjgl3. + */ + public long monitorID = 0; - /** - * height - height that was return from Lwjgl3. - */ - public int height = 1920; + /** + * width - width that was return from Lwjgl3. + */ + public int width = 1080; - /** - * rate - refresh rate that was return from Lwjgl3. - */ - public int rate = 60; - - /** - * primary - indicates if the monitor is the primary monitor. - */ - public boolean primary = false; - - /** - * name - monitor name that was return from Lwjgl3. - */ - public String name = "Generic Monitor"; + /** + * height - height that was return from Lwjgl3. + */ + public int height = 1920; + + /** + * rate - refresh rate that was return from Lwjgl3. + */ + public int rate = 60; + + /** + * primary - indicates if the monitor is the primary monitor. + */ + public boolean primary = false; + + /** + * name - monitor name that was return from Lwjgl3. + */ + public String name = "Generic Monitor"; } diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java index 61a874d201..b834e518f8 100644 --- a/jme3-core/src/main/java/com/jme3/system/Monitors.java +++ b/jme3-core/src/main/java/com/jme3/system/Monitors.java @@ -1,119 +1,105 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine - * All rights reserved. + * Copyright (c) 2009-2023 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: + * 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 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. + * * 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. + * * 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. + * 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. */ package com.jme3.system; import java.util.ArrayList; /** - * This class holds all information about all monitors that where - * return from the glfwGetMonitors() call. It stores them into - * an + * This class holds all information about all monitors that where return from the glfwGetMonitors() + * call. It stores them into an * * @author Kevin Bales */ public class Monitors { - private ArrayList monitors = new ArrayList(); - - public int addNewMonitor(long monitorID) - { - MonitorInfo info = new MonitorInfo(); - info.monitorID = monitorID; - monitors.add(info); - return monitors.size() - 1; - } - - /** - * This function returns the size of the monitor ArrayList - * @return the - */ - public int size() - { - return monitors.size(); - } - - /** - * Call to get monitor information on a certain monitor. - * - * @param pos the position in the arraylist of the monitor - * information that you want to get. - * @return returns the MonitorInfo data for the monitor - * called for. - */ - public MonitorInfo get(int pos) - { - if (pos < monitors.size()) - return monitors.get(pos); - - return null; - } + private ArrayList monitors = new ArrayList(); - /** - * Set information about this monitor stored in monPos position - * in the array list. - * - * @param monPos arraylist position of monitor to update - * @param width the current width the monitor is displaying - * @param height the current height the monitor is displaying - * @param rate the current refresh rate the monitor is set to - */ - public void setInfo(int monPos, String name, int width, int height, int rate) { - if (monPos < monitors.size() ) { - MonitorInfo info = monitors.get(monPos); - if (info != null) { - info.width = width; - info.height = height; - info.rate = rate; - info.name = name; - } - } - } + public int addNewMonitor(long monitorID) { + MonitorInfo info = new MonitorInfo(); + info.monitorID = monitorID; + monitors.add(info); + return monitors.size() - 1; + } + + /** + * This function returns the size of the monitor ArrayList + * + * @return the + */ + public int size() { + return monitors.size(); + } + + /** + * Call to get monitor information on a certain monitor. + * + * @param pos the position in the arraylist of the monitor information that you want to get. + * @return returns the MonitorInfo data for the monitor called for. + */ + public MonitorInfo get(int pos) { + if (pos < monitors.size()) + return monitors.get(pos); + + return null; + } - /** - * This function will mark a certain monitor as the - * primary monitor. - * - * @param monPos the position in the arraylist of which - * monitor is the primary monitor - */ - public void setPrimaryMonitor(int monPos) { - if (monPos < monitors.size() ) { - MonitorInfo info = monitors.get(monPos); - if (info != null) - info.primary = true; + /** + * Set information about this monitor stored in monPos position in the array list. + * + * @param monPos arraylist position of monitor to update + * @param width the current width the monitor is displaying + * @param height the current height the monitor is displaying + * @param rate the current refresh rate the monitor is set to + */ + public void setInfo(int monPos, String name, int width, int height, int rate) { + if (monPos < monitors.size()) { + MonitorInfo info = monitors.get(monPos); + if (info != null) { + info.width = width; + info.height = height; + info.rate = rate; + info.name = name; } - - } - - + } + } + + /** + * This function will mark a certain monitor as the primary monitor. + * + * @param monPos the position in the arraylist of which monitor is the primary monitor + */ + public void setPrimaryMonitor(int monPos) { + if (monPos < monitors.size()) { + MonitorInfo info = monitors.get(monPos); + if (info != null) + info.primary = true; + } + + } + + } diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index f0eccdc112..e58f143b45 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -307,15 +307,15 @@ public int getWindowYPosition() { throw new UnsupportedOperationException("null context"); } - @Override - public Monitors getMonitors() { + @Override + public Monitors getMonitors() { // TODO Auto-generated method stub return null; - } + } - @Override - public int getPrimaryMonitor() { + @Override + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; - } + } } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index 23a46c8930..afb8003fcd 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -329,15 +329,15 @@ public int getWindowYPosition() { return inputSource.getY(); } - @Override - public Monitors getMonitors() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryMonitor() { - // TODO Auto-generated method stub - return 0; - } + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index f673c22afc..bf3b837fdd 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -53,199 +53,188 @@ import com.jme3.system.Monitors; /** - * Tests the capability to change which monitor the window - * will be created on. Also, shows that you can force - * JME to center the window. Also, it shows to to force JME to - * set the window to x,y coords. Center window and window - * position doesn't apply if in fullscreen. + * Tests the capability to change which monitor the window will be created on. + * Also, shows that you can force JME to center the window. Also, it shows to to + * force JME to set the window to x,y coords. Center window and window position + * doesn't apply if in fullscreen. * * @author Kevin Bales */ -public class TestMonitorApp extends SimpleApplication implements ActionListener { - - private BitmapText txt; - private BitmapText selectedMonitorTxt; - private BitmapText fullScreenTxt; - private int monitorSelected = 0; - private Monitors monitors = null; - - public static void main(String[] args){ - TestMonitorApp app = new TestMonitorApp(); - AppSettings settings = new AppSettings(true); - settings.setResizable(false); - app.setShowSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL33); - settings.setMonitor(0); - settings.setResolution(800, 600); - - settings.setFullscreen(true); - - //Force JME to center the window, this only applies if it is - //not fullscreen. - settings.setCenterWindow(true); - - //If center window is not turned on, you can force JME to - //open the window at certain x,y coords. These are ignored - //if the screen is set to "fullscreen". - settings.setWindowXPosition(0); - settings.setWindowYPosition(0); - - try - { - //Let's try and load the AppSetting parameters back into memory - InputStream out = new FileInputStream("TestMonitorApp.prefs"); - settings.load(out); - } - catch (IOException e) - { - System.out.println("failed to load settings, reverting to defaults"); - } - app.setSettings(settings); - - app.start(); - } - - - @Override - public void simpleInitApp() { - flyCam.setDragToRotate(true); - int numMonitors = 1; - - //If monitor is define, Jme supports multiple monitors. Setup to keys - if (monitors == null) { - inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("fullscreen", new KeyTrigger(KeyInput.KEY_F)); - inputManager.addListener(this, "down", "fullscreen"); - } - - //Get the selected monitor - monitorSelected = settings.getMonitor(); - monitors = context.getMonitors(); - if (monitors != null) - numMonitors = monitors.size(); - - - - //Let's define the labels for users to see what is going on with Multiple Monitor - String labelValue = ""; - labelValue = "There are "+numMonitors+" monitor(s) hooked up to this computer."; - txt = new BitmapText(loadGuiFont()); - txt.setText(labelValue); - txt.setLocalTranslation(0, settings.getHeight(), 0); - guiNode.attachChild(txt); - - txt = new BitmapText(loadGuiFont()); - if (!settings.isFullscreen()) - txt.setText("Window is on Monitor N/A (fullscreen only feature)"); - else - txt.setText("Window is on Monitor "+settings.getMonitor()); - - txt.setLocalTranslation(0, settings.getHeight() - 40, 0); - guiNode.attachChild(txt); - - if (monitors != null) { - selectedMonitorTxt = new BitmapText(loadGuiFont()); - //Lets display information about selected monitor - String label = "Selected Monitor "+ - "Name: "+monitors.get(settings.getMonitor()).name+" "+ - monitorSelected+ " Res: " + - monitors.get(settings.getMonitor()).width+","+ - monitors.get(settings.getMonitor()).height + - " refresh: "+monitors.get(settings.getMonitor()).rate; - selectedMonitorTxt.setText(label); - selectedMonitorTxt.setLocalTranslation(0, settings.getHeight() - 80, 0); - guiNode.attachChild(selectedMonitorTxt); - - //Let's loop through all the monitors and display on the screen - for(int i = 0; i < monitors.size(); i++) { - MonitorInfo monitor = monitors.get(i); - labelValue = "Mon : "+i+" "+monitor.name+" " + monitor.width +","+ monitor.height +" refresh: "+ monitor.rate; - txt = new BitmapText(loadGuiFont()); - txt.setText(labelValue); - txt.setLocalTranslation(0, settings.getHeight() - 160 - (40*i), 0); - guiNode.attachChild(txt); - } - } - - //Lets put a label up there for FullScreen/Window toggle - fullScreenTxt = new BitmapText(loadGuiFont()); - if (!settings.isFullscreen()) - fullScreenTxt.setText("(f) Window Screen"); - else - fullScreenTxt.setText("(f) Fullscreen"); - - fullScreenTxt.setLocalTranslation(00, settings.getHeight() - 240, 0); - guiNode.attachChild(fullScreenTxt); - - BitmapText infoTxt = new BitmapText(loadGuiFont()); - infoTxt.setText("Restart is required to activate changes in settings."); - infoTxt.setLocalTranslation(0, settings.getHeight() - 300, 0); - guiNode.attachChild(infoTxt); - - - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { +public class TestMonitorApp extends SimpleApplication + implements ActionListener { + + private BitmapText txt; + private BitmapText selectedMonitorTxt; + private BitmapText fullScreenTxt; + private int monitorSelected = 0; + private Monitors monitors = null; + + public static void main(String[] args) { + TestMonitorApp app = new TestMonitorApp(); + AppSettings settings = new AppSettings(true); + settings.setResizable(false); + app.setShowSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL33); + settings.setMonitor(0); + settings.setResolution(800, 600); + + settings.setFullscreen(true); + + // Force JME to center the window, this only applies if it is + // not fullscreen. + settings.setCenterWindow(true); + + // If center window is not turned on, you can force JME to + // open the window at certain x,y coords. These are ignored + // if the screen is set to "fullscreen". + settings.setWindowXPosition(0); + settings.setWindowYPosition(0); + + try { + // Let's try and load the AppSetting parameters back into memory + InputStream out = new FileInputStream("TestMonitorApp.prefs"); + settings.load(out); + } catch (IOException e) { + System.out.println("failed to load settings, reverting to defaults"); + } + app.setSettings(settings); + + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setDragToRotate(true); + int numMonitors = 1; + + // If monitor is define, Jme supports multiple monitors. Setup to keys + if (monitors == null) { + inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("fullscreen", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addListener(this, "down", "fullscreen"); + } + + // Get the selected monitor + monitorSelected = settings.getMonitor(); + monitors = context.getMonitors(); + if (monitors != null) + numMonitors = monitors.size(); + + // Let's define the labels for users to see what is going on with Multiple + // Monitor + String labelValue = ""; + labelValue = "There are " + numMonitors + + " monitor(s) hooked up to this computer."; + txt = new BitmapText(loadGuiFont()); + txt.setText(labelValue); + txt.setLocalTranslation(0, settings.getHeight(), 0); + guiNode.attachChild(txt); + + txt = new BitmapText(loadGuiFont()); + if (!settings.isFullscreen()) + txt.setText("Window is on Monitor N/A (fullscreen only feature)"); + else + txt.setText("Window is on Monitor " + settings.getMonitor()); + + txt.setLocalTranslation(0, settings.getHeight() - 40, 0); + guiNode.attachChild(txt); + + if (monitors != null) { + selectedMonitorTxt = new BitmapText(loadGuiFont()); + // Lets display information about selected monitor + String label = "Selected Monitor " + "Name: " + + monitors.get(settings.getMonitor()).name + " " + + monitorSelected + " Res: " + + monitors.get(settings.getMonitor()).width + "," + + monitors.get(settings.getMonitor()).height + " refresh: " + + monitors.get(settings.getMonitor()).rate; + selectedMonitorTxt.setText(label); + selectedMonitorTxt.setLocalTranslation(0, settings.getHeight() - 80, + 0); + guiNode.attachChild(selectedMonitorTxt); + + // Let's loop through all the monitors and display on the screen + for (int i = 0; i < monitors.size(); i++) { + MonitorInfo monitor = monitors.get(i); + labelValue = "Mon : " + i + " " + monitor.name + " " + monitor.width + + "," + monitor.height + " refresh: " + monitor.rate; + txt = new BitmapText(loadGuiFont()); + txt.setText(labelValue); + txt.setLocalTranslation(0, settings.getHeight() - 160 - (40 * i), + 0); + guiNode.attachChild(txt); + } + } + + // Lets put a label up there for FullScreen/Window toggle + fullScreenTxt = new BitmapText(loadGuiFont()); + if (!settings.isFullscreen()) + fullScreenTxt.setText("(f) Window Screen"); + else + fullScreenTxt.setText("(f) Fullscreen"); + + fullScreenTxt.setLocalTranslation(00, settings.getHeight() - 240, 0); + guiNode.attachChild(fullScreenTxt); + + BitmapText infoTxt = new BitmapText(loadGuiFont()); + infoTxt.setText("Restart is required to activate changes in settings."); + infoTxt.setLocalTranslation(0, settings.getHeight() - 300, 0); + guiNode.attachChild(infoTxt); + + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { if (monitors == null) return; - + if (name.equals("down") && isPressed) { monitorSelected++; if (monitorSelected >= monitors.size()) monitorSelected = 0; saveSettings(); - } - else if (name.equals("up") && isPressed) { + } else if (name.equals("up") && isPressed) { monitorSelected--; if (monitorSelected < 0) - monitorSelected = monitors.size()-1; + monitorSelected = monitors.size() - 1; saveSettings(); - } - else if (name.equals("fullscreen") && isPressed) { + } else if (name.equals("fullscreen") && isPressed) { settings.setFullscreen(!settings.isFullscreen()); saveSettings(); - } + } } - - /** - * This function saves out the AppSettings into a file to be loaded back in - * on start of application. - */ - public void saveSettings() - { - - try - { - settings.setMonitor(monitorSelected); - OutputStream out = new FileOutputStream("TestMonitorApp.prefs"); - settings.save(out); - - int monitorSelected = settings.getMonitor(); - String label = "Selected Monitor "+ monitorSelected+ - " "+ monitors.get(monitorSelected).name+ - " Res: " +monitors.get(monitorSelected).width+","+ - monitors.get(monitorSelected).height + - "refresh: "+monitors.get(monitorSelected).rate; - selectedMonitorTxt.setText(label); - if (!settings.isFullscreen()) - fullScreenTxt.setText("(f) Window Screen"); - else - fullScreenTxt.setText("(f) Fullscreen"); - } - catch (FileNotFoundException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - catch (IOException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + /** + * This function saves out the AppSettings into a file to be loaded back in + * on start of application. + */ + public void saveSettings() { + + try { + settings.setMonitor(monitorSelected); + OutputStream out = new FileOutputStream("TestMonitorApp.prefs"); + settings.save(out); + + int monitorSelected = settings.getMonitor(); + String label = "Selected Monitor " + monitorSelected + " " + + monitors.get(monitorSelected).name + " Res: " + + monitors.get(monitorSelected).width + "," + + monitors.get(monitorSelected).height + "refresh: " + + monitors.get(monitorSelected).rate; + selectedMonitorTxt.setText(label); + if (!settings.isFullscreen()) + fullScreenTxt.setText("(f) Window Screen"); + else + fullScreenTxt.setText("(f) Fullscreen"); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index d19a18c44a..2a18b56569 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -268,17 +268,15 @@ public int getWindowYPosition() { throw new UnsupportedOperationException("not implemented yet"); } - @Override - public Monitors getMonitors() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryMonitor() - { - // TODO Auto-generated method stub - return 0; - } + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 17d0b9bd6c..7728c11257 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -1,33 +1,27 @@ /* - * Copyright (c) 2009-2021 jMonkeyEngine - * All rights reserved. + * Copyright (c) 2009-2021 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: + * 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 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. + * * 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. + * * 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. + * 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. */ package com.jme3.system.lwjgl; @@ -51,470 +45,453 @@ public class LwjglCanvas extends LwjglAbstractDisplay implements JmeCanvasContext { - protected static final int TASK_NOTHING = 0, - TASK_DESTROY_DISPLAY = 1, - TASK_CREATE_DISPLAY = 2, - TASK_COMPLETE = 3; - -// protected static final boolean USE_SHARED_CONTEXT = -// Boolean.parseBoolean(System.getProperty("jme3.canvas.sharedctx", "true")); - - protected static final boolean USE_SHARED_CONTEXT = false; - - private static final Logger logger = Logger.getLogger(LwjglDisplay.class.getName()); - private Canvas canvas; - private int width; - private int height; - - private final Object taskLock = new Object(); - private int desiredTask = TASK_NOTHING; - - private Thread renderThread; - private boolean runningFirstTime = true; - private boolean mouseWasGrabbed = false; - - private boolean mouseWasCreated = false; - private boolean keyboardWasCreated = false; - - private Pbuffer pbuffer; - private PixelFormat pbufferFormat; - private PixelFormat canvasFormat; - - private class GLCanvas extends Canvas { - @Override - public void addNotify(){ - super.addNotify(); - - if (renderThread != null && renderThread.getState() == Thread.State.TERMINATED) { - return; // already destroyed. - } - - if (renderThread == null){ - logger.log(Level.FINE, "EDT: Creating OGL thread."); - - // Also set some settings on the canvas here. - // So we don't do it outside the AWT thread. - canvas.setFocusable(true); - canvas.setIgnoreRepaint(true); - - renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); - renderThread.start(); - }else if (needClose.get()){ - return; - } - - logger.log(Level.FINE, "EDT: Telling OGL to create display .."); - synchronized (taskLock){ - desiredTask = TASK_CREATE_DISPLAY; -// while (desiredTask != TASK_COMPLETE){ -// try { -// taskLock.wait(); -// } catch (InterruptedException ex) { -// return; -// } -// } -// desiredTask = TASK_NOTHING; - } -// logger.log(Level.FINE, "EDT: OGL has created the display"); - } + protected static final int TASK_NOTHING = 0, TASK_DESTROY_DISPLAY = 1, TASK_CREATE_DISPLAY = 2, + TASK_COMPLETE = 3; - @Override - public void removeNotify(){ - if (needClose.get()){ - logger.log(Level.FINE, "EDT: Application is stopped. Not restoring canvas."); - super.removeNotify(); - return; - } - - // We must tell GL context to shut down and wait for it to - // shut down. Otherwise, issues will occur. - logger.log(Level.FINE, "EDT: Telling OGL to destroy display .."); - synchronized (taskLock){ - desiredTask = TASK_DESTROY_DISPLAY; - while (desiredTask != TASK_COMPLETE){ - try { - taskLock.wait(); - } catch (InterruptedException ex){ - super.removeNotify(); - return; - } - } - desiredTask = TASK_NOTHING; - } - - logger.log(Level.FINE, "EDT: Acknowledged receipt of canvas death"); - // GL context is dead at this point + // protected static final boolean USE_SHARED_CONTEXT = + // Boolean.parseBoolean(System.getProperty("jme3.canvas.sharedctx", "true")); - super.removeNotify(); - } - } + protected static final boolean USE_SHARED_CONTEXT = false; - public LwjglCanvas(){ - super(); - canvas = new GLCanvas(); - } + private static final Logger logger = Logger.getLogger(LwjglDisplay.class.getName()); + private Canvas canvas; + private int width; + private int height; - @Override - public Type getType() { - return Type.Canvas; - } + private final Object taskLock = new Object(); + private int desiredTask = TASK_NOTHING; - @Override - public void create(boolean waitFor){ - if (renderThread == null){ - logger.log(Level.FINE, "MAIN: Creating OGL thread."); + private Thread renderThread; + private boolean runningFirstTime = true; + private boolean mouseWasGrabbed = false; - renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); - renderThread.start(); - } - // do not do anything. - // superclass's create() will be called at initInThread() - if (waitFor) { - waitFor(true); - } - } + private boolean mouseWasCreated = false; + private boolean keyboardWasCreated = false; + + private Pbuffer pbuffer; + private PixelFormat pbufferFormat; + private PixelFormat canvasFormat; + private class GLCanvas extends Canvas { @Override - public void setTitle(String title) { + public void addNotify() { + super.addNotify(); + + if (renderThread != null && renderThread.getState() == Thread.State.TERMINATED) { + return; // already destroyed. + } + + if (renderThread == null) { + logger.log(Level.FINE, "EDT: Creating OGL thread."); + + // Also set some settings on the canvas here. + // So we don't do it outside the AWT thread. + canvas.setFocusable(true); + canvas.setIgnoreRepaint(true); + + renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); + renderThread.start(); + } else if (needClose.get()) { + return; + } + + logger.log(Level.FINE, "EDT: Telling OGL to create display .."); + synchronized (taskLock) { + desiredTask = TASK_CREATE_DISPLAY; + // while (desiredTask != TASK_COMPLETE){ + // try { + // taskLock.wait(); + // } catch (InterruptedException ex) { + // return; + // } + // } + // desiredTask = TASK_NOTHING; + } + // logger.log(Level.FINE, "EDT: OGL has created the display"); } @Override - public void restart() { - frameRate = settings.getFrameRate(); - // TODO: Handle other cases, like change of pixel format, etc. + public void removeNotify() { + if (needClose.get()) { + logger.log(Level.FINE, "EDT: Application is stopped. Not restoring canvas."); + super.removeNotify(); + return; + } + + // We must tell GL context to shut down and wait for it to + // shut down. Otherwise, issues will occur. + logger.log(Level.FINE, "EDT: Telling OGL to destroy display .."); + synchronized (taskLock) { + desiredTask = TASK_DESTROY_DISPLAY; + while (desiredTask != TASK_COMPLETE) { + try { + taskLock.wait(); + } catch (InterruptedException ex) { + super.removeNotify(); + return; + } + } + desiredTask = TASK_NOTHING; + } + + logger.log(Level.FINE, "EDT: Acknowledged receipt of canvas death"); + // GL context is dead at this point + + super.removeNotify(); } + } - @Override - public Canvas getCanvas(){ - return canvas; + public LwjglCanvas() { + super(); + canvas = new GLCanvas(); + } + + @Override + public Type getType() { + return Type.Canvas; + } + + @Override + public void create(boolean waitFor) { + if (renderThread == null) { + logger.log(Level.FINE, "MAIN: Creating OGL thread."); + + renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); + renderThread.start(); } - - @Override - protected void runLoop(){ - if (desiredTask != TASK_NOTHING){ - synchronized (taskLock){ - switch (desiredTask){ - case TASK_CREATE_DISPLAY: - logger.log(Level.FINE, "OGL: Creating display .."); - restoreCanvas(); - listener.gainFocus(); - desiredTask = TASK_NOTHING; - break; - case TASK_DESTROY_DISPLAY: - logger.log(Level.FINE, "OGL: Destroying display .."); - listener.loseFocus(); - pauseCanvas(); - break; - } - desiredTask = TASK_COMPLETE; - taskLock.notifyAll(); - } - } - - if (renderable.get()){ - int newWidth = Math.max(canvas.getWidth(), 1); - int newHeight = Math.max(canvas.getHeight(), 1); - if (width != newWidth || height != newHeight){ - width = newWidth; - height = newHeight; - if (listener != null){ - listener.reshape(width, height); - } - } - }else{ - if (frameRate <= 0){ - // NOTE: MUST be done otherwise - // Windows OS will freeze - Display.sync(30); - } + // do not do anything. + // superclass's create() will be called at initInThread() + if (waitFor) { + waitFor(true); + } + } + + @Override + public void setTitle(String title) {} + + @Override + public void restart() { + frameRate = settings.getFrameRate(); + // TODO: Handle other cases, like change of pixel format, etc. + } + + @Override + public Canvas getCanvas() { + return canvas; + } + + @Override + protected void runLoop() { + if (desiredTask != TASK_NOTHING) { + synchronized (taskLock) { + switch (desiredTask) { + case TASK_CREATE_DISPLAY: + logger.log(Level.FINE, "OGL: Creating display .."); + restoreCanvas(); + listener.gainFocus(); + desiredTask = TASK_NOTHING; + break; + case TASK_DESTROY_DISPLAY: + logger.log(Level.FINE, "OGL: Destroying display .."); + listener.loseFocus(); + pauseCanvas(); + break; } - - super.runLoop(); + desiredTask = TASK_COMPLETE; + taskLock.notifyAll(); + } } - private void pauseCanvas(){ - if (Mouse.isCreated()){ - if (Mouse.isGrabbed()){ - Mouse.setGrabbed(false); - mouseWasGrabbed = true; - } - mouseWasCreated = true; - Mouse.destroy(); - } - if (Keyboard.isCreated()){ - keyboardWasCreated = true; - Keyboard.destroy(); + if (renderable.get()) { + int newWidth = Math.max(canvas.getWidth(), 1); + int newHeight = Math.max(canvas.getHeight(), 1); + if (width != newWidth || height != newHeight) { + width = newWidth; + height = newHeight; + if (listener != null) { + listener.reshape(width, height); } + } + } else { + if (frameRate <= 0) { + // NOTE: MUST be done otherwise + // Windows OS will freeze + Display.sync(30); + } + } + + super.runLoop(); + } + + private void pauseCanvas() { + if (Mouse.isCreated()) { + if (Mouse.isGrabbed()) { + Mouse.setGrabbed(false); + mouseWasGrabbed = true; + } + mouseWasCreated = true; + Mouse.destroy(); + } + if (Keyboard.isCreated()) { + keyboardWasCreated = true; + Keyboard.destroy(); + } - renderable.set(false); - destroyContext(); + renderable.set(false); + destroyContext(); + } + + /** + * Called to restore the canvas. + */ + private void restoreCanvas() { + logger.log(Level.FINE, "OGL: Waiting for canvas to become displayable.."); + while (!canvas.isDisplayable()) { + try { + Thread.sleep(10); + } catch (InterruptedException ex) { + logger.log(Level.SEVERE, "OGL: Interrupted! ", ex); + } } - /** - * Called to restore the canvas. - */ - private void restoreCanvas(){ - logger.log(Level.FINE, "OGL: Waiting for canvas to become displayable.."); - while (!canvas.isDisplayable()){ - try { - Thread.sleep(10); - } catch (InterruptedException ex) { - logger.log(Level.SEVERE, "OGL: Interrupted! ", ex); - } - } - - logger.log(Level.FINE, "OGL: Creating display context .."); + logger.log(Level.FINE, "OGL: Creating display context .."); - // Set renderable to true, since canvas is now displayable. - renderable.set(true); - createContext(settings); + // Set renderable to true, since canvas is now displayable. + renderable.set(true); + createContext(settings); - logger.log(Level.FINE, "OGL: Display is active!"); + logger.log(Level.FINE, "OGL: Display is active!"); - try { - if (mouseWasCreated){ - Mouse.create(); - if (mouseWasGrabbed){ - Mouse.setGrabbed(true); - mouseWasGrabbed = false; - } - } - if (keyboardWasCreated){ - Keyboard.create(); - keyboardWasCreated = false; - } - } catch (LWJGLException ex){ - logger.log(Level.SEVERE, "Encountered exception when restoring input", ex); + try { + if (mouseWasCreated) { + Mouse.create(); + if (mouseWasGrabbed) { + Mouse.setGrabbed(true); + mouseWasGrabbed = false; } + } + if (keyboardWasCreated) { + Keyboard.create(); + keyboardWasCreated = false; + } + } catch (LWJGLException ex) { + logger.log(Level.SEVERE, "Encountered exception when restoring input", ex); + } - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - canvas.requestFocus(); - } - }); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + canvas.requestFocus(); + } + }); + } + + /** + * It seems it is best to use one pixel format for all shared contexts. + * + * @see http://developer.apple.com/library/mac/#qa/qa1248/_index.html + * + * @param forPbuffer true→zero samples, false→correct number of samples + * @return a new instance + */ + protected PixelFormat acquirePixelFormat(boolean forPbuffer) { + if (forPbuffer) { + // Use 0 samples for pbuffer format, prevents + // crashes on bad drivers + if (pbufferFormat == null) { + pbufferFormat = new PixelFormat(settings.getBitsPerPixel(), settings.getAlphaBits(), + settings.getDepthBits(), settings.getStencilBits(), 0, // samples + 0, 0, 0, settings.useStereo3D()); + } + return pbufferFormat; + } else { + if (canvasFormat == null) { + int samples = getNumSamplesToUse(); + canvasFormat = new PixelFormat(settings.getBitsPerPixel(), settings.getAlphaBits(), + settings.getDepthBits(), settings.getStencilBits(), samples, 0, 0, 0, + settings.useStereo3D()); + } + return canvasFormat; } - - /** - * It seems it is best to use one pixel format for all shared contexts. - * @see http://developer.apple.com/library/mac/#qa/qa1248/_index.html - * - * @param forPbuffer true→zero samples, false→correct number of samples - * @return a new instance - */ - protected PixelFormat acquirePixelFormat(boolean forPbuffer){ - if (forPbuffer){ - // Use 0 samples for pbuffer format, prevents - // crashes on bad drivers - if (pbufferFormat == null){ - pbufferFormat = new PixelFormat(settings.getBitsPerPixel(), - settings.getAlphaBits(), - settings.getDepthBits(), - settings.getStencilBits(), - 0, // samples - 0, - 0, - 0, - settings.useStereo3D()); - } - return pbufferFormat; - }else{ - if (canvasFormat == null){ - int samples = getNumSamplesToUse(); - canvasFormat = new PixelFormat(settings.getBitsPerPixel(), - settings.getAlphaBits(), - settings.getDepthBits(), - settings.getStencilBits(), - samples, - 0, - 0, - 0, - settings.useStereo3D()); - } - return canvasFormat; - } + } + + /** + * Makes sure the pbuffer is available and ready for use + * + * @throws LWJGLException if the buffer can't be made current + */ + protected void makePbufferAvailable() throws LWJGLException { + if (pbuffer != null && pbuffer.isBufferLost()) { + logger.log(Level.WARNING, "PBuffer was lost!"); + pbuffer.destroy(); + pbuffer = null; } - /** - * Makes sure the pbuffer is available and ready for use - * - * @throws LWJGLException if the buffer can't be made current - */ - protected void makePbufferAvailable() throws LWJGLException{ - if (pbuffer != null && pbuffer.isBufferLost()){ - logger.log(Level.WARNING, "PBuffer was lost!"); - pbuffer.destroy(); - pbuffer = null; - } - - if (pbuffer == null) { - pbuffer = new Pbuffer(1, 1, acquirePixelFormat(true), null); - pbuffer.makeCurrent(); - logger.log(Level.FINE, "OGL: Pbuffer has been created"); - - // Any created objects are no longer valid - if (!runningFirstTime){ - renderer.resetGLObjects(); - } + if (pbuffer == null) { + pbuffer = new Pbuffer(1, 1, acquirePixelFormat(true), null); + pbuffer.makeCurrent(); + logger.log(Level.FINE, "OGL: Pbuffer has been created"); + + // Any created objects are no longer valid + if (!runningFirstTime) { + renderer.resetGLObjects(); + } + } + + pbuffer.makeCurrent(); + if (!pbuffer.isCurrent()) { + throw new LWJGLException("Pbuffer cannot be made current"); + } + } + + protected void destroyPbuffer() { + if (pbuffer != null) { + if (!pbuffer.isBufferLost()) { + pbuffer.destroy(); + } + pbuffer = null; + } + } + + /** + * This is called: 1) When the context thread ends 2) Any time the canvas becomes non-displayable + */ + @Override + protected void destroyContext() { + try { + // invalidate the state so renderer can resume operation + if (!USE_SHARED_CONTEXT) { + renderer.cleanup(); + } + + if (Display.isCreated()) { + /* + * FIXES: org.lwjgl.LWJGLException: X Error BadWindow (invalid Window parameter) + * request_code: 2 minor_code: 0 + * + * Destroying keyboard early prevents the error above, triggered by destroying keyboard in + * by Display.destroy() or Display.setParent(null). Therefore, Keyboard.destroy() should + * precede any of these calls. + */ + if (Keyboard.isCreated()) { + // Should only happen if called in + // LwjglAbstractDisplay.deinitInThread(). + Keyboard.destroy(); } - - pbuffer.makeCurrent(); - if (!pbuffer.isCurrent()){ - throw new LWJGLException("Pbuffer cannot be made current"); + + // try { + // NOTE: On Windows XP, not calling setParent(null) + // freezes the application. + // On Mac it freezes the application. + // On Linux it fixes a crash with X Window System. + if (JmeSystem.getPlatform() == Platform.Windows32 + || JmeSystem.getPlatform() == Platform.Windows64) { + // Display.setParent(null); } + // } catch (LWJGLException ex) { + // logger.log(Level.SEVERE, "Encountered exception when setting parent to null", ex); + // } + + Display.destroy(); + } + + // The canvas is no longer visible, + // but the context thread is still running. + if (!needClose.get()) { + // MUST make sure there's still a context current here. + // Display is dead, make PBuffer available to the system. + makePbufferAvailable(); + + renderer.invalidateState(); + } else { + // The context thread is no longer running. + // Destroy pbuffer. + destroyPbuffer(); + } + } catch (LWJGLException ex) { + listener.handleError("Failed make pbuffer available", ex); } - - protected void destroyPbuffer(){ - if (pbuffer != null){ - if (!pbuffer.isBufferLost()){ - pbuffer.destroy(); - } - pbuffer = null; + } + + /** + * This is called: 1) When the context thread starts 2) Any time the canvas becomes displayable + * again. In the first call of this method, OpenGL context is not ready yet. Therefore, OpenCL + * context cannot be created. The second call of this method is done after "simpleInitApp" is + * called. Therefore, OpenCL won't be available in "simpleInitApp" if Canvas/Swing is used. To use + * OpenCL with Canvas/Swing, you need to use OpenCL in the rendering loop "simpleUpdate" and check + * for "context.getOpenCLContext()!=null". + */ + @Override + protected void createContext(AppSettings settings) { + // In case canvas is not visible, we still take framerate + // from settings to prevent "100% CPU usage" + frameRate = settings.getFrameRate(); + allowSwapBuffers = settings.isSwapBuffers(); + + try { + if (renderable.get()) { + if (!runningFirstTime) { + // because the display is a different opengl context + // must reset the context state. + if (!USE_SHARED_CONTEXT) { + renderer.cleanup(); + } } - } - - /** - * This is called: - * 1) When the context thread ends - * 2) Any time the canvas becomes non-displayable - */ - @Override - protected void destroyContext(){ - try { - // invalidate the state so renderer can resume operation - if (!USE_SHARED_CONTEXT){ - renderer.cleanup(); - } - - if (Display.isCreated()){ - /* FIXES: - * org.lwjgl.LWJGLException: X Error - * BadWindow (invalid Window parameter) request_code: 2 minor_code: 0 - * - * Destroying keyboard early prevents the error above, triggered - * by destroying keyboard in by Display.destroy() or Display.setParent(null). - * Therefore, Keyboard.destroy() should precede any of these calls. - */ - if (Keyboard.isCreated()){ - // Should only happen if called in - // LwjglAbstractDisplay.deinitInThread(). - Keyboard.destroy(); - } - - //try { - // NOTE: On Windows XP, not calling setParent(null) - // freezes the application. - // On Mac it freezes the application. - // On Linux it fixes a crash with X Window System. - if (JmeSystem.getPlatform() == Platform.Windows32 - || JmeSystem.getPlatform() == Platform.Windows64){ - //Display.setParent(null); - } - //} catch (LWJGLException ex) { - // logger.log(Level.SEVERE, "Encountered exception when setting parent to null", ex); - //} - - Display.destroy(); - } - - // The canvas is no longer visible, - // but the context thread is still running. - if (!needClose.get()){ - // MUST make sure there's still a context current here. - // Display is dead, make PBuffer available to the system. - makePbufferAvailable(); - - renderer.invalidateState(); - }else{ - // The context thread is no longer running. - // Destroy pbuffer. - destroyPbuffer(); - } - } catch (LWJGLException ex) { - listener.handleError("Failed make pbuffer available", ex); + + // if the pbuffer is currently active, + // make sure to deactivate it + destroyPbuffer(); + + if (Keyboard.isCreated()) { + Keyboard.destroy(); } - } - /** - * This is called: - * 1) When the context thread starts - * 2) Any time the canvas becomes displayable again. - * In the first call of this method, OpenGL context is not ready yet. Therefore, OpenCL context cannot be created. - * The second call of this method is done after "simpleInitApp" is called. Therefore, OpenCL won't be available in "simpleInitApp" if Canvas/Swing is used. - * To use OpenCL with Canvas/Swing, you need to use OpenCL in the rendering loop "simpleUpdate" and check for "context.getOpenCLContext()!=null". - */ - @Override - protected void createContext(AppSettings settings) { - // In case canvas is not visible, we still take framerate - // from settings to prevent "100% CPU usage" - frameRate = settings.getFrameRate(); - allowSwapBuffers = settings.isSwapBuffers(); - try { - if (renderable.get()){ - if (!runningFirstTime){ - // because the display is a different opengl context - // must reset the context state. - if (!USE_SHARED_CONTEXT){ - renderer.cleanup(); - } - } - - // if the pbuffer is currently active, - // make sure to deactivate it - destroyPbuffer(); - - if (Keyboard.isCreated()){ - Keyboard.destroy(); - } - - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - } - - Display.setVSyncEnabled(settings.isVSync()); - Display.setParent(canvas); - - if (USE_SHARED_CONTEXT){ - Display.create(acquirePixelFormat(false), pbuffer); - }else{ - Display.create(acquirePixelFormat(false)); - } - if (settings.isOpenCLSupport()) { - initOpenCL(); - } - - renderer.invalidateState(); - }else{ - // First create the pbuffer, if it is needed. - makePbufferAvailable(); - } - - // At this point, the OpenGL context is active. - if (runningFirstTime){ - // THIS is the part that creates the renderer. - // It must always be called, now that we have the pbuffer workaround. - initContextFirstTime(); - runningFirstTime = false; - } - } catch (LWJGLException ex) { - listener.handleError("Failed to initialize OpenGL context", ex); - // TODO: Fix deadlock that happens after the error (throw runtime exception?) + Thread.sleep(1000); + } catch (InterruptedException ex) { + } + + Display.setVSyncEnabled(settings.isVSync()); + Display.setParent(canvas); + + if (USE_SHARED_CONTEXT) { + Display.create(acquirePixelFormat(false), pbuffer); + } else { + Display.create(acquirePixelFormat(false)); + } + if (settings.isOpenCLSupport()) { + initOpenCL(); } - } - @Override - public Monitors getMonitors() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryMonitor() - { - // TODO Auto-generated method stub - return 0; - } + renderer.invalidateState(); + } else { + // First create the pbuffer, if it is needed. + makePbufferAvailable(); + } + + // At this point, the OpenGL context is active. + if (runningFirstTime) { + // THIS is the part that creates the renderer. + // It must always be called, now that we have the pbuffer workaround. + initContextFirstTime(); + runningFirstTime = false; + } + } catch (LWJGLException ex) { + listener.handleError("Failed to initialize OpenGL context", ex); + // TODO: Fix deadlock that happens after the error (throw runtime exception?) + } + } + + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index bf7eef3aa0..020746256b 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -284,18 +284,16 @@ private ByteBuffer imageToByteBuffer(BufferedImage image) { return ByteBuffer.wrap(imageBuffer); } - @Override - public Monitors getMonitors() - { - // TODO Auto-generated method stub - return null; - } + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } - @Override - public int getPrimaryMonitor() - { - // TODO Auto-generated method stub - return 0; - } + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 1965d19ec0..86add690a4 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -220,18 +220,16 @@ public TouchInput getTouchInput() { public void setTitle(String title) { } - @Override - public Monitors getMonitors() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryMonitor() - { - // TODO Auto-generated method stub - return 0; - } + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index e0002d6424..d9f23baeeb 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -291,9 +291,9 @@ public void invoke(int error, long description) { // long monitor = NULL; - /** - * Let's grab the monitor selected, if not found it will return primaryMonitor. - * if not full screen just use primary monitor data. + /** + * Let's grab the monitor selected, if not found it will return + * primaryMonitor. if not full screen just use primary monitor data. */ if (settings.isFullscreen()) { monitor = getMonitor(settings.getMonitor()); @@ -305,18 +305,19 @@ public void invoke(int error, long description) { int requestWidth = settings.getWindowWidth(); int requestHeight = settings.getWindowHeight(); if (requestWidth <= 0 || requestHeight <= 0) { - requestWidth = videoMode.width(); - requestHeight = videoMode.height(); + requestWidth = videoMode.width(); + requestHeight = videoMode.height(); } - //Lets use the monitor selected from AppSettings if FullScreen is - //set. + // Lets use the monitor selected from AppSettings if FullScreen is + // set. if (settings.isFullscreen()) - window = glfwCreateWindow(requestWidth, requestHeight, settings.getTitle(), monitor, NULL); - else - window = glfwCreateWindow(requestWidth, requestHeight, settings.getTitle(), NULL, NULL); + window = glfwCreateWindow(requestWidth, requestHeight, + settings.getTitle(), monitor, NULL); + else + window = glfwCreateWindow(requestWidth, requestHeight, + settings.getTitle(), NULL, NULL); - if (window == NULL) { throw new RuntimeException("Failed to create the GLFW window"); } diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index 888c8b879d..f7f08126ba 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -53,17 +53,15 @@ public Context getOpenCLContext() { return null; } - @Override - public Monitors getMonitors() - { - // TODO Auto-generated method stub - return null; - } + @Override + public Monitors getMonitors() { + // TODO Auto-generated method stub + return null; + } - @Override - public int getPrimaryMonitor() - { - // TODO Auto-generated method stub - return 0; - } + @Override + public int getPrimaryMonitor() { + // TODO Auto-generated method stub + return 0; + } } From 8594c1d129a17456b595e1223934339595e528fd Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Fri, 22 Sep 2023 15:18:00 -0500 Subject: [PATCH 07/18] renamed monitor data into generic form of Display for compatibility for other devices. --- .../com/jme3/system/android/OGLESContext.java | 4 +-- .../java/com/jme3/app/LegacyApplication.java | 8 +++--- .../{MonitorInfo.java => DisplayInfo.java} | 4 +-- .../system/{Monitors.java => Displays.java} | 26 +++++++++---------- .../main/java/com/jme3/system/JmeContext.java | 12 ++++----- .../java/com/jme3/system/NullContext.java | 4 +-- .../main/java/com/jme3/system/AWTContext.java | 4 +-- .../com/jme3/system/awt/AwtPanelsContext.java | 4 +-- .../java/jme3test/app/TestMonitorApp.java | 10 +++---- .../com/jme3/system/ios/IGLESContext.java | 4 +-- .../com/jme3/system/lwjgl/LwjglCanvas.java | 6 ++--- .../com/jme3/system/lwjgl/LwjglDisplay.java | 6 ++--- .../system/lwjgl/LwjglOffscreenBuffer.java | 6 ++--- .../com/jme3/system/lwjgl/LwjglWindow.java | 18 ++++++------- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 6 ++--- 15 files changed, 61 insertions(+), 61 deletions(-) rename jme3-core/src/main/java/com/jme3/system/{MonitorInfo.java => DisplayInfo.java} (97%) rename jme3-core/src/main/java/com/jme3/system/{Monitors.java => Displays.java} (81%) diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index 005a579b7e..e15dbeb930 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -557,13 +557,13 @@ private Rect getSurfaceFrame() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index e74874b095..47f0a90f1b 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -825,8 +825,8 @@ public Object call() { * * @return returns a list of monitors and their information. */ - public Monitors getMonitors() { - return context.getMonitors(); + public Displays getDisplays() { + return context.getDisplays(); } /** @@ -835,7 +835,7 @@ public Monitors getMonitors() { * * @return the position of the value in the arraylist of the primary monitor. */ - public int getPrimaryMonitor() { - return context.getPrimaryMonitor(); + public int getPrimaryDisplay() { + return context.getPrimaryDisplay(); } } diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java similarity index 97% rename from jme3-core/src/main/java/com/jme3/system/MonitorInfo.java rename to jme3-core/src/main/java/com/jme3/system/DisplayInfo.java index a7791d37b2..249d7f52ec 100644 --- a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java @@ -31,12 +31,12 @@ * * @author Kevin Bales */ -public class MonitorInfo { +public class DisplayInfo { /** * monitorID - monitor id that was return from Lwjgl3. */ - public long monitorID = 0; + public long displayID = 0; /** * width - width that was return from Lwjgl3. diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Displays.java similarity index 81% rename from jme3-core/src/main/java/com/jme3/system/Monitors.java rename to jme3-core/src/main/java/com/jme3/system/Displays.java index b834e518f8..ea61eefd6a 100644 --- a/jme3-core/src/main/java/com/jme3/system/Monitors.java +++ b/jme3-core/src/main/java/com/jme3/system/Displays.java @@ -28,24 +28,24 @@ import java.util.ArrayList; /** - * This class holds all information about all monitors that where return from the glfwGetMonitors() + * This class holds all information about all displays that where return from the glfwGetMonitors() * call. It stores them into an * * @author Kevin Bales */ -public class Monitors { +public class Displays { - private ArrayList monitors = new ArrayList(); + private ArrayList monitors = new ArrayList(); public int addNewMonitor(long monitorID) { - MonitorInfo info = new MonitorInfo(); - info.monitorID = monitorID; + DisplayInfo info = new DisplayInfo(); + info.displayID = monitorID; monitors.add(info); return monitors.size() - 1; } /** - * This function returns the size of the monitor ArrayList + * This function returns the size of the displays ArrayList * * @return the */ @@ -54,12 +54,12 @@ public int size() { } /** - * Call to get monitor information on a certain monitor. + * Call to get monitor information on a certain display. * - * @param pos the position in the arraylist of the monitor information that you want to get. - * @return returns the MonitorInfo data for the monitor called for. + * @param pos the position in the arraylist of the display information that you want to get. + * @return returns the DisplayInfo data for the display called for. */ - public MonitorInfo get(int pos) { + public DisplayInfo get(int pos) { if (pos < monitors.size()) return monitors.get(pos); @@ -76,7 +76,7 @@ public MonitorInfo get(int pos) { */ public void setInfo(int monPos, String name, int width, int height, int rate) { if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); + DisplayInfo info = monitors.get(monPos); if (info != null) { info.width = width; info.height = height; @@ -91,9 +91,9 @@ public void setInfo(int monPos, String name, int width, int height, int rate) { * * @param monPos the position in the arraylist of which monitor is the primary monitor */ - public void setPrimaryMonitor(int monPos) { + public void setActiveMonitor(int monPos) { if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); + DisplayInfo info = monitors.get(monPos); if (info != null) info.primary = true; } diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index 258639634f..d735033cef 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -227,18 +227,18 @@ public enum Type { public int getWindowYPosition(); /** - * This call will return a list of Monitors that glfwGetMonitors() returns and information about + * This call will return a list of Displays that glfwGetMonitors() returns and information about * the monitor, like width, height, and refresh rate. * - * @return returns a list of monitors and their information. + * @return returns a list of displays and their information. */ - public Monitors getMonitors(); + public Displays getDisplays(); /** - * Use this to get the positional number of the primary monitor from the glfwGetMonitors() + * Use this to get the positional number of the primary Displays from the glfwGetMonitors() * function call. * - * @return the position of the value in the arraylist of the primary monitor. + * @return the position of the value in the arraylist of the primary Displays. */ - public int getPrimaryMonitor(); + public int getPrimaryDisplay(); } diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index e58f143b45..b317ce24ed 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -308,13 +308,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java index c58b2c44af..095bcd6691 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java @@ -277,13 +277,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index afb8003fcd..fc165bb1fd 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -330,13 +330,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index bf3b837fdd..e4018f8f9e 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -49,8 +49,8 @@ import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.system.AppSettings; -import com.jme3.system.MonitorInfo; -import com.jme3.system.Monitors; +import com.jme3.system.DisplayInfo; +import com.jme3.system.Displays; /** * Tests the capability to change which monitor the window will be created on. @@ -67,7 +67,7 @@ public class TestMonitorApp extends SimpleApplication private BitmapText selectedMonitorTxt; private BitmapText fullScreenTxt; private int monitorSelected = 0; - private Monitors monitors = null; + private Displays monitors = null; public static void main(String[] args) { TestMonitorApp app = new TestMonitorApp(); @@ -116,7 +116,7 @@ public void simpleInitApp() { // Get the selected monitor monitorSelected = settings.getMonitor(); - monitors = context.getMonitors(); + monitors = context.getDisplays(); if (monitors != null) numMonitors = monitors.size(); @@ -155,7 +155,7 @@ public void simpleInitApp() { // Let's loop through all the monitors and display on the screen for (int i = 0; i < monitors.size(); i++) { - MonitorInfo monitor = monitors.get(i); + DisplayInfo monitor = monitors.get(i); labelValue = "Mon : " + i + " " + monitor.name + " " + monitor.width + "," + monitor.height + " refresh: " + monitor.rate; txt = new BitmapText(loadGuiFont()); diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index 2a18b56569..0343dadbd8 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -269,13 +269,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 7728c11257..7fe2964ac8 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -30,7 +30,7 @@ import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystem; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import com.jme3.system.Platform; import java.awt.Canvas; import java.util.logging.Level; @@ -484,13 +484,13 @@ protected void createContext(AppSettings settings) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 020746256b..1516dc54a1 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -34,7 +34,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext.Type; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import java.awt.Graphics2D; import java.awt.image.BufferedImage; @@ -285,13 +285,13 @@ private ByteBuffer imageToByteBuffer(BufferedImage image) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 86add690a4..727890a981 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -38,7 +38,7 @@ import com.jme3.input.TouchInput; import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -221,13 +221,13 @@ public void setTitle(String title) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index d9f23baeeb..5770f1c437 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -43,7 +43,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import com.jme3.system.NanoTimer; import com.jme3.util.BufferUtils; import com.jme3.util.SafeArrayList; @@ -882,12 +882,12 @@ public int getWindowYPosition() { * @return returns the Primary Monitor Position. */ @Override - public int getPrimaryMonitor() + public int getPrimaryDisplay() { long prim = glfwGetPrimaryMonitor(); - Monitors monitors = getMonitors(); + Displays monitors = getDisplays(); for ( int i = 0; i < monitors.size(); i++ ) { - long monitorI = monitors.get(i).monitorID; + long monitorI = monitors.get(i).displayID; if (monitorI == prim) return i; } @@ -905,9 +905,9 @@ public int getPrimaryMonitor() * @return return the monitorID if found otherwise return Primary Monitor */ private long getMonitor(int pos) { - Monitors monitors = getMonitors(); + Displays monitors = getDisplays(); if (pos < monitors.size()) - return monitors.get(pos).monitorID; + return monitors.get(pos).displayID; LOGGER.log(Level.SEVERE,"Couldn't locate Monitor requested in the list of Monitors. pos:"+pos+" size: "+ monitors.size()); return glfwGetPrimaryMonitor(); @@ -922,17 +922,17 @@ private long getMonitor(int pos) { */ @Override - public Monitors getMonitors() { + public Displays getDisplays() { PointerBuffer monitors = glfwGetMonitors(); long primary = glfwGetPrimaryMonitor(); - Monitors monitorList = new Monitors(); + Displays monitorList = new Displays(); for ( int i = 0; i < monitors.limit(); i++ ) { long monitorI = monitors.get(i); int monPos = monitorList.addNewMonitor(monitorI); //lets check if this monitor is the primary monitor. If use mark it as such. if (primary == monitorI) - monitorList.setPrimaryMonitor(monPos); + monitorList.setActiveMonitor(monPos); final GLFWVidMode modes = glfwGetVideoMode(monitorI); String name = glfwGetMonitorName(monitorI); diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index f7f08126ba..2f557d8ae5 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -32,7 +32,7 @@ package com.jme3.system.lwjgl; import com.jme3.opencl.Context; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; /** * A VR oriented LWJGL display. @@ -54,13 +54,13 @@ public Context getOpenCLContext() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } From 03dd250b2da997678785800016e35a106dc216ce Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Fri, 22 Sep 2023 15:25:06 -0500 Subject: [PATCH 08/18] Revert "renamed monitor data into generic form of Display for compatibility for other devices." This reverts commit 8594c1d129a17456b595e1223934339595e528fd. --- .../com/jme3/system/android/OGLESContext.java | 4 +-- .../java/com/jme3/app/LegacyApplication.java | 8 +++--- .../main/java/com/jme3/system/JmeContext.java | 12 ++++----- .../{DisplayInfo.java => MonitorInfo.java} | 4 +-- .../system/{Displays.java => Monitors.java} | 26 +++++++++---------- .../java/com/jme3/system/NullContext.java | 4 +-- .../main/java/com/jme3/system/AWTContext.java | 4 +-- .../com/jme3/system/awt/AwtPanelsContext.java | 4 +-- .../java/jme3test/app/TestMonitorApp.java | 10 +++---- .../com/jme3/system/ios/IGLESContext.java | 4 +-- .../com/jme3/system/lwjgl/LwjglCanvas.java | 6 ++--- .../com/jme3/system/lwjgl/LwjglDisplay.java | 6 ++--- .../system/lwjgl/LwjglOffscreenBuffer.java | 6 ++--- .../com/jme3/system/lwjgl/LwjglWindow.java | 18 ++++++------- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 6 ++--- 15 files changed, 61 insertions(+), 61 deletions(-) rename jme3-core/src/main/java/com/jme3/system/{DisplayInfo.java => MonitorInfo.java} (97%) rename jme3-core/src/main/java/com/jme3/system/{Displays.java => Monitors.java} (81%) diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index e15dbeb930..005a579b7e 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -557,13 +557,13 @@ private Rect getSurfaceFrame() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index 47f0a90f1b..e74874b095 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -825,8 +825,8 @@ public Object call() { * * @return returns a list of monitors and their information. */ - public Displays getDisplays() { - return context.getDisplays(); + public Monitors getMonitors() { + return context.getMonitors(); } /** @@ -835,7 +835,7 @@ public Displays getDisplays() { * * @return the position of the value in the arraylist of the primary monitor. */ - public int getPrimaryDisplay() { - return context.getPrimaryDisplay(); + public int getPrimaryMonitor() { + return context.getPrimaryMonitor(); } } diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index d735033cef..258639634f 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -227,18 +227,18 @@ public enum Type { public int getWindowYPosition(); /** - * This call will return a list of Displays that glfwGetMonitors() returns and information about + * This call will return a list of Monitors that glfwGetMonitors() returns and information about * the monitor, like width, height, and refresh rate. * - * @return returns a list of displays and their information. + * @return returns a list of monitors and their information. */ - public Displays getDisplays(); + public Monitors getMonitors(); /** - * Use this to get the positional number of the primary Displays from the glfwGetMonitors() + * Use this to get the positional number of the primary monitor from the glfwGetMonitors() * function call. * - * @return the position of the value in the arraylist of the primary Displays. + * @return the position of the value in the arraylist of the primary monitor. */ - public int getPrimaryDisplay(); + public int getPrimaryMonitor(); } diff --git a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java similarity index 97% rename from jme3-core/src/main/java/com/jme3/system/DisplayInfo.java rename to jme3-core/src/main/java/com/jme3/system/MonitorInfo.java index 249d7f52ec..a7791d37b2 100644 --- a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java @@ -31,12 +31,12 @@ * * @author Kevin Bales */ -public class DisplayInfo { +public class MonitorInfo { /** * monitorID - monitor id that was return from Lwjgl3. */ - public long displayID = 0; + public long monitorID = 0; /** * width - width that was return from Lwjgl3. diff --git a/jme3-core/src/main/java/com/jme3/system/Displays.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java similarity index 81% rename from jme3-core/src/main/java/com/jme3/system/Displays.java rename to jme3-core/src/main/java/com/jme3/system/Monitors.java index ea61eefd6a..b834e518f8 100644 --- a/jme3-core/src/main/java/com/jme3/system/Displays.java +++ b/jme3-core/src/main/java/com/jme3/system/Monitors.java @@ -28,24 +28,24 @@ import java.util.ArrayList; /** - * This class holds all information about all displays that where return from the glfwGetMonitors() + * This class holds all information about all monitors that where return from the glfwGetMonitors() * call. It stores them into an * * @author Kevin Bales */ -public class Displays { +public class Monitors { - private ArrayList monitors = new ArrayList(); + private ArrayList monitors = new ArrayList(); public int addNewMonitor(long monitorID) { - DisplayInfo info = new DisplayInfo(); - info.displayID = monitorID; + MonitorInfo info = new MonitorInfo(); + info.monitorID = monitorID; monitors.add(info); return monitors.size() - 1; } /** - * This function returns the size of the displays ArrayList + * This function returns the size of the monitor ArrayList * * @return the */ @@ -54,12 +54,12 @@ public int size() { } /** - * Call to get monitor information on a certain display. + * Call to get monitor information on a certain monitor. * - * @param pos the position in the arraylist of the display information that you want to get. - * @return returns the DisplayInfo data for the display called for. + * @param pos the position in the arraylist of the monitor information that you want to get. + * @return returns the MonitorInfo data for the monitor called for. */ - public DisplayInfo get(int pos) { + public MonitorInfo get(int pos) { if (pos < monitors.size()) return monitors.get(pos); @@ -76,7 +76,7 @@ public DisplayInfo get(int pos) { */ public void setInfo(int monPos, String name, int width, int height, int rate) { if (monPos < monitors.size()) { - DisplayInfo info = monitors.get(monPos); + MonitorInfo info = monitors.get(monPos); if (info != null) { info.width = width; info.height = height; @@ -91,9 +91,9 @@ public void setInfo(int monPos, String name, int width, int height, int rate) { * * @param monPos the position in the arraylist of which monitor is the primary monitor */ - public void setActiveMonitor(int monPos) { + public void setPrimaryMonitor(int monPos) { if (monPos < monitors.size()) { - DisplayInfo info = monitors.get(monPos); + MonitorInfo info = monitors.get(monPos); if (info != null) info.primary = true; } diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index b317ce24ed..e58f143b45 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -308,13 +308,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java index 095bcd6691..c58b2c44af 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java @@ -277,13 +277,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index fc165bb1fd..afb8003fcd 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -330,13 +330,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index e4018f8f9e..bf3b837fdd 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -49,8 +49,8 @@ import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.system.AppSettings; -import com.jme3.system.DisplayInfo; -import com.jme3.system.Displays; +import com.jme3.system.MonitorInfo; +import com.jme3.system.Monitors; /** * Tests the capability to change which monitor the window will be created on. @@ -67,7 +67,7 @@ public class TestMonitorApp extends SimpleApplication private BitmapText selectedMonitorTxt; private BitmapText fullScreenTxt; private int monitorSelected = 0; - private Displays monitors = null; + private Monitors monitors = null; public static void main(String[] args) { TestMonitorApp app = new TestMonitorApp(); @@ -116,7 +116,7 @@ public void simpleInitApp() { // Get the selected monitor monitorSelected = settings.getMonitor(); - monitors = context.getDisplays(); + monitors = context.getMonitors(); if (monitors != null) numMonitors = monitors.size(); @@ -155,7 +155,7 @@ public void simpleInitApp() { // Let's loop through all the monitors and display on the screen for (int i = 0; i < monitors.size(); i++) { - DisplayInfo monitor = monitors.get(i); + MonitorInfo monitor = monitors.get(i); labelValue = "Mon : " + i + " " + monitor.name + " " + monitor.width + "," + monitor.height + " refresh: " + monitor.rate; txt = new BitmapText(loadGuiFont()); diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index 0343dadbd8..2a18b56569 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -269,13 +269,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 7fe2964ac8..7728c11257 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -30,7 +30,7 @@ import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystem; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import com.jme3.system.Platform; import java.awt.Canvas; import java.util.logging.Level; @@ -484,13 +484,13 @@ protected void createContext(AppSettings settings) { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 1516dc54a1..020746256b 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -34,7 +34,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext.Type; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import java.awt.Graphics2D; import java.awt.image.BufferedImage; @@ -285,13 +285,13 @@ private ByteBuffer imageToByteBuffer(BufferedImage image) { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 727890a981..86add690a4 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -38,7 +38,7 @@ import com.jme3.input.TouchInput; import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -221,13 +221,13 @@ public void setTitle(String title) { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index 5770f1c437..d9f23baeeb 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -43,7 +43,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import com.jme3.system.NanoTimer; import com.jme3.util.BufferUtils; import com.jme3.util.SafeArrayList; @@ -882,12 +882,12 @@ public int getWindowYPosition() { * @return returns the Primary Monitor Position. */ @Override - public int getPrimaryDisplay() + public int getPrimaryMonitor() { long prim = glfwGetPrimaryMonitor(); - Displays monitors = getDisplays(); + Monitors monitors = getMonitors(); for ( int i = 0; i < monitors.size(); i++ ) { - long monitorI = monitors.get(i).displayID; + long monitorI = monitors.get(i).monitorID; if (monitorI == prim) return i; } @@ -905,9 +905,9 @@ public int getPrimaryDisplay() * @return return the monitorID if found otherwise return Primary Monitor */ private long getMonitor(int pos) { - Displays monitors = getDisplays(); + Monitors monitors = getMonitors(); if (pos < monitors.size()) - return monitors.get(pos).displayID; + return monitors.get(pos).monitorID; LOGGER.log(Level.SEVERE,"Couldn't locate Monitor requested in the list of Monitors. pos:"+pos+" size: "+ monitors.size()); return glfwGetPrimaryMonitor(); @@ -922,17 +922,17 @@ private long getMonitor(int pos) { */ @Override - public Displays getDisplays() { + public Monitors getMonitors() { PointerBuffer monitors = glfwGetMonitors(); long primary = glfwGetPrimaryMonitor(); - Displays monitorList = new Displays(); + Monitors monitorList = new Monitors(); for ( int i = 0; i < monitors.limit(); i++ ) { long monitorI = monitors.get(i); int monPos = monitorList.addNewMonitor(monitorI); //lets check if this monitor is the primary monitor. If use mark it as such. if (primary == monitorI) - monitorList.setActiveMonitor(monPos); + monitorList.setPrimaryMonitor(monPos); final GLFWVidMode modes = glfwGetVideoMode(monitorI); String name = glfwGetMonitorName(monitorI); diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index 2f557d8ae5..f7f08126ba 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -32,7 +32,7 @@ package com.jme3.system.lwjgl; import com.jme3.opencl.Context; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; /** * A VR oriented LWJGL display. @@ -54,13 +54,13 @@ public Context getOpenCLContext() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } From 7050d7a6068a3aadd9fb7dbc202050829b4eb292 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Fri, 22 Sep 2023 15:33:57 -0500 Subject: [PATCH 09/18] renamed monitor data into generic form of Display for compatibility for other devices. --- .../com/jme3/system/android/OGLESContext.java | 4 ++-- .../java/com/jme3/app/LegacyApplication.java | 16 ++++++++-------- .../{MonitorInfo.java => DisplayInfo.java} | 4 ++-- .../jme3/system/{Monitors.java => Displays.java} | 14 +++++++------- .../main/java/com/jme3/system/JmeContext.java | 4 ++-- .../main/java/com/jme3/system/NullContext.java | 4 ++-- .../main/java/com/jme3/system/AWTContext.java | 4 ++-- .../com/jme3/system/awt/AwtPanelsContext.java | 4 ++-- .../main/java/jme3test/app/TestMonitorApp.java | 10 +++++----- .../java/com/jme3/system/ios/IGLESContext.java | 4 ++-- .../java/com/jme3/system/lwjgl/LwjglCanvas.java | 6 +++--- .../java/com/jme3/system/lwjgl/LwjglDisplay.java | 6 +++--- .../jme3/system/lwjgl/LwjglOffscreenBuffer.java | 6 +++--- .../java/com/jme3/system/lwjgl/LwjglWindow.java | 16 ++++++++-------- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 6 +++--- 15 files changed, 54 insertions(+), 54 deletions(-) rename jme3-core/src/main/java/com/jme3/system/{MonitorInfo.java => DisplayInfo.java} (97%) rename jme3-core/src/main/java/com/jme3/system/{Monitors.java => Displays.java} (91%) diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index 005a579b7e..e15dbeb930 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -557,13 +557,13 @@ private Rect getSurfaceFrame() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index e74874b095..3565191b1a 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -820,22 +820,22 @@ public Object call() { } /** - * This call will return a list of Monitors that glfwGetMonitors() returns and information about + * This call will return a list of Displays that glfwGetMonitors() returns and information about * the monitor, like width, height, and refresh rate. * - * @return returns a list of monitors and their information. + * @return returns a list of Displays and their information. */ - public Monitors getMonitors() { - return context.getMonitors(); + public Displays getDisplays() { + return context.getDisplays(); } /** - * Use this to get the positional number of the primary monitor from the glfwGetMonitors() + * Use this to get the positional number of the primary Displays from the glfwGetMonitors() * function call. * - * @return the position of the value in the arraylist of the primary monitor. + * @return the position of the value in the arraylist of the primary Displays. */ - public int getPrimaryMonitor() { - return context.getPrimaryMonitor(); + public int getPrimaryDisplay() { + return context.getPrimaryDisplay(); } } diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java similarity index 97% rename from jme3-core/src/main/java/com/jme3/system/MonitorInfo.java rename to jme3-core/src/main/java/com/jme3/system/DisplayInfo.java index a7791d37b2..249d7f52ec 100644 --- a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java @@ -31,12 +31,12 @@ * * @author Kevin Bales */ -public class MonitorInfo { +public class DisplayInfo { /** * monitorID - monitor id that was return from Lwjgl3. */ - public long monitorID = 0; + public long displayID = 0; /** * width - width that was return from Lwjgl3. diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Displays.java similarity index 91% rename from jme3-core/src/main/java/com/jme3/system/Monitors.java rename to jme3-core/src/main/java/com/jme3/system/Displays.java index b834e518f8..f6d9446a2c 100644 --- a/jme3-core/src/main/java/com/jme3/system/Monitors.java +++ b/jme3-core/src/main/java/com/jme3/system/Displays.java @@ -33,13 +33,13 @@ * * @author Kevin Bales */ -public class Monitors { +public class Displays { - private ArrayList monitors = new ArrayList(); + private ArrayList monitors = new ArrayList(); public int addNewMonitor(long monitorID) { - MonitorInfo info = new MonitorInfo(); - info.monitorID = monitorID; + DisplayInfo info = new DisplayInfo(); + info.displayID = monitorID; monitors.add(info); return monitors.size() - 1; } @@ -59,7 +59,7 @@ public int size() { * @param pos the position in the arraylist of the monitor information that you want to get. * @return returns the MonitorInfo data for the monitor called for. */ - public MonitorInfo get(int pos) { + public DisplayInfo get(int pos) { if (pos < monitors.size()) return monitors.get(pos); @@ -76,7 +76,7 @@ public MonitorInfo get(int pos) { */ public void setInfo(int monPos, String name, int width, int height, int rate) { if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); + DisplayInfo info = monitors.get(monPos); if (info != null) { info.width = width; info.height = height; @@ -93,7 +93,7 @@ public void setInfo(int monPos, String name, int width, int height, int rate) { */ public void setPrimaryMonitor(int monPos) { if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); + DisplayInfo info = monitors.get(monPos); if (info != null) info.primary = true; } diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index 258639634f..34e4971f63 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -232,7 +232,7 @@ public enum Type { * * @return returns a list of monitors and their information. */ - public Monitors getMonitors(); + public Displays getDisplays(); /** * Use this to get the positional number of the primary monitor from the glfwGetMonitors() @@ -240,5 +240,5 @@ public enum Type { * * @return the position of the value in the arraylist of the primary monitor. */ - public int getPrimaryMonitor(); + public int getPrimaryDisplay(); } diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index e58f143b45..b317ce24ed 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -308,13 +308,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java index c58b2c44af..095bcd6691 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java @@ -277,13 +277,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index afb8003fcd..fc165bb1fd 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -330,13 +330,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index bf3b837fdd..e4018f8f9e 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -49,8 +49,8 @@ import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.system.AppSettings; -import com.jme3.system.MonitorInfo; -import com.jme3.system.Monitors; +import com.jme3.system.DisplayInfo; +import com.jme3.system.Displays; /** * Tests the capability to change which monitor the window will be created on. @@ -67,7 +67,7 @@ public class TestMonitorApp extends SimpleApplication private BitmapText selectedMonitorTxt; private BitmapText fullScreenTxt; private int monitorSelected = 0; - private Monitors monitors = null; + private Displays monitors = null; public static void main(String[] args) { TestMonitorApp app = new TestMonitorApp(); @@ -116,7 +116,7 @@ public void simpleInitApp() { // Get the selected monitor monitorSelected = settings.getMonitor(); - monitors = context.getMonitors(); + monitors = context.getDisplays(); if (monitors != null) numMonitors = monitors.size(); @@ -155,7 +155,7 @@ public void simpleInitApp() { // Let's loop through all the monitors and display on the screen for (int i = 0; i < monitors.size(); i++) { - MonitorInfo monitor = monitors.get(i); + DisplayInfo monitor = monitors.get(i); labelValue = "Mon : " + i + " " + monitor.name + " " + monitor.width + "," + monitor.height + " refresh: " + monitor.rate; txt = new BitmapText(loadGuiFont()); diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index 2a18b56569..0343dadbd8 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -269,13 +269,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 7728c11257..7fe2964ac8 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -30,7 +30,7 @@ import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystem; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import com.jme3.system.Platform; import java.awt.Canvas; import java.util.logging.Level; @@ -484,13 +484,13 @@ protected void createContext(AppSettings settings) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 020746256b..1516dc54a1 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -34,7 +34,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext.Type; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import java.awt.Graphics2D; import java.awt.image.BufferedImage; @@ -285,13 +285,13 @@ private ByteBuffer imageToByteBuffer(BufferedImage image) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 86add690a4..727890a981 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -38,7 +38,7 @@ import com.jme3.input.TouchInput; import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -221,13 +221,13 @@ public void setTitle(String title) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index d9f23baeeb..f7bfb06c53 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -43,7 +43,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import com.jme3.system.NanoTimer; import com.jme3.util.BufferUtils; import com.jme3.util.SafeArrayList; @@ -882,12 +882,12 @@ public int getWindowYPosition() { * @return returns the Primary Monitor Position. */ @Override - public int getPrimaryMonitor() + public int getPrimaryDisplay() { long prim = glfwGetPrimaryMonitor(); - Monitors monitors = getMonitors(); + Displays monitors = getDisplays(); for ( int i = 0; i < monitors.size(); i++ ) { - long monitorI = monitors.get(i).monitorID; + long monitorI = monitors.get(i).displayID; if (monitorI == prim) return i; } @@ -905,9 +905,9 @@ public int getPrimaryMonitor() * @return return the monitorID if found otherwise return Primary Monitor */ private long getMonitor(int pos) { - Monitors monitors = getMonitors(); + Displays monitors = getDisplays(); if (pos < monitors.size()) - return monitors.get(pos).monitorID; + return monitors.get(pos).displayID; LOGGER.log(Level.SEVERE,"Couldn't locate Monitor requested in the list of Monitors. pos:"+pos+" size: "+ monitors.size()); return glfwGetPrimaryMonitor(); @@ -922,10 +922,10 @@ private long getMonitor(int pos) { */ @Override - public Monitors getMonitors() { + public Displays getDisplays() { PointerBuffer monitors = glfwGetMonitors(); long primary = glfwGetPrimaryMonitor(); - Monitors monitorList = new Monitors(); + Displays monitorList = new Displays(); for ( int i = 0; i < monitors.limit(); i++ ) { long monitorI = monitors.get(i); diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index f7f08126ba..2f557d8ae5 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -32,7 +32,7 @@ package com.jme3.system.lwjgl; import com.jme3.opencl.Context; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; /** * A VR oriented LWJGL display. @@ -54,13 +54,13 @@ public Context getOpenCLContext() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } From 48a7980c35bc2d788b3cb5481337cfccbb33e309 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Fri, 22 Sep 2023 19:32:04 -0500 Subject: [PATCH 10/18] Revert "renamed monitor data into generic form of Display for compatibility for other devices." This reverts commit 7050d7a6068a3aadd9fb7dbc202050829b4eb292. --- .../com/jme3/system/android/OGLESContext.java | 4 ++-- .../java/com/jme3/app/LegacyApplication.java | 16 ++++++++-------- .../main/java/com/jme3/system/JmeContext.java | 4 ++-- .../{DisplayInfo.java => MonitorInfo.java} | 4 ++-- .../jme3/system/{Displays.java => Monitors.java} | 14 +++++++------- .../main/java/com/jme3/system/NullContext.java | 4 ++-- .../main/java/com/jme3/system/AWTContext.java | 4 ++-- .../com/jme3/system/awt/AwtPanelsContext.java | 4 ++-- .../main/java/jme3test/app/TestMonitorApp.java | 10 +++++----- .../java/com/jme3/system/ios/IGLESContext.java | 4 ++-- .../java/com/jme3/system/lwjgl/LwjglCanvas.java | 6 +++--- .../java/com/jme3/system/lwjgl/LwjglDisplay.java | 6 +++--- .../jme3/system/lwjgl/LwjglOffscreenBuffer.java | 6 +++--- .../java/com/jme3/system/lwjgl/LwjglWindow.java | 16 ++++++++-------- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 6 +++--- 15 files changed, 54 insertions(+), 54 deletions(-) rename jme3-core/src/main/java/com/jme3/system/{DisplayInfo.java => MonitorInfo.java} (97%) rename jme3-core/src/main/java/com/jme3/system/{Displays.java => Monitors.java} (91%) diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index e15dbeb930..005a579b7e 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -557,13 +557,13 @@ private Rect getSurfaceFrame() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index 3565191b1a..e74874b095 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -820,22 +820,22 @@ public Object call() { } /** - * This call will return a list of Displays that glfwGetMonitors() returns and information about + * This call will return a list of Monitors that glfwGetMonitors() returns and information about * the monitor, like width, height, and refresh rate. * - * @return returns a list of Displays and their information. + * @return returns a list of monitors and their information. */ - public Displays getDisplays() { - return context.getDisplays(); + public Monitors getMonitors() { + return context.getMonitors(); } /** - * Use this to get the positional number of the primary Displays from the glfwGetMonitors() + * Use this to get the positional number of the primary monitor from the glfwGetMonitors() * function call. * - * @return the position of the value in the arraylist of the primary Displays. + * @return the position of the value in the arraylist of the primary monitor. */ - public int getPrimaryDisplay() { - return context.getPrimaryDisplay(); + public int getPrimaryMonitor() { + return context.getPrimaryMonitor(); } } diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index 34e4971f63..258639634f 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -232,7 +232,7 @@ public enum Type { * * @return returns a list of monitors and their information. */ - public Displays getDisplays(); + public Monitors getMonitors(); /** * Use this to get the positional number of the primary monitor from the glfwGetMonitors() @@ -240,5 +240,5 @@ public enum Type { * * @return the position of the value in the arraylist of the primary monitor. */ - public int getPrimaryDisplay(); + public int getPrimaryMonitor(); } diff --git a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java similarity index 97% rename from jme3-core/src/main/java/com/jme3/system/DisplayInfo.java rename to jme3-core/src/main/java/com/jme3/system/MonitorInfo.java index 249d7f52ec..a7791d37b2 100644 --- a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java @@ -31,12 +31,12 @@ * * @author Kevin Bales */ -public class DisplayInfo { +public class MonitorInfo { /** * monitorID - monitor id that was return from Lwjgl3. */ - public long displayID = 0; + public long monitorID = 0; /** * width - width that was return from Lwjgl3. diff --git a/jme3-core/src/main/java/com/jme3/system/Displays.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java similarity index 91% rename from jme3-core/src/main/java/com/jme3/system/Displays.java rename to jme3-core/src/main/java/com/jme3/system/Monitors.java index f6d9446a2c..b834e518f8 100644 --- a/jme3-core/src/main/java/com/jme3/system/Displays.java +++ b/jme3-core/src/main/java/com/jme3/system/Monitors.java @@ -33,13 +33,13 @@ * * @author Kevin Bales */ -public class Displays { +public class Monitors { - private ArrayList monitors = new ArrayList(); + private ArrayList monitors = new ArrayList(); public int addNewMonitor(long monitorID) { - DisplayInfo info = new DisplayInfo(); - info.displayID = monitorID; + MonitorInfo info = new MonitorInfo(); + info.monitorID = monitorID; monitors.add(info); return monitors.size() - 1; } @@ -59,7 +59,7 @@ public int size() { * @param pos the position in the arraylist of the monitor information that you want to get. * @return returns the MonitorInfo data for the monitor called for. */ - public DisplayInfo get(int pos) { + public MonitorInfo get(int pos) { if (pos < monitors.size()) return monitors.get(pos); @@ -76,7 +76,7 @@ public DisplayInfo get(int pos) { */ public void setInfo(int monPos, String name, int width, int height, int rate) { if (monPos < monitors.size()) { - DisplayInfo info = monitors.get(monPos); + MonitorInfo info = monitors.get(monPos); if (info != null) { info.width = width; info.height = height; @@ -93,7 +93,7 @@ public void setInfo(int monPos, String name, int width, int height, int rate) { */ public void setPrimaryMonitor(int monPos) { if (monPos < monitors.size()) { - DisplayInfo info = monitors.get(monPos); + MonitorInfo info = monitors.get(monPos); if (info != null) info.primary = true; } diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index b317ce24ed..e58f143b45 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -308,13 +308,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java index 095bcd6691..c58b2c44af 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java @@ -277,13 +277,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index fc165bb1fd..afb8003fcd 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -330,13 +330,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index e4018f8f9e..bf3b837fdd 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -49,8 +49,8 @@ import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.system.AppSettings; -import com.jme3.system.DisplayInfo; -import com.jme3.system.Displays; +import com.jme3.system.MonitorInfo; +import com.jme3.system.Monitors; /** * Tests the capability to change which monitor the window will be created on. @@ -67,7 +67,7 @@ public class TestMonitorApp extends SimpleApplication private BitmapText selectedMonitorTxt; private BitmapText fullScreenTxt; private int monitorSelected = 0; - private Displays monitors = null; + private Monitors monitors = null; public static void main(String[] args) { TestMonitorApp app = new TestMonitorApp(); @@ -116,7 +116,7 @@ public void simpleInitApp() { // Get the selected monitor monitorSelected = settings.getMonitor(); - monitors = context.getDisplays(); + monitors = context.getMonitors(); if (monitors != null) numMonitors = monitors.size(); @@ -155,7 +155,7 @@ public void simpleInitApp() { // Let's loop through all the monitors and display on the screen for (int i = 0; i < monitors.size(); i++) { - DisplayInfo monitor = monitors.get(i); + MonitorInfo monitor = monitors.get(i); labelValue = "Mon : " + i + " " + monitor.name + " " + monitor.width + "," + monitor.height + " refresh: " + monitor.rate; txt = new BitmapText(loadGuiFont()); diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index 0343dadbd8..2a18b56569 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -269,13 +269,13 @@ public int getWindowYPosition() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 7fe2964ac8..7728c11257 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -30,7 +30,7 @@ import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystem; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import com.jme3.system.Platform; import java.awt.Canvas; import java.util.logging.Level; @@ -484,13 +484,13 @@ protected void createContext(AppSettings settings) { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 1516dc54a1..020746256b 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -34,7 +34,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext.Type; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import java.awt.Graphics2D; import java.awt.image.BufferedImage; @@ -285,13 +285,13 @@ private ByteBuffer imageToByteBuffer(BufferedImage image) { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 727890a981..86add690a4 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -38,7 +38,7 @@ import com.jme3.input.TouchInput; import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -221,13 +221,13 @@ public void setTitle(String title) { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index f7bfb06c53..d9f23baeeb 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -43,7 +43,7 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; import com.jme3.system.NanoTimer; import com.jme3.util.BufferUtils; import com.jme3.util.SafeArrayList; @@ -882,12 +882,12 @@ public int getWindowYPosition() { * @return returns the Primary Monitor Position. */ @Override - public int getPrimaryDisplay() + public int getPrimaryMonitor() { long prim = glfwGetPrimaryMonitor(); - Displays monitors = getDisplays(); + Monitors monitors = getMonitors(); for ( int i = 0; i < monitors.size(); i++ ) { - long monitorI = monitors.get(i).displayID; + long monitorI = monitors.get(i).monitorID; if (monitorI == prim) return i; } @@ -905,9 +905,9 @@ public int getPrimaryDisplay() * @return return the monitorID if found otherwise return Primary Monitor */ private long getMonitor(int pos) { - Displays monitors = getDisplays(); + Monitors monitors = getMonitors(); if (pos < monitors.size()) - return monitors.get(pos).displayID; + return monitors.get(pos).monitorID; LOGGER.log(Level.SEVERE,"Couldn't locate Monitor requested in the list of Monitors. pos:"+pos+" size: "+ monitors.size()); return glfwGetPrimaryMonitor(); @@ -922,10 +922,10 @@ private long getMonitor(int pos) { */ @Override - public Displays getDisplays() { + public Monitors getMonitors() { PointerBuffer monitors = glfwGetMonitors(); long primary = glfwGetPrimaryMonitor(); - Displays monitorList = new Displays(); + Monitors monitorList = new Monitors(); for ( int i = 0; i < monitors.limit(); i++ ) { long monitorI = monitors.get(i); diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index 2f557d8ae5..f7f08126ba 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -32,7 +32,7 @@ package com.jme3.system.lwjgl; import com.jme3.opencl.Context; -import com.jme3.system.Displays; +import com.jme3.system.Monitors; /** * A VR oriented LWJGL display. @@ -54,13 +54,13 @@ public Context getOpenCLContext() { } @Override - public Displays getDisplays() { + public Monitors getMonitors() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryDisplay() { + public int getPrimaryMonitor() { // TODO Auto-generated method stub return 0; } From 80881090e7f05122642b183759ec58603069b03c Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Fri, 22 Sep 2023 20:35:17 -0500 Subject: [PATCH 11/18] Merge branch 'master' of https://github.com/bob0bob/jmonkeyengine # Conflicts: # jme3-core/src/main/java/com/jme3/app/LegacyApplication.java --- .github/workflows/format.yml | 21 + .github/workflows/main.yml | 12 +- .vscode/JME_style.xml | 8 +- README.md | 4 +- build.gradle | 2 +- common.gradle | 27 +- config/checkstyle/checkstyle-suppressions.xml | 6 + config/checkstyle/checkstyle.xml | 361 ++++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- jme3-android-examples/build.gradle | 2 +- .../com/jme3/renderer/android/AndroidGL.java | 32 +- .../jme3/system/android/JmeAndroidSystem.java | 4 +- .../main/java/com/jme3/anim/ArmatureMask.java | 49 +- .../com/jme3/anim/tween/AbstractTween.java | 3 + .../anim/tween/action/BlendableAction.java | 3 + .../src/main/java/com/jme3/app/AppTask.java | 13 +- .../main/java/com/jme3/app/Application.java | 6 +- .../main/java/com/jme3/app/BasicProfiler.java | 6 +- .../java/com/jme3/app/BasicProfilerState.java | 83 +- .../com/jme3/app/ChaseCameraAppState.java | 6 +- .../java/com/jme3/app/DebugKeysAppState.java | 11 +- .../java/com/jme3/app/DetailedProfiler.java | 23 +- .../com/jme3/app/DetailedProfilerState.java | 53 +- .../java/com/jme3/app/LegacyApplication.java | 841 ------------------ .../java/com/jme3/app/SimpleApplication.java | 20 +- .../src/main/java/com/jme3/app/StatsView.java | 11 +- .../main/java/com/jme3/asset/AssetConfig.java | 4 +- .../java/com/jme3/asset/AssetManager.java | 21 +- .../com/jme3/asset/DesktopAssetManager.java | 8 +- .../main/java/com/jme3/audio/Environment.java | 25 + .../java/com/jme3/export/JmeExporter.java | 23 +- .../com/jme3/export/SavableClassUtil.java | 4 + .../input/JoystickCompatibilityMappings.java | 8 +- .../main/java/com/jme3/light/PointLight.java | 5 + .../com/jme3/post/FilterPostProcessor.java | 8 +- .../main/java/com/jme3/post/HDRRenderer.java | 6 +- .../src/main/java/com/jme3/renderer/Caps.java | 16 + .../java/com/jme3/renderer/RenderManager.java | 40 +- .../main/java/com/jme3/renderer/Renderer.java | 6 + .../com/jme3/renderer/opengl/GLES_30.java | 7 + .../jme3/renderer/opengl/GLImageFormats.java | 2 +- .../com/jme3/renderer/opengl/GLRenderer.java | 134 ++- .../scene/instancing/InstancedGeometry.java | 14 + .../com/jme3/shader/ShaderNodeDefinition.java | 4 +- .../java/com/jme3/system/AppSettings.java | 4 +- .../com/jme3/system/JmeSystemDelegate.java | 5 +- .../main/java/com/jme3/system/JmeVersion.java | 4 +- .../java/com/jme3/system/NullRenderer.java | 5 + .../main/java/com/jme3/system/Platform.java | 14 +- .../jme3/util/res/DefaultResourceLoader.java | 72 ++ .../com/jme3/util/res/ResourceLoader.java | 81 ++ .../java/com/jme3/util/res/Resources.java | 182 ++++ .../Common/MatDefs/Blur/HGaussianBlur.j3md | 9 +- .../Common/MatDefs/Blur/RadialBlur.j3md | 6 +- .../Common/MatDefs/Blur/VGaussianBlur.j3md | 9 +- .../resources/Common/MatDefs/Gui/Gui.j3md | 19 +- .../resources/Common/MatDefs/Hdr/LogLum.j3md | 6 +- .../resources/Common/MatDefs/Hdr/ToneMap.j3md | 6 +- .../Common/MatDefs/Light/Deferred.j3md | 6 +- .../Common/MatDefs/Light/Deferred.vert | 2 + .../resources/Common/MatDefs/Light/GBuf.vert | 2 + .../Common/MatDefs/Light/Lighting.j3md | 33 +- .../Common/MatDefs/Light/PBRLighting.j3md | 28 +- .../Common/MatDefs/Misc/ColoredTextured.j3md | 12 +- .../Common/MatDefs/Misc/ColoredTextured.vert | 2 + .../Common/MatDefs/Misc/Particle.j3md | 21 +- .../Common/MatDefs/Misc/ShowNormals.j3md | 6 +- .../resources/Common/MatDefs/Misc/Sky.j3md | 6 +- .../Common/MatDefs/Misc/SkyNonCube.j3md | 6 +- .../Common/MatDefs/Misc/Unshaded.j3md | 26 +- .../MatDefs/Shadow/BasicPostShadow.j3md | 6 +- .../Common/MatDefs/Shadow/PostShadow.j3md | 6 +- .../MatDefs/Shadow/PostShadowFilter.j3md | 11 +- .../Common/MatDefs/Shadow/PreShadow.j3md | 12 +- .../Common/ShaderLib/GLSLCompat.glsllib | 36 +- .../Common/ShaderLib/Shadows.glsllib | 3 +- .../jme3/asset/plugins/ClasspathLocator.java | 20 +- .../jme3/export/binary/BinaryExporter.java | 4 +- .../jme3/export/binary/BinaryImporter.java | 7 +- .../anim/tween/action/ClipActionTest.java | 80 ++ .../jme3/material/MaterialMatParamTest.java | 2 +- .../java/com/jme3/material/MaterialTest.java | 2 +- .../jme3/system/MockJmeSystemDelegate.java | 4 +- .../test/java/com/jme3/system/TestUtil.java | 12 +- .../main/java/com/jme3/app/AppletHarness.java | 4 +- .../com/jme3/system/JmeDesktopSystem.java | 4 +- .../com/jme3/system/NativeLibraryLoader.java | 12 +- .../Common/MatDefs/Post/BloomExtract.j3md | 6 +- .../Common/MatDefs/Post/BloomFinal.j3md | 8 +- .../Common/MatDefs/Post/CartoonEdge.j3md | 6 +- .../Common/MatDefs/Post/Compose.j3md | 6 +- .../MatDefs/Post/ContrastAdjustment.frag | 6 +- .../MatDefs/Post/ContrastAdjustment.j3md | 16 +- .../MatDefs/Post/ContrastAdjustment15.frag | 95 -- .../Common/MatDefs/Post/CrossHatch.j3md | 9 +- .../Common/MatDefs/Post/DepthOfField.j3md | 6 +- .../resources/Common/MatDefs/Post/FXAA.j3md | 9 +- .../resources/Common/MatDefs/Post/Fade.j3md | 6 +- .../resources/Common/MatDefs/Post/Fog.j3md | 6 +- .../Common/MatDefs/Post/LightScattering.j3md | 6 +- .../Common/MatDefs/Post/Overlay.j3md | 6 +- .../resources/Common/MatDefs/Post/Post15.vert | 2 + .../Common/MatDefs/Post/Posterization.j3md | 8 +- .../Common/MatDefs/Post/ToneMap.j3md | 6 +- .../resources/Common/MatDefs/SSAO/ssao.j3md | 4 +- .../Common/MatDefs/SSAO/ssaoBlur.j3md | 4 +- .../Common/MatDefs/Water/SimpleWater.j3md | 9 +- .../resources/Common/MatDefs/Water/Water.j3md | 4 +- .../java/jme3test/export/TestIssue2068.java | 96 ++ .../java/jme3test/renderer/TestIssue2011.java | 107 +++ .../java/jme3test/renderer/TestIssue798.java | 156 ++++ .../terrain/TerrainGridTileLoaderTest.java | 2 +- .../java/com/jme3/renderer/ios/IosGL.java | 15 + .../com/jme3/system/ios/JmeIosSystem.java | 4 +- jme3-jogg/build.gradle | 2 +- jme3-lwjgl/build.gradle | 1 - .../Common/MatDefs/Nifty/NiftyQuad.j3md | 4 +- .../Common/MatDefs/Nifty/NiftyQuadGrad.j3md | 4 +- .../Common/MatDefs/Nifty/NiftyTex.j3md | 4 +- jme3-plugins-json-gson/build.gradle | 16 + .../java/com/jme3/plugins/gson/GsonArray.java | 80 ++ .../com/jme3/plugins/gson/GsonElement.java | 104 +++ .../com/jme3/plugins/gson/GsonObject.java | 113 +++ .../com/jme3/plugins/gson/GsonParser.java | 48 + .../com/jme3/plugins/gson/GsonPrimitive.java | 64 ++ .../com/jme3/plugins/gson/package-info.java | 37 + jme3-plugins-json/build.gradle | 14 + .../main/java/com/jme3/plugins/json/Json.java | 111 +++ .../java/com/jme3/plugins/json/JsonArray.java | 55 ++ .../com/jme3/plugins/json/JsonElement.java | 102 +++ .../com/jme3/plugins/json/JsonObject.java | 95 ++ .../com/jme3/plugins/json/JsonParser.java | 50 ++ .../com/jme3/plugins/json/JsonPrimitive.java | 90 ++ .../com/jme3/plugins/json/package-info.java | 36 + jme3-plugins/build.gradle | 3 +- .../plugins/gltf/CustomContentManager.java | 4 +- .../scene/plugins/gltf/ExtensionLoader.java | 2 +- .../jme3/scene/plugins/gltf/ExtrasLoader.java | 3 +- .../jme3/scene/plugins/gltf/GltfLoader.java | 10 +- .../jme3/scene/plugins/gltf/GltfUtils.java | 17 +- .../gltf/LightsPunctualExtensionLoader.java | 6 +- .../gltf/PBRSpecGlossExtensionLoader.java | 3 +- .../gltf/TextureTransformExtensionLoader.java | 6 +- .../plugins/gltf/UnlitExtensionLoader.java | 3 +- .../plugin/export/material/J3MExporter.java | 7 +- .../java/com/jme3/export/JmeExporterTest.java | 125 +++ .../com/jme3/export/xml/DOMInputCapsule.java | 2 +- .../java/com/jme3/export/xml/XMLExporter.java | 7 +- .../MatDefs/Terrain/AdvancedPBRTerrain.j3md | 16 +- .../MatDefs/Terrain/HeightBasedTerrain.j3md | 9 +- .../Common/MatDefs/Terrain/PBRTerrain.j3md | 16 +- .../Common/MatDefs/Terrain/Terrain.j3md | 6 +- .../MatDefs/Terrain/TerrainLighting.j3md | 26 +- .../resources/Materials/Geom/SimpleGeom.geom | 2 + .../Materials/Tess/SimpleTess.tsctrl | 2 + .../Materials/Tess/SimpleTess.tseval | 2 + jme3-vr/build.gradle | 1 + .../main/java/com/jme3/app/VRApplication.java | 3 +- .../Common/MatDefs/VR/CartoonSSAO.j3md | 11 +- .../Common/MatDefs/VR/GuiOverlay.j3md | 11 +- .../resources/Common/MatDefs/VR/OpenVR.j3md | 15 +- .../Common/MatDefs/VR/PostShadowFilter.j3md | 11 +- .../resources/Common/MatDefs/VR/Unshaded.j3md | 11 +- settings.gradle | 3 + 164 files changed, 3336 insertions(+), 1386 deletions(-) create mode 100644 .github/workflows/format.yml create mode 100644 config/checkstyle/checkstyle-suppressions.xml create mode 100644 config/checkstyle/checkstyle.xml delete mode 100644 jme3-core/src/main/java/com/jme3/app/LegacyApplication.java create mode 100644 jme3-core/src/main/java/com/jme3/util/res/DefaultResourceLoader.java create mode 100644 jme3-core/src/main/java/com/jme3/util/res/ResourceLoader.java create mode 100644 jme3-core/src/main/java/com/jme3/util/res/Resources.java create mode 100644 jme3-core/src/test/java/com/jme3/anim/tween/action/ClipActionTest.java delete mode 100644 jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment15.frag create mode 100644 jme3-examples/src/main/java/jme3test/export/TestIssue2068.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java create mode 100644 jme3-plugins-json-gson/build.gradle create mode 100644 jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonArray.java create mode 100644 jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonElement.java create mode 100644 jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonObject.java create mode 100644 jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonParser.java create mode 100644 jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonPrimitive.java create mode 100644 jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/package-info.java create mode 100644 jme3-plugins-json/build.gradle create mode 100644 jme3-plugins-json/src/main/java/com/jme3/plugins/json/Json.java create mode 100644 jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonArray.java create mode 100644 jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonElement.java create mode 100644 jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonObject.java create mode 100644 jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonParser.java create mode 100644 jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonPrimitive.java create mode 100644 jme3-plugins-json/src/main/java/com/jme3/plugins/json/package-info.java create mode 100644 jme3-plugins/src/test/java/com/jme3/export/JmeExporterTest.java diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000000..e9a84895e6 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,21 @@ +name: auto-format +on: + push: + +jobs: + format: + runs-on: ubuntu-latest + if: github.repository != 'jMonkeyEngine/jmonkeyengine' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Prettify code + uses: creyD/prettier_action@v4.3 + with: + prettier_options: --tab-width 4 --print-width 110 --write **/**/*.java + prettier_version: "2.8.8" + only_changed: True + commit_message: "auto-format" + prettier_plugins: "prettier-plugin-java" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 23d0923658..8d588302c9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -65,11 +65,11 @@ jobs: steps: - name: Clone the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 - name: Validate the Gradle wrapper - uses: gradle/wrapper-validation-action@v1.0.5 + uses: gradle/wrapper-validation-action@v1 - name: Build run: | ./gradlew -PuseCommitHashAsVersionName=true --no-daemon -PbuildNativeProjects=true \ @@ -108,7 +108,7 @@ jobs: steps: - name: Clone the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 @@ -125,7 +125,7 @@ jobs: path: build/native - name: Validate the Gradle wrapper - uses: gradle/wrapper-validation-action@v1.0.5 + uses: gradle/wrapper-validation-action@v1 - name: Build Engine shell: bash run: | @@ -301,7 +301,7 @@ jobs: # We need to clone everything again for uploadToMaven.sh ... - name: Clone the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 @@ -345,7 +345,7 @@ jobs: # We need to clone everything again for uploadToMaven.sh ... - name: Clone the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 diff --git a/.vscode/JME_style.xml b/.vscode/JME_style.xml index 7e54d4f76f..b4014b077e 100644 --- a/.vscode/JME_style.xml +++ b/.vscode/JME_style.xml @@ -43,7 +43,7 @@ - + @@ -89,7 +89,7 @@ - + @@ -220,7 +220,7 @@ - + @@ -264,7 +264,7 @@ - + diff --git a/README.md b/README.md index f267b36b85..792e20d798 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ jMonkeyEngine [![Build Status](https://github.com/jMonkeyEngine/jmonkeyengine/workflows/Build%20jMonkeyEngine/badge.svg)](https://github.com/jMonkeyEngine/jmonkeyengine/actions) jMonkeyEngine is a 3-D game engine for adventurous Java developers. It’s open-source, cross-platform, and cutting-edge. -v3.6.0 is the latest stable version of the engine. +v3.6.1 is the latest stable version of the engine. The engine is used by several commercial game studios and computer-science courses. Here's a taste: @@ -28,9 +28,9 @@ The engine is used by several commercial game studios and computer-science cours - [Chatter Games](https://chatter-games.com) - [Exotic Matter](https://exoticmatter.io) - [Demon Lord (on Google Play)](https://play.google.com/store/apps/details?id=com.dreiInitiative.demonLord&pli=1) - - [Wild Magic](http://wildmagicgame.ru/) - [Marvelous Marbles (on Steam)](https://store.steampowered.com/app/2244540/Marvelous_Marbles/) - [Boxer (on Google Play)](https://play.google.com/store/apps/details?id=com.tharg.boxer) + - [Depthris (on Itch)](https://codewalker.itch.io/depthris) ## Getting started diff --git a/build.gradle b/build.gradle index 2a7b4ed0c5..f4c20e0e4c 100644 --- a/build.gradle +++ b/build.gradle @@ -283,7 +283,7 @@ if (skipPrebuildLibraries != "true" && buildNativeProjects != "true") { //} wrapper { - gradleVersion = '7.6' + gradleVersion = '7.6.2' } diff --git a/common.gradle b/common.gradle index e97fe498ad..dc429f97aa 100644 --- a/common.gradle +++ b/common.gradle @@ -7,6 +7,8 @@ apply plugin: 'groovy' apply plugin: 'maven-publish' apply plugin: 'signing' apply plugin: 'eclipse' +apply plugin: 'checkstyle' + eclipse.jdt.file.withProperties { props -> props.setProperty "org.eclipse.jdt.core.circularClasspath", "warning" } @@ -41,7 +43,7 @@ dependencies { // Adding dependencies here will add the dependencies to each subproject. testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:3.12.4' - testImplementation 'org.codehaus.groovy:groovy-test:3.0.17' + testImplementation 'org.codehaus.groovy:groovy-test:3.0.19' } // Uncomment if you want to see the status of every test that is run and @@ -183,7 +185,7 @@ publishing { } publishToMavenLocal.doLast { - println 'published ' + project.getName() + "-${jmeFullVersion} to mavenLocal" + println 'published ' + project.getName() + "-${jmeFullVersion} to mavenLocal" } task('install') { dependsOn 'publishToMavenLocal' @@ -200,3 +202,24 @@ signing { tasks.withType(Sign) { onlyIf { gradle.rootProject.hasProperty('signingKey') } } + +checkstyle { + toolVersion '9.3' + configFile file("${gradle.rootProject.rootDir}/config/checkstyle/checkstyle.xml") +} + +checkstyleMain { + source ='src/main/java' +} + +checkstyleTest { + source ='src/test/java' +} + +tasks.withType(Checkstyle) { + reports { + xml.enabled false + html.enabled true + } + include("**/com/jme3/renderer/**/*.java") +} \ No newline at end of file diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml new file mode 100644 index 0000000000..919d0a916f --- /dev/null +++ b/config/checkstyle/checkstyle-suppressions.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..927c3779c9 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 508322917b..4e86b92707 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jme3-android-examples/build.gradle b/jme3-android-examples/build.gradle index 5bc2d1cecd..44bd254d84 100644 --- a/jme3-android-examples/build.gradle +++ b/jme3-android-examples/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 28 - buildToolsVersion "28.0.3" + buildToolsVersion "30.0.2" lintOptions { // Fix nifty gui referencing "java.awt" package. diff --git a/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java b/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java index c9b4dac5e2..4c2601e1d4 100644 --- a/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java +++ b/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java @@ -45,6 +45,7 @@ public class AndroidGL implements GL, GL2, GLES_30, GLExt, GLFbo { IntBuffer tmpBuff = BufferUtils.createIntBuffer(1); + IntBuffer tmpBuff16 = BufferUtils.createIntBuffer(16); @Override public void resetStats() { @@ -694,10 +695,17 @@ public void glPolygonMode(int face, int mode) { // Wrapper to DrawBuffers as there's no DrawBuffer method in GLES @Override public void glDrawBuffer(int mode) { - tmpBuff.clear(); - tmpBuff.put(0, mode); - tmpBuff.rewind(); - glDrawBuffers(tmpBuff); + int nBuffers = (mode - GLFbo.GL_COLOR_ATTACHMENT0_EXT) + 1; + if (nBuffers <= 0 || nBuffers > 16) { + throw new IllegalArgumentException("Draw buffer outside range: " + Integer.toHexString(mode)); + } + tmpBuff16.clear(); + for (int i = 0; i < nBuffers - 1; i++) { + tmpBuff16.put(GL.GL_NONE); + } + tmpBuff16.put(mode); + tmpBuff16.flip(); + glDrawBuffers(tmpBuff16); } @Override @@ -729,5 +737,21 @@ public void glTexSubImage3D(int target, int level, int xoffset, int yoffset, int GLES30.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data); } + @Override + public void glBindVertexArray(int array) { + GLES30.glBindVertexArray(array); + } + + @Override + public void glDeleteVertexArrays(IntBuffer arrays) { + GLES30.glDeleteVertexArrays(arrays.limit(),arrays); + } + + @Override + public void glGenVertexArrays(IntBuffer arrays) { + GLES30.glGenVertexArrays(arrays.limit(),arrays); + + } + } diff --git a/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java b/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java index 0d6ee82c6d..dc0cfe5588 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java +++ b/jme3-android/src/main/java/com/jme3/system/android/JmeAndroidSystem.java @@ -17,7 +17,7 @@ import com.jme3.system.*; import com.jme3.system.JmeContext.Type; import com.jme3.util.AndroidScreenshots; -import com.jme3.util.functional.VoidFunction; +import com.jme3.util.res.Resources; import java.io.File; import java.io.IOException; @@ -52,7 +52,7 @@ public JmeAndroidSystem(){ @Override public URL getPlatformAssetConfigURL() { - return Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Android.cfg"); + return Resources.getResource("com/jme3/asset/Android.cfg"); } @Override diff --git a/jme3-core/src/main/java/com/jme3/anim/ArmatureMask.java b/jme3-core/src/main/java/com/jme3/anim/ArmatureMask.java index 3aa2342f28..7f889fc042 100644 --- a/jme3-core/src/main/java/com/jme3/anim/ArmatureMask.java +++ b/jme3-core/src/main/java/com/jme3/anim/ArmatureMask.java @@ -1,3 +1,34 @@ +/* + * Copyright (c) 2009-2023 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. + */ package com.jme3.anim; import java.util.BitSet; @@ -49,6 +80,9 @@ private BitSet getAffectedJoints() { * @param armature the Armature containing the joints (not null, unaffected) * @param jointNames the names of the joints to be removed * @return this + * + * @throws IllegalArgumentException if it can not find the joint + * with the specified name on the provided armature */ public ArmatureMask removeJoints(Armature armature, String... jointNames) { for (String jointName : jointNames) { @@ -72,6 +106,9 @@ public boolean contains(Object target) { * @param armature the Armature containing the joints (not null) * @param fromJoint the name of the ancestor joint * @return a new mask + * + * @throws IllegalArgumentException if it can not find the joint + * with the specified name on the provided armature */ public static ArmatureMask createMask(Armature armature, String fromJoint) { ArmatureMask mask = new ArmatureMask(); @@ -85,13 +122,13 @@ public static ArmatureMask createMask(Armature armature, String fromJoint) { * @param armature the Armature containing the joints (not null) * @param joints the names of the joints to be included * @return a new mask + * + * @throws IllegalArgumentException if it can not find the joint + * with the specified name on the provided armature */ public static ArmatureMask createMask(Armature armature, String... joints) { ArmatureMask mask = new ArmatureMask(); mask.addBones(armature, joints); - for (String joint : joints) { - mask.affectedJoints.set(armature.getJoint(joint).getId()); - } return mask; } @@ -100,6 +137,9 @@ public static ArmatureMask createMask(Armature armature, String... joints) { * * @param armature the Armature containing the joints * @param jointNames the names of the joints to be influenced + * + * @throws IllegalArgumentException if it can not find the joint + * with the specified name on the provided armature */ public void addBones(Armature armature, String... jointNames) { for (String jointName : jointNames) { @@ -121,6 +161,9 @@ private Joint findJoint(Armature armature, String jointName) { * * @param armature the Armature containing the ancestor joint * @param jointName the names of the ancestor joint + * + * @throws IllegalArgumentException if it can not find the joint + * with the specified name on the provided armature */ public void addFromJoint(Armature armature, String jointName) { Joint joint = findJoint(armature, jointName); diff --git a/jme3-core/src/main/java/com/jme3/anim/tween/AbstractTween.java b/jme3-core/src/main/java/com/jme3/anim/tween/AbstractTween.java index 9dd961b530..5216051f64 100644 --- a/jme3-core/src/main/java/com/jme3/anim/tween/AbstractTween.java +++ b/jme3-core/src/main/java/com/jme3/anim/tween/AbstractTween.java @@ -57,6 +57,9 @@ public double getLength() { } public void setLength(double length) { + if (length < 0.0) { + throw new IllegalArgumentException("length must be greater than or equal to 0"); + } this.length = length; } diff --git a/jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java b/jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java index c9882529f9..9064fb042e 100644 --- a/jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java +++ b/jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java @@ -105,6 +105,9 @@ public double getTransitionLength() { } public void setTransitionLength(double transitionLength) { + if (transitionLength < 0.0) { + throw new IllegalArgumentException("transitionLength must be greater than or equal to 0"); + } this.transitionLength = transitionLength; this.transition.setLength(transitionLength); } diff --git a/jme3-core/src/main/java/com/jme3/app/AppTask.java b/jme3-core/src/main/java/com/jme3/app/AppTask.java index 59e96c4046..a7122765a5 100644 --- a/jme3-core/src/main/java/com/jme3/app/AppTask.java +++ b/jme3-core/src/main/java/com/jme3/app/AppTask.java @@ -31,7 +31,12 @@ */ package com.jme3.app; -import java.util.concurrent.*; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; @@ -52,7 +57,8 @@ public class AppTask implements Future { private V result; private ExecutionException exception; - private boolean cancelled, finished; + private boolean cancelled; + private boolean finished; private final ReentrantLock stateLock = new ReentrantLock(); private final Condition finishedCondition = stateLock.newCondition(); @@ -100,7 +106,8 @@ public V get() throws InterruptedException, ExecutionException { } @Override - public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + public V get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { stateLock.lock(); try { if (!isDone()) { diff --git a/jme3-core/src/main/java/com/jme3/app/Application.java b/jme3-core/src/main/java/com/jme3/app/Application.java index 198d730efa..dba60e140c 100644 --- a/jme3-core/src/main/java/com/jme3/app/Application.java +++ b/jme3-core/src/main/java/com/jme3/app/Application.java @@ -41,7 +41,9 @@ import com.jme3.renderer.RenderManager; import com.jme3.renderer.Renderer; import com.jme3.renderer.ViewPort; -import com.jme3.system.*; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeContext; +import com.jme3.system.Timer; import java.util.concurrent.Callable; import java.util.concurrent.Future; @@ -226,7 +228,7 @@ public interface Application { * After the application has stopped, it cannot be used anymore. * @param waitFor true→wait for the context to be fully destroyed, - * true→don't wait + * false→don't wait */ public void stop(boolean waitFor); diff --git a/jme3-core/src/main/java/com/jme3/app/BasicProfiler.java b/jme3-core/src/main/java/com/jme3/app/BasicProfiler.java index e7ae0a7884..1c95730bbc 100644 --- a/jme3-core/src/main/java/com/jme3/app/BasicProfiler.java +++ b/jme3-core/src/main/java/com/jme3/app/BasicProfiler.java @@ -32,7 +32,11 @@ package com.jme3.app; -import com.jme3.profile.*; + +import com.jme3.profile.AppProfiler; +import com.jme3.profile.AppStep; +import com.jme3.profile.SpStep; +import com.jme3.profile.VpStep; import com.jme3.renderer.ViewPort; import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.scene.Mesh; diff --git a/jme3-core/src/main/java/com/jme3/app/BasicProfilerState.java b/jme3-core/src/main/java/com/jme3/app/BasicProfilerState.java index d7b56511a6..68ee1483fb 100644 --- a/jme3-core/src/main/java/com/jme3/app/BasicProfilerState.java +++ b/jme3-core/src/main/java/com/jme3/app/BasicProfilerState.java @@ -122,53 +122,52 @@ protected void refreshBackground() { float frameTime = 1000f / 60; mesh.setBuffer(Type.Position, 3, new float[] { - // first quad - 0, 0, 0, - size, 0, 0, - size, frameTime, 0, - 0, frameTime, 0, - - // second quad - 0, frameTime, 0, - size, frameTime, 0, - size, frameTime * 2, 0, - 0, frameTime * 2, 0, - - // A lower dark border just to frame the - // 'update' stats against bright backgrounds - 0, -2, 0, - size, -2, 0, - size, 0, 0, - 0, 0, 0 - }); + // first quad + 0, 0, 0, + size, 0, 0, + size, frameTime, 0, + 0, frameTime, 0, + // second quad + 0, frameTime, 0, + size, frameTime, 0, + size, frameTime * 2, 0, + 0, frameTime * 2, 0, + + // A lower dark border just to frame the + // 'update' stats against bright backgrounds + 0, -2, 0, + size, -2, 0, + size, 0, 0, + 0, 0, 0 + }); mesh.setBuffer(Type.Color, 4, new float[] { // first quad, within normal frame limits - 0, 1, 0, 0.25f, - 0, 1, 0, 0.25f, - 0, 0.25f, 0, 0.25f, - 0, 0.25f, 0, 0.25f, - - // Second quad, dropped frames - 0.25f, 0, 0, 0.25f, - 0.25f, 0, 0, 0.25f, - 1, 0, 0, 0.25f, - 1, 0, 0, 0.25f, - - 0, 0, 0, 0.5f, - 0, 0, 0, 0.5f, - 0, 0, 0, 0.5f, - 0, 0, 0, 0.5f - }); + 0, 1, 0, 0.25f, + 0, 1, 0, 0.25f, + 0, 0.25f, 0, 0.25f, + 0, 0.25f, 0, 0.25f, + + // Second quad, dropped frames + 0.25f, 0, 0, 0.25f, + 0.25f, 0, 0, 0.25f, + 1, 0, 0, 0.25f, + 1, 0, 0, 0.25f, + + 0, 0, 0, 0.5f, + 0, 0, 0, 0.5f, + 0, 0, 0, 0.5f, + 0, 0, 0, 0.5f + }); mesh.setBuffer(Type.Index, 3, new short[] { - 0, 1, 2, - 0, 2, 3, - 4, 5, 6, - 4, 6, 7, - 8, 9, 10, - 8, 10, 11 - }); + 0, 1, 2, + 0, 2, 3, + 4, 5, 6, + 4, 6, 7, + 8, 9, 10, + 8, 10, 11 + }); } @Override diff --git a/jme3-core/src/main/java/com/jme3/app/ChaseCameraAppState.java b/jme3-core/src/main/java/com/jme3/app/ChaseCameraAppState.java index f4beacdf85..9e3740bec9 100644 --- a/jme3-core/src/main/java/com/jme3/app/ChaseCameraAppState.java +++ b/jme3-core/src/main/java/com/jme3/app/ChaseCameraAppState.java @@ -82,7 +82,8 @@ public class ChaseCameraAppState extends AbstractAppState implements ActionListe protected Vector3f leftVector = new Vector3f(); protected Trigger[] zoomOutTrigger = {new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true)}; protected Trigger[] zoomInTrigger = {new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false)}; - protected Trigger[] toggleRotateTrigger = {new MouseButtonTrigger(MouseInput.BUTTON_LEFT), new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)}; + protected Trigger[] toggleRotateTrigger = {new MouseButtonTrigger(MouseInput.BUTTON_LEFT), + new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)}; // // protected boolean rotating = false; @@ -209,7 +210,8 @@ public void setTarget(Spatial targetSpatial) { @Override public void update(float tpf) { if (spatial == null) { - throw new IllegalArgumentException("The spatial to follow is null, please use the setTarget method"); + throw new IllegalArgumentException( + "The spatial to follow is null, please use the setTarget method"); } target.setLocalTranslation(spatial.getWorldTranslation()); camNode.lookAt(target.getWorldTranslation(), upVector); diff --git a/jme3-core/src/main/java/com/jme3/app/DebugKeysAppState.java b/jme3-core/src/main/java/com/jme3/app/DebugKeysAppState.java index 61919d4f86..143e13210a 100644 --- a/jme3-core/src/main/java/com/jme3/app/DebugKeysAppState.java +++ b/jme3-core/src/main/java/com/jme3/app/DebugKeysAppState.java @@ -55,7 +55,7 @@ public class DebugKeysAppState extends AbstractAppState { public static final String INPUT_MAPPING_MEMORY = "SIMPLEAPP_Memory"; private Application app; - final private DebugKeyListener keyListener = new DebugKeyListener(); + private final DebugKeyListener keyListener = new DebugKeyListener(); private InputManager inputManager; public DebugKeysAppState() { @@ -83,10 +83,12 @@ public void initialize(AppStateManager stateManager, Application app) { public void cleanup() { super.cleanup(); - if (inputManager.hasMapping(INPUT_MAPPING_CAMERA_POS)) + if (inputManager.hasMapping(INPUT_MAPPING_CAMERA_POS)) { inputManager.deleteMapping(INPUT_MAPPING_CAMERA_POS); - if (inputManager.hasMapping(INPUT_MAPPING_MEMORY)) + } + if (inputManager.hasMapping(INPUT_MAPPING_MEMORY)) { inputManager.deleteMapping(INPUT_MAPPING_MEMORY); + } inputManager.removeListener(keyListener); } @@ -111,7 +113,8 @@ public void onAction(String name, boolean value, float tpf) { System.out.println("Camera Direction: " + cam.getDirection()); System.out.println("cam.setLocation(new Vector3f(" + loc.x + "f, " + loc.y + "f, " + loc.z + "f));"); - System.out.println("cam.setRotation(new Quaternion(" + rot.getX() + "f, " +rot.getY()+ "f, " + rot.getZ() + "f, " + rot.getW() + "f));"); + System.out.println("cam.setRotation(new Quaternion(" + rot.getX() + "f, " + rot.getY() + + "f, " + rot.getZ() + "f, " + rot.getW() + "f));"); } } else if (name.equals(INPUT_MAPPING_MEMORY)) { diff --git a/jme3-core/src/main/java/com/jme3/app/DetailedProfiler.java b/jme3-core/src/main/java/com/jme3/app/DetailedProfiler.java index 13700a870a..2936a30072 100644 --- a/jme3-core/src/main/java/com/jme3/app/DetailedProfiler.java +++ b/jme3-core/src/main/java/com/jme3/app/DetailedProfiler.java @@ -43,7 +43,7 @@ */ public class DetailedProfiler implements AppProfiler { - private final static int MAX_FRAMES = 100; + private static final int MAX_FRAMES = 100; private Map data; private Map pool; private long startFrame; @@ -59,10 +59,10 @@ public class DetailedProfiler implements AppProfiler { private String curSpPath = null; private VpStep lastVpStep = null; - final private StringBuilder path = new StringBuilder(256); - final private StringBuilder vpPath = new StringBuilder(256); + private final StringBuilder path = new StringBuilder(256); + private final StringBuilder vpPath = new StringBuilder(256); - final private Deque idsPool = new ArrayDeque<>(100); + private final Deque idsPool = new ArrayDeque<>(100); StatLine frameTime; @@ -152,14 +152,17 @@ public void vpStep(VpStep step, ViewPort vp, RenderQueue.Bucket bucket) { if (data != null) { vpPath.setLength(0); - vpPath.append(vp.getName()).append("/").append((bucket == null ? step.name() : bucket.name() + " Bucket")); + vpPath.append(vp.getName()).append("/") + .append((bucket == null ? step.name() : bucket.name() + " Bucket")); path.setLength(0); if ((lastVpStep == VpStep.PostQueue || lastVpStep == VpStep.PostFrame) && bucket != null) { - path.append(curAppPath).append("/").append(curVpPath).append(curSpPath).append("/").append(vpPath); + path.append(curAppPath).append("/").append(curVpPath).append(curSpPath).append("/") + .append(vpPath); curVpPath = vpPath.toString(); } else { if (bucket != null) { - path.append(curAppPath).append("/").append(curVpPath).append("/").append(bucket.name() + " Bucket"); + path.append(curAppPath).append("/").append(curVpPath).append("/") + .append(bucket.name() + " Bucket"); } else { path.append(curAppPath).append("/").append(vpPath); curVpPath = vpPath.toString(); @@ -185,7 +188,7 @@ public void spStep(SpStep step, String... additionalInfo) { public Map getStats() { if (data != null) { - return data;//new LinkedHashMap<>(data); + return data; //new LinkedHashMap<>(data); } return null; } @@ -256,8 +259,8 @@ private int getUnusedTaskId() { } public static class StatLine { - final private long[] cpuTimes = new long[MAX_FRAMES]; - final private long[] gpuTimes = new long[MAX_FRAMES]; + private final long[] cpuTimes = new long[MAX_FRAMES]; + private final long[] gpuTimes = new long[MAX_FRAMES]; private int startCursor = 0; private int cpuCursor = 0; private int gpuCursor = 0; diff --git a/jme3-core/src/main/java/com/jme3/app/DetailedProfilerState.java b/jme3-core/src/main/java/com/jme3/app/DetailedProfilerState.java index 1aa244a797..7a3e0393cc 100644 --- a/jme3-core/src/main/java/com/jme3/app/DetailedProfilerState.java +++ b/jme3-core/src/main/java/com/jme3/app/DetailedProfilerState.java @@ -60,13 +60,13 @@ public class DetailedProfilerState extends BaseAppState { private static final String TOGGLE_KEY = "Toggle_Detailed_Profiler"; private static final String CLICK_KEY = "Click_Detailed_Profiler"; private static final String INSIGNIFICANT = "Hide insignificant stat"; - final private DetailedProfiler prof = new DetailedProfiler(); + private final DetailedProfiler prof = new DetailedProfiler(); private float time = 0; private BitmapFont font; private BitmapFont bigFont; - final private Node ui = new Node("Stats ui"); - final private Map lines = new HashMap<>(); + private final Node ui = new Node("Stats ui"); + private final Map lines = new HashMap<>(); private double totalTimeCpu; private double totalTimeGpu; private int maxLevel = 0; @@ -83,14 +83,14 @@ public class DetailedProfilerState extends BaseAppState { private StatLineView rootLine; private int height = 0; - final private DecimalFormat df = new DecimalFormat("##0.00", new DecimalFormatSymbols(Locale.US)); + private final DecimalFormat df = new DecimalFormat("##0.00", new DecimalFormatSymbols(Locale.US)); - final private ColorRGBA dimmedWhite = ColorRGBA.White.mult(0.7f); - final private ColorRGBA dimmedGreen = ColorRGBA.Green.mult(0.7f); - final private ColorRGBA dimmedOrange = ColorRGBA.Orange.mult(0.7f); - final private ColorRGBA dimmedRed = ColorRGBA.Red.mult(0.7f); + private final ColorRGBA dimmedWhite = ColorRGBA.White.mult(0.7f); + private final ColorRGBA dimmedGreen = ColorRGBA.Green.mult(0.7f); + private final ColorRGBA dimmedOrange = ColorRGBA.Orange.mult(0.7f); + private final ColorRGBA dimmedRed = ColorRGBA.Red.mult(0.7f); - final private ProfilerInputListener inputListener = new ProfilerInputListener(); + private final ProfilerInputListener inputListener = new ProfilerInputListener(); public DetailedProfilerState() { @@ -101,7 +101,8 @@ protected void initialize(Application app) { Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); mat.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); - Geometry darkenStats = new Geometry("StatsDarken", new Quad(PANEL_WIDTH, app.getCamera().getHeight())); + Geometry darkenStats = new Geometry("StatsDarken", new Quad(PANEL_WIDTH, + app.getCamera().getHeight())); darkenStats.setMaterial(mat); darkenStats.setLocalTranslation(0, -app.getCamera().getHeight(), -1); @@ -116,17 +117,20 @@ protected void initialize(Application app) { BitmapText frameLabel = new BitmapText(bigFont); frameLabel.setText("Total Frame Time: "); ui.attachChild(frameLabel); - frameLabel.setLocalTranslation(new Vector3f(PANEL_WIDTH / 2 - bigFont.getLineWidth(frameLabel.getText()), -PADDING, 0)); + frameLabel.setLocalTranslation( + new Vector3f(PANEL_WIDTH / 2 - bigFont.getLineWidth(frameLabel.getText()), -PADDING, 0)); BitmapText cpuLabel = new BitmapText(bigFont); cpuLabel.setText("CPU"); ui.attachChild(cpuLabel); - cpuLabel.setLocalTranslation(PANEL_WIDTH / 4 - bigFont.getLineWidth(cpuLabel.getText()) / 2, -PADDING - 30, 0); + cpuLabel.setLocalTranslation(PANEL_WIDTH / 4 - bigFont.getLineWidth(cpuLabel.getText()) / 2, + -PADDING - 30, 0); BitmapText gpuLabel = new BitmapText(bigFont); gpuLabel.setText("GPU"); ui.attachChild(gpuLabel); - gpuLabel.setLocalTranslation(3 * PANEL_WIDTH / 4 - bigFont.getLineWidth(gpuLabel.getText()) / 2, -PADDING - 30, 0); + gpuLabel.setLocalTranslation(3 * PANEL_WIDTH / 4 - bigFont.getLineWidth(gpuLabel.getText()) / 2, + -PADDING - 30, 0); frameTimeValue = new BitmapText(bigFont); frameCpuTimeValue = new BitmapText(bigFont); @@ -221,16 +225,22 @@ private void layout() { setColor(frameTimeValue, prof.getAverageFrameTime(), totalTimeCpu, false, false); frameCpuTimeValue.setText(df.format(getMsFromNs(totalTimeCpu)) + "ms"); - frameCpuTimeValue.setLocalTranslation(new Vector3f(PANEL_WIDTH / 4 - bigFont.getLineWidth(frameCpuTimeValue.getText()) / 2, -PADDING - 50, 0)); + frameCpuTimeValue.setLocalTranslation( + new Vector3f(PANEL_WIDTH / 4 - bigFont.getLineWidth(frameCpuTimeValue.getText()) / 2, + -PADDING - 50, 0)); setColor(frameCpuTimeValue, totalTimeCpu, totalTimeCpu, false, false); frameGpuTimeValue.setText(df.format(getMsFromNs(totalTimeGpu)) + "ms"); - frameGpuTimeValue.setLocalTranslation(new Vector3f(3 * PANEL_WIDTH / 4 - bigFont.getLineWidth(frameGpuTimeValue.getText()) / 2, -PADDING - 50, 0)); + frameGpuTimeValue.setLocalTranslation( + new Vector3f(3 * PANEL_WIDTH / 4 - bigFont.getLineWidth(frameGpuTimeValue.getText()) / 2, + -PADDING - 50, 0)); setColor(frameGpuTimeValue, totalTimeGpu, totalTimeGpu, false, false); - selectedField.setText("Selected: " + df.format(getMsFromNs(selectedValueCpu)) + "ms / " + df.format(getMsFromNs(selectedValueGpu)) + "ms"); + selectedField.setText("Selected: " + df.format(getMsFromNs(selectedValueCpu)) + "ms / " + + df.format(getMsFromNs(selectedValueGpu)) + "ms"); - selectedField.setLocalTranslation(3 * PANEL_WIDTH / 4 - font.getLineWidth(selectedField.getText()) / 2, -PADDING - 75, 0); + selectedField.setLocalTranslation( + 3 * PANEL_WIDTH / 4 - font.getLineWidth(selectedField.getText()) / 2, -PADDING - 75, 0); } private StatLineView getStatLineView(String path) { @@ -285,7 +295,8 @@ protected void onDisable() { ui.removeFromParent(); } - public boolean setColor(BitmapText t, double value, double totalTime, boolean isParent, boolean expended) { + public boolean setColor(BitmapText t, double value, double totalTime, boolean isParent, + boolean expended) { boolean dimmed = isParent && expended; boolean insignificant = false; @@ -413,7 +424,8 @@ public void layout(int indent) { int y = -(height * LINE_HEIGHT + HEADER_HEIGHT); label.setLocalTranslation(PADDING + indent * PADDING, y, 0); - float gpuPos = PANEL_WIDTH - font.getLineWidth(gpuText.getText()) - PADDING * (maxLevel - indent + 1); + float gpuPos = PANEL_WIDTH - font.getLineWidth(gpuText.getText()) + - PADDING * (maxLevel - indent + 1); cpuText.setLocalTranslation(gpuPos - font.getLineWidth(cpuText.getText()), y, 0); gpuText.setLocalTranslation(gpuPos, y, 0); @@ -466,7 +478,8 @@ public void setVisible(boolean visible) { @Override public String toString() { - return label.getText() + " - " + df.format(getMsFromNs(cpuValue)) + "ms / " + df.format(getMsFromNs(gpuValue)) + "ms"; + return label.getText() + " - " + df.format(getMsFromNs(cpuValue)) + "ms / " + + df.format(getMsFromNs(gpuValue)) + "ms"; } } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java deleted file mode 100644 index e74874b095..0000000000 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ /dev/null @@ -1,841 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ -package com.jme3.app; - -import com.jme3.app.state.AppState; -import com.jme3.app.state.AppStateManager; -import com.jme3.asset.AssetManager; -import com.jme3.audio.AudioContext; -import com.jme3.audio.AudioRenderer; -import com.jme3.audio.Listener; -import com.jme3.input.*; -import com.jme3.math.Vector3f; -import com.jme3.profile.AppProfiler; -import com.jme3.profile.AppStep; -import com.jme3.renderer.Camera; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.Renderer; -import com.jme3.renderer.ViewPort; -import com.jme3.system.*; -import com.jme3.system.JmeContext.Type; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Future; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * The LegacyApplication class represents an instance of a real-time 3D rendering jME - * application. - * - * An LegacyApplication provides all the tools that are commonly used in jME3 - * applications. - * - * jME3 applications *SHOULD NOT EXTEND* this class but extend - * {@link com.jme3.app.SimpleApplication} instead. - * - */ -public class LegacyApplication implements Application, SystemListener { - - private static final Logger logger = Logger.getLogger(LegacyApplication.class.getName()); - - protected AssetManager assetManager; - - protected AudioRenderer audioRenderer; - protected Renderer renderer; - protected RenderManager renderManager; - protected ViewPort viewPort; - protected ViewPort guiViewPort; - - protected JmeContext context; - protected AppSettings settings; - protected Timer timer = new NanoTimer(); - protected Camera cam; - protected Listener listener; - - protected boolean inputEnabled = true; - protected LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus; - protected float speed = 1f; - protected boolean paused = false; - protected MouseInput mouseInput; - protected KeyInput keyInput; - protected JoyInput joyInput; - protected TouchInput touchInput; - protected InputManager inputManager; - protected AppStateManager stateManager; - - protected AppProfiler prof; - - private final ConcurrentLinkedQueue> taskQueue = new ConcurrentLinkedQueue<>(); - - /** - * Create a new instance of LegacyApplication. - */ - public LegacyApplication() { - this((AppState[]) null); - } - - /** - * Create a new instance of LegacyApplication, preinitialized with the specified set - * of app states. - * - * @param initialStates app states to pre-attach, or null for none - */ - public LegacyApplication(AppState... initialStates) { - initStateManager(); - - if (initialStates != null) { - for (AppState a : initialStates) { - if (a != null) { - stateManager.attach(a); - } - } - } - } - - /** - * Determine the application's behavior when unfocused. - * - * @return The lost focus behavior of the application. - */ - @Override - public LostFocusBehavior getLostFocusBehavior() { - return lostFocusBehavior; - } - - /** - * Changes the application's behavior when unfocused. - * - * By default, the application will {@link LostFocusBehavior#ThrottleOnLostFocus throttle the - * update loop} so as not to use 100% of the CPU when out of focus, e.g. alt-tabbed, minimized, or - * hidden by another window. - * - * @param lostFocusBehavior The new lost focus behavior to use. - * - * @see LostFocusBehavior - */ - @Override - public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) { - this.lostFocusBehavior = lostFocusBehavior; - } - - /** - * Returns true if pause on lost focus is enabled, false otherwise. - * - * @return true if pause on lost focus is enabled - * - * @see #getLostFocusBehavior() - */ - @Override - public boolean isPauseOnLostFocus() { - return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus; - } - - /** - * 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 be undesirable, so this feature should be disabled. For other applications, it is best to - * keep it enabled so the CPU is not used unnecessarily. - * - * @param pauseOnLostFocus True to enable pause on lost focus, false otherwise. - * - * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior) - */ - @Override - public void setPauseOnLostFocus(boolean pauseOnLostFocus) { - if (pauseOnLostFocus) { - setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus); - } else { - setLostFocusBehavior(LostFocusBehavior.Disabled); - } - } - - @Deprecated - public void setAssetManager(AssetManager assetManager) { - if (this.assetManager != null) - throw new IllegalStateException("Can only set asset manager" + " before initialization."); - - this.assetManager = assetManager; - } - - private void initAssetManager() { - URL assetCfgUrl = null; - - if (settings != null) { - String assetCfg = settings.getString("AssetConfigURL"); - if (assetCfg != null) { - try { - assetCfgUrl = new URL(assetCfg); - } catch (MalformedURLException ex) { - } - if (assetCfgUrl == null) { - assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg); - if (assetCfgUrl == null) { - logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", - assetCfg); - return; - } - } - } - } - if (assetCfgUrl == null) { - assetCfgUrl = JmeSystem.getPlatformAssetConfigURL(); - } - if (assetManager == null) { - assetManager = JmeSystem.newAssetManager(assetCfgUrl); - } - } - - /** - * Set the display settings to define the display created. - *

- * Examples of display parameters include display pixel width and height, color bit depth, - * z-buffer bits, anti-aliasing samples, and update frequency. If this method is called while the - * application is already running, then {@link #restart() } must be called to apply the settings - * to the display. - * - * @param settings The settings to set. - */ - @Override - public void setSettings(AppSettings settings) { - this.settings = settings; - if (context != null && settings.useInput() != inputEnabled) { - // may need to create or destroy input based - // on settings change - inputEnabled = !inputEnabled; - if (inputEnabled) { - initInput(); - } else { - destroyInput(); - } - } else { - inputEnabled = settings.useInput(); - } - } - - /** - * Sets the Timer implementation that will be used for calculating frame times. By default, - * Application will use the Timer as returned by the current JmeContext implementation. - */ - @Override - public void setTimer(Timer timer) { - this.timer = timer; - - if (timer != null) { - timer.reset(); - } - - if (renderManager != null) { - renderManager.setTimer(timer); - } - } - - @Override - public Timer getTimer() { - return timer; - } - - private void initDisplay() { - // acquire important objects - // from the context - settings = context.getSettings(); - - // Only reset the timer if a user has not already provided one - if (timer == null) { - timer = context.getTimer(); - } - - renderer = context.getRenderer(); - } - - private void initAudio() { - if (settings.getAudioRenderer() != null && context.getType() != Type.Headless) { - audioRenderer = JmeSystem.newAudioRenderer(settings); - audioRenderer.initialize(); - AudioContext.setAudioRenderer(audioRenderer); - - listener = new Listener(); - audioRenderer.setListener(listener); - } - } - - /** - * Creates the camera to use for rendering. Default values are perspective projection with 45° - * field of view, with near and far values 1 and 1000 units respectively. - */ - private void initCamera() { - cam = new Camera(settings.getWidth(), settings.getHeight()); - - cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 1f, 1000f); - cam.setLocation(new Vector3f(0f, 0f, 10f)); - cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); - - renderManager = new RenderManager(renderer); - // Remy - 09/14/2010 set the timer in the renderManager - renderManager.setTimer(timer); - - if (prof != null) { - renderManager.setAppProfiler(prof); - } - - viewPort = renderManager.createMainView("Default", cam); - viewPort.setClearFlags(true, true, true); - - // Create a new cam for the gui - Camera guiCam = new Camera(settings.getWidth(), settings.getHeight()); - guiViewPort = renderManager.createPostView("Gui Default", guiCam); - guiViewPort.setClearFlags(false, false, false); - } - - /** - * Initializes mouse and keyboard input. Also initializes joystick input if joysticks are enabled - * in the AppSettings. - */ - private void initInput() { - mouseInput = context.getMouseInput(); - if (mouseInput != null) - mouseInput.initialize(); - - keyInput = context.getKeyInput(); - if (keyInput != null) - keyInput.initialize(); - - touchInput = context.getTouchInput(); - if (touchInput != null) - touchInput.initialize(); - - if (settings.useJoysticks()) { - joyInput = context.getJoyInput(); - if (joyInput != null) - joyInput.initialize(); - } - - inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput); - } - - private void initStateManager() { - stateManager = new AppStateManager(this); - - // Always register a ResetStatsState to make sure - // that the stats are cleared every frame - stateManager.attach(new ResetStatsState()); - } - - /** - * @return The {@link AssetManager asset manager} for this application. - */ - @Override - public AssetManager getAssetManager() { - return assetManager; - } - - /** - * @return the {@link InputManager input manager}. - */ - @Override - public InputManager getInputManager() { - return inputManager; - } - - /** - * @return the {@link AppStateManager app state manager} - */ - @Override - public AppStateManager getStateManager() { - return stateManager; - } - - /** - * @return the {@link RenderManager render manager} - */ - @Override - public RenderManager getRenderManager() { - return renderManager; - } - - /** - * @return The {@link Renderer renderer} for the application - */ - @Override - public Renderer getRenderer() { - return renderer; - } - - /** - * @return The {@link AudioRenderer audio renderer} for the application - */ - @Override - public AudioRenderer getAudioRenderer() { - return audioRenderer; - } - - /** - * @return The {@link Listener listener} object for audio - */ - @Override - public Listener getListener() { - return listener; - } - - /** - * @return The {@link JmeContext display context} for the application - */ - @Override - public JmeContext getContext() { - return context; - } - - /** - * @return The {@link Camera camera} for the application - */ - @Override - public Camera getCamera() { - return cam; - } - - /** - * Starts the application in {@link Type#Display display} mode. - * - * @see #start(com.jme3.system.JmeContext.Type) - */ - @Override - public void start() { - start(JmeContext.Type.Display, false); - } - - /** - * Starts the application in {@link Type#Display display} mode. - * - * @param waitFor true→wait for the context to be initialized, false→don't wait - * @see #start(com.jme3.system.JmeContext.Type) - */ - @Override - public void start(boolean waitFor) { - start(JmeContext.Type.Display, waitFor); - } - - /** - * Starts the application. Creating a rendering context and executing the main loop in a separate - * thread. - * - * @param contextType the type of context to create - */ - public void start(JmeContext.Type contextType) { - start(contextType, false); - } - - /** - * Starts the application. Creating a rendering context and executing the main loop in a separate - * thread. - * - * @param contextType the type of context to create - * @param waitFor true→wait for the context to be initialized, false→don't wait - */ - public void start(JmeContext.Type contextType, boolean waitFor) { - if (context != null && context.isCreated()) { - logger.warning("start() called when application already created!"); - return; - } - - if (settings == null) { - settings = new AppSettings(true); - } - - logger.log(Level.FINE, "Starting application: {0}", getClass().getName()); - context = JmeSystem.newContext(settings, contextType); - context.setSystemListener(this); - context.create(waitFor); - } - - /** - * Sets an AppProfiler hook that will be called back for specific steps within a single update - * frame. Value defaults to null. - * - * @param prof the profiler to use (alias created) or null for none - */ - @Override - public void setAppProfiler(AppProfiler prof) { - this.prof = prof; - if (renderManager != null) { - renderManager.setAppProfiler(prof); - } - } - - /** - * Returns the current AppProfiler hook, or null if none is set. - */ - @Override - public AppProfiler getAppProfiler() { - return prof; - } - - /** - * Initializes the application's canvas for use. - *

- * After calling this method, cast the {@link #getContext()} context to JmeCanvasContext, then - * acquire the canvas with 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 Type#Canvas - */ - public void createCanvas() { - if (context != null && context.isCreated()) { - logger.warning("createCanvas() called when application already created!"); - return; - } - - if (settings == null) { - settings = new AppSettings(true); - } - - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "Starting application: {0}", getClass().getName()); - } - context = JmeSystem.newContext(settings, JmeContext.Type.Canvas); - 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. - */ - @Override - public void reshape(int w, int h) { - if (renderManager != null) { - renderManager.notifyReshape(w, h); - } - } - - - @Override - public void rescale(float x, float y) { - if (renderManager != null) { - renderManager.notifyRescale(x, y); - } - } - - /** - * 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. - */ - @Override - 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) - */ - @Override - public void stop() { - stop(false); - } - - /** - * 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. - * - * @param waitFor true→wait for the context to be fully destroyed, true→don't wait - */ - @Override - public void stop(boolean waitFor) { - logger.log(Level.FINE, "Closing application: {0}", getClass().getName()); - context.destroy(waitFor); - } - - /** - * 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; perspective projection with 45° field of view, with near and far values 1 and 1000 - * units respectively. - */ - @Override - public void initialize() { - if (assetManager == null) { - initAssetManager(); - } - - initDisplay(); - initCamera(); - - if (inputEnabled) { - initInput(); - } - initAudio(); - - // update timer so that the next delta is not too large - // timer.update(); - timer.reset(); - - // user code here - } - - /** - * Internal use only. - */ - @Override - public void handleError(String errMsg, Throwable t) { - // Print error to log. - logger.log(Level.SEVERE, errMsg, t); - // Display error message on screen if not in headless mode - if (context.getType() != JmeContext.Type.Headless) { - if (t != null) { - JmeSystem.handleErrorMessage(errMsg + "\n" + t.getClass().getSimpleName() - + (t.getMessage() != null ? ": " + t.getMessage() : "")); - } else { - JmeSystem.handleErrorMessage(errMsg); - } - } - - stop(); // stop the application - } - - /** - * Internal use only. - */ - @Override - public void gainFocus() { - if (lostFocusBehavior != LostFocusBehavior.Disabled) { - if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { - paused = false; - } - context.setAutoFlushFrames(true); - if (inputManager != null) { - inputManager.reset(); - } - } - } - - /** - * Internal use only. - */ - @Override - public void loseFocus() { - if (lostFocusBehavior != LostFocusBehavior.Disabled) { - if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) { - paused = true; - } - context.setAutoFlushFrames(false); - } - } - - /** - * Internal use only. - */ - @Override - public void requestClose(boolean esc) { - context.destroy(false); - } - - /** - * Enqueues a task/callable object to execute in the jME3 rendering thread. - *

- * Callables are executed right at the beginning of the main loop. They are executed even if the - * application is currently paused or out of focus. - * - * @param type of result returned by the Callable - * @param callable The callable to run in the main jME3 thread - * @return a new instance - */ - @Override - public Future enqueue(Callable callable) { - AppTask task = new AppTask<>(callable); - taskQueue.add(task); - return task; - } - - /** - * Enqueues a runnable object to execute in the jME3 rendering thread. - *

- * Runnables are executed right at the beginning of the main loop. They are executed even if the - * application is currently paused or out of focus. - * - * @param runnable The runnable to run in the main jME3 thread - */ - @Override - @SuppressWarnings("unchecked") - public void enqueue(Runnable runnable) { - enqueue(new RunnableWrapper(runnable)); - } - - /** - * Runs tasks enqueued via {@link #enqueue(Callable)} - */ - protected void runQueuedTasks() { - AppTask task; - while ((task = taskQueue.poll()) != null) { - if (!task.isCancelled()) { - task.invoke(); - } - } - } - - /** - * Do not call manually. Callback from ContextListener. - */ - @Override - public void update() { - // Make sure the audio renderer is available to callables - AudioContext.setAudioRenderer(audioRenderer); - - if (prof != null) - prof.appStep(AppStep.QueuedTasks); - runQueuedTasks(); - - if (speed == 0 || paused) - return; - - timer.update(); - - if (inputEnabled) { - if (prof != null) - prof.appStep(AppStep.ProcessInput); - inputManager.update(timer.getTimePerFrame()); - } - - if (audioRenderer != null) { - if (prof != null) - prof.appStep(AppStep.ProcessAudio); - audioRenderer.update(timer.getTimePerFrame()); - } - - // user code here - } - - protected void destroyInput() { - if (mouseInput != null) - mouseInput.destroy(); - - if (keyInput != null) - keyInput.destroy(); - - if (joyInput != null) - joyInput.destroy(); - - if (touchInput != null) - touchInput.destroy(); - - inputManager = null; - } - - /** - * Do not call manually. Callback from ContextListener. - */ - @Override - public void destroy() { - stateManager.cleanup(); - - destroyInput(); - if (audioRenderer != null) - audioRenderer.cleanup(); - - timer.reset(); - } - - /** - * @return The GUI viewport. Which is used for the on screen statistics and FPS. - */ - @Override - public ViewPort getGuiViewPort() { - return guiViewPort; - } - - @Override - public ViewPort getViewPort() { - return viewPort; - } - - private class RunnableWrapper implements Callable { - private final Runnable runnable; - - public RunnableWrapper(Runnable runnable) { - this.runnable = runnable; - } - - @Override - public Object call() { - runnable.run(); - return null; - } - } - - /** - * This call will return a list of Monitors that glfwGetMonitors() returns and information about - * the monitor, like width, height, and refresh rate. - * - * @return returns a list of monitors and their information. - */ - public Monitors getMonitors() { - return context.getMonitors(); - } - - /** - * Use this to get the positional number of the primary monitor from the glfwGetMonitors() - * function call. - * - * @return the position of the value in the arraylist of the primary monitor. - */ - public int getPrimaryMonitor() { - return context.getPrimaryMonitor(); - } -} diff --git a/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java b/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java index 90e1bb33e0..f1f21b58cc 100644 --- a/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/SimpleApplication.java @@ -76,7 +76,7 @@ public abstract class SimpleApplication extends LegacyApplication { protected BitmapFont guiFont; protected FlyByCamera flyCam; protected boolean showSettings = true; - final private AppActionListener actionListener = new AppActionListener(); + private final AppActionListener actionListener = new AppActionListener(); private class AppActionListener implements ActionListener { @@ -242,8 +242,9 @@ public void initialize() { @Override public void update() { - if (prof != null) + if (prof != null) { prof.appStep(AppStep.BeginFrame); + } super.update(); // makes sure to execute AppTasks if (speed == 0 || paused) { @@ -253,15 +254,17 @@ public void update() { float tpf = timer.getTimePerFrame() * speed; // update states - if (prof != null) + if (prof != null) { prof.appStep(AppStep.StateManagerUpdate); + } stateManager.update(tpf); // simple update and root node simpleUpdate(tpf); - if (prof != null) + if (prof != null) { prof.appStep(AppStep.SpatialUpdate); + } rootNode.updateLogicalState(tpf); guiNode.updateLogicalState(tpf); @@ -269,18 +272,21 @@ public void update() { guiNode.updateGeometricState(); // render states - if (prof != null) + if (prof != null) { prof.appStep(AppStep.StateManagerRender); + } stateManager.render(renderManager); - if (prof != null) + if (prof != null) { prof.appStep(AppStep.RenderFrame); + } renderManager.render(tpf, context.isRenderable()); simpleRender(renderManager); stateManager.postRender(); - if (prof != null) + if (prof != null) { prof.appStep(AppStep.EndFrame); + } } public void setDisplayFps(boolean show) { diff --git a/jme3-core/src/main/java/com/jme3/app/StatsView.java b/jme3-core/src/main/java/com/jme3/app/StatsView.java index f6b28fb642..8e274e97b5 100644 --- a/jme3-core/src/main/java/com/jme3/app/StatsView.java +++ b/jme3-core/src/main/java/com/jme3/app/StatsView.java @@ -60,11 +60,11 @@ * */ public class StatsView extends Node implements Control, JmeCloneable { - final private BitmapText statText; - final private Statistics statistics; + private final BitmapText statText; + private final Statistics statistics; - final private String[] statLabels; - final private int[] statData; + private final String[] statLabels; + private final int[] statData; private boolean enabled = true; @@ -96,8 +96,9 @@ public float getHeight() { @Override public void update(float tpf) { - if (!isEnabled()) + if (!isEnabled()) { return; + } statistics.getData(statData); stringBuilder.setLength(0); diff --git a/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java b/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java index be2c834ea9..3307cca4cb 100644 --- a/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java +++ b/jme3-core/src/main/java/com/jme3/asset/AssetConfig.java @@ -39,6 +39,8 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.jme3.util.res.Resources; + /** * AssetConfig loads a config file to configure the asset manager. * @@ -101,7 +103,7 @@ public static void loadText(AssetManager assetManager, URL configUrl) throws IOE } } else if (cmd.equals("INCLUDE")) { String includedCfg = scan.nextLine().trim(); - URL includedCfgUrl = Thread.currentThread().getContextClassLoader().getResource(includedCfg); + URL includedCfgUrl = Resources.getResource(includedCfg); if (includedCfgUrl != null) { loadText(assetManager, includedCfgUrl); } else { diff --git a/jme3-core/src/main/java/com/jme3/asset/AssetManager.java b/jme3-core/src/main/java/com/jme3/asset/AssetManager.java index cde85ecec1..73762a1234 100644 --- a/jme3-core/src/main/java/com/jme3/asset/AssetManager.java +++ b/jme3-core/src/main/java/com/jme3/asset/AssetManager.java @@ -46,6 +46,7 @@ import com.jme3.texture.plugins.TGALoader; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.EnumSet; import java.util.List; @@ -86,7 +87,7 @@ * so that modifications to one instance do not leak onto others. */ public interface AssetManager { - + /** * Adds a {@link ClassLoader} that is used to load {@link Class classes} * that are needed for finding and loading Assets. @@ -94,23 +95,35 @@ public interface AssetManager { * use registerLocator for that. * * @param loader A ClassLoader that Classes in asset files can be loaded from. + * @deprecated use {@link com.jme3.util.res.Resources} */ - public void addClassLoader(ClassLoader loader); + @Deprecated + public default void addClassLoader(ClassLoader loader) { + + } /** * Remove a {@link ClassLoader} from the list of registered ClassLoaders * * @param loader the ClassLoader to be removed + * @deprecated use {@link com.jme3.util.res.Resources} */ - public void removeClassLoader(ClassLoader loader); + @Deprecated + public default void removeClassLoader(ClassLoader loader) { + + } /** * Retrieve the list of registered ClassLoaders that are used for loading * {@link Class classes} from asset files. * * @return an unmodifiable list + * @deprecated use {@link com.jme3.util.res.Resources} */ - public List getClassLoaders(); + @Deprecated + public default List getClassLoaders() { + return new ArrayList<>(); + } /** * Register an {@link AssetLoader} by using a class object. diff --git a/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java b/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java index c81e56fec5..a8ff73f2c4 100644 --- a/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java +++ b/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java @@ -73,8 +73,8 @@ public class DesktopAssetManager implements AssetManager { final private CopyOnWriteArrayList eventListeners = new CopyOnWriteArrayList<>(); - final private List classLoaders = - Collections.synchronizedList(new ArrayList<>()); + @Deprecated + final private List classLoaders = Collections.synchronizedList(new ArrayList<>()); public DesktopAssetManager() { this(null); @@ -99,21 +99,23 @@ private void loadConfigFile(URL configFile) { } } + @Deprecated @Override public void addClassLoader(ClassLoader loader) { classLoaders.add(loader); } + @Deprecated @Override public void removeClassLoader(ClassLoader loader) { classLoaders.remove(loader); } + @Deprecated @Override public List getClassLoaders() { return Collections.unmodifiableList(classLoaders); } - @Override public void addAssetEventListener(AssetEventListener listener) { eventListeners.add(listener); diff --git a/jme3-core/src/main/java/com/jme3/audio/Environment.java b/jme3-core/src/main/java/com/jme3/audio/Environment.java index b974ee25d3..d6d39b8a76 100644 --- a/jme3-core/src/main/java/com/jme3/audio/Environment.java +++ b/jme3-core/src/main/java/com/jme3/audio/Environment.java @@ -252,4 +252,29 @@ public float getRoomRolloffFactor() { public void setRoomRolloffFactor(float roomRolloffFactor) { this.roomRolloffFactor = roomRolloffFactor; } + + @Override + public boolean equals(Object env2) { + if (env2 == null) + return false; + if (env2 == this) + return true; + if (!(env2 instanceof Environment)) + return false; + + Environment e2 = (Environment) env2; + return (e2.airAbsorbGainHf == airAbsorbGainHf + && e2.decayHFRatio == decayHFRatio + && e2.decayHfLimit == decayHfLimit + && e2.decayTime == decayTime + && e2.density == density + && e2.diffusion == diffusion + && e2.gain == gain + && e2.gainHf == gainHf + && e2.lateReverbDelay == lateReverbDelay + && e2.lateReverbGain == lateReverbGain + && e2.reflectDelay == reflectDelay + && e2.reflectGain == reflectGain + && e2.roomRolloffFactor == roomRolloffFactor); + } } diff --git a/jme3-core/src/main/java/com/jme3/export/JmeExporter.java b/jme3-core/src/main/java/com/jme3/export/JmeExporter.java index b8c3abc605..f93cb2560d 100644 --- a/jme3-core/src/main/java/com/jme3/export/JmeExporter.java +++ b/jme3-core/src/main/java/com/jme3/export/JmeExporter.java @@ -51,14 +51,29 @@ public interface JmeExporter { public void save(Savable object, OutputStream f) throws IOException; /** - * Export the {@link Savable} to a file. - * + * Export the {@link Savable} to a file. If the path to the file doesn't exist, the directories are + * made. + * * @param object The savable to export * @param f The file to export to * @throws IOException If an io exception occurs during export */ - public void save(Savable object, File f) throws IOException; - + default void save(Savable object, File f) throws IOException { + save(object, f, true); + } + + /** + * Export the {@link Savable} to a file. If the path to the file doesn't exist, the parent + * directories can be created if the createDirectories flag is true. If the path does + * not exist and createDirectories is false, then an exception is thrown. + * + * @param object The savable to export + * @param f The file to export to + * @param createDirectories flag to indicate if the directories should be created + * @throws IOException If an io exception occurs during export + */ + public void save(Savable object, File f, boolean createDirectories) throws IOException; + /** * Returns the {@link OutputCapsule} for the given savable object. * diff --git a/jme3-core/src/main/java/com/jme3/export/SavableClassUtil.java b/jme3-core/src/main/java/com/jme3/export/SavableClassUtil.java index 81887511cf..2c63050a4d 100644 --- a/jme3-core/src/main/java/com/jme3/export/SavableClassUtil.java +++ b/jme3-core/src/main/java/com/jme3/export/SavableClassUtil.java @@ -201,6 +201,10 @@ public static Savable fromName(String className) } } + /** + * @deprecated use {@link #fromName(java.lang.String)} instead + */ + @Deprecated public static Savable fromName(String className, List loaders) throws InstantiationException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, ClassNotFoundException, IOException { diff --git a/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java b/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java index 105440855d..3bc6187700 100644 --- a/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java +++ b/jme3-core/src/main/java/com/jme3/input/JoystickCompatibilityMappings.java @@ -44,6 +44,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.jme3.util.res.Resources; + /** * Provides compatibility mapping to different joysticks @@ -554,9 +556,9 @@ public static void loadMappingProperties(URL u) throws IOException { } } - protected static void loadMappings(ClassLoader cl, String path) throws IOException { + protected static void loadMappings(String path) throws IOException { logger.log(Level.FINE, "Searching for mappings for path:{0}", path); - for (Enumeration en = cl.getResources(path); en.hasMoreElements(); ) { + for (Enumeration en = Resources.getResources(path); en.hasMoreElements(); ) { URL u = en.nextElement(); try { loadMappingProperties(u); @@ -574,7 +576,7 @@ protected static void loadMappings(ClassLoader cl, String path) throws IOExcepti protected static void loadDefaultMappings() { for (String s : searchPaths) { try { - loadMappings(JoystickCompatibilityMappings.class.getClassLoader(), s); + loadMappings(s); } catch (IOException e) { logger.log(Level.SEVERE, "Error searching resource path:{0}", s); } diff --git a/jme3-core/src/main/java/com/jme3/light/PointLight.java b/jme3-core/src/main/java/com/jme3/light/PointLight.java index 959147c9a0..75b6e919b4 100644 --- a/jme3-core/src/main/java/com/jme3/light/PointLight.java +++ b/jme3-core/src/main/java/com/jme3/light/PointLight.java @@ -165,6 +165,11 @@ public final void setRadius(float radius) { if (radius < 0) { throw new IllegalArgumentException("Light radius cannot be negative"); } + + if (radius == Float.POSITIVE_INFINITY) { + radius = Float.MAX_VALUE; + } + this.radius = radius; if (radius != 0f) { this.invRadius = 1f / radius; diff --git a/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java b/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java index f7b6d185df..5b881b5116 100644 --- a/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java +++ b/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java @@ -149,10 +149,12 @@ public void initialize(RenderManager rm, ViewPort vp) { fsQuad.setHeight(1); if (!renderer.getCaps().contains(Caps.PackedFloatTexture)) { - if (!renderer.getCaps().contains(Caps.FloatTexture)) { - fbFormat = Format.RGB8; - } else { + if(renderer.getCaps().contains(Caps.FloatColorBufferRGB)){ fbFormat = Format.RGB16F; + } else if(renderer.getCaps().contains(Caps.FloatColorBufferRGBA)){ + fbFormat = Format.RGBA16F; + } else { + fbFormat = Format.RGB8; } } diff --git a/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java b/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java index 241401ff15..2e31413d24 100644 --- a/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java +++ b/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java @@ -91,7 +91,7 @@ public class HDRRenderer implements SceneProcessor { private float whiteLevel = 100f; private float throttle = -1; private int maxIterations = -1; - private Image.Format bufFormat = Format.RGB16F; + private Image.Format bufFormat = Format.RGB8; private MinFilter fbMinFilter = MinFilter.BilinearNoMipMaps; private MagFilter fbMagFilter = MagFilter.Bilinear; @@ -106,8 +106,10 @@ public HDRRenderer(AssetManager manager, Renderer renderer) { Collection caps = renderer.getCaps(); if (caps.contains(Caps.PackedFloatColorBuffer)) bufFormat = Format.RGB111110F; - else if (caps.contains(Caps.FloatColorBuffer)) + else if (caps.contains(Caps.FloatColorBufferRGB)) bufFormat = Format.RGB16F; + else if (caps.contains(Caps.FloatColorBufferRGBA)) + bufFormat = Format.RGBA16F; else { enabled = false; return; diff --git a/jme3-core/src/main/java/com/jme3/renderer/Caps.java b/jme3-core/src/main/java/com/jme3/renderer/Caps.java index 961d78ae6f..647d44a9a6 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Caps.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Caps.java @@ -227,6 +227,16 @@ public enum Caps { */ FloatTexture, + /** + * Supports rendering on RGB floating point textures + */ + FloatColorBufferRGB, + + /** + * Supports rendering on RGBA floating point textures + */ + FloatColorBufferRGBA, + /** * Supports integer textures. */ @@ -236,6 +246,7 @@ public enum Caps { * Supports floating point FBO color buffers (Format.RGB16F). */ FloatColorBuffer, + /** * Supports floating point depth buffer. @@ -341,6 +352,11 @@ public enum Caps { */ OpenGLES20, + /** + * Supports WebGL + */ + WebGL, + /** * Supports RGB8 / RGBA8 textures. */ diff --git a/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java b/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java index a1b453a096..5969a1d5bd 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java +++ b/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java @@ -58,8 +58,10 @@ import com.jme3.shader.Shader; import com.jme3.shader.UniformBinding; import com.jme3.shader.UniformBindingManager; +import com.jme3.shader.VarType; import com.jme3.system.NullRenderer; import com.jme3.system.Timer; +import com.jme3.texture.FrameBuffer; import com.jme3.util.SafeArrayList; import java.util.ArrayList; import java.util.Collections; @@ -101,6 +103,7 @@ public class RenderManager { private LightFilter lightFilter = new DefaultLightFilter(); private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass; private int singlePassLightBatchSize = 1; + private MatParamOverride boundDrawBufferId=new MatParamOverride(VarType.Int,"BoundDrawBuffer",0); /** @@ -111,6 +114,7 @@ public class RenderManager { */ public RenderManager(Renderer renderer) { this.renderer = renderer; + this.forcedOverrides.add(boundDrawBufferId); } /** @@ -629,6 +633,12 @@ public void renderGeometry(Geometry geom) { setWorldMatrix(geom.getWorldMatrix()); } + // Use material override to pass the current target index (used in api such as GL ES that do not support glDrawBuffer) + FrameBuffer currentFb = this.renderer.getCurrentFrameBuffer(); + if (currentFb != null && !currentFb.isMultiTarget()) { + this.boundDrawBufferId.setValue(currentFb.getTargetIndex()); + } + // Perform light filtering if we have a light filter. LightList lightList = geom.getWorldLightList(); @@ -639,7 +649,7 @@ public void renderGeometry(Geometry geom) { } Material material = geom.getMaterial(); - + // If forcedTechnique exists, we try to force it for the render. // If it does not exist in the mat def, we check for forcedMaterial and render the geom if not null. // Otherwise, the geometry is not rendered. @@ -1298,4 +1308,32 @@ public void render(float tpf, boolean mainFrameBufferActive) { } } } + + + /** + * Returns true if the draw buffer target id is passed to the shader. + * + * @return True if the draw buffer target id is passed to the shaders. + */ + public boolean getPassDrawBufferTargetIdToShaders() { + return this.forcedOverrides.contains(boundDrawBufferId); + } + + /** + * Enable or disable passing the draw buffer target id to the shaders. This + * is needed to handle FrameBuffer.setTargetIndex correctly in some + * backends. + * + * @param v + * True to enable, false to disable (default is true) + */ + public void setPassDrawBufferTargetIdToShaders(boolean v) { + if (v) { + if (!this.forcedOverrides.contains(boundDrawBufferId)) { + this.forcedOverrides.add(boundDrawBufferId); + } + } else { + this.forcedOverrides.remove(boundDrawBufferId); + } + } } diff --git a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java index 753bf2f1a6..63e49f030b 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java @@ -527,4 +527,10 @@ public default void pushDebugGroup(String name) { } + /** + * Returns the current FrameBuffer that is being rendered to. + * @return the FrameBuffer or null if rendering to the screen. + */ + public FrameBuffer getCurrentFrameBuffer(); + } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLES_30.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLES_30.java index 42c59d940b..755e076cac 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLES_30.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLES_30.java @@ -31,6 +31,8 @@ */ package com.jme3.renderer.opengl; +import java.nio.IntBuffer; + /** * GL functions and constants only available on vanilla OpenGL ES 3.0. * @@ -40,5 +42,10 @@ public interface GLES_30 extends GL { public static final int GL_RGB10_A2 = 0x8059; public static final int GL_UNSIGNED_INT_2_10_10_10_REV = 0x8368; + + public void glBindVertexArray(int array); + public void glDeleteVertexArrays(IntBuffer arrays); + + public void glGenVertexArrays(IntBuffer arrays); } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java index 2532f5837e..396af9ee34 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java @@ -121,7 +121,7 @@ public static GLImageFormat[][] getFormatsForCaps(EnumSet caps) { formatSrgbSwiz(formatToGL, Format.Luminance8Alpha8, GLExt.GL_SRGB8_ALPHA8_EXT, GL3.GL_RG, GL.GL_UNSIGNED_BYTE); } - if (caps.contains(Caps.OpenGL20)) { + if (caps.contains(Caps.OpenGL20)||caps.contains(Caps.OpenGLES30)) { if (!caps.contains(Caps.CoreProfile)) { format(formatToGL, Format.Alpha8, GL2.GL_ALPHA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE); format(formatToGL, Format.Luminance8, GL2.GL_LUMINANCE8, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE); diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index 82bcca3a4f..59bc8e3838 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -187,7 +187,12 @@ private HashSet loadExtensions() { return extensionSet; } + public static boolean isWebGL(String version) { + return version.contains("WebGL"); + } + public static int extractVersion(String version) { + if (version.startsWith("WebGL 2.0")) return 300; Matcher m = GLVERSION_PATTERN.matcher(version); if (m.matches()) { int major = Integer.parseInt(m.group(1)); @@ -208,7 +213,11 @@ private boolean hasExtension(String extensionName) { } private void loadCapabilitiesES() { - int oglVer = extractVersion(gl.glGetString(GL.GL_VERSION)); + String version = gl.glGetString(GL.GL_VERSION); + int oglVer = extractVersion(version); + if (isWebGL(version)) { + caps.add(Caps.WebGL); + } caps.add(Caps.GLSL100); caps.add(Caps.OpenGLES20); @@ -378,7 +387,7 @@ private void loadCapabilitiesCommon() { hasExtension("GL_ARB_half_float_pixel"); if (!hasFloatTexture) { - hasFloatTexture = caps.contains(Caps.OpenGL30); + hasFloatTexture = caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30); } } @@ -409,9 +418,14 @@ private void loadCapabilitiesCommon() { } if (hasExtension("GL_ARB_color_buffer_float") && - hasExtension("GL_ARB_half_float_pixel")) { + hasExtension("GL_ARB_half_float_pixel") + ||caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { // XXX: Require both 16- and 32-bit float support for FloatColorBuffer. caps.add(Caps.FloatColorBuffer); + caps.add(Caps.FloatColorBufferRGBA); + if (!caps.contains(Caps.OpenGLES30)) { + caps.add(Caps.FloatColorBufferRGB); + } } if (caps.contains(Caps.OpenGLES30) || hasExtension("GL_ARB_depth_buffer_float")) { @@ -450,13 +464,13 @@ private void loadCapabilitiesCommon() { // == end texture format extensions == - if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30)) { + if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) ) { caps.add(Caps.VertexBufferArray); } if (hasExtension("GL_ARB_texture_non_power_of_two") || hasExtension("GL_OES_texture_npot") || - caps.contains(Caps.OpenGL30)) { + caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { caps.add(Caps.NonPowerOfTwoTextures); } else { logger.log(Level.WARNING, "Your graphics card does not " @@ -530,7 +544,7 @@ private void loadCapabilitiesCommon() { // Supports sRGB pipeline. if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB")) - || caps.contains(Caps.OpenGL30)) { + || caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { caps.add(Caps.Srgb); } @@ -539,8 +553,10 @@ private void loadCapabilitiesCommon() { caps.add(Caps.SeamlessCubemap); } - if (caps.contains(Caps.OpenGL32) && !hasExtension("GL_ARB_compatibility")) { - caps.add(Caps.CoreProfile); + if ((caps.contains(Caps.OpenGLES30) || caps.contains(Caps.OpenGL32)) && !hasExtension("GL_ARB_compatibility")) { + if (JmeSystem.getPlatform().getOs() != Platform.Os.iOS) { // some features are not supported on iOS + caps.add(Caps.CoreProfile); + } } if (hasExtension("GL_ARB_get_program_binary")) { @@ -679,9 +695,17 @@ public void initialize() { if (caps.contains(Caps.CoreProfile)) { // Core Profile requires VAO to be bound. - gl3.glGenVertexArrays(intBuf16); - int vaoId = intBuf16.get(0); - gl3.glBindVertexArray(vaoId); + if(gl3!=null){ + gl3.glGenVertexArrays(intBuf16); + int vaoId = intBuf16.get(0); + gl3.glBindVertexArray(vaoId); + }else if(gl instanceof GLES_30){ + ((GLES_30)gl).glGenVertexArrays(intBuf16); + int vaoId = intBuf16.get(0); + ((GLES_30)gl).glBindVertexArray(vaoId); + } else{ + throw new UnsupportedOperationException("Core profile not supported"); + } } if (gl2 != null && !(gl instanceof GLES_30)) { gl2.glEnable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE); @@ -1247,6 +1271,37 @@ protected void updateUniformLocation(Shader shader, Uniform uniform) { } } + private boolean isValidNumber(float v) { + return !Float.isNaN(v); + } + + private boolean isValidNumber(FloatBuffer fb) { + for(int i = 0; i < fb.limit(); i++) { + if (!isValidNumber(fb.get(i))) return false; + } + return true; + } + + private boolean isValidNumber(Vector2f v) { + return isValidNumber(v.x) && isValidNumber(v.y); + } + + private boolean isValidNumber(Vector3f v) { + return isValidNumber(v.x) && isValidNumber(v.y) && isValidNumber(v.z); + } + + private boolean isValidNumber(Quaternion q) { + return isValidNumber(q.getX()) && isValidNumber(q.getY()) && isValidNumber(q.getZ()) && isValidNumber(q.getW()); + } + + private boolean isValidNumber(ColorRGBA c) { + return isValidNumber(c.r) && isValidNumber(c.g) && isValidNumber(c.b) && isValidNumber(c.a); + } + + private boolean isValidNumber(Vector4f c) { + return isValidNumber(c.x) && isValidNumber(c.y) && isValidNumber(c.z) && isValidNumber(c.w); + } + protected void updateUniform(Shader shader, Uniform uniform) { int shaderId = shader.getId(); @@ -1282,26 +1337,32 @@ protected void updateUniform(Shader shader, Uniform uniform) { switch (uniform.getVarType()) { case Float: Float f = (Float) uniform.getValue(); + assert isValidNumber(f) : "Invalid float value " + f; gl.glUniform1f(loc, f.floatValue()); break; case Vector2: Vector2f v2 = (Vector2f) uniform.getValue(); + assert isValidNumber(v2) : "Invalid Vector2f value " + v2; gl.glUniform2f(loc, v2.getX(), v2.getY()); break; case Vector3: Vector3f v3 = (Vector3f) uniform.getValue(); + assert isValidNumber(v3) : "Invalid Vector3f value " + v3; gl.glUniform3f(loc, v3.getX(), v3.getY(), v3.getZ()); break; case Vector4: Object val = uniform.getValue(); if (val instanceof ColorRGBA) { ColorRGBA c = (ColorRGBA) val; + assert isValidNumber(c) : "Invalid ColorRGBA value " + c; gl.glUniform4f(loc, c.r, c.g, c.b, c.a); } else if (val instanceof Vector4f) { Vector4f c = (Vector4f) val; + assert isValidNumber(c) : "Invalid Vector4f value " + c; gl.glUniform4f(loc, c.x, c.y, c.z, c.w); } else { Quaternion c = (Quaternion) uniform.getValue(); + assert isValidNumber(c) : "Invalid Quaternion value " + c; gl.glUniform4f(loc, c.getX(), c.getY(), c.getZ(), c.getW()); } break; @@ -1311,11 +1372,13 @@ protected void updateUniform(Shader shader, Uniform uniform) { break; case Matrix3: fb = uniform.getMultiData(); + assert isValidNumber(fb) : "Invalid Matrix3f value " + uniform.getValue(); assert fb.remaining() == 9; gl.glUniformMatrix3(loc, false, fb); break; case Matrix4: fb = uniform.getMultiData(); + assert isValidNumber(fb) : "Invalid Matrix4f value " + uniform.getValue(); assert fb.remaining() == 16; gl.glUniformMatrix4(loc, false, fb); break; @@ -1325,22 +1388,27 @@ protected void updateUniform(Shader shader, Uniform uniform) { break; case FloatArray: fb = uniform.getMultiData(); + assert isValidNumber(fb) : "Invalid float array value " + Arrays.asList((float[]) uniform.getValue()); gl.glUniform1(loc, fb); break; case Vector2Array: fb = uniform.getMultiData(); + assert isValidNumber(fb) : "Invalid Vector2f array value " + Arrays.deepToString((Vector2f[]) uniform.getValue()); gl.glUniform2(loc, fb); break; case Vector3Array: fb = uniform.getMultiData(); + assert isValidNumber(fb) : "Invalid Vector3f array value " + Arrays.deepToString((Vector3f[]) uniform.getValue()); gl.glUniform3(loc, fb); break; case Vector4Array: fb = uniform.getMultiData(); + assert isValidNumber(fb) : "Invalid Vector4f array value " + Arrays.deepToString((Vector4f[]) uniform.getValue()); gl.glUniform4(loc, fb); break; case Matrix4Array: fb = uniform.getMultiData(); + assert isValidNumber(fb) : "Invalid Matrix4f array value " + Arrays.deepToString((Matrix4f[]) uniform.getValue()); gl.glUniformMatrix4(loc, false, fb); break; case Int: @@ -1477,7 +1545,6 @@ public void updateShaderSourceData(ShaderSource source) { + "Only GLSL 1.00 shaders are supported."); } - boolean insertPrecision = false; // Upload shader source. // Merge the defines and source code. stringBuf.setLength(0); @@ -1508,16 +1575,8 @@ public void updateShaderSourceData(ShaderSource source) { } } - if (gles2 || gles3) { - //Inserting precision only to fragment shaders creates some link failures because of different precision between shaders - //But adding the precision to all shaders generates rendering glitches in some devices if not set to highp - if (source.getType() == ShaderType.Fragment) { - // GLES requires precision qualifier. - insertPrecision = true; - } - } } - + if (linearizeSrgbImages) { stringBuf.append("#define SRGB 1\n"); } @@ -1526,24 +1585,6 @@ public void updateShaderSourceData(ShaderSource source) { stringBuf.append(source.getDefines()); stringBuf.append(source.getSource()); - if(insertPrecision){ - // default precision could be defined in GLSLCompat.glsllib so final users can use custom defined precision instead - // precision token is not a preprocessor directive therefore it must be placed after #extension tokens to avoid - // Error P0001: Extension directive must occur before any non-preprocessor tokens - int idx = stringBuf.lastIndexOf("#extension"); - idx = stringBuf.indexOf("\n", idx); - - if(version>=310) { - stringBuf.insert(idx + 1, "precision highp sampler2DMS;\n"); - } - if(version>=300) { - stringBuf.insert(idx + 1, "precision highp sampler2DArray;\n"); - stringBuf.insert(idx + 1, "precision highp sampler2DShadow;\n"); - stringBuf.insert(idx + 1, "precision highp sampler3D;\n"); - stringBuf.insert(idx + 1, "precision highp sampler2D;\n"); - } - stringBuf.insert(idx + 1, "precision highp float;\n"); - } intBuf1.clear(); intBuf1.put(0, stringBuf.length()); @@ -1668,7 +1709,7 @@ public void updateShaderData(Shader shader) { public void setShader(Shader shader) { if (shader == null) { throw new IllegalArgumentException("Shader cannot be null"); - } else { + } else { if (shader.isUpdateNeeded()) { updateShaderData(shader); } @@ -2029,8 +2070,17 @@ public void setMainFrameBufferOverride(FrameBuffer fb) { mainFbOverride = fb; } + + @Override + public FrameBuffer getCurrentFrameBuffer() { + if(mainFbOverride!=null){ + return mainFbOverride; + } + return context.boundFB; + } + public void setReadDrawBuffers(FrameBuffer fb) { - if (gl2 == null || gl instanceof GLES_30) { + if (gl2 == null) { return; } @@ -2635,7 +2685,7 @@ public void setTexture(int unit, Texture tex) throws TextureUnitException { if (unit < 0 || unit >= RenderContext.maxTextureUnits) { throw new TextureUnitException(); } - + Image image = tex.getImage(); if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) { // Check NPOT requirements diff --git a/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java b/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java index 70266e401d..96195e583f 100644 --- a/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java +++ b/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java @@ -75,6 +75,7 @@ public class InstancedGeometry extends Geometry { private int firstUnusedIndex = 0; private int numVisibleInstances = 0; + private Camera cam; public InstancedGeometry() { super(); @@ -275,6 +276,13 @@ private void swap(int idx1, int idx2) { } } + /** + * @Deprecated use {@link #updateInstances(com.jme3.renderer.Camera) + */ + public void updateInstances() { + updateInstances(cam); + } + public void updateInstances(Camera cam) { FloatBuffer fb = (FloatBuffer) transformInstanceData.getData(); fb.limit(fb.capacity()); @@ -415,6 +423,12 @@ private void updateAllInstanceData() { allInstanceData = allData.toArray(new VertexBuffer[allData.size()]); } + @Override + public boolean checkCulling(Camera cam) { + this.cam = cam; + return super.checkCulling(cam); + } + @Override public int collideWith(Collidable other, CollisionResults results) { return 0; // Ignore collision diff --git a/jme3-core/src/main/java/com/jme3/shader/ShaderNodeDefinition.java b/jme3-core/src/main/java/com/jme3/shader/ShaderNodeDefinition.java index fce3369a99..a6addf0cc0 100644 --- a/jme3-core/src/main/java/com/jme3/shader/ShaderNodeDefinition.java +++ b/jme3-core/src/main/java/com/jme3/shader/ShaderNodeDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2021 jMonkeyEngine + * Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -201,7 +201,7 @@ public void write(JmeExporter ex) throws IOException { oc.write(shadersPath.toArray(str), "shadersPath", null); oc.write(type, "type", null); oc.writeSavableArrayList((ArrayList) inputs, "inputs", new ArrayList()); - oc.writeSavableArrayList((ArrayList) outputs, "inputs", new ArrayList()); + oc.writeSavableArrayList((ArrayList) outputs, "outputs", new ArrayList()); } public List getShadersLanguage() { diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java index cfa98ec41e..b878dde298 100644 --- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java +++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java @@ -876,12 +876,12 @@ public void setBitsPerPixel(int value) { } /** - * Set the number of samples per pixel. A value of 1 indicates + * Set the number of samples per pixel. A value of 0 or 1 indicates * each pixel should be single-sampled, higher values indicate * a pixel should be multi-sampled. * * @param value The number of samples - * (Default: 1) + * (Default: 0) */ public void setSamples(int value) { putInteger("Samples", value); diff --git a/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java b/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java index 35143fca4a..c9d8b79182 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java @@ -35,6 +35,7 @@ import com.jme3.asset.DesktopAssetManager; import com.jme3.audio.AudioRenderer; import com.jme3.input.SoftTextDialogInput; +import com.jme3.util.res.Resources; import java.io.File; import java.io.IOException; @@ -126,11 +127,11 @@ public String getFullName() { } public InputStream getResourceAsStream(String name) { - return this.getClass().getResourceAsStream(name); + return Resources.getResourceAsStream(name,this.getClass()); } public URL getResource(String name) { - return this.getClass().getResource(name); + return Resources.getResource(name,this.getClass()); } public boolean trackDirectMemory() { diff --git a/jme3-core/src/main/java/com/jme3/system/JmeVersion.java b/jme3-core/src/main/java/com/jme3/system/JmeVersion.java index f15bc2dcff..2599949d8f 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeVersion.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeVersion.java @@ -36,6 +36,8 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.jme3.util.res.Resources; + /** * Pulls in version info from the version.properties file. * @@ -48,7 +50,7 @@ public class JmeVersion { static { try { - props.load(JmeVersion.class.getResourceAsStream("version.properties")); + props.load(Resources.getResourceAsStream("version.properties",JmeVersion.class)); } catch (IOException | NullPointerException ex) { logger.log(Level.WARNING, "Unable to read version info!", ex); } diff --git a/jme3-core/src/main/java/com/jme3/system/NullRenderer.java b/jme3-core/src/main/java/com/jme3/system/NullRenderer.java index e82dea5149..4975b69a17 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullRenderer.java +++ b/jme3-core/src/main/java/com/jme3/system/NullRenderer.java @@ -293,4 +293,9 @@ public boolean isLinearizeSrgbImages() { public boolean isMainFrameBufferSrgb() { return false; } + + @Override + public FrameBuffer getCurrentFrameBuffer() { + return null; + } } diff --git a/jme3-core/src/main/java/com/jme3/system/Platform.java b/jme3-core/src/main/java/com/jme3/system/Platform.java index f187d2fbdf..64595a9106 100644 --- a/jme3-core/src/main/java/com/jme3/system/Platform.java +++ b/jme3-core/src/main/java/com/jme3/system/Platform.java @@ -139,7 +139,13 @@ public enum Platform { /** * Android running on unknown platform (could be x86 or mips for example). */ - Android_Other(Os.Android); + Android_Other(Os.Android), + + /** + * Generic web platform on unknown architecture + */ + Web(Os.Web, true) // assume always 64-bit, it shouldn't matter for web + ; /** @@ -165,7 +171,11 @@ public enum Os { /** * Android operating systems */ - Android + Android, + /** + * Generic web platform + */ + Web } private final boolean is64bit; diff --git a/jme3-core/src/main/java/com/jme3/util/res/DefaultResourceLoader.java b/jme3-core/src/main/java/com/jme3/util/res/DefaultResourceLoader.java new file mode 100644 index 0000000000..b3f4e7d47f --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/util/res/DefaultResourceLoader.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.util.res; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; + +/** + * Default implementation of {@link ResourceLoader}. + * Loads from classpath. + */ +class DefaultResourceLoader implements ResourceLoader { + + DefaultResourceLoader() { + + } + + @Override + public InputStream getResourceAsStream(String path, Class parent) { + if (parent == null) { + return Thread.currentThread().getContextClassLoader().getResourceAsStream(path); + } else { + return parent.getResourceAsStream(path); + } + } + + @Override + public URL getResource(String path, Class parent) { + if (parent == null) { + return Thread.currentThread().getContextClassLoader().getResource(path); + } else { + return parent.getResource(path); + } + } + + @Override + public Enumeration getResources(String path) throws IOException { + return Thread.currentThread().getContextClassLoader().getResources(path); + } + +} diff --git a/jme3-core/src/main/java/com/jme3/util/res/ResourceLoader.java b/jme3-core/src/main/java/com/jme3/util/res/ResourceLoader.java new file mode 100644 index 0000000000..a7f4ddcfae --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/util/res/ResourceLoader.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.util.res; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; + +public interface ResourceLoader { + /** + * Finds the resource with the given name relative to the given parent class + * or to the root if the parent is null. + * + * @param path + * The resource name + * @param parent + * Optional parent class + * @return The resource URL or null if not found + */ + public URL getResource(String path, Class parent); + + /** + * Finds the resource with the given name relative to the given parent class + * or to the root if the parent is null. + * + * @param path + * The resource name + * @param parent + * Optional parent class + * @return An input stream to the resource or null if not found + */ + public InputStream getResourceAsStream(String path, Class parent); + + + /** + * Finds all resources with the given name. + * + * + * @param path + * The resource name + * @return An enumeration of {@link java.net.URL URL} objects for + * the resource. If no resources could be found, the enumeration + * will be empty. + * + * @throws IOException + * If I/O errors occur + * + * @throws IOException + */ + public Enumeration getResources(String path) throws IOException; +} diff --git a/jme3-core/src/main/java/com/jme3/util/res/Resources.java b/jme3-core/src/main/java/com/jme3/util/res/Resources.java new file mode 100644 index 0000000000..6323e656e7 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/util/res/Resources.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.util.res; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class is used to load resources from the default location usually the + * classpath. + */ +public class Resources { + /** + * The property name to set the ResourceLoader to use. Should be set automatically + * by the JmeSystemDelegate. + * Note: changing this property after the first use of the ResourceLoader will have no effect. + */ + public static final String PROPERTY_RESOURCE_LOADER_IMPLEMENTATION = "com.jme3.ResourceLoaderImplementation"; + + private static final String DEFAULT_IMPL = "com.jme3.util.res.DefaultResourceLoader"; + private static final Logger LOGGER = Logger.getLogger(Resources.class.getName()); + private static ResourceLoader impl = null; + + @SuppressWarnings("unchecked") + private static Class findResourceLoaderClass(String className) { + Class clazz = null; + + try { + clazz = Class.forName(className); + } catch (final Throwable e) { + LOGGER.log(Level.WARNING, "Unable to access {0}", className); + } + + if (clazz != null && !ResourceLoader.class.isAssignableFrom(clazz)) { + LOGGER.log(Level.WARNING, "{0} does not implement {1}", new Object[] { className, ResourceLoader.class.getName() }); + clazz = null; + } + + return (Class) clazz; + } + + private static ResourceLoader getResourceLoader() { + if (impl != null) return impl; + Class clazz = null; + String userDefinedImpl = System.getProperty(PROPERTY_RESOURCE_LOADER_IMPLEMENTATION, null); + + if (userDefinedImpl != null) { + LOGGER.log(Level.FINE, "Loading user defined ResourceLoader implementation {0}", userDefinedImpl); + clazz = findResourceLoaderClass(userDefinedImpl); + } + + if (clazz == null) { + LOGGER.log(Level.FINE, "No usable user defined ResourceLoader implementation found, using default implementation {0}", DEFAULT_IMPL); + clazz = findResourceLoaderClass(DEFAULT_IMPL); + } + + if (clazz == null) { + throw new RuntimeException("No ResourceLoader implementation found"); + } + + try { + impl = (ResourceLoader) clazz.getDeclaredConstructor().newInstance(); + } catch (final Throwable e) { + throw new RuntimeException("Could not instantiate ResourceLoader class " + clazz.getName(), e); + } + + return impl; + } + + /** + * Sets the resource loader implementation to use. + * @param impl The resource loader implementation + */ + public static void setResourceLoader(ResourceLoader impl) { + Resources.impl = impl; + } + + /** + * Finds the resource with the given name. + * + * @param path + * The resource name + * @return The resource URL or null if not found + */ + public static URL getResource(String path) { + return getResourceLoader().getResource(path, null); + } + + /** + * Finds the resource with the given name relative to the given parent class + * or to the root if the parent is null. + * + * @param path + * The resource name + * @param parent + * Optional parent class + * @return The resource URL or null if not found + */ + public static URL getResource(String path, Class parent) { + return getResourceLoader().getResource(path, parent); + } + + /** + * Finds the resource with the given name. + * + * @param path + * The resource name + * @return An input stream to the resource or null if not found + */ + public static InputStream getResourceAsStream(String path) { + return getResourceLoader().getResourceAsStream(path, null); + } + + /** + * Finds the resource with the given name relative to the given parent class + * or to the root if the parent is null. + * + * @param path + * The resource name + * @param parent + * Optional parent class + * @return An input stream to the resource or null if not found + */ + public static InputStream getResourceAsStream(String path, Class parent) { + return getResourceLoader().getResourceAsStream(path, parent); + } + + /** + * Finds all resources with the given name. + * + * + * @param path + * The resource name + * + * + * @return An enumeration of {@link java.net.URL URL} objects for + * the resource. If no resources could be found, the enumeration + * will be empty. + * + * @throws IOException + * If I/O errors occur + * + * @throws IOException + */ + public static Enumeration getResources(String path) throws IOException { + return getResourceLoader().getResources(path); + } + +} diff --git a/jme3-core/src/main/resources/Common/MatDefs/Blur/HGaussianBlur.j3md b/jme3-core/src/main/resources/Common/MatDefs/Blur/HGaussianBlur.j3md index 7c5fddeb6c..f7011c5f20 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Blur/HGaussianBlur.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Blur/HGaussianBlur.j3md @@ -1,6 +1,7 @@ MaterialDef HGaussianBlur { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture Float Size @@ -8,10 +9,14 @@ MaterialDef HGaussianBlur { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Post/Post.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Blur/HGaussianBlur.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Blur/HGaussianBlur.frag WorldParameters { } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } } \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/Blur/RadialBlur.j3md b/jme3-core/src/main/resources/Common/MatDefs/Blur/RadialBlur.j3md index 977007f073..806bb55473 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Blur/RadialBlur.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Blur/RadialBlur.j3md @@ -1,6 +1,7 @@ MaterialDef Radial Blur { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture Color Color @@ -10,13 +11,14 @@ MaterialDef Radial Blur { } Technique { - VertexShader GLSL300 GLSL120 GLSL150: Common/MatDefs/Post/Post.vert - FragmentShader GLSL300 GLSL120 GLSL150: Common/MatDefs/Blur/RadialBlur.frag + VertexShader GLSL300 GLSL150 GLSL120 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL120 : Common/MatDefs/Blur/RadialBlur.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples } } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Blur/VGaussianBlur.j3md b/jme3-core/src/main/resources/Common/MatDefs/Blur/VGaussianBlur.j3md index 68e5d15baf..8bcb4292f2 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Blur/VGaussianBlur.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Blur/VGaussianBlur.j3md @@ -1,6 +1,7 @@ MaterialDef VGaussianBlur { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture Float Size @@ -8,10 +9,14 @@ MaterialDef VGaussianBlur { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Post/Post.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Blur/VGaussianBlur.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Blur/VGaussianBlur.frag WorldParameters { } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } } \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/Gui/Gui.j3md b/jme3-core/src/main/resources/Common/MatDefs/Gui/Gui.j3md index 23fbff8261..b3da65be47 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Gui/Gui.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Gui/Gui.j3md @@ -1,37 +1,26 @@ MaterialDef Default GUI { MaterialParameters { + Int BoundDrawBuffer Texture2D Texture Color Color (Color) Boolean VertexColor (UseVertexColor) } Technique { - VertexShader GLSL150: Common/MatDefs/Gui/Gui.vert - FragmentShader GLSL150: Common/MatDefs/Gui/Gui.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Gui/Gui.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Gui/Gui.frag WorldParameters { WorldViewProjectionMatrix } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer TEXTURE : Texture VERTEX_COLOR : VertexColor } } - Technique { - VertexShader GLSL100: Common/MatDefs/Gui/Gui.vert - FragmentShader GLSL100: Common/MatDefs/Gui/Gui.frag - - WorldParameters { - WorldViewProjectionMatrix - } - - Defines { - TEXTURE : Texture - VERTEX_COLOR : VertexColor - } - } } \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/Hdr/LogLum.j3md b/jme3-core/src/main/resources/Common/MatDefs/Hdr/LogLum.j3md index 0c4c6c889e..31358d224e 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Hdr/LogLum.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Hdr/LogLum.j3md @@ -1,6 +1,7 @@ MaterialDef Log Lum 2D { MaterialParameters { + Int BoundDrawBuffer Texture2D Texture Vector2 BlockSize Vector2 PixelSize @@ -12,14 +13,15 @@ MaterialDef Log Lum 2D { } Technique { - VertexShader GLSL100: Common/MatDefs/Gui/Gui.vert - FragmentShader GLSL100: Common/MatDefs/Hdr/LogLum.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Gui/Gui.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Hdr/LogLum.frag WorldParameters { WorldViewProjectionMatrix } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer TEXTURE ENCODE_LUM : EncodeLum DECODE_LUM : DecodeLum diff --git a/jme3-core/src/main/resources/Common/MatDefs/Hdr/ToneMap.j3md b/jme3-core/src/main/resources/Common/MatDefs/Hdr/ToneMap.j3md index 24fbd04ae6..b515639eda 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Hdr/ToneMap.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Hdr/ToneMap.j3md @@ -1,5 +1,6 @@ MaterialDef Tone Mapper { MaterialParameters { + Int BoundDrawBuffer Texture2D Texture Texture2D Lum Texture2D Lum2 @@ -9,14 +10,15 @@ MaterialDef Tone Mapper { Float Gamma } Technique { - VertexShader GLSL100: Common/MatDefs/Gui/Gui.vert - FragmentShader GLSL100: Common/MatDefs/Hdr/ToneMap.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Gui/Gui.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Hdr/ToneMap.frag WorldParameters { WorldViewProjectionMatrix } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer TEXTURE } } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.j3md index f0b7ee5a6f..08a7d007f8 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.j3md @@ -2,6 +2,7 @@ MaterialDef Phong Lighting Deferred { MaterialParameters { + Int BoundDrawBuffer // Use more efficient algorithms to improve performance Boolean LowQuality @@ -35,8 +36,8 @@ MaterialDef Phong Lighting Deferred { Technique { LightMode MultiPass - VertexShader GLSL100: Common/MatDefs/Light/Deferred.vert - FragmentShader GLSL100: Common/MatDefs/Light/Deferred.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Deferred.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Deferred.frag WorldParameters { WorldViewProjectionMatrix @@ -46,6 +47,7 @@ MaterialDef Phong Lighting Deferred { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer ATTENUATION : Attenuation V_TANGENT : VTangent MINNAERT : Minnaert diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.vert index 0743cc1a94..1d22a36edb 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Deferred.vert @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + varying vec2 texCoord; attribute vec3 inPosition; diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/GBuf.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/GBuf.vert index f4ad199635..66eca303b0 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/GBuf.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/GBuf.vert @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + uniform mat4 g_WorldViewProjectionMatrix; uniform mat4 g_WorldMatrix; diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md index 4a5fa256ee..ec85c0729e 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md @@ -1,6 +1,7 @@ MaterialDef Phong Lighting { MaterialParameters { + Int BoundDrawBuffer // Compute vertex lighting in the shader // For better performance @@ -133,8 +134,8 @@ MaterialDef Phong Lighting { Technique { LightMode SinglePass - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Light/SPLighting.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Light/SPLighting.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/SPLighting.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/SPLighting.frag WorldParameters { WorldViewProjectionMatrix @@ -146,7 +147,8 @@ MaterialDef Phong Lighting { ViewProjectionMatrix } - Defines { + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer VERTEX_COLOR : UseVertexColor VERTEX_LIGHTING : VertexLighting MATERIAL_COLORS : UseMaterialColors @@ -180,8 +182,8 @@ MaterialDef Phong Lighting { LightMode MultiPass - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Light/Lighting.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Light/Lighting.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100 : Common/MatDefs/Light/Lighting.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Lighting.frag WorldParameters { WorldViewProjectionMatrix @@ -194,6 +196,7 @@ MaterialDef Phong Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer VERTEX_COLOR : UseVertexColor VERTEX_LIGHTING : VertexLighting MATERIAL_COLORS : UseMaterialColors @@ -225,8 +228,8 @@ MaterialDef Phong Lighting { Technique PreShadow { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -236,6 +239,7 @@ MaterialDef Phong Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer DISCARD_ALPHA : AlphaDiscardThreshold NUM_BONES : NumberOfBones INSTANCING : UseInstancing @@ -255,8 +259,8 @@ MaterialDef Phong Lighting { Technique PostShadow { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -267,6 +271,7 @@ MaterialDef Phong Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge @@ -292,8 +297,8 @@ MaterialDef Phong Lighting { Technique PreNormalPass { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/SSAO/normal.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/SSAO/normal.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/SSAO/normal.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/SSAO/normal.frag WorldParameters { WorldViewProjectionMatrix @@ -304,6 +309,7 @@ MaterialDef Phong Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer DIFFUSEMAP_ALPHA : DiffuseMap NUM_BONES : NumberOfBones INSTANCING : UseInstancing @@ -315,8 +321,8 @@ MaterialDef Phong Lighting { Technique Glow { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Misc/Unshaded.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Light/Glow.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Glow.frag WorldParameters { WorldViewProjectionMatrix @@ -325,6 +331,7 @@ MaterialDef Phong Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NEED_TEXCOORD1 HAS_GLOWMAP : GlowMap HAS_GLOWCOLOR : GlowColor diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md index 57954738a7..2b2d5453f4 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md @@ -1,6 +1,7 @@ MaterialDef PBR Lighting { MaterialParameters { + Int BoundDrawBuffer // Alpha threshold for fragment discarding Float AlphaDiscardThreshold (AlphaTestFallOff) @@ -129,8 +130,8 @@ MaterialDef PBR Lighting { Technique { LightMode SinglePassAndImageBased - VertexShader GLSL300 GLSL110 GLSL150: Common/MatDefs/Light/PBRLighting.vert - FragmentShader GLSL300 GLSL110 GLSL150: Common/MatDefs/Light/PBRLighting.frag + VertexShader GLSL300 GLSL150 GLSL110: Common/MatDefs/Light/PBRLighting.vert + FragmentShader GLSL300 GLSL150 GLSL110: Common/MatDefs/Light/PBRLighting.frag WorldParameters { WorldViewProjectionMatrix @@ -141,7 +142,8 @@ MaterialDef PBR Lighting { ViewMatrix } - Defines { + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer BASECOLORMAP : BaseColorMap NORMALMAP : NormalMap NORMALSCALE : NormalScale @@ -176,8 +178,8 @@ MaterialDef PBR Lighting { Technique PreShadow { - VertexShader GLSL300 GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL300 GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadowPBR.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadowPBR.frag WorldParameters { WorldViewProjectionMatrix @@ -187,6 +189,7 @@ MaterialDef PBR Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer DISCARD_ALPHA : AlphaDiscardThreshold NUM_BONES : NumberOfBones INSTANCING : UseInstancing @@ -206,8 +209,8 @@ MaterialDef PBR Lighting { Technique PostShadow { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadowPBR.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowPBR.frag WorldParameters { WorldViewProjectionMatrix @@ -217,6 +220,7 @@ MaterialDef PBR Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge @@ -241,8 +245,8 @@ MaterialDef PBR Lighting { Technique PreNormalPass { - VertexShader GLSL100 : Common/MatDefs/SSAO/normal.vert - FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.frag WorldParameters { WorldViewProjectionMatrix @@ -253,6 +257,7 @@ MaterialDef PBR Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer BASECOLORMAP_ALPHA : BaseColorMap NUM_BONES : NumberOfBones INSTANCING : UseInstancing @@ -264,8 +269,8 @@ MaterialDef PBR Lighting { Technique Glow { - VertexShader GLSL100 GLSL150: Common/MatDefs/Misc/Unshaded.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Light/Glow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Glow.frag WorldParameters { WorldViewProjectionMatrix @@ -274,6 +279,7 @@ MaterialDef PBR Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NEED_TEXCOORD1 NUM_BONES : NumberOfBones INSTANCING : UseInstancing diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md index 497b7d0a7b..86b1d8e212 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md @@ -2,20 +2,22 @@ Exception This material definition is deprecated. Please use Unshaded.j3md inste MaterialDef Colored Textured { MaterialParameters { + Int BoundDrawBuffer Texture2D ColorMap Color Color (Color) } Technique { - VertexShader GLSL100: Common/MatDefs/Misc/ColoredTextured.vert - FragmentShader GLSL100: Common/MatDefs/Misc/ColoredTextured.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/ColoredTextured.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/ColoredTextured.frag WorldParameters { WorldViewProjectionMatrix } + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } - Technique { - } - + } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.vert b/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.vert index 572d841917..1ff1602be4 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.vert @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + uniform mat4 g_WorldViewProjectionMatrix; attribute vec3 inPosition; diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/Particle.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/Particle.j3md index 504062ffaa..db49951cd7 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/Particle.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/Particle.j3md @@ -1,6 +1,7 @@ MaterialDef Point Sprite { MaterialParameters { + Int BoundDrawBuffer Texture2D Texture Float Quadratic Boolean PointSprite @@ -24,8 +25,8 @@ MaterialDef Point Sprite { // Point sprite should be used if running on ES2, but crash // if on desktop (because its not supported by HW) - VertexShader GLSL100 GLSL100 GLSL150 : Common/MatDefs/Misc/Particle.vert - FragmentShader GLSL100 GLSL120 GLSL150 : Common/MatDefs/Misc/Particle.frag + VertexShader GLSL300 GLSL150 GLSL120 GLSL100: Common/MatDefs/Misc/Particle.vert + FragmentShader GLSL300 GLSL150 GLSL120 GLSL100: Common/MatDefs/Misc/Particle.frag WorldParameters { WorldViewProjectionMatrix @@ -41,6 +42,7 @@ MaterialDef Point Sprite { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer USE_TEXTURE : Texture POINT_SPRITE : PointSprite } @@ -48,8 +50,8 @@ MaterialDef Point Sprite { Technique PreShadow { - VertexShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -59,6 +61,7 @@ MaterialDef Point Sprite { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer COLOR_MAP : Texture } @@ -74,8 +77,8 @@ MaterialDef Point Sprite { Technique SoftParticles{ - VertexShader GLSL100 GLSL150 : Common/MatDefs/Misc/SoftParticle.vert - FragmentShader GLSL120 GLSL150 : Common/MatDefs/Misc/SoftParticle.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/SoftParticle.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/SoftParticle.frag WorldParameters { WorldViewProjectionMatrix @@ -91,6 +94,7 @@ MaterialDef Point Sprite { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer USE_TEXTURE : Texture POINT_SPRITE : PointSprite RESOLVE_DEPTH_MS : NumSamplesDepth @@ -99,14 +103,15 @@ MaterialDef Point Sprite { Technique Glow { - VertexShader GLSL100 GLSL150: Common/MatDefs/Misc/Unshaded.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Light/Glow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Glow.frag WorldParameters { WorldViewProjectionMatrix } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NEED_TEXCOORD1 HAS_GLOWMAP : GlowMap HAS_GLOWCOLOR : GlowColor diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/ShowNormals.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/ShowNormals.j3md index 8972d7d9cf..a067c49fb6 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/ShowNormals.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/ShowNormals.j3md @@ -1,12 +1,13 @@ MaterialDef Debug Normals { MaterialParameters { + Int BoundDrawBuffer // For instancing Boolean UseInstancing } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Misc/ShowNormals.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Misc/ShowNormals.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/ShowNormals.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/ShowNormals.frag WorldParameters { WorldViewProjectionMatrix @@ -16,6 +17,7 @@ MaterialDef Debug Normals { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer INSTANCING : UseInstancing } } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/Sky.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/Sky.j3md index b4710db62e..e1b503472d 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/Sky.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/Sky.j3md @@ -1,13 +1,14 @@ MaterialDef Sky Plane { MaterialParameters { + Int BoundDrawBuffer TextureCubeMap Texture Boolean SphereMap Boolean EquirectMap Vector3 NormalScale } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Misc/Sky.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Misc/Sky.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Misc/Sky.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Misc/Sky.frag WorldParameters { ViewMatrix @@ -16,6 +17,7 @@ MaterialDef Sky Plane { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer SPHERE_MAP : SphereMap EQUIRECT_MAP : EquirectMap } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/SkyNonCube.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/SkyNonCube.j3md index 15bb8c8be9..d039af39f5 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/SkyNonCube.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/SkyNonCube.j3md @@ -1,13 +1,14 @@ MaterialDef Sky Plane { MaterialParameters { + Int BoundDrawBuffer Texture2D Texture Boolean SphereMap Boolean EquirectMap Vector3 NormalScale } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Misc/Sky.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Misc/Sky.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Sky.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Sky.frag WorldParameters { ViewMatrix @@ -16,6 +17,7 @@ MaterialDef Sky Plane { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer SPHERE_MAP : SphereMap EQUIRECT_MAP : EquirectMap } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md index 4617b4b354..b5854c2a23 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md @@ -1,6 +1,7 @@ MaterialDef Unshaded { MaterialParameters { + Int BoundDrawBuffer Texture2D ColorMap Texture2D LightMap Color Color (Color) @@ -65,8 +66,8 @@ MaterialDef Unshaded { } Technique { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Misc/Unshaded.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Misc/Unshaded.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100 : Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100 : Common/MatDefs/Misc/Unshaded.frag WorldParameters { WorldViewProjectionMatrix @@ -75,6 +76,7 @@ MaterialDef Unshaded { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer INSTANCING : UseInstancing SEPARATE_TEXCOORD : SeparateTexCoord HAS_COLORMAP : ColorMap @@ -92,8 +94,8 @@ MaterialDef Unshaded { Technique PreNormalPass { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/SSAO/normal.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/SSAO/normal.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/SSAO/normal.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/SSAO/normal.frag WorldParameters { WorldViewProjectionMatrix @@ -104,6 +106,7 @@ MaterialDef Unshaded { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer COLORMAP_ALPHA : ColorMap NUM_BONES : NumberOfBones INSTANCING : UseInstancing @@ -114,8 +117,8 @@ MaterialDef Unshaded { Technique PreShadow { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -125,6 +128,7 @@ MaterialDef Unshaded { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer COLOR_MAP : ColorMap DISCARD_ALPHA : AlphaDiscardThreshold NUM_BONES : NumberOfBones @@ -145,8 +149,8 @@ MaterialDef Unshaded { Technique PostShadow { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -156,6 +160,7 @@ MaterialDef Unshaded { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge @@ -181,8 +186,8 @@ MaterialDef Unshaded { Technique Glow { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Misc/Unshaded.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Light/Glow.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Glow.frag WorldParameters { WorldViewProjectionMatrix @@ -191,6 +196,7 @@ MaterialDef Unshaded { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NEED_TEXCOORD1 HAS_GLOWMAP : GlowMap HAS_GLOWCOLOR : GlowColor diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/BasicPostShadow.j3md b/jme3-core/src/main/resources/Common/MatDefs/Shadow/BasicPostShadow.j3md index 4ba3815446..71e215b62e 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/BasicPostShadow.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/BasicPostShadow.j3md @@ -1,13 +1,14 @@ MaterialDef Basic Post Shadow { MaterialParameters { + Int BoundDrawBuffer Texture2D ShadowMap Matrix4 LightViewProjectionMatrix } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Shadow/BasicPostShadow.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Shadow/BasicPostShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/BasicPostShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/BasicPostShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -15,6 +16,7 @@ MaterialDef Basic Post Shadow { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NO_SHADOW2DPROJ } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md index c3d0c51afc..6aad6d4ac8 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md @@ -1,6 +1,7 @@ MaterialDef Post Shadow { MaterialParameters { + Int BoundDrawBuffer Int FilterMode Boolean HardwareShadows @@ -35,8 +36,8 @@ MaterialDef Post Shadow { } Technique { - VertexShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.vert - FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.frag + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -44,6 +45,7 @@ MaterialDef Post Shadow { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter.j3md b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter.j3md index 05188796c6..e5739281f8 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter.j3md @@ -1,6 +1,7 @@ MaterialDef Post Shadow { MaterialParameters { + Int BoundDrawBuffer Int FilterMode Boolean HardwareShadows @@ -42,14 +43,15 @@ MaterialDef Post Shadow { } Technique { - VertexShader GLSL310 GLSL150: Common/MatDefs/Shadow/PostShadowFilter.vert - FragmentShader GLSL310 GLSL150: Common/MatDefs/Shadow/PostShadowFilter15.frag + VertexShader GLSL310 GLSL300 GLSL150 : Common/MatDefs/Shadow/PostShadowFilter.vert + FragmentShader GLSL310 GLSL300 GLSL150 : Common/MatDefs/Shadow/PostShadowFilter15.frag WorldParameters { ResolutionInverse } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth HARDWARE_SHADOWS : HardwareShadows @@ -65,14 +67,15 @@ MaterialDef Post Shadow { } Technique { - VertexShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.vert - FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowFilter.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowFilter.frag WorldParameters { ResolutionInverse } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PreShadow.j3md b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PreShadow.j3md index a76b36310b..72f1097bfc 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PreShadow.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PreShadow.j3md @@ -1,7 +1,15 @@ MaterialDef Pre Shadow { + MaterialParameters { + Int BoundDrawBuffer + } + Technique { - VertexShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.frag + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } WorldParameters { WorldViewProjectionMatrix diff --git a/jme3-core/src/main/resources/Common/ShaderLib/GLSLCompat.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/GLSLCompat.glsllib index 1805595627..77cb34c8c0 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/GLSLCompat.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/GLSLCompat.glsllib @@ -1,3 +1,17 @@ +#ifdef FRAGMENT_SHADER + precision highp float; + precision highp int; + precision highp sampler2DArray; + precision highp sampler2DShadow; + precision highp samplerCube; + precision highp sampler3D; + precision highp sampler2D; + #if __VERSION__ >= 310 + precision highp sampler2DMS; + #endif + +#endif + #if defined GL_ES # define hfloat highp float # define hvec2 highp vec2 @@ -19,11 +33,25 @@ #endif #if __VERSION__ >= 130 -# ifdef GL_ES -out highp vec4 outFragColor; -# else -out vec4 outFragColor; + +#ifdef FRAGMENT_SHADER + #ifdef GL_ES + #ifdef BOUND_DRAW_BUFFER + #for i=0..15 ( #if $i<=BOUND_DRAW_BUFFER $0 #endif ) + #if BOUND_DRAW_BUFFER == $i + layout( location = $i ) out highp vec4 outFragColor; + #else + layout( location = $i ) out highp vec4 outNOP$i; + #endif + #endfor + #else + out highp vec4 outFragColor; + #endif + #else + out vec4 outFragColor; + #endif #endif + # define texture1D texture # define texture2D texture # define texture3D texture diff --git a/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib index 34eba74237..2910679a47 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib @@ -177,8 +177,7 @@ float Shadow_DoPCF(in SHADOWMAP tex,in vec4 projCoord){ if (border > 0.0) return 1.0; - float bound = KERNEL * 0.5 - 0.5; - bound *= PCFEDGE; + const float bound = (KERNEL * 0.5 - 0.5 ) * PCFEDGE; for (float y = -bound; y <= bound; y += PCFEDGE){ for (float x = -bound; x <= bound; x += PCFEDGE){ #if __VERSION__ < 130 diff --git a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java index dbdd33c65a..2c9ede0d02 100644 --- a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java +++ b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java @@ -33,6 +33,8 @@ import com.jme3.asset.*; import com.jme3.system.JmeSystem; +import com.jme3.util.res.Resources; + import java.io.File; import java.io.IOException; import java.net.URISyntaxException; @@ -87,20 +89,10 @@ public AssetInfo locate(AssetManager manager, AssetKey key) { // name = root + name; // } - if (JmeSystem.isLowPermissions()){ - url = ClasspathLocator.class.getResource("/" + name); - }else{ - url = Thread.currentThread().getContextClassLoader().getResource(name); - } - - if (url == null) { - final List classLoaders = manager.getClassLoaders(); - for (final ClassLoader classLoader : classLoaders) { - url = classLoader.getResource(name); - if(url != null) { - break; - } - } + if (JmeSystem.isLowPermissions()) { + url = Resources.getResource("/" + name, ClasspathLocator.class); + } else { + url = Resources.getResource(name); } if (url == null) diff --git a/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java b/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java index 3bd039714a..7b6c6ca79e 100644 --- a/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java +++ b/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java @@ -328,9 +328,9 @@ protected byte[] fixClassAlias(byte[] bytes, int width) { } @Override - public void save(Savable object, File f) throws IOException { + public void save(Savable object, File f, boolean createDirectories) throws IOException { File parentDirectory = f.getParentFile(); - if (parentDirectory != null && !parentDirectory.exists()) { + if (parentDirectory != null && !parentDirectory.exists() && createDirectories) { parentDirectory.mkdirs(); } diff --git a/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryImporter.java b/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryImporter.java index 42a2be80e7..0be52a8192 100644 --- a/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryImporter.java +++ b/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryImporter.java @@ -329,12 +329,7 @@ public Savable readObject(int id) { int dataLength = ByteUtils.convertIntFromBytes(dataArray, loc); loc+=4; - Savable out = null; - if (assetManager != null) { - out = SavableClassUtil.fromName(bco.className, assetManager.getClassLoaders()); - } else { - out = SavableClassUtil.fromName(bco.className); - } + Savable out = SavableClassUtil.fromName(bco.className); BinaryInputCapsule cap = new BinaryInputCapsule(this, out, bco); cap.setContent(dataArray, loc, loc+dataLength); diff --git a/jme3-core/src/test/java/com/jme3/anim/tween/action/ClipActionTest.java b/jme3-core/src/test/java/com/jme3/anim/tween/action/ClipActionTest.java new file mode 100644 index 0000000000..cbcdc416ea --- /dev/null +++ b/jme3-core/src/test/java/com/jme3/anim/tween/action/ClipActionTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023 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. + */ +package com.jme3.anim.tween.action; + +import com.jme3.anim.AnimClip; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +/** + * Test for ClipAction. + * + * @author Saichand Chowdary + */ +public class ClipActionTest { + + /** + * Test to verify setTransitionLength on BlendableAction does not accept negative values. + */ + @Test + public void testSetTransitionLength_negativeInput_exceptionThrown() { + AnimClip animClip = new AnimClip("clip"); + ClipAction clipAction = new ClipAction(animClip); + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, + () -> clipAction.setTransitionLength(-1)); + assertEquals("transitionLength must be greater than or equal to 0", thrown.getMessage()); + } + + /** + * Test to verify setTransitionLength on BlendableAction accepts zero. + */ + @Test + public void testSetTransitionLength_zeroInput_noExceptionThrown() { + AnimClip animClip = new AnimClip("clip"); + ClipAction clipAction = new ClipAction(animClip); + clipAction.setTransitionLength(0); + assertEquals(0, clipAction.getTransitionLength(), 0); + } + + /** + * Test to verify setTransitionLength on BlendableAction accepts positive values. + */ + @Test + public void testSetTransitionLength_positiveNumberInput_noExceptionThrown() { + AnimClip animClip = new AnimClip("clip"); + ClipAction clipAction = new ClipAction(animClip); + clipAction.setTransitionLength(1.23d); + assertEquals(1.23d, clipAction.getTransitionLength(), 0); + } + +} diff --git a/jme3-core/src/test/java/com/jme3/material/MaterialMatParamTest.java b/jme3-core/src/test/java/com/jme3/material/MaterialMatParamTest.java index fc4503b1aa..9b572e8e93 100644 --- a/jme3-core/src/test/java/com/jme3/material/MaterialMatParamTest.java +++ b/jme3-core/src/test/java/com/jme3/material/MaterialMatParamTest.java @@ -449,7 +449,7 @@ public void setTexture(int unit, Texture texture) { MaterialMatParamTest.this.usedTextures[unit] = texture; } }; - private final RenderManager renderManager = new RenderManager(renderer); + private final RenderManager renderManager = TestUtil.createRenderManager(renderer); private boolean evaluated = false; private Shader usedShader = null; diff --git a/jme3-core/src/test/java/com/jme3/material/MaterialTest.java b/jme3-core/src/test/java/com/jme3/material/MaterialTest.java index e48b33b2dd..6edd3ed34a 100644 --- a/jme3-core/src/test/java/com/jme3/material/MaterialTest.java +++ b/jme3-core/src/test/java/com/jme3/material/MaterialTest.java @@ -104,7 +104,7 @@ public void testSelectDefaultTechnique_GLSL120Cap_MultipleLangs() { material.selectTechnique("Default", renderManager); - checkRequiredCaps(Caps.GLSL100, Caps.GLSL120); + checkRequiredCaps(Caps.GLSL120); } @Test diff --git a/jme3-core/src/test/java/com/jme3/system/MockJmeSystemDelegate.java b/jme3-core/src/test/java/com/jme3/system/MockJmeSystemDelegate.java index ca981877eb..d26f961341 100644 --- a/jme3-core/src/test/java/com/jme3/system/MockJmeSystemDelegate.java +++ b/jme3-core/src/test/java/com/jme3/system/MockJmeSystemDelegate.java @@ -32,6 +32,8 @@ package com.jme3.system; import com.jme3.audio.AudioRenderer; +import com.jme3.util.res.Resources; + import java.io.IOException; import java.io.OutputStream; import java.net.URL; @@ -45,7 +47,7 @@ public void writeImageFile(OutputStream outStream, String format, ByteBuffer ima @Override public URL getPlatformAssetConfigURL() { - return Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/General.cfg"); + return Resources.getResource("com/jme3/asset/General.cfg"); } @Override diff --git a/jme3-core/src/test/java/com/jme3/system/TestUtil.java b/jme3-core/src/test/java/com/jme3/system/TestUtil.java index ba6b833252..b23d1846ee 100644 --- a/jme3-core/src/test/java/com/jme3/system/TestUtil.java +++ b/jme3-core/src/test/java/com/jme3/system/TestUtil.java @@ -35,6 +35,8 @@ import com.jme3.asset.AssetManager; import com.jme3.asset.DesktopAssetManager; import com.jme3.renderer.RenderManager; +import com.jme3.renderer.Renderer; + import java.util.logging.Level; import java.util.logging.Logger; @@ -55,7 +57,13 @@ public static AssetManager createAssetManager() { return new DesktopAssetManager(true); } - public static RenderManager createRenderManager() { - return new RenderManager(new NullRenderer()); + public static RenderManager createRenderManager() { + return createRenderManager(new NullRenderer()); + } + + public static RenderManager createRenderManager(Renderer renderer) { + RenderManager rm = new RenderManager(renderer); + rm.setPassDrawBufferTargetIdToShaders(false); + return rm; } } diff --git a/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java b/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java index 2ce2a55885..eddf09b333 100644 --- a/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java +++ b/jme3-desktop/src/main/java/com/jme3/app/AppletHarness.java @@ -34,6 +34,8 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeSystem; +import com.jme3.util.res.Resources; + import java.applet.Applet; import java.awt.Canvas; import java.awt.Graphics; @@ -150,7 +152,7 @@ public void init(){ assetCfg = new URL(getParameter("AssetConfigURL")); } catch (MalformedURLException ex){ System.out.println(ex.getMessage()); - assetCfg = getClass().getResource("/com/jme3/asset/Desktop.cfg"); + assetCfg = Resources.getResource("/com/jme3/asset/Desktop.cfg",this.getClass()); } createCanvas(); diff --git a/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java b/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java index 645a83b9ed..81c197a3c5 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java +++ b/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java @@ -39,6 +39,8 @@ import com.jme3.system.JmeContext.Type; import com.jme3.texture.Image; import com.jme3.texture.image.ColorSpace; +import com.jme3.util.res.Resources; + import jme3tools.converters.ImageToAwt; import javax.imageio.IIOImage; @@ -70,7 +72,7 @@ public JmeDesktopSystem() { @Override public URL getPlatformAssetConfigURL() { - return Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Desktop.cfg"); + return Resources.getResource("com/jme3/asset/Desktop.cfg"); } private static BufferedImage verticalFlip(BufferedImage original) { diff --git a/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java b/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java index 85810d4164..c0eb8613e6 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java +++ b/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java @@ -44,6 +44,8 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.jme3.util.res.Resources; + /** * Utility class to register, extract, and load native libraries. *
@@ -274,7 +276,7 @@ private static void setExtractionFolderToUserCache() { private static int computeNativesHash() { URLConnection conn = null; String classpath = System.getProperty("java.class.path"); - URL url = Thread.currentThread().getContextClassLoader().getResource("com/jme3/system/NativeLibraryLoader.class"); + URL url = Resources.getResource("com/jme3/system/NativeLibraryLoader.class"); try { StringBuilder sb = new StringBuilder(url.toString()); @@ -371,9 +373,9 @@ public static File getJarForNativeLibrary(Platform platform, String name) { fileNameInJar = pathInJar; } - URL url = Thread.currentThread().getContextClassLoader().getResource(pathInJar); + URL url = Resources.getResource(pathInJar); if (url == null) { - url = Thread.currentThread().getContextClassLoader().getResource(fileNameInJar); + url = Resources.getResource(fileNameInJar); } if (url == null) { @@ -401,7 +403,7 @@ public static void extractNativeLibrary(Platform platform, String name, File tar return; } - URL url = Thread.currentThread().getContextClassLoader().getResource(pathInJar); + URL url = Resources.getResource(pathInJar); if (url == null) { return; } @@ -462,7 +464,7 @@ public static void loadNativeLibrary(String name, boolean isRequired) { return; } - URL url = Thread.currentThread().getContextClassLoader().getResource(pathInJar); + URL url = Resources.getResource(pathInJar); if (url == null) { if (isRequired) { diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomExtract.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomExtract.j3md index d3e51dd573..4171380e6d 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomExtract.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomExtract.j3md @@ -1,6 +1,7 @@ MaterialDef Bloom { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture Float ExposurePow @@ -10,13 +11,14 @@ MaterialDef Bloom { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/bloomExtract.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/bloomExtract.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HAS_GLOWMAP : GlowMap DO_EXTRACT : Extract RESOLVE_MS : NumSamples diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomFinal.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomFinal.j3md index 817764cab9..e356e1f07f 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomFinal.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/BloomFinal.j3md @@ -1,20 +1,22 @@ MaterialDef Bloom Final { MaterialParameters { - Int NumSamples + Int BoundDrawBuffer + Int NumSamples Texture2D Texture Texture2D BloomTex Float BloomIntensity } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/bloomFinal.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/bloomFinal.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples } } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/CartoonEdge.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/CartoonEdge.j3md index c7a740bcc0..59001feec2 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/CartoonEdge.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/CartoonEdge.j3md @@ -1,6 +1,7 @@ MaterialDef Cartoon Edge { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -16,8 +17,8 @@ MaterialDef Cartoon Edge { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/CartoonEdge.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/CartoonEdge.frag WorldParameters { WorldViewMatrix @@ -25,6 +26,7 @@ MaterialDef Cartoon Edge { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/Compose.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/Compose.j3md index 8f5e584df0..b24909cdb8 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/Compose.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/Compose.j3md @@ -1,6 +1,7 @@ MaterialDef Default GUI { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -8,13 +9,14 @@ MaterialDef Default GUI { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/Compose.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Compose.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.frag b/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.frag index f3e499d64c..363d078a1b 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.frag +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.frag @@ -37,9 +37,11 @@ * Then a power law is applied, using the exponent for each channel. * Finally, the output value is scaled linearly, using the scaling factor for each channel. * - * Supports GLSL100 GLSL110 GLSL120 GLSL130. */ +#import "Common/ShaderLib/GLSLCompat.glsllib" +#import "Common/ShaderLib/MultiSample.glsllib" + //constant inputs from java source uniform float m_redChannelExponent; uniform float m_greenChannelExponent; @@ -55,7 +57,7 @@ uniform float m_lowerLimit; uniform float m_upperLimit; //container for the input from post.vert -uniform sampler2D m_Texture; +uniform COLORTEXTURE m_Texture; //varying input from post.vert vertex shader varying vec2 texCoord; diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.j3md index 83c0e1125f..7c2ee7bea7 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment.j3md @@ -4,6 +4,7 @@ MaterialDef ColorAdjustmentFilter { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture Float redChannelExponent @@ -15,14 +16,17 @@ MaterialDef ColorAdjustmentFilter { Float greenChannelScale Float blueChannelScale } + Technique { - VertexShader GLSL150 GLSL300 GLSL310 GLSL320: Common/MatDefs/Post/Post15.vert - FragmentShader GLSL150 GLSL300 GLSL310 GLSL320: Common/MatDefs/Post/ContrastAdjustment15.frag - } + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/ContrastAdjustment.frag + WorldParameters { + } - Technique { - VertexShader GLSL100 GLSL110 GLSL120 GLSL130: Common/MatDefs/Post/Post.vert - FragmentShader GLSL100 GLSL110 GLSL120 GLSL130: Common/MatDefs/Post/ContrastAdjustment.frag + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + NUM_SAMPLES : NumSamples + } } } \ No newline at end of file diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment15.frag b/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment15.frag deleted file mode 100644 index c92bbc9901..0000000000 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/ContrastAdjustment15.frag +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -/* - * Used by ContrastAdjustment.j3md to adjust the color channels. - * - * First, the input range is normalized to upper and lower limits. - * Then a power law is applied, using the exponent for each channel. - * Finally, the output value is scaled linearly, using the scaling factor for each channel. - * - * Supports glsl150 and glsl150+ including android GLES glsl300, glsl310 and glsl320. - */ - -#import "Common/ShaderLib/GLSLCompat.glsllib" -#import "Common/ShaderLib/MultiSample.glsllib" - -//constant inputs from java source -uniform float m_redChannelExponent; -uniform float m_greenChannelExponent; -uniform float m_blueChannelExponent; - -//final scale values -uniform float m_redChannelScale; -uniform float m_greenChannelScale; -uniform float m_blueChannelScale; - -//input range -uniform float m_lowerLimit; -uniform float m_upperLimit; - -//container for the input from post15.vert -uniform COLORTEXTURE m_Texture; - -//varying input from post15.vert vertex shader -in vec2 texCoord; - -//the output color -out vec4 fragColor; - -void main() { - //get the color from a 2d sampler. - vec4 color = texture2D(m_Texture, texCoord); - - //apply the color transfer function. - - //1) adjust the channels input range - color.rgb = (color.rgb - vec3(m_lowerLimit)) / (vec3(m_upperLimit) - vec3(m_lowerLimit)); - - // avoid negative levels - color.r = max(color.r, 0.0); - color.g = max(color.g, 0.0); - color.b = max(color.b, 0.0); - - //2) apply transfer functions on different channels. - color.r = pow(color.r, m_redChannelExponent); - color.g = pow(color.g, m_greenChannelExponent); - color.b = pow(color.b, m_blueChannelExponent); - - //3) scale the output levels - color.r = color.r * m_redChannelScale; - color.b = color.b * m_blueChannelScale; - color.g = color.g * m_greenChannelScale; - - //4) process the textures colors. - fragColor = color; -} \ No newline at end of file diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/CrossHatch.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/CrossHatch.j3md index e5c168a630..3526dd3a3a 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/CrossHatch.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/CrossHatch.j3md @@ -1,6 +1,7 @@ MaterialDef CrossHatch { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture; Vector4 LineColor; @@ -18,11 +19,15 @@ MaterialDef CrossHatch { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/CrossHatch.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/CrossHatch.frag WorldParameters { } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } } \ No newline at end of file diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/DepthOfField.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/DepthOfField.j3md index 908889951b..8a7d2f354b 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/DepthOfField.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/DepthOfField.j3md @@ -1,6 +1,7 @@ MaterialDef Depth Of Field { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -14,14 +15,15 @@ MaterialDef Depth Of Field { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/DepthOfField.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/DepthOfField.frag WorldParameters { FrustumNearFar } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth BLUR_THRESHOLD : BlurThreshold diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/FXAA.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/FXAA.j3md index 2debc760c7..385a3a1666 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/FXAA.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/FXAA.j3md @@ -1,5 +1,6 @@ MaterialDef FXAA { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture Float SubPixelShift @@ -8,10 +9,14 @@ MaterialDef FXAA { Float ReduceMul } Technique { - VertexShader GLSL300 GLSL100 GLSL150: Common/MatDefs/Post/FXAA.vert - FragmentShader GLSL300 GLSL100 GLSL150: Common/MatDefs/Post/FXAA.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/FXAA.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/FXAA.frag WorldParameters { ResolutionInverse } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/Fade.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/Fade.j3md index e9a55ab8b2..cac57cf21f 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/Fade.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/Fade.j3md @@ -1,19 +1,21 @@ MaterialDef Fade { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture Float Value } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/Fade.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Fade.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples } } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/Fog.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/Fog.j3md index b1d28103ce..b6267326a0 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/Fog.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/Fog.j3md @@ -1,6 +1,7 @@ MaterialDef Fade { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -11,13 +12,14 @@ MaterialDef Fade { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/Fog.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Fog.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/LightScattering.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/LightScattering.j3md index 590dbdc051..d7929bd022 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/LightScattering.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/LightScattering.j3md @@ -1,5 +1,6 @@ MaterialDef Light Scattering { - MaterialParameters { + MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -14,13 +15,14 @@ MaterialDef Light Scattering { } Technique { - VertexShader GLSL300 GLSL150 GLSL120: Common/MatDefs/Post/Post.vert + VertexShader GLSL300 GLSL150 GLSL120: Common/MatDefs/Post/Post.vert FragmentShader GLSL300 GLSL150 GLSL120: Common/MatDefs/Post/LightScattering.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth DISPLAY: Display diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/Overlay.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/Overlay.j3md index 6cdb458883..51eb543573 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/Overlay.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/Overlay.j3md @@ -1,6 +1,7 @@ MaterialDef Default GUI { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -8,13 +9,14 @@ MaterialDef Default GUI { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/Overlay.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Overlay.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/Post15.vert b/jme3-effects/src/main/resources/Common/MatDefs/Post/Post15.vert index 3bcd2ede01..975780ea29 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/Post15.vert +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/Post15.vert @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + in vec4 inPosition; in vec2 inTexCoord; diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/Posterization.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/Posterization.j3md index 635dc0f536..71ca681a48 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/Posterization.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/Posterization.j3md @@ -1,6 +1,7 @@ MaterialDef Posterization { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture; @@ -10,14 +11,15 @@ MaterialDef Posterization { } Technique { - VertexShader GLSL150 GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/Posterization.frag + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Post/Posterization.frag WorldParameters { } Defines { - RESOLVE_MS : NumSamples + BOUND_DRAW_BUFFER: BoundDrawBuffer + RESOLVE_MS : NumSamples } } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Post/ToneMap.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Post/ToneMap.j3md index 7c1eb6673d..2ca259838f 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Post/ToneMap.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Post/ToneMap.j3md @@ -1,6 +1,7 @@ MaterialDef Default GUI { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -8,13 +9,14 @@ MaterialDef Default GUI { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Post/Post.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Post/ToneMap.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/ToneMap.frag WorldParameters { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NUM_SAMPLES : NumSamples } } diff --git a/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssao.j3md b/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssao.j3md index 0f5b5433e7..f61dd1a32e 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssao.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssao.j3md @@ -1,6 +1,7 @@ MaterialDef SSAO { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -18,7 +19,7 @@ MaterialDef SSAO { } Technique { - VertexShader GLSL300 GLSL150 GLSL120: Common/MatDefs/Post/Post.vert + VertexShader GLSL300 GLSL150 GLSL120: Common/MatDefs/Post/Post.vert FragmentShader GLSL300 GLSL150 GLSL120: Common/MatDefs/SSAO/ssao.frag WorldParameters { @@ -28,6 +29,7 @@ MaterialDef SSAO { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth APPROXIMATE_NORMALS : ApproximateNormals diff --git a/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssaoBlur.j3md b/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssaoBlur.j3md index 2314876d6d..773d34c363 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssaoBlur.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssaoBlur.j3md @@ -1,6 +1,7 @@ MaterialDef SSAOBlur { - MaterialParameters { + MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D Texture @@ -22,6 +23,7 @@ MaterialDef SSAOBlur { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer USE_AO : UseAo USE_ONLY_AO : UseOnlyAo RESOLVE_MS : NumSamples diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Water/SimpleWater.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Water/SimpleWater.j3md index 7ef8775b3a..710dcd5151 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Water/SimpleWater.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Water/SimpleWater.j3md @@ -1,6 +1,7 @@ MaterialDef Simple Water { MaterialParameters { + Int BoundDrawBuffer Texture2D water_reflection Texture2D water_refraction Texture2D water_depthmap @@ -18,8 +19,8 @@ MaterialDef Simple Water { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Water/simple_water.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Water/simple_water.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Water/simple_water.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/Water/simple_water.frag WorldParameters { WorldViewProjectionMatrix @@ -27,5 +28,9 @@ MaterialDef Simple Water { Resolution CameraPosition } + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } + } } \ No newline at end of file diff --git a/jme3-effects/src/main/resources/Common/MatDefs/Water/Water.j3md b/jme3-effects/src/main/resources/Common/MatDefs/Water/Water.j3md index 49c5a06e53..f75e263aba 100644 --- a/jme3-effects/src/main/resources/Common/MatDefs/Water/Water.j3md +++ b/jme3-effects/src/main/resources/Common/MatDefs/Water/Water.j3md @@ -1,6 +1,7 @@ MaterialDef Advanced Water { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D FoamMap @@ -59,7 +60,8 @@ MaterialDef Advanced Water { } Defines { - RESOLVE_MS : NumSamples + BOUND_DRAW_BUFFER: BoundDrawBuffer + RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth ENABLE_RIPPLES : UseRipples ENABLE_HQ_SHORELINE : UseHQShoreline diff --git a/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java b/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java new file mode 100644 index 0000000000..b94fa7a816 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 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. + */ +package jme3test.export; + +import com.jme3.app.SimpleApplication; +import com.jme3.export.JmeExporter; +import com.jme3.export.xml.XMLExporter; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Test case for JME issue: #2068 exporting a Map to XML results in a + * DOMException. + * + *

If the issue is unresolved, the application will exit prematurely with an + * uncaught exception. + * + *

If the issue is resolved, the application will complete normally. + * + * @author Stephen Gold sgold@sonic.net + */ +public class TestIssue2068 extends SimpleApplication { + // ************************************************************************* + // constants and loggers + + /** + * message logger for this class + */ + final public static Logger logger + = Logger.getLogger(TestIssue2068.class.getName()); + // ************************************************************************* + // new methods exposed + + /** + * Main entry point for the TestIssue2068 application. + * + * @param args array of command-line arguments (not null) + */ + public static void main(String[] args) { + TestIssue2068 app = new TestIssue2068(); + app.start(); + } + + /** + * Initialize the application. + */ + @Override + public void simpleInitApp() { + Map map = new HashMap<>(); + map.put("key", "value"); + rootNode.setUserData("map", map); + + String outputFilename = "TestIssue2068.xml"; + File xmlFile = new File(outputFilename); + JmeExporter exporter = XMLExporter.getInstance(); + try { + exporter.save(rootNode, xmlFile); + } catch (IOException exception) { + logger.log(Level.SEVERE, exception.getMessage(), exception); + } + stop(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java new file mode 100644 index 0000000000..037dd980a6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.system.AppSettings; + +/** + * Test for JMonkeyEngine issue #2011: context profiles are not defined for + * OpenGL v3.0/v3.1 + *

+ * If the issue is resolved, then pressing the "0" or "1" key shouldn't crash + * the app; it should close the app display and create a new display, mostly + * black with statistics displayed in the lower left. + *

+ * If the issue is not resolved, then pressing the "0" or "1" key should crash + * the app with multiple exceptions. + *

+ * Since the issue was specific to LWJGL v3, this test should be built with the + * jme3-lwjgl3 library, not jme3-lwjgl. + * + * @author Stephen Gold + */ +public class TestIssue2011 extends SimpleApplication { + /** + * Main entry point for the TestIssue2011 application. + * + * @param args array of command-line arguments (not null) + */ + public static void main(String[] args) { + TestIssue2011 app = new TestIssue2011(); + app.start(); + } + + /** + * Initialize this application. + */ + @Override + public void simpleInitApp() { + inputManager.addMapping("3.0", new KeyTrigger(KeyInput.KEY_0), + new KeyTrigger(KeyInput.KEY_NUMPAD0)); + inputManager.addMapping("3.1", new KeyTrigger(KeyInput.KEY_1), + new KeyTrigger(KeyInput.KEY_NUMPAD1)); + inputManager.addMapping("3.2", new KeyTrigger(KeyInput.KEY_2), + new KeyTrigger(KeyInput.KEY_NUMPAD2)); + + ActionListener listener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("3.0") && keyPressed) { + setApi(AppSettings.LWJGL_OPENGL30); + } else if (name.equals("3.1") && keyPressed) { + setApi(AppSettings.LWJGL_OPENGL31); + } else if (name.equals("3.2") && keyPressed) { + setApi(AppSettings.LWJGL_OPENGL32); + } + } + }; + + inputManager.addListener(listener, "3.0", "3.1", "3.2"); + } + + /** + * Restart the app, specifying which OpenGL version to use. + * + * @param desiredApi the string to be passed to setRenderer() + */ + private void setApi(String desiredApi) { + System.out.println("desiredApi = " + desiredApi); + settings.setRenderer(desiredApi); + setSettings(settings); + + restart(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java new file mode 100644 index 0000000000..d350566d03 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; + +/** + * Test for JMonkeyEngine issue #798: OpenGLException on restart with changed + * display settings. + *

+ * If the issue is resolved, then pressing the "P", "T", or "Y" key shouldn't + * crash the app; it should close the app display and create a new display, + * mostly black with statistics displayed in the lower left. + *

+ * If the issue is not resolved, the expected failure mode depends on whether + * assertions are enabled. If they're enabled, the app will crash with an + * OpenGLException. If assertions aren't enabled, the new window will be + * entirely black, with no statistics visible. + *

+ * Since the issue was specific to LWJGL v2, this test should be built with the + * jme3-lwjgl library, not jme3-lwjgl3. + * + * @author Stephen Gold + */ +public class TestIssue798 extends SimpleApplication { + /** + * Main entry point for the TestIssue798 application. + * + * @param args array of command-line arguments (not null) + */ + public static void main(String[] args) { + TestIssue798 app = new TestIssue798(); + app.start(); + } + + /** + * Initialize this application. + */ + @Override + public void simpleInitApp() { + inputManager.addMapping("windowedMode", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addMapping("moreSamples", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addMapping("toggleDepth", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addMapping("toggleBpp", new KeyTrigger(KeyInput.KEY_Y)); + + ActionListener listener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("moreSamples") && keyPressed) { + moreSamples(); + } else if (name.equals("toggleBpp") && keyPressed) { + toggleBpp(); + } else if (name.equals("toggleDepth") && keyPressed) { + toggleDepth(); + } else if (name.equals("windowedMode") && keyPressed) { + windowedMode(); + } + } + }; + + inputManager.addListener(listener, + "moreSamples", "toggleBpp", "toggleDepth", "windowedMode"); + } + + /** + * Restart the app, requesting 2 more MSAA samples per pixel. + */ + private void moreSamples() { + int numSamples = settings.getSamples(); + numSamples += 2; + System.out.println("numSamples = " + numSamples); + settings.setSamples(numSamples); + setSettings(settings); + + restart(); + } + + /** + * Restart the app, requesting a different number of bits per pixel in the + * RGB buffer. + */ + private void toggleBpp() { + int bpp = settings.getBitsPerPixel(); + bpp = (bpp == 24) ? 16 : 24; + System.out.println("BPP = " + bpp); + settings.setBitsPerPixel(bpp); + setSettings(settings); + + restart(); + } + + /** + * Restart the app, requesting a different number of bits per pixel in the + * depth buffer. + */ + private void toggleDepth() { + int depthBits = settings.getDepthBits(); + depthBits = (depthBits == 24) ? 16 : 24; + System.out.println("depthBits = " + depthBits); + settings.setDepthBits(depthBits); + setSettings(settings); + + restart(); + } + + /** + * If the app is in fullscreen mode, restart it in 640x480 windowed mode. + */ + private void windowedMode() { + boolean isFullscreen = settings.isFullscreen(); + if (!isFullscreen) { + System.out.println("Request ignored: already in windowed mode!"); + return; + } + + System.out.println("fullscreen = " + false); + settings.setFullscreen(false); + settings.setWidth(640); + settings.setHeight(480); + setSettings(settings); + + restart(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainGridTileLoaderTest.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainGridTileLoaderTest.java index 0bf655aeee..5f9ca109fe 100644 --- a/jme3-examples/src/main/java/jme3test/terrain/TerrainGridTileLoaderTest.java +++ b/jme3-examples/src/main/java/jme3test/terrain/TerrainGridTileLoaderTest.java @@ -114,7 +114,7 @@ public void simpleInitApp() { final BulletAppState bulletAppState = new BulletAppState(); stateManager.attach(bulletAppState); - this.getCamera().setLocation(new Vector3f(0, 256, 0)); + cam.setLocation(new Vector3f(257f, 256f, -514f)); cam.setRotation(new Quaternion(-0.0075f, 0.949784f, -0.312f, -0.0227f)); this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); diff --git a/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java b/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java index dcef2a64a6..7a46d6ee9d 100644 --- a/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java +++ b/jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java @@ -789,5 +789,20 @@ public void glTexSubImage3D(int target, int level, int xoffset, int yoffset, int JmeIosGLES.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data); } + @Override + public void glBindVertexArray(int array) { + throw new UnsupportedOperationException("Unimplemented method 'glBindVertexArray'"); + } + + @Override + public void glDeleteVertexArrays(IntBuffer arrays) { + throw new UnsupportedOperationException("Unimplemented method 'glDeleteVertexArrays'"); + } + + @Override + public void glGenVertexArrays(IntBuffer arrays) { + throw new UnsupportedOperationException("Unimplemented method 'glGenVertexArrays'"); + } + } diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java b/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java index 77f41c1f82..297549f5fd 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/JmeIosSystem.java @@ -35,7 +35,7 @@ import com.jme3.system.JmeContext; import com.jme3.system.JmeSystemDelegate; import com.jme3.system.NullContext; -import com.jme3.util.functional.VoidFunction; +import com.jme3.util.res.Resources; import com.jme3.audio.AudioRenderer; import com.jme3.audio.ios.IosAL; import com.jme3.audio.ios.IosALC; @@ -64,7 +64,7 @@ public JmeIosSystem() { @Override public URL getPlatformAssetConfigURL() { - return Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/IOS.cfg"); + return Resources.getResource("com/jme3/asset/IOS.cfg"); } @Override diff --git a/jme3-jogg/build.gradle b/jme3-jogg/build.gradle index a039b96bca..46f529116b 100644 --- a/jme3-jogg/build.gradle +++ b/jme3-jogg/build.gradle @@ -1,4 +1,4 @@ dependencies { api project(':jme3-core') - api 'com.github.stephengold:j-ogg-vorbis:1.0.3' + api 'com.github.stephengold:j-ogg-vorbis:1.0.4' } diff --git a/jme3-lwjgl/build.gradle b/jme3-lwjgl/build.gradle index 846c2fd254..afb8d91c77 100644 --- a/jme3-lwjgl/build.gradle +++ b/jme3-lwjgl/build.gradle @@ -3,7 +3,6 @@ dependencies { api project(':jme3-desktop') api 'org.jmonkeyengine:lwjgl:2.9.5' - runtimeOnly 'org.jmonkeyengine:lwjgl-platform:2.9.5' /* * Upgrades the default jinput-2.0.5 to jinput-2.0.9 to fix a bug with gamepads on Linux. diff --git a/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuad.j3md b/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuad.j3md index 73c71ac47d..ad4b26a294 100644 --- a/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuad.j3md +++ b/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuad.j3md @@ -5,8 +5,8 @@ MaterialDef Default GUI { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Nifty/NiftyQuad.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Nifty/NiftyQuad.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Nifty/NiftyQuad.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Nifty/NiftyQuad.frag WorldParameters { WorldViewProjectionMatrix diff --git a/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuadGrad.j3md b/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuadGrad.j3md index ca351d8ea7..fb9b19fd97 100644 --- a/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuadGrad.j3md +++ b/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyQuadGrad.j3md @@ -4,8 +4,8 @@ MaterialDef Default GUI { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Nifty/NiftyQuadGrad.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Nifty/NiftyQuadGrad.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Nifty/NiftyQuadGrad.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Nifty/NiftyQuadGrad.frag WorldParameters { WorldViewProjectionMatrix diff --git a/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyTex.j3md b/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyTex.j3md index e1d26494b8..12f83cf652 100644 --- a/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyTex.j3md +++ b/jme3-niftygui/src/main/resources/Common/MatDefs/Nifty/NiftyTex.j3md @@ -6,8 +6,8 @@ MaterialDef Default GUI { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Nifty/NiftyTex.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Nifty/NiftyTex.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Nifty/NiftyTex.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Nifty/NiftyTex.frag WorldParameters { WorldViewProjectionMatrix diff --git a/jme3-plugins-json-gson/build.gradle b/jme3-plugins-json-gson/build.gradle new file mode 100644 index 0000000000..6d22f7a774 --- /dev/null +++ b/jme3-plugins-json-gson/build.gradle @@ -0,0 +1,16 @@ +sourceSets { + main { + java { + + srcDir 'src/main/java' + + } + } +} + +dependencies { + + api project(':jme3-plugins-json') + api 'com.google.code.gson:gson:2.9.1' + +} diff --git a/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonArray.java b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonArray.java new file mode 100644 index 0000000000..8cd98f89d2 --- /dev/null +++ b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonArray.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.gson; + +import java.util.Iterator; + +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonElement; + +/** + * GSON implementation of {@link JsonArray}. + */ +class GsonArray extends GsonElement implements JsonArray { + + GsonArray(com.google.gson.JsonElement element) { + super(element); + } + + private com.google.gson.JsonArray arr() { + return element.getAsJsonArray(); + } + + @Override + public Iterator iterator() { + return new Iterator() { + Iterator it = arr().iterator(); + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public JsonElement next() { + return new GsonElement(it.next()).autoCast(); + } + }; + } + + @Override + public JsonElement get(int i) { + com.google.gson.JsonElement el = arr().get(i); + return isNull(el)?null:new GsonElement(el).autoCast(); + } + + @Override + public int size() { + return arr().size(); + } + +} diff --git a/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonElement.java b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonElement.java new file mode 100644 index 0000000000..6e929be9d4 --- /dev/null +++ b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonElement.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.gson; + +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonElement; +import com.jme3.plugins.json.JsonObject; +import com.jme3.plugins.json.JsonPrimitive; + +/** + * GSON implementation of {@link JsonElement} + */ +class GsonElement implements JsonElement { + com.google.gson.JsonElement element; + + GsonElement(com.google.gson.JsonElement element) { + this.element = element; + } + + protected boolean isNull(com.google.gson.JsonElement element) { + if (element == null) return true; + if (element.isJsonNull()) return true; + return false; + } + + @Override + public String getAsString() { + return element.getAsString(); + } + + @Override + public JsonObject getAsJsonObject() { + return new GsonObject(element.getAsJsonObject()); + } + + @Override + public float getAsFloat() { + return element.getAsFloat(); + } + + @Override + public int getAsInt() { + return element.getAsInt(); + } + + @Override + public Number getAsNumber() { + return element.getAsNumber(); + } + + @Override + public boolean getAsBoolean() { + return element.getAsBoolean(); + } + + @Override + public JsonArray getAsJsonArray() { + return new GsonArray(element.getAsJsonArray()); + } + + @Override + public JsonPrimitive getAsJsonPrimitive() { + return new GsonPrimitive(element.getAsJsonPrimitive()); + } + + @SuppressWarnings("unchecked") + public T autoCast() { + if(isNull(element)) return null; + if (element.isJsonArray()) return (T) new GsonArray(element.getAsJsonArray()); + if (element.isJsonObject()) return (T) new GsonObject(element.getAsJsonObject()); + if (element.isJsonPrimitive()) return (T) new GsonPrimitive(element.getAsJsonPrimitive()); + return (T) new GsonElement(element); + } + +} diff --git a/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonObject.java b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonObject.java new file mode 100644 index 0000000000..8aadbfb182 --- /dev/null +++ b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonObject.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.gson; + +import java.util.Set; +import java.util.Map.Entry; + +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonElement; +import com.jme3.plugins.json.JsonObject; +import com.jme3.plugins.json.JsonPrimitive; + +/** + * GSON implementation of {@link JsonObject} + */ +class GsonObject extends GsonElement implements JsonObject { + + GsonObject(com.google.gson.JsonObject gsonObject) { + super(gsonObject); + } + + private com.google.gson.JsonObject obj() { + return (com.google.gson.JsonObject) element; + } + + @Override + public JsonArray getAsJsonArray(String string) { + com.google.gson.JsonArray el = obj().getAsJsonArray(string); + return isNull(el) ? null : new GsonArray(el); + } + + @Override + public JsonObject getAsJsonObject(String string) { + com.google.gson.JsonObject el = obj().getAsJsonObject(string); + return isNull(el) ? null : new GsonObject(el); + } + + @Override + public boolean has(String string) { + return obj().has(string); + } + + @Override + public JsonElement get(String string) { + com.google.gson.JsonElement el = obj().get(string); + return isNull(el)?null:new GsonElement(el).autoCast(); + } + + @Override + public Entry[] entrySet() { + Set> entrySet = obj().entrySet(); + Entry[] entries = new Entry[entrySet.size()]; + int i = 0; + for (Entry entry : entrySet) { + + Entry e = new Entry() { + @Override + public String getKey() { + return entry.getKey(); + } + + @Override + public GsonElement getValue() { + return new GsonElement(entry.getValue()).autoCast(); + } + + @Override + public GsonElement setValue(JsonElement value) { + throw new UnsupportedOperationException("Unimplemented method 'setValue'"); + } + }; + + entries[i++] = e; + } + return entries; + + } + + @Override + public JsonPrimitive getAsJsonPrimitive(String string) { + com.google.gson.JsonPrimitive el= obj().getAsJsonPrimitive(string); + return isNull(el) ? null : new GsonPrimitive(el); + } +} \ No newline at end of file diff --git a/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonParser.java b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonParser.java new file mode 100644 index 0000000000..fd7fd0462c --- /dev/null +++ b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonParser.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.gson; + +import java.io.InputStream; +import java.io.InputStreamReader; + +import com.jme3.plugins.json.JsonObject; +import com.jme3.plugins.json.JsonParser; + +/** + * GSON implementation of {@link JsonParser} + */ +public class GsonParser implements JsonParser { + @Override + public JsonObject parse(InputStream stream) { + return new GsonObject(com.google.gson.JsonParser.parseReader(new com.google.gson.stream.JsonReader(new InputStreamReader(stream))).getAsJsonObject()); + } +} diff --git a/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonPrimitive.java b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonPrimitive.java new file mode 100644 index 0000000000..91399bcebb --- /dev/null +++ b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/GsonPrimitive.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.gson; + +import com.jme3.plugins.json.JsonPrimitive; + +/** + * GSON implementation of {@link JsonPrimitive} + */ +public class GsonPrimitive extends GsonElement implements JsonPrimitive { + + public GsonPrimitive(com.google.gson.JsonPrimitive element) { + super(element); + } + + private com.google.gson.JsonPrimitive prim() { + return (com.google.gson.JsonPrimitive) element; + } + + @Override + public boolean isNumber() { + return prim().isNumber(); + } + + @Override + public boolean isBoolean() { + return prim().isBoolean(); + } + + @Override + public boolean isString() { + return prim().isString(); + } + +} diff --git a/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/package-info.java b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/package-info.java new file mode 100644 index 0000000000..df1e88063f --- /dev/null +++ b/jme3-plugins-json-gson/src/main/java/com/jme3/plugins/gson/package-info.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2009-2023 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. + */ + +/** + * A JSON parser that uses Gson internally + */ + +package com.jme3.plugins.gson; diff --git a/jme3-plugins-json/build.gradle b/jme3-plugins-json/build.gradle new file mode 100644 index 0000000000..9a0bb3e43b --- /dev/null +++ b/jme3-plugins-json/build.gradle @@ -0,0 +1,14 @@ +sourceSets { + main { + java { + + srcDir 'src/main/java' + + } + } +} + +dependencies { + + +} diff --git a/jme3-plugins-json/src/main/java/com/jme3/plugins/json/Json.java b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/Json.java new file mode 100644 index 0000000000..19eb8490d6 --- /dev/null +++ b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/Json.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.json; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * A json parser factory that allows you to set the parser to use. + * + * @author Riccardo Balbo + */ +public class Json { + /** + * The property name to set the parser to use. + * Should be set automatically by the JmeSystemDelegate. + * Note: changing this property after the first call to Json.create() will have no effect. + */ + public static final String PROPERTY_JSON_PARSER_IMPLEMENTATION = "com.jme3.JsonParserImplementation"; + private static final Logger LOGGER = Logger.getLogger(Json.class.getName()); + private static final String DEFAULT_JSON_PARSER_IMPLEMENTATION = "com.jme3.plugins.gson.GsonParser"; + + private static Class clazz = null; + + /** + * Set the parser to use. + * + * @param clazz + * a class that implements JsonParser + */ + public static void setParser(Class clazz) { + Json.clazz = clazz; + } + + @SuppressWarnings("unchecked") + private static Class findJsonParser(String className) { + Class clazz = null; + + try { + clazz = Class.forName(className); + } catch (final Throwable e) { + LOGGER.log(Level.WARNING, "Unable to access {0}", className); + } + + if (clazz != null && !JsonParser.class.isAssignableFrom(clazz)) { + LOGGER.log(Level.WARNING, "{0} does not implement {1}", new Object[] { className, JsonParser.class.getName() }); + clazz = null; + } + + return (Class) clazz; + } + + /** + * Create a new JsonParser instance. + * + * @return a new JsonParser instance + */ + + public static JsonParser create() { + if (Json.clazz == null) { + String userDefinedImpl = System.getProperty(PROPERTY_JSON_PARSER_IMPLEMENTATION, null); + if (userDefinedImpl != null) { + LOGGER.log(Level.FINE, "Loading user defined JsonParser implementation {0}", userDefinedImpl); + Json.clazz = findJsonParser(userDefinedImpl); + } + if (Json.clazz == null) { + LOGGER.log(Level.FINE, "No usable user defined JsonParser implementation found, using default implementation {0}", DEFAULT_JSON_PARSER_IMPLEMENTATION); + Json.clazz = findJsonParser(DEFAULT_JSON_PARSER_IMPLEMENTATION); + } + } + + if (Json.clazz == null) { + throw new RuntimeException("No JsonParser implementation found"); + } + + try { + return clazz.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException("Could not instantiate JsonParser class " + clazz.getName(), e); + } + } +} diff --git a/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonArray.java b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonArray.java new file mode 100644 index 0000000000..3be3e0321c --- /dev/null +++ b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonArray.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.json; + +/** + * Represents an array. + * + * @author Riccardo Balbo + */ +public interface JsonArray extends Iterable { + /** + * Get the element at index i + * + * @param i + * index + * @return the element + */ + public JsonElement get(int i); + + /** + * Get the size of the array + * + * @return the size + */ + public int size(); +} diff --git a/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonElement.java b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonElement.java new file mode 100644 index 0000000000..e47f94389d --- /dev/null +++ b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonElement.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.json; + +/** + * A generic element + * + * @author Riccardo Balbo + */ +public interface JsonElement { + + /** + * Returns the object as a String + * + * @return the string + */ + public String getAsString(); + + /** + * Returns the object as a JsonObject + * + * @return the JsonObject + */ + public JsonObject getAsJsonObject(); + + /** + * Returns the object as a float + * + * @return the float + */ + public float getAsFloat(); + + /** + * Returns the object as an int + * + * @return the int + */ + public int getAsInt(); + + /** + * Returns the object as a boolean + * + * @return the boolean + */ + public boolean getAsBoolean(); + + /** + * Returns the object as a JsonArray + * + * @return the JsonArray + */ + public JsonArray getAsJsonArray(); + + /** + * Returns the object as a Number + * @return the Number + */ + public Number getAsNumber(); + + + /** + * Returns the object as a JsonPrimitive + * @return the json primitive + */ + public JsonPrimitive getAsJsonPrimitive(); + + /** + * Cast this JsonElement to a specific type + * @return the casted JsonElement + */ + public T autoCast(); + +} diff --git a/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonObject.java b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonObject.java new file mode 100644 index 0000000000..230cba0da1 --- /dev/null +++ b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonObject.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.json; + +import java.util.Map.Entry; + +/** + * A generic object/map + * + * @author Riccardo Balbo + */ +public interface JsonObject extends JsonElement { + + /** + * Returns the object property as a String + * + * @param string + * name of the property + * @return the string + */ + public JsonArray getAsJsonArray(String string); + + /** + * Returns the object property as a JsonObject + * + * @param string + * name of the property + * @return the JsonObject + */ + public JsonObject getAsJsonObject(String string); + + /** + * Check if the object has a property + * + * @param string + * name of the property + * @return true if it exists, false otherwise + */ + public boolean has(String string); + + /** + * Returns the object property as generic element + * + * @param string + * name of the property + * @return the element + */ + public JsonElement get(String string); + + /** + * Returns the object's key-value pairs + * + * @return an array of key-value pairs + */ + public Entry[] entrySet(); + + /** + * Returns the object property as a wrapped primitive + * + * @param string + * name of the property + * @return the wrapped primitive + */ + public JsonPrimitive getAsJsonPrimitive(String string); + +} diff --git a/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonParser.java b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonParser.java new file mode 100644 index 0000000000..7e87912c87 --- /dev/null +++ b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonParser.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.json; + +import java.io.InputStream; + +/** + * A json parser + * + * @author Riccardo Balbo + */ +public interface JsonParser { + /** + * Parse a json input stream and returns a {@link JsonObject} + * + * @param stream + * the stream to parse + * @return the JsonObject + */ + public JsonObject parse(InputStream stream); +} diff --git a/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonPrimitive.java b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonPrimitive.java new file mode 100644 index 0000000000..ed55a8db77 --- /dev/null +++ b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/JsonPrimitive.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.plugins.json; + +/** + * A wrapped primitive + * + * @author Riccardo Balbo + */ +public interface JsonPrimitive { + /** + * Returns the wrapped primitive as a float + * + * @return the float value + */ + public float getAsFloat(); + + /** + * Returns the wrapped primitive as an int + * + * @return the int value + */ + public int getAsInt(); + + /* + * Returns the wrapped primitive as a boolean + * + * @return the boolean value + */ + public boolean getAsBoolean(); + + /** + * Check if the wrapped primitive is a number + * @return true if it is a number + */ + public boolean isNumber(); + + /** + * Check if the wrapped primitive is a boolean + * @return true if it is a boolean + */ + public boolean isBoolean(); + + /** + * Check if the wrapped primitive is a string + * @return true if it is a string + */ + public boolean isString(); + + /** + * Returns the wrapped primitive as a string + * @return the string value + */ + public String getAsString(); + + /** + * Returns the wrapped primitive as a generic number + * @return the number value + */ + public Number getAsNumber(); +} diff --git a/jme3-plugins-json/src/main/java/com/jme3/plugins/json/package-info.java b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/package-info.java new file mode 100644 index 0000000000..55a9208e1c --- /dev/null +++ b/jme3-plugins-json/src/main/java/com/jme3/plugins/json/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009-2023 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. + */ + +/** + * An abstraction layer to implement JSON parsers in jMonkeyEngine + */ +package com.jme3.plugins.json; diff --git a/jme3-plugins/build.gradle b/jme3-plugins/build.gradle index b88f0a64fd..1d325314ee 100644 --- a/jme3-plugins/build.gradle +++ b/jme3-plugins/build.gradle @@ -11,6 +11,7 @@ sourceSets { dependencies { api project(':jme3-core') - api 'com.google.code.gson:gson:2.9.1' + implementation project(':jme3-plugins-json') + implementation project(':jme3-plugins-json-gson') testRuntimeOnly project(':jme3-desktop') } diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/CustomContentManager.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/CustomContentManager.java index 5e76201819..6168132313 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/CustomContentManager.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/CustomContentManager.java @@ -31,9 +31,9 @@ */ package com.jme3.scene.plugins.gltf; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.jme3.asset.AssetLoadException; +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonElement; import java.io.IOException; import java.util.HashMap; diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtensionLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtensionLoader.java index 4bdbb29eff..033b200378 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtensionLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtensionLoader.java @@ -31,8 +31,8 @@ */ package com.jme3.scene.plugins.gltf; -import com.google.gson.JsonElement; +import com.jme3.plugins.json.JsonElement; import java.io.IOException; /** diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtrasLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtrasLoader.java index c470478db1..3c4c9819dc 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtrasLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/ExtrasLoader.java @@ -30,8 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jme3.scene.plugins.gltf; - -import com.google.gson.JsonElement; +import com.jme3.plugins.json.JsonElement; /** * Interface to handle a glTF extra. diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java index 2475c01ea9..a8c5070086 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java @@ -31,8 +31,10 @@ */ package com.jme3.scene.plugins.gltf; -import com.google.gson.*; -import com.google.gson.stream.JsonReader; +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonObject; +import com.jme3.plugins.json.JsonPrimitive; +import com.jme3.plugins.json.JsonElement; import com.jme3.anim.*; import com.jme3.asset.*; import com.jme3.material.Material; @@ -119,7 +121,7 @@ protected Object loadFromStream(AssetInfo assetInfo, InputStream stream) throws defaultMat.setFloat("Roughness", 1f); } - docRoot = JsonParser.parseReader(new JsonReader(new InputStreamReader(stream))).getAsJsonObject(); + docRoot = parse(stream); JsonObject asset = docRoot.getAsJsonObject().get("asset").getAsJsonObject(); getAsString(asset, "generator"); @@ -1050,7 +1052,7 @@ public void readSkins() throws IOException { // These inverse bind matrices, once inverted again, // will give us the real bind pose of the bones (in model space), - // since the skeleton in not guaranteed to be exported in bind pose. + // since the skeleton is not guaranteed to be exported in bind pose. Integer matricesIndex = getAsInteger(skin, "inverseBindMatrices"); Matrix4f[] inverseBindMatrices = null; if (matricesIndex != null) { diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java index e5b42d99a1..2586a99f15 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java @@ -31,11 +31,15 @@ */ package com.jme3.scene.plugins.gltf; -import com.google.gson.*; import com.jme3.asset.AssetInfo; import com.jme3.asset.AssetLoadException; import com.jme3.math.*; import com.jme3.scene.*; +import com.jme3.plugins.json.Json; +import com.jme3.plugins.json.JsonParser; +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonObject; +import com.jme3.plugins.json.JsonElement; import com.jme3.texture.Texture; import com.jme3.util.*; import java.io.*; @@ -57,6 +61,17 @@ public class GltfUtils { private GltfUtils() { } + + /** + * Parse a json input stream and returns a {@link JsonObject} + * @param stream the stream to parse + * @return the JsonObject + */ + public static JsonObject parse(InputStream stream) { + JsonParser parser = Json.create(); + return parser.parse(stream); + } + public static Mesh.Mode getMeshMode(Integer mode) { if (mode == null) { return Mesh.Mode.Triangles; diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/LightsPunctualExtensionLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/LightsPunctualExtensionLoader.java index 6b98e3f8d7..b3df7dbc88 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/LightsPunctualExtensionLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/LightsPunctualExtensionLoader.java @@ -31,9 +31,9 @@ */ package com.jme3.scene.plugins.gltf; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonObject; +import com.jme3.plugins.json.JsonElement; import com.jme3.asset.AssetLoadException; import com.jme3.light.DirectionalLight; import com.jme3.light.Light; diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/PBRSpecGlossExtensionLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/PBRSpecGlossExtensionLoader.java index 365c49eb29..2ab3862db3 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/PBRSpecGlossExtensionLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/PBRSpecGlossExtensionLoader.java @@ -31,11 +31,10 @@ */ package com.jme3.scene.plugins.gltf; -import com.google.gson.JsonElement; import com.jme3.asset.AssetKey; import java.io.IOException; - +import com.jme3.plugins.json.JsonElement; import static com.jme3.scene.plugins.gltf.GltfUtils.getAsColor; import static com.jme3.scene.plugins.gltf.GltfUtils.getAsFloat; diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/TextureTransformExtensionLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/TextureTransformExtensionLoader.java index d54382d8ac..ea643cea0c 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/TextureTransformExtensionLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/TextureTransformExtensionLoader.java @@ -31,9 +31,9 @@ */ package com.jme3.scene.plugins.gltf; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import com.jme3.plugins.json.JsonArray; +import com.jme3.plugins.json.JsonObject; +import com.jme3.plugins.json.JsonElement; import com.jme3.asset.AssetLoadException; import com.jme3.math.Matrix3f; import com.jme3.math.Vector3f; diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/UnlitExtensionLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/UnlitExtensionLoader.java index b9e8d5066a..cb45fcc533 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/UnlitExtensionLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/UnlitExtensionLoader.java @@ -30,8 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jme3.scene.plugins.gltf; - -import com.google.gson.JsonElement; +import com.jme3.plugins.json.JsonElement; import com.jme3.asset.AssetKey; /** diff --git a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MExporter.java b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MExporter.java index 4bb9282270..4affcd64c8 100644 --- a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MExporter.java +++ b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/material/J3MExporter.java @@ -55,7 +55,12 @@ public void save(Savable object, OutputStream f) throws IOException { } @Override - public void save(Savable object, File f) throws IOException { + public void save(Savable object, File f, boolean createDirectories) throws IOException { + File parentDirectory = f.getParentFile(); + if (parentDirectory != null && !parentDirectory.exists() && createDirectories) { + parentDirectory.mkdirs(); + } + try (FileOutputStream fos = new FileOutputStream(f); BufferedOutputStream bos = new BufferedOutputStream(fos)) { save(object, bos); diff --git a/jme3-plugins/src/test/java/com/jme3/export/JmeExporterTest.java b/jme3-plugins/src/test/java/com/jme3/export/JmeExporterTest.java new file mode 100644 index 0000000000..8a672ab37a --- /dev/null +++ b/jme3-plugins/src/test/java/com/jme3/export/JmeExporterTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2023 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. + */ +package com.jme3.export; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import com.jme3.asset.AssetManager; +import com.jme3.asset.DesktopAssetManager; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.export.xml.XMLExporter; +import com.jme3.material.Material; +import com.jme3.material.plugin.export.material.J3MExporter; + +/** + * Tests the methods on classes that implements the JmeExporter interface. + */ +@RunWith(Parameterized.class) +public class JmeExporterTest { + + // test saving with a material since the J3MExporter expects one + private static Material material; + + private final JmeExporter exporter; + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + + @BeforeClass + public static void beforeClass() { + AssetManager assetManager = new DesktopAssetManager(true); + material = new Material(assetManager, "Common/MatDefs/Gui/Gui.j3md"); + } + + public JmeExporterTest(JmeExporter exporter) { + this.exporter = exporter; + } + + @Parameterized.Parameters + public static Collection defineExporters() { + return Arrays.asList(new BinaryExporter(), new XMLExporter(), new J3MExporter()); + } + + private File fileWithMissingParent() { + File dir = new File(folder.getRoot(), "missingDir"); + return new File(dir, "afile.txt"); + } + + private File fileWithExistingParent() throws IOException { + File dir = folder.newFolder(); + return new File(dir, "afile.txt"); + } + + @Test + public void testSaveWhenPathDoesntExist() throws IOException { + File file = fileWithMissingParent(); + Assert.assertFalse(file.exists()); + exporter.save(material, file); + Assert.assertTrue(file.exists()); + } + + @Test + public void testSaveWhenPathDoesExist() throws IOException { + File file = fileWithExistingParent(); + exporter.save(material, file); + Assert.assertTrue(file.exists()); + } + + @Test(expected = FileNotFoundException.class) + public void testSaveWhenPathDoesntExistWithoutCreateDirs() throws IOException { + File file = fileWithMissingParent(); + exporter.save(material, file, false); + Assert.assertTrue(file.exists()); + } + + @Test + public void testSaveWithNullParent() throws IOException { + File file = new File("someFile.txt"); + try { + exporter.save(material, file); + Assert.assertTrue(file.exists()); + } finally { + file.delete(); + } + } +} diff --git a/jme3-plugins/src/xml/java/com/jme3/export/xml/DOMInputCapsule.java b/jme3-plugins/src/xml/java/com/jme3/export/xml/DOMInputCapsule.java index 52cd509f10..245bcdacbf 100644 --- a/jme3-plugins/src/xml/java/com/jme3/export/xml/DOMInputCapsule.java +++ b/jme3-plugins/src/xml/java/com/jme3/export/xml/DOMInputCapsule.java @@ -924,7 +924,7 @@ private Savable readSavableFromCurrentElem(Savable defVal) throws } else if (defVal != null) { className = defVal.getClass().getName(); } - tmp = SavableClassUtil.fromName(className, null); + tmp = SavableClassUtil.fromName(className); String versionsStr = currentElem.getAttribute("savable_versions"); if (versionsStr != null && !versionsStr.equals("")){ diff --git a/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java b/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java index 5472737bc6..add3f5ab70 100644 --- a/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java +++ b/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java @@ -77,7 +77,12 @@ public void save(Savable object, OutputStream f) throws IOException { } @Override - public void save(Savable object, File f) throws IOException { + public void save(Savable object, File f, boolean createDirectories) throws IOException { + File parentDirectory = f.getParentFile(); + if (parentDirectory != null && !parentDirectory.exists() && createDirectories) { + parentDirectory.mkdirs(); + } + FileOutputStream fos = new FileOutputStream(f); try { save(object, fos); diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md index 192c175165..fe0680482b 100644 --- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md +++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md @@ -2,6 +2,7 @@ MaterialDef Advanced PBR Terrain { MaterialParameters { + Int BoundDrawBuffer Boolean UseVertexColorsAsSunIntensity //set true to make the vertex color's R channel how exposed a vertex is to the sun @@ -255,8 +256,8 @@ MaterialDef Advanced PBR Terrain { LightMode SinglePassAndImageBased - VertexShader GLSL150: Common/MatDefs/Terrain/PBRTerrain.vert - FragmentShader GLSL150: Common/MatDefs/Terrain/AdvancedPBRTerrain.frag + VertexShader GLSL300 GLSL150 : Common/MatDefs/Terrain/PBRTerrain.vert + FragmentShader GLSL300 GLSL150 : Common/MatDefs/Terrain/AdvancedPBRTerrain.frag WorldParameters { WorldViewProjectionMatrix @@ -270,6 +271,7 @@ MaterialDef Advanced PBR Terrain { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer AFFLICTIONTEXTURE : AfflictionAlphaMap AFFLICTIONALBEDOMAP: SplatAlbedoMap @@ -340,8 +342,8 @@ MaterialDef Advanced PBR Terrain { Technique PreShadow { - VertexShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -351,6 +353,7 @@ MaterialDef Advanced PBR Terrain { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer DISCARD_ALPHA : AlphaDiscardThreshold NUM_BONES : NumberOfBones INSTANCING : UseInstancing @@ -368,8 +371,8 @@ MaterialDef Advanced PBR Terrain { Technique PostShadow{ - VertexShader GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -379,6 +382,7 @@ MaterialDef Advanced PBR Terrain { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/HeightBasedTerrain.j3md b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/HeightBasedTerrain.j3md index e8ec3589b3..d2bfa0c01d 100644 --- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/HeightBasedTerrain.j3md +++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/HeightBasedTerrain.j3md @@ -11,6 +11,7 @@ MaterialDef Terrain { // slopeTileFactor: the texture scale for slopes // terrainSize: the total size of the terrain (used for scaling the texture) MaterialParameters { + Int BoundDrawBuffer Texture2D region1ColorMap Texture2D region2ColorMap Texture2D region3ColorMap @@ -25,14 +26,18 @@ MaterialDef Terrain { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Terrain/HeightBasedTerrain.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Terrain/HeightBasedTerrain.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/HeightBasedTerrain.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/HeightBasedTerrain.frag WorldParameters { WorldViewProjectionMatrix WorldMatrix NormalMatrix } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } Technique { diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.j3md b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.j3md index 67796e5846..572bf8ef49 100644 --- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.j3md +++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.j3md @@ -2,6 +2,7 @@ MaterialDef PBR Terrain { MaterialParameters { + Int BoundDrawBuffer Boolean UseVertexColorsAsSunIntensity //set true to make the vertex color's R channel how exposed a vertex is to the sun @@ -228,8 +229,8 @@ MaterialDef PBR Terrain { LightMode SinglePassAndImageBased - VertexShader GLSL100 GLSL130 GLSL150: Common/MatDefs/Terrain/PBRTerrain.vert - FragmentShader GLSL100 GLSL130 GLSL150: Common/MatDefs/Terrain/PBRTerrain.frag + VertexShader GLSL300 GLSL150 GLSL130 GLSL100: Common/MatDefs/Terrain/PBRTerrain.vert + FragmentShader GLSL300 GLSL150 GLSL130 GLSL100: Common/MatDefs/Terrain/PBRTerrain.frag WorldParameters { WorldViewProjectionMatrix @@ -243,6 +244,7 @@ MaterialDef PBR Terrain { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer TILELOCATION : TileLocation AFFLICTIONTEXTURE : AfflictionAlphaMap @@ -318,8 +320,8 @@ MaterialDef PBR Terrain { Technique PreShadow { - VertexShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -329,6 +331,7 @@ MaterialDef PBR Terrain { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer DISCARD_ALPHA : AlphaDiscardThreshold NUM_BONES : NumberOfBones INSTANCING : UseInstancing @@ -346,8 +349,8 @@ MaterialDef PBR Terrain { Technique PostShadow{ - VertexShader GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Shadow/PostShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -357,6 +360,7 @@ MaterialDef PBR Terrain { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/Terrain.j3md b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/Terrain.j3md index 98fe3eb9e7..1ac3b21dc1 100644 --- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/Terrain.j3md +++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/Terrain.j3md @@ -1,6 +1,7 @@ MaterialDef Terrain { MaterialParameters { + Int BoundDrawBuffer // use tri-planar mapping Boolean useTriPlanarMapping @@ -15,14 +16,15 @@ MaterialDef Terrain { } Technique { - VertexShader GLSL100 GLSL150: Common/MatDefs/Terrain/Terrain.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Terrain/Terrain.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/Terrain.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/Terrain.frag WorldParameters { WorldViewProjectionMatrix } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer TRI_PLANAR_MAPPING : useTriPlanarMapping } } diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md index 353ff4e627..341ef1c683 100644 --- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md +++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md @@ -2,6 +2,7 @@ MaterialDef Terrain Lighting { MaterialParameters { + Int BoundDrawBuffer // use tri-planar mapping Boolean useTriPlanarMapping @@ -108,8 +109,8 @@ MaterialDef Terrain Lighting { LightMode MultiPass - VertexShader GLSL100 GLSL150: Common/MatDefs/Terrain/TerrainLighting.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Terrain/TerrainLighting.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/TerrainLighting.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/TerrainLighting.frag WorldParameters { WorldViewProjectionMatrix @@ -119,6 +120,7 @@ MaterialDef Terrain Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer TRI_PLANAR_MAPPING : useTriPlanarMapping TERRAIN_GRID : isTerrainGrid WARDISO : WardIso @@ -173,8 +175,8 @@ MaterialDef Terrain Lighting { LightMode SinglePass - VertexShader GLSL100 GLSL150: Common/MatDefs/Terrain/SPTerrainLighting.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Terrain/SPTerrainLighting.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.frag WorldParameters { WorldViewProjectionMatrix @@ -184,6 +186,7 @@ MaterialDef Terrain Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer TRI_PLANAR_MAPPING : useTriPlanarMapping TERRAIN_GRID : isTerrainGrid WARDISO : WardIso @@ -236,8 +239,8 @@ MaterialDef Terrain Lighting { Technique PreShadow { - VertexShader GLSL100 GLSL150: Common/MatDefs/Shadow/PreShadow.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Shadow/PreShadow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.frag WorldParameters { WorldViewProjectionMatrix @@ -245,6 +248,7 @@ MaterialDef Terrain Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer DIFFUSEMAP_ALPHA : DiffuseMap } @@ -260,8 +264,8 @@ MaterialDef Terrain Lighting { Technique PreNormalPass { - VertexShader GLSL100 GLSL150: Common/MatDefs/SSAO/normal.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/SSAO/normal.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/SSAO/normal.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/SSAO/normal.frag WorldParameters { WorldViewProjectionMatrix @@ -270,6 +274,7 @@ MaterialDef Terrain Lighting { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer DIFFUSEMAP_ALPHA : DiffuseMap } @@ -283,14 +288,15 @@ MaterialDef Terrain Lighting { Technique Glow { - VertexShader GLSL100 GLSL150: Common/MatDefs/Misc/Unshaded.vert - FragmentShader GLSL100 GLSL150: Common/MatDefs/Light/Glow.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/Glow.frag WorldParameters { WorldViewProjectionMatrix } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HAS_GLOWMAP : GlowMap HAS_GLOWCOLOR : GlowColor } diff --git a/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.geom b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.geom index 7acd056e8f..46d34e809f 100644 --- a/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.geom +++ b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.geom @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + layout (points) in; layout (line_strip) out; layout (max_vertices = 11) out; diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tsctrl b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tsctrl index 81b4e291a5..2732b59f1f 100644 --- a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tsctrl +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tsctrl @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + layout(vertices=4) out; out gl_PerVertex{ vec4 gl_Position; diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tseval b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tseval index 4dbf976f31..1bc159a663 100644 --- a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tseval +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tseval @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + layout (quads,equal_spacing,cw) in; uniform mat4 g_WorldViewProjectionMatrix; diff --git a/jme3-vr/build.gradle b/jme3-vr/build.gradle index 6fbc20d209..07e3330c9c 100644 --- a/jme3-vr/build.gradle +++ b/jme3-vr/build.gradle @@ -27,3 +27,4 @@ javadoc { options.addStringOption('Xdoclint:none', '-quiet') } } + diff --git a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java index 02ab733230..501567f902 100644 --- a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java +++ b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java @@ -49,6 +49,7 @@ import com.jme3.system.lwjgl.LwjglOffscreenBufferVR; import com.jme3.util.VRGUIPositioningMode; import com.jme3.util.VRGuiManager; +import com.jme3.util.res.Resources; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; @@ -1177,7 +1178,7 @@ private void initAssetManager(){ } catch (MalformedURLException ex) { } if (assetCfgUrl == null) { - assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg); + assetCfgUrl = Resources.getResource(assetCfg); if (assetCfgUrl == null) { logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg); return; diff --git a/jme3-vr/src/main/resources/Common/MatDefs/VR/CartoonSSAO.j3md b/jme3-vr/src/main/resources/Common/MatDefs/VR/CartoonSSAO.j3md index 5faaf9260b..7772941ce5 100644 --- a/jme3-vr/src/main/resources/Common/MatDefs/VR/CartoonSSAO.j3md +++ b/jme3-vr/src/main/resources/Common/MatDefs/VR/CartoonSSAO.j3md @@ -1,6 +1,7 @@ MaterialDef CartoonSSAO { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Int NumSamplesDepth Texture2D DepthTexture @@ -14,8 +15,8 @@ MaterialDef CartoonSSAO { } Technique { - VertexShader GLSL150: Common/MatDefs/Post/Post15.vert - FragmentShader GLSL150: Common/MatDefs/VR/CartoonSSAO.frag + VertexShader GLSL300 GLSL150: Common/MatDefs/Post/Post15.vert + FragmentShader GLSL300 GLSL150: Common/MatDefs/VR/CartoonSSAO.frag WorldParameters { WorldViewProjectionMatrix @@ -24,14 +25,15 @@ MaterialDef CartoonSSAO { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NO_OUTLINE : disableOutline INSTANCING : useInstancing } } Technique { - VertexShader GLSL100: Common/MatDefs/Post/Post.vert - FragmentShader GLSL100: Common/MatDefs/VR/CartoonSSAO.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/VR/CartoonSSAO.frag WorldParameters { WorldViewProjectionMatrix @@ -40,6 +42,7 @@ MaterialDef CartoonSSAO { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer NO_OUTLINE : disableOutline INSTANCING : useInstancing } diff --git a/jme3-vr/src/main/resources/Common/MatDefs/VR/GuiOverlay.j3md b/jme3-vr/src/main/resources/Common/MatDefs/VR/GuiOverlay.j3md index 79b7759237..427627732b 100644 --- a/jme3-vr/src/main/resources/Common/MatDefs/VR/GuiOverlay.j3md +++ b/jme3-vr/src/main/resources/Common/MatDefs/VR/GuiOverlay.j3md @@ -1,6 +1,7 @@ MaterialDef GuiOverlay { MaterialParameters { + Int BoundDrawBuffer Texture2D ColorMap // For VR instancing @@ -8,8 +9,8 @@ MaterialDef GuiOverlay { } Technique { - VertexShader GLSL150: Common/MatDefs/VR/GuiOverlay15.vert - FragmentShader GLSL150: Common/MatDefs/VR/GuiOverlay15.frag + VertexShader GLSL300 GLSL150: Common/MatDefs/VR/GuiOverlay15.vert + FragmentShader GLSL300 GLSL150: Common/MatDefs/VR/GuiOverlay15.frag WorldParameters { WorldViewProjectionMatrix @@ -17,13 +18,14 @@ MaterialDef GuiOverlay { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer INSTANCING : RightEyeViewProjectionMatrix // For VR instancing } } Technique { - VertexShader GLSL100: Common/MatDefs/VR/GuiOverlay.vert - FragmentShader GLSL100: Common/MatDefs/VR/GuiOverlay.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/VR/GuiOverlay.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/VR/GuiOverlay.frag WorldParameters { WorldViewProjectionMatrix @@ -31,6 +33,7 @@ MaterialDef GuiOverlay { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer INSTANCING : RightEyeViewProjectionMatrix // For VR instancing } } diff --git a/jme3-vr/src/main/resources/Common/MatDefs/VR/OpenVR.j3md b/jme3-vr/src/main/resources/Common/MatDefs/VR/OpenVR.j3md index 7cadd0af08..c4385c91c0 100644 --- a/jme3-vr/src/main/resources/Common/MatDefs/VR/OpenVR.j3md +++ b/jme3-vr/src/main/resources/Common/MatDefs/VR/OpenVR.j3md @@ -1,5 +1,6 @@ MaterialDef OpenVR { MaterialParameters { + Int BoundDrawBuffer Int NumSamples Texture2D Texture @@ -9,25 +10,27 @@ MaterialDef OpenVR { } Technique { - VertexShader GLSL150: Common/MatDefs/VR/OpenVR15.vert - FragmentShader GLSL150: Common/MatDefs/VR/OpenVR15.frag + VertexShader GLSL300 GLSL150: Common/MatDefs/VR/OpenVR15.vert + FragmentShader GLSL300 GLSL150: Common/MatDefs/VR/OpenVR15.frag WorldParameters { } Defines { - } + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } Technique { - VertexShader GLSL100: Common/MatDefs/VR/OpenVR.vert - FragmentShader GLSL100: Common/MatDefs/VR/OpenVR.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/VR/OpenVR.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/VR/OpenVR.frag WorldParameters { } Defines { - } + BOUND_DRAW_BUFFER: BoundDrawBuffer + } } } \ No newline at end of file diff --git a/jme3-vr/src/main/resources/Common/MatDefs/VR/PostShadowFilter.j3md b/jme3-vr/src/main/resources/Common/MatDefs/VR/PostShadowFilter.j3md index 3bdd5b2ea1..f85a94b047 100644 --- a/jme3-vr/src/main/resources/Common/MatDefs/VR/PostShadowFilter.j3md +++ b/jme3-vr/src/main/resources/Common/MatDefs/VR/PostShadowFilter.j3md @@ -1,6 +1,7 @@ MaterialDef Post Shadow { MaterialParameters { + Int BoundDrawBuffer Int FilterMode Boolean HardwareShadows @@ -46,14 +47,15 @@ MaterialDef Post Shadow { } Technique { - VertexShader GLSL150: Common/MatDefs/VR/PostShadowFilter.vert - FragmentShader GLSL150: Common/MatDefs/VR/PostShadowFilter.frag + VertexShader GLSL300 GLSL150: Common/MatDefs/VR/PostShadowFilter.vert + FragmentShader GLSL300 GLSL150: Common/MatDefs/VR/PostShadowFilter.frag WorldParameters { ResolutionInverse } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer RESOLVE_MS : NumSamples RESOLVE_DEPTH_MS : NumSamplesDepth HARDWARE_SHADOWS : HardwareShadows @@ -72,14 +74,15 @@ MaterialDef Post Shadow { } Technique { - VertexShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.vert - FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowFilter.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowFilter.frag WorldParameters { ResolutionInverse } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer HARDWARE_SHADOWS : HardwareShadows FILTER_MODE : FilterMode PCFEDGE : PCFEdge diff --git a/jme3-vr/src/main/resources/Common/MatDefs/VR/Unshaded.j3md b/jme3-vr/src/main/resources/Common/MatDefs/VR/Unshaded.j3md index 81e1ebecc4..13a9cf2b5e 100644 --- a/jme3-vr/src/main/resources/Common/MatDefs/VR/Unshaded.j3md +++ b/jme3-vr/src/main/resources/Common/MatDefs/VR/Unshaded.j3md @@ -1,6 +1,7 @@ MaterialDef Unshaded { MaterialParameters { + Int BoundDrawBuffer Texture2D ColorMap Color Color (Color) @@ -9,8 +10,8 @@ MaterialDef Unshaded { } Technique { - VertexShader GLSL150: Common/MatDefs/VR/Unshaded.vert - FragmentShader GLSL150: Common/MatDefs/VR/Unshaded.frag + VertexShader GLSL300 GLSL150: Common/MatDefs/VR/Unshaded.vert + FragmentShader GLSL300 GLSL150: Common/MatDefs/VR/Unshaded.frag WorldParameters { WorldViewProjectionMatrix @@ -19,6 +20,7 @@ MaterialDef Unshaded { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer INSTANCING : RightEyeViewProjectionMatrix // For VR instancing HAS_COLORMAP : ColorMap HAS_COLOR : Color @@ -26,8 +28,8 @@ MaterialDef Unshaded { } Technique { - VertexShader GLSL100: Common/MatDefs/VR/Unshaded.vert - FragmentShader GLSL100: Common/MatDefs/VR/Unshaded.frag + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/VR/Unshaded.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/VR/Unshaded.frag WorldParameters { WorldViewProjectionMatrix @@ -36,6 +38,7 @@ MaterialDef Unshaded { } Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer INSTANCING : RightEyeViewProjectionMatrix // For VR instancing HAS_COLORMAP : ColorMap HAS_COLOR : Color diff --git a/settings.gradle b/settings.gradle index 3f6acceb8e..074b2b8a50 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,6 +8,9 @@ include 'jme3-core' include 'jme3-effects' include 'jme3-networking' include 'jme3-plugins' +include 'jme3-plugins-json' +include 'jme3-plugins-json-gson' + include 'jme3-terrain' // Desktop dependent java classes From 35e8857b5c613dec19ba1ef854489cb0a751e9af Mon Sep 17 00:00:00 2001 From: bob0bob Date: Sat, 23 Sep 2023 01:45:01 +0000 Subject: [PATCH 12/18] auto-format --- .../java/com/jme3/app/LegacyApplication.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index ef2a550ee9..3f2e13cfcf 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -52,11 +52,11 @@ import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeContext.Type; -import com.jme3.util.res.Resources; import com.jme3.system.JmeSystem; import com.jme3.system.NanoTimer; import com.jme3.system.SystemListener; import com.jme3.system.Timer; +import com.jme3.util.res.Resources; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.Callable; @@ -199,8 +199,7 @@ public void setPauseOnLostFocus(boolean pauseOnLostFocus) { @Deprecated public void setAssetManager(AssetManager assetManager) { if (this.assetManager != null) { - throw new IllegalStateException("Can only set asset manager" - + " before initialization."); + throw new IllegalStateException("Can only set asset manager" + " before initialization."); } this.assetManager = assetManager; @@ -220,13 +219,16 @@ private void initAssetManager() { if (assetCfgUrl == null) { assetCfgUrl = Resources.getResource(assetCfg); if (assetCfgUrl == null) { - logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", - assetCfg); + logger.log( + Level.SEVERE, + "Unable to access AssetConfigURL in asset config:{0}", + assetCfg + ); return; } } } - } + } if (assetCfgUrl == null) { assetCfgUrl = JmeSystem.getPlatformAssetConfigURL(); } @@ -595,7 +597,6 @@ public void reshape(int w, int h) { } } - @Override public void rescale(float x, float y) { if (renderManager != null) { @@ -668,9 +669,8 @@ public void initialize() { initAudio(); // update timer so that the next delta is not too large -// timer.update(); + // timer.update(); timer.reset(); - // user code here } @@ -684,8 +684,12 @@ public void handleError(String errMsg, Throwable t) { // Display error message on screen if not in headless mode if (context.getType() != JmeContext.Type.Headless) { if (t != null) { - JmeSystem.handleErrorMessage(errMsg + "\n" + t.getClass().getSimpleName() - + (t.getMessage() != null ? ": " + t.getMessage() : "")); + JmeSystem.handleErrorMessage( + errMsg + + "\n" + + t.getClass().getSimpleName() + + (t.getMessage() != null ? ": " + t.getMessage() : "") + ); } else { JmeSystem.handleErrorMessage(errMsg); } @@ -811,7 +815,6 @@ public void update() { } audioRenderer.update(timer.getTimePerFrame()); } - // user code here } @@ -866,6 +869,7 @@ public ViewPort getViewPort() { } private class RunnableWrapper implements Callable { + private final Runnable runnable; public RunnableWrapper(Runnable runnable) { From 1bda3f0cd20e6d052c9ee3d508e644221b53adc8 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Sat, 23 Sep 2023 10:29:51 -0500 Subject: [PATCH 13/18] merging new files. --- .../java/com/jme3/system/MonitorInfo.java | 66 --- .../main/java/com/jme3/system/Monitors.java | 105 ---- .../jme3test/app/state/RootNodeState.java | 54 -- .../jme3test/app/state/TestAppStates.java | 107 ---- .../java/jme3test/app/state/package-info.java | 35 -- .../java/jme3test/asset/TestAssetCache.java | 230 -------- .../java/jme3test/asset/TestOnlineJar.java | 82 --- .../java/jme3test/asset/TestUrlLoading.java | 80 --- .../java/jme3test/asset/package-info.java | 35 -- .../main/java/jme3test/audio/TestAmbient.java | 88 --- .../main/java/jme3test/audio/TestDoppler.java | 94 --- .../java/jme3test/audio/TestIssue1761.java | 86 --- .../java/jme3test/audio/TestMusicPlayer.form | 117 ---- .../java/jme3test/audio/TestMusicPlayer.java | 311 ---------- .../jme3test/audio/TestMusicStreaming.java | 60 -- .../src/main/java/jme3test/audio/TestOgg.java | 70 --- .../main/java/jme3test/audio/TestReverb.java | 84 --- .../src/main/java/jme3test/audio/TestWav.java | 64 --- .../java/jme3test/audio/package-info.java | 35 -- .../main/java/jme3test/awt/AppHarness.java | 155 ----- .../main/java/jme3test/awt/TestApplet.java | 151 ----- .../main/java/jme3test/awt/TestAwtPanels.java | 152 ----- .../main/java/jme3test/awt/TestCanvas.java | 283 --------- .../java/jme3test/awt/TestSafeCanvas.java | 68 --- .../main/java/jme3test/awt/package-info.java | 36 -- .../java/jme3test/batching/TestBatchNode.java | 162 ------ .../batching/TestBatchNodeCluster.java | 362 ------------ .../jme3test/batching/TestBatchNodeTower.java | 250 -------- .../java/jme3test/batching/package-info.java | 36 -- .../jme3test/bounding/TestRayCollision.java | 65 --- .../java/jme3test/bounding/package-info.java | 35 -- .../java/jme3test/bullet/BombControl.java | 221 ------- .../jme3test/bullet/PhysicsHoverControl.java | 258 --------- .../jme3test/bullet/PhysicsTestHelper.java | 371 ------------ .../jme3test/bullet/TestAttachDriver.java | 300 ---------- .../bullet/TestAttachGhostObject.java | 129 ----- .../jme3test/bullet/TestBetterCharacter.java | 297 ---------- .../java/jme3test/bullet/TestBoneRagdoll.java | 244 -------- .../java/jme3test/bullet/TestBrickTower.java | 251 -------- .../java/jme3test/bullet/TestBrickWall.java | 204 ------- .../main/java/jme3test/bullet/TestCcd.java | 153 ----- .../jme3test/bullet/TestCollisionGroups.java | 107 ---- .../bullet/TestCollisionListener.java | 95 --- .../bullet/TestCollisionShapeFactory.java | 137 ----- .../java/jme3test/bullet/TestFancyCar.java | 226 -------- .../java/jme3test/bullet/TestGhostObject.java | 117 ---- .../jme3test/bullet/TestHoveringTank.java | 304 ---------- .../java/jme3test/bullet/TestIssue1120.java | 214 ------- .../java/jme3test/bullet/TestIssue1125.java | 229 -------- .../java/jme3test/bullet/TestIssue877.java | 148 ----- .../java/jme3test/bullet/TestIssue883.java | 87 --- .../TestKinematicAddToPhysicsSpaceIssue.java | 107 ---- .../jme3test/bullet/TestLocalPhysics.java | 122 ---- .../java/jme3test/bullet/TestPhysicsCar.java | 225 -------- .../jme3test/bullet/TestPhysicsCharacter.java | 212 ------- .../bullet/TestPhysicsHingeJoint.java | 110 ---- .../jme3test/bullet/TestPhysicsRayCast.java | 69 --- .../jme3test/bullet/TestPhysicsReadWrite.java | 153 ----- .../src/main/java/jme3test/bullet/TestQ3.java | 183 ------ .../java/jme3test/bullet/TestRagDoll.java | 152 ----- .../jme3test/bullet/TestRagdollCharacter.java | 246 -------- .../jme3test/bullet/TestSimplePhysics.java | 111 ---- .../java/jme3test/bullet/TestSweepTest.java | 77 --- .../java/jme3test/bullet/TestWalkingChar.java | 460 --------------- .../java/jme3test/bullet/package-info.java | 35 -- .../bullet/shape/TestGimpactShape.java | 342 ----------- .../jme3test/bullet/shape/package-info.java | 36 -- .../java/jme3test/collision/RayTrace.java | 101 ---- .../jme3test/collision/TestMousePick.java | 153 ----- .../jme3test/collision/TestRayCasting.java | 95 --- .../collision/TestTriangleCollision.java | 127 ---- .../java/jme3test/collision/package-info.java | 36 -- .../jme3test/conversion/TestMipMapGen.java | 93 --- .../jme3test/conversion/package-info.java | 35 -- .../java/jme3test/effect/TestEverything.java | 201 ------- .../jme3test/effect/TestExplosionEffect.java | 282 --------- .../java/jme3test/effect/TestIssue1773.java | 303 ---------- .../jme3test/effect/TestMovingParticle.java | 96 ---- .../effect/TestParticleExportingCloning.java | 74 --- .../java/jme3test/effect/TestPointSprite.java | 91 --- .../jme3test/effect/TestSoftParticles.java | 184 ------ .../java/jme3test/effect/package-info.java | 35 -- .../jme3test/export/TestAssetLinkNode.java | 131 ----- .../java/jme3test/export/TestIssue2068.java | 96 ---- .../java/jme3test/export/TestOgreConvert.java | 81 --- .../java/jme3test/export/package-info.java | 35 -- .../main/java/jme3test/games/CubeField.java | 414 ------------- .../java/jme3test/games/RollingTheMonkey.java | 411 ------------- .../java/jme3test/games/WorldOfInception.java | 535 ----------------- .../java/jme3test/games/package-info.java | 35 -- .../java/jme3test/gui/TestBitmapFont.java | 134 ----- .../jme3test/gui/TestBitmapFontAlignment.java | 144 ----- .../jme3test/gui/TestBitmapFontLayout.java | 543 ------------------ .../java/jme3test/gui/TestBitmapText3D.java | 70 --- .../main/java/jme3test/gui/TestCursor.java | 77 --- .../src/main/java/jme3test/gui/TestOrtho.java | 58 -- .../java/jme3test/gui/TestRtlBitmapText.java | 70 --- .../java/jme3test/gui/TestSoftwareMouse.java | 136 ----- .../main/java/jme3test/gui/TestZOrder.java | 64 --- .../main/java/jme3test/gui/package-info.java | 36 -- .../jme3test/helloworld/HelloAnimation.java | 123 ---- .../java/jme3test/helloworld/HelloAssets.java | 91 --- .../java/jme3test/helloworld/HelloAudio.java | 84 --- .../jme3test/helloworld/HelloCollision.java | 190 ------ .../jme3test/helloworld/HelloEffects.java | 112 ---- .../java/jme3test/helloworld/HelloInput.java | 112 ---- .../java/jme3test/helloworld/HelloJME3.java | 61 -- .../java/jme3test/helloworld/HelloLoop.java | 71 --- .../jme3test/helloworld/HelloMaterial.java | 104 ---- .../java/jme3test/helloworld/HelloNode.java | 85 --- .../jme3test/helloworld/HelloPhysics.java | 225 -------- .../jme3test/helloworld/HelloPicking.java | 182 ------ .../jme3test/helloworld/HelloTerrain.java | 125 ---- .../helloworld/HelloTerrainCollision.java | 228 -------- .../jme3test/helloworld/package-info.java | 35 -- .../java/jme3test/input/TestCameraNode.java | 157 ----- .../java/jme3test/input/TestChaseCamera.java | 162 ------ .../input/TestChaseCameraAppState.java | 156 ----- .../java/jme3test/input/TestControls.java | 75 --- .../java/jme3test/input/TestIssue1692.java | 134 ----- .../java/jme3test/input/TestJoystick.java | 493 ---------------- .../jme3test/input/combomoves/ComboMove.java | 143 ----- .../input/combomoves/ComboMoveExecution.java | 126 ---- .../input/combomoves/TestComboMoves.java | 217 ------- .../input/combomoves/package-info.java | 35 -- .../java/jme3test/input/package-info.java | 35 -- .../jme3test/light/ShadowTestUIManager.java | 181 ------ .../java/jme3test/light/TestColorApp.java | 88 --- .../jme3test/light/TestConeVSFrustum.java | 263 --------- .../light/TestDirectionalLightShadow.java | 377 ------------ .../light/TestEnvironmentMapping.java | 98 ---- .../java/jme3test/light/TestGltfUnlit.java | 61 -- .../light/TestLightControl2Directional.java | 169 ------ .../jme3test/light/TestLightControl2Spot.java | 178 ------ .../light/TestLightControlDirectional.java | 168 ------ .../jme3test/light/TestLightControlSpot.java | 177 ------ .../java/jme3test/light/TestLightRadius.java | 109 ---- .../java/jme3test/light/TestLightingFog.java | 79 --- .../java/jme3test/light/TestManyLights.java | 54 -- .../jme3test/light/TestManyLightsSingle.java | 272 --------- .../java/jme3test/light/TestObbVsBounds.java | 300 ---------- ...stPointDirectionalAndSpotLightShadows.java | 175 ------ .../jme3test/light/TestPointLightShadows.java | 133 ----- .../java/jme3test/light/TestShadowBug.java | 129 ----- .../java/jme3test/light/TestShadowsPerf.java | 173 ------ .../jme3test/light/TestSimpleLighting.java | 124 ---- .../java/jme3test/light/TestSpotLight.java | 155 ----- .../jme3test/light/TestSpotLightShadows.java | 200 ------- .../jme3test/light/TestSpotLightTerrain.java | 206 ------- .../java/jme3test/light/TestTangentCube.java | 95 --- .../java/jme3test/light/TestTangentGen.java | 134 ----- .../jme3test/light/TestTangentGenBadUV.java | 109 ---- .../java/jme3test/light/TestTangentSpace.java | 131 ----- .../jme3test/light/TestTransparentShadow.java | 148 ----- .../jme3test/light/TestTwoSideLighting.java | 122 ---- .../java/jme3test/light/package-info.java | 35 -- .../light/pbr/ConsoleProgressReporter.java | 75 --- .../main/java/jme3test/light/pbr/RefEnv.java | 170 ------ .../jme3test/light/pbr/TestIssue1340.java | 92 --- .../light/pbr/TestIssue1903Compat.java | 91 --- .../jme3test/light/pbr/TestIssue1903Core.java | 71 --- .../light/pbr/TestPBRDirectLighting.java | 122 ---- .../jme3test/light/pbr/TestPBRLighting.java | 221 ------- .../java/jme3test/light/pbr/package-info.java | 35 -- .../java/jme3test/material/TestBumpModel.java | 102 ---- .../jme3test/material/TestColoredTexture.java | 83 --- .../jme3test/material/TestGeometryShader.java | 46 -- .../material/TestMatParamOverride.java | 113 ---- .../material/TestMaterialCompare.java | 138 ----- .../jme3test/material/TestNormalMapping.java | 93 --- .../java/jme3test/material/TestParallax.java | 150 ----- .../jme3test/material/TestParallaxPBR.java | 155 ----- .../jme3test/material/TestShaderNodes.java | 43 -- .../jme3test/material/TestSimpleBumps.java | 93 --- .../material/TestTessellationShader.java | 73 --- .../jme3test/material/TestUnshadedModel.java | 44 -- .../java/jme3test/material/package-info.java | 35 -- .../java/jme3test/math/TestHalfFloat.java | 55 -- .../main/java/jme3test/math/package-info.java | 35 -- .../java/jme3test/model/TestGltfLoading.java | 334 ----------- .../java/jme3test/model/TestHoverTank.java | 96 ---- .../java/jme3test/model/TestMonkeyHead.java | 100 ---- .../jme3test/model/TestObjGroupsLoading.java | 119 ---- .../java/jme3test/model/TestObjLoading.java | 60 -- .../java/jme3test/model/TestOgreLoading.java | 112 ---- .../java/jme3test/model/anim/EraseTimer.java | 109 ---- .../model/anim/TestAnimMigration.java | 277 --------- .../anim/TestAnimMorphSerialization.java | 198 ------- .../model/anim/TestAnimSerialization.java | 199 ------- .../model/anim/TestAnimationFactory.java | 90 --- .../jme3test/model/anim/TestArmature.java | 218 ------- .../model/anim/TestAttachmentsNode.java | 129 ----- .../model/anim/TestBaseAnimSerialization.java | 246 -------- .../jme3test/model/anim/TestCustomAnim.java | 152 ----- .../jme3test/model/anim/TestHWSkinning.java | 132 ----- .../model/anim/TestHWSkinningOld.java | 112 ---- .../jme3test/model/anim/TestIssue1395.java | 80 --- .../model/anim/TestModelExportingCloning.java | 81 --- .../java/jme3test/model/anim/TestMorph.java | 149 ----- .../jme3test/model/anim/TestOgreAnim.java | 121 ---- .../model/anim/TestOgreComplexAnim.java | 135 ----- .../anim/TestSkeletonControlRefresh.java | 172 ------ .../jme3test/model/anim/TestSpatialAnim.java | 85 --- .../jme3test/model/anim/package-info.java | 35 -- .../java/jme3test/model/package-info.java | 35 -- .../jme3test/model/shape/TestBillboard.java | 113 ---- .../java/jme3test/model/shape/TestBox.java | 57 -- .../jme3test/model/shape/TestCustomMesh.java | 153 ----- .../jme3test/model/shape/TestCylinder.java | 66 --- .../jme3test/model/shape/TestDebugShapes.java | 94 --- .../model/shape/TestExpandingTorus.java | 71 --- .../java/jme3test/model/shape/TestSphere.java | 65 --- .../jme3test/model/shape/package-info.java | 35 -- .../java/jme3test/network/MovingAverage.java | 63 -- .../java/jme3test/network/TestChatClient.java | 236 -------- .../network/TestChatClientAndServer.java | 74 --- .../java/jme3test/network/TestChatServer.java | 237 -------- .../java/jme3test/network/TestLatency.java | 125 ---- .../java/jme3test/network/TestMessages.java | 90 --- .../jme3test/network/TestNetworkStress.java | 68 --- .../java/jme3test/network/TestRemoteCall.java | 119 ---- .../jme3test/network/TestSerialization.java | 159 ----- .../java/jme3test/network/TestThroughput.java | 118 ---- .../java/jme3test/network/package-info.java | 35 -- .../niftygui/StartScreenController.java | 92 --- .../java/jme3test/niftygui/TestIssue1013.java | 127 ---- .../java/jme3test/niftygui/TestIssue99.java | 107 ---- .../jme3test/niftygui/TestNiftyExamples.java | 67 --- .../java/jme3test/niftygui/TestNiftyGui.java | 78 --- .../jme3test/niftygui/TestNiftyToMesh.java | 93 --- .../java/jme3test/niftygui/package-info.java | 35 -- .../java/jme3test/opencl/HelloOpenCL.java | 311 ---------- .../jme3test/opencl/TestContextSwitching.java | 254 -------- .../opencl/TestMultipleApplications.java | 169 ------ .../jme3test/opencl/TestOpenCLLibraries.java | 401 ------------- .../opencl/TestVertexBufferSharing.java | 183 ------ .../jme3test/opencl/TestWriteToTexture.java | 179 ------ .../java/jme3test/opencl/package-info.java | 35 -- .../src/main/java/jme3test/post/BloomUI.java | 110 ---- .../java/jme3test/post/LightScatteringUI.java | 140 ----- .../src/main/java/jme3test/post/SSAOUI.java | 148 ----- .../main/java/jme3test/post/TestBloom.java | 164 ------ .../post/TestBloomAlphaThreshold.java | 182 ------ .../java/jme3test/post/TestCartoonEdge.java | 133 ----- .../jme3test/post/TestContrastAdjustment.java | 220 ------- .../java/jme3test/post/TestCrossHatch.java | 159 ----- .../java/jme3test/post/TestDepthOfField.java | 237 -------- .../jme3test/post/TestFBOPassthrough.java | 118 ---- .../src/main/java/jme3test/post/TestFog.java | 209 ------- .../java/jme3test/post/TestIssue1798.java | 135 ----- .../jme3test/post/TestLightScattering.java | 104 ---- .../jme3test/post/TestMultiRenderTarget.java | 235 -------- .../jme3test/post/TestMultiViewsFilters.java | 198 ------- .../jme3test/post/TestMultiplesFilters.java | 158 ----- .../java/jme3test/post/TestPostFilters.java | 174 ------ .../post/TestPostFiltersCompositing.java | 117 ---- .../java/jme3test/post/TestPosterization.java | 137 ----- .../jme3test/post/TestRenderToCubemap.java | 137 ----- .../jme3test/post/TestRenderToMemory.java | 270 --------- .../jme3test/post/TestRenderToTexture.java | 149 ----- .../src/main/java/jme3test/post/TestSSAO.java | 96 ---- .../main/java/jme3test/post/TestSSAO2.java | 116 ---- .../java/jme3test/post/TestToneMapFilter.java | 147 ----- .../post/TestTransparentCartoonEdge.java | 98 ---- .../jme3test/post/TestTransparentSSAO.java | 78 --- .../main/java/jme3test/post/package-info.java | 35 -- .../renderer/TestAlphaToCoverage.java | 54 -- .../java/jme3test/renderer/TestAspectFov.java | 126 ---- .../jme3test/renderer/TestAspectRatio.java | 68 --- .../renderer/TestBackgroundImage.java | 145 ----- .../jme3test/renderer/TestBlendEquations.java | 142 ----- .../jme3test/renderer/TestContextRestart.java | 129 ----- .../renderer/TestDepthFuncChange.java | 90 --- .../jme3test/renderer/TestDepthStencil.java | 155 ----- .../TestInconsistentCompareDetection.java | 121 ---- .../java/jme3test/renderer/TestIssue2011.java | 107 ---- .../java/jme3test/renderer/TestIssue37.java | 110 ---- .../java/jme3test/renderer/TestIssue798.java | 156 ----- .../java/jme3test/renderer/TestIssue801.java | 87 --- .../java/jme3test/renderer/TestLineWidth.java | 103 ---- .../jme3test/renderer/TestMultiViews.java | 110 ---- .../renderer/TestParallelProjection.java | 85 --- .../jme3test/renderer/TestSplitScreen.java | 114 ---- .../java/jme3test/renderer/package-info.java | 35 -- .../scene/TestLineWidthRenderState.java | 87 --- .../jme3test/scene/TestRefreshFlagBug.java | 45 -- .../java/jme3test/scene/TestSceneLoading.java | 98 ---- .../java/jme3test/scene/TestSceneStress.java | 162 ------ .../java/jme3test/scene/TestUserData.java | 58 -- .../scene/instancing/TestInstanceNode.java | 192 ------- .../instancing/TestInstanceNodeWithLight.java | 62 -- ...tInstancedNodeAttachDetachWithPicking.java | 195 ------- ...ancedNodeAttachDetachWithShadowFilter.java | 176 ------ .../TestInstancingWithWaterFilter.java | 90 --- .../scene/instancing/package-info.java | 35 -- .../java/jme3test/scene/package-info.java | 35 -- .../java/jme3test/stress/TestBatchLod.java | 88 --- .../java/jme3test/stress/TestLeakingGL.java | 92 --- .../jme3test/stress/TestLodGeneration.java | 208 ------- .../java/jme3test/stress/TestLodStress.java | 91 --- .../stress/TestParallelTangentGeneration.java | 81 --- .../stress/TestShaderNodesStress.java | 109 ---- .../java/jme3test/stress/package-info.java | 35 -- .../terrain/PBRTerrainAdvancedTest.java | 457 --------------- .../java/jme3test/terrain/PBRTerrainTest.java | 365 ------------ .../terrain/TerrainFractalGridTest.java | 141 ----- .../terrain/TerrainGridAlphaMapTest.java | 359 ------------ .../terrain/TerrainGridSerializationTest.java | 184 ------ .../jme3test/terrain/TerrainGridTest.java | 232 -------- .../terrain/TerrainGridTileLoaderTest.java | 243 -------- .../java/jme3test/terrain/TerrainTest.java | 216 ------- .../jme3test/terrain/TerrainTestAdvanced.java | 340 ----------- .../jme3test/terrain/TerrainTestAndroid.java | 197 ------- .../terrain/TerrainTestCollision.java | 328 ----------- .../terrain/TerrainTestModifyHeight.java | 339 ----------- .../terrain/TerrainTestReadWrite.java | 292 ---------- .../jme3test/terrain/TerrainTestTile.java | 372 ------------ .../java/jme3test/terrain/package-info.java | 35 -- .../texture/TestAnisotropicFilter.java | 117 ---- .../jme3test/texture/TestImageRaster.java | 139 ----- .../java/jme3test/texture/TestSkyLoading.java | 60 -- .../jme3test/texture/TestSkyRotation.java | 147 ----- .../java/jme3test/texture/TestTexture3D.java | 131 ----- .../texture/TestTexture3DLoading.java | 81 --- .../jme3test/texture/TestTextureArray.java | 87 --- .../texture/TestTextureArrayCompressed.java | 87 --- .../jme3test/texture/dds/TestLoadDds.java | 95 --- .../jme3test/texture/ktx/TestLoadKtx.java | 108 ---- .../jme3test/texture/ktx/package-info.java | 36 -- .../java/jme3test/texture/package-info.java | 35 -- .../java/jme3test/tools/TestSaveGame.java | 85 --- .../java/jme3test/tools/TestTextureAtlas.java | 90 --- .../java/jme3test/tools/package-info.java | 35 -- .../jme3test/water/TestMultiPostWater.java | 216 ------- .../java/jme3test/water/TestPostWater.java | 326 ----------- .../jme3test/water/TestPostWaterLake.java | 127 ---- .../java/jme3test/water/TestSceneWater.java | 147 ----- .../java/jme3test/water/TestSimpleWater.java | 169 ------ .../src/main/java/jme3test/water/WaterUI.java | 123 ---- .../java/jme3test/water/package-info.java | 35 -- 340 files changed, 47946 deletions(-) delete mode 100644 jme3-core/src/main/java/com/jme3/system/MonitorInfo.java delete mode 100644 jme3-core/src/main/java/com/jme3/system/Monitors.java delete mode 100644 jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java delete mode 100644 jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java delete mode 100644 jme3-examples/src/main/java/jme3test/app/state/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java delete mode 100644 jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java delete mode 100644 jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/asset/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestAmbient.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestDoppler.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestOgg.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestReverb.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/TestWav.java delete mode 100644 jme3-examples/src/main/java/jme3test/audio/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/awt/AppHarness.java delete mode 100644 jme3-examples/src/main/java/jme3test/awt/TestApplet.java delete mode 100644 jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java delete mode 100644 jme3-examples/src/main/java/jme3test/awt/TestCanvas.java delete mode 100644 jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java delete mode 100644 jme3-examples/src/main/java/jme3test/awt/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java delete mode 100644 jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java delete mode 100644 jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java delete mode 100644 jme3-examples/src/main/java/jme3test/batching/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java delete mode 100644 jme3-examples/src/main/java/jme3test/bounding/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/BombControl.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCcd.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestQ3.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java delete mode 100644 jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/collision/RayTrace.java delete mode 100644 jme3-examples/src/main/java/jme3test/collision/TestMousePick.java delete mode 100644 jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java delete mode 100644 jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java delete mode 100644 jme3-examples/src/main/java/jme3test/collision/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java delete mode 100644 jme3-examples/src/main/java/jme3test/conversion/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/TestEverything.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java delete mode 100644 jme3-examples/src/main/java/jme3test/effect/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java delete mode 100644 jme3-examples/src/main/java/jme3test/export/TestIssue2068.java delete mode 100644 jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java delete mode 100644 jme3-examples/src/main/java/jme3test/export/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/games/CubeField.java delete mode 100644 jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java delete mode 100644 jme3-examples/src/main/java/jme3test/games/WorldOfInception.java delete mode 100644 jme3-examples/src/main/java/jme3test/games/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestCursor.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestOrtho.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/TestZOrder.java delete mode 100644 jme3-examples/src/main/java/jme3test/gui/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java delete mode 100644 jme3-examples/src/main/java/jme3test/helloworld/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/TestCameraNode.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/TestControls.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/TestIssue1692.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/TestJoystick.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/input/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestColorApp.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightRadius.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightingFog.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestManyLights.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestShadowBug.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestSpotLight.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentCube.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentGen.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java delete mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestBumpModel.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestParallax.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java delete mode 100644 jme3-examples/src/main/java/jme3test/material/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java delete mode 100644 jme3-examples/src/main/java/jme3test/math/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/TestHoverTank.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/TestObjLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/anim/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestBox.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java delete mode 100644 jme3-examples/src/main/java/jme3test/model/shape/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/MovingAverage.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestChatClient.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestChatServer.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestLatency.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestMessages.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestSerialization.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/TestThroughput.java delete mode 100644 jme3-examples/src/main/java/jme3test/network/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java delete mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java delete mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java delete mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java delete mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java delete mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java delete mode 100644 jme3-examples/src/main/java/jme3test/niftygui/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java delete mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestContextSwitching.java delete mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java delete mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java delete mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java delete mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java delete mode 100644 jme3-examples/src/main/java/jme3test/opencl/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/BloomUI.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/LightScatteringUI.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/SSAOUI.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestBloom.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestFog.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestIssue1798.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestLightScattering.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestPostFilters.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestPosterization.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestSSAO.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestSSAO2.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java delete mode 100644 jme3-examples/src/main/java/jme3test/post/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java delete mode 100644 jme3-examples/src/main/java/jme3test/renderer/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/TestUserData.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/scene/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java delete mode 100644 jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java delete mode 100644 jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java delete mode 100644 jme3-examples/src/main/java/jme3test/stress/TestLodStress.java delete mode 100644 jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java delete mode 100644 jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java delete mode 100644 jme3-examples/src/main/java/jme3test/stress/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridSerializationTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridTileLoaderTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTest.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestAdvanced.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestAndroid.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestCollision.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java delete mode 100644 jme3-examples/src/main/java/jme3test/terrain/package-info.java delete mode 100755 jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/texture/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java delete mode 100644 jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java delete mode 100644 jme3-examples/src/main/java/jme3test/tools/package-info.java delete mode 100644 jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java delete mode 100644 jme3-examples/src/main/java/jme3test/water/TestPostWater.java delete mode 100644 jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java delete mode 100644 jme3-examples/src/main/java/jme3test/water/TestSceneWater.java delete mode 100644 jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java delete mode 100644 jme3-examples/src/main/java/jme3test/water/WaterUI.java delete mode 100644 jme3-examples/src/main/java/jme3test/water/package-info.java diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java deleted file mode 100644 index a7791d37b2..0000000000 --- a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package com.jme3.system; - -/** - * This class holds information about the monitor that was returned by glfwGetMonitors() calls in - * the context class - * - * @author Kevin Bales - */ -public class MonitorInfo { - - /** - * monitorID - monitor id that was return from Lwjgl3. - */ - public long monitorID = 0; - - /** - * width - width that was return from Lwjgl3. - */ - public int width = 1080; - - /** - * height - height that was return from Lwjgl3. - */ - public int height = 1920; - - /** - * rate - refresh rate that was return from Lwjgl3. - */ - public int rate = 60; - - /** - * primary - indicates if the monitor is the primary monitor. - */ - public boolean primary = false; - - /** - * name - monitor name that was return from Lwjgl3. - */ - public String name = "Generic Monitor"; - -} diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java deleted file mode 100644 index b834e518f8..0000000000 --- a/jme3-core/src/main/java/com/jme3/system/Monitors.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package com.jme3.system; - -import java.util.ArrayList; - -/** - * This class holds all information about all monitors that where return from the glfwGetMonitors() - * call. It stores them into an - * - * @author Kevin Bales - */ -public class Monitors { - - private ArrayList monitors = new ArrayList(); - - public int addNewMonitor(long monitorID) { - MonitorInfo info = new MonitorInfo(); - info.monitorID = monitorID; - monitors.add(info); - return monitors.size() - 1; - } - - /** - * This function returns the size of the monitor ArrayList - * - * @return the - */ - public int size() { - return monitors.size(); - } - - /** - * Call to get monitor information on a certain monitor. - * - * @param pos the position in the arraylist of the monitor information that you want to get. - * @return returns the MonitorInfo data for the monitor called for. - */ - public MonitorInfo get(int pos) { - if (pos < monitors.size()) - return monitors.get(pos); - - return null; - } - - /** - * Set information about this monitor stored in monPos position in the array list. - * - * @param monPos arraylist position of monitor to update - * @param width the current width the monitor is displaying - * @param height the current height the monitor is displaying - * @param rate the current refresh rate the monitor is set to - */ - public void setInfo(int monPos, String name, int width, int height, int rate) { - if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); - if (info != null) { - info.width = width; - info.height = height; - info.rate = rate; - info.name = name; - } - } - } - - /** - * This function will mark a certain monitor as the primary monitor. - * - * @param monPos the position in the arraylist of which monitor is the primary monitor - */ - public void setPrimaryMonitor(int monPos) { - if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); - if (info != null) - info.primary = true; - } - - } - - - -} diff --git a/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java b/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java deleted file mode 100644 index 463ada9307..0000000000 --- a/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.app.state; - -import com.jme3.app.state.AbstractAppState; -import com.jme3.scene.Node; - -public class RootNodeState extends AbstractAppState { - - final private Node rootNode = new Node("Root Node"); - - public Node getRootNode(){ - return rootNode; - } - - @Override - public void update(float tpf) { - super.update(tpf); - - rootNode.updateLogicalState(tpf); - rootNode.updateGeometricState(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java b/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java deleted file mode 100644 index dbc90d1200..0000000000 --- a/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ - -package jme3test.app.state; - -import com.jme3.app.LegacyApplication; -import com.jme3.niftygui.NiftyJmeDisplay; -import com.jme3.scene.Spatial; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeContext; -import com.jme3.texture.image.ColorSpace; -import jme3test.niftygui.StartScreenController; - -public class TestAppStates extends LegacyApplication { - - public static void main(String[] args){ - TestAppStates app = new TestAppStates(); - app.start(); - } - - @Override - public void start(JmeContext.Type contextType){ - AppSettings settings = new AppSettings(true); - settings.setResolution(1024, 768); - setSettings(settings); - - super.start(contextType); - } - - @Override - public void initialize(){ - super.initialize(); - - System.out.println("Initialize"); - - RootNodeState state = new RootNodeState(); - viewPort.attachScene(state.getRootNode()); - stateManager.attach(state); - - Spatial model = assetManager.loadModel("Models/Teapot/Teapot.obj"); - model.scale(3); - model.setMaterial(assetManager.loadMaterial("Interface/Logo/Logo.j3m")); - state.getRootNode().attachChild(model); - - ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() - ? ColorSpace.sRGB : ColorSpace.Linear; - NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, - inputManager, - audioRenderer, - guiViewPort, - colorSpace); - StartScreenController startScreen = new StartScreenController(this); - niftyDisplay.getNifty().fromXml("Interface/Nifty/HelloJme.xml", "start", - startScreen); - guiViewPort.addProcessor(niftyDisplay); - } - - @Override - public void update(){ - super.update(); - - // do some animation - float tpf = timer.getTimePerFrame(); - - stateManager.update(tpf); - stateManager.render(renderManager); - - // render the viewports - renderManager.render(tpf, context.isRenderable()); - } - - @Override - public void destroy(){ - super.destroy(); - - System.out.println("Destroy"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/app/state/package-info.java b/jme3-examples/src/main/java/jme3test/app/state/package-info.java deleted file mode 100644 index e16b33942e..0000000000 --- a/jme3-examples/src/main/java/jme3test/app/state/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for appstates - */ -package jme3test.app.state; diff --git a/jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java b/jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java deleted file mode 100644 index d7cef54c90..0000000000 --- a/jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.asset; - -import com.jme3.asset.AssetKey; -import com.jme3.asset.AssetProcessor; -import com.jme3.asset.CloneableAssetProcessor; -import com.jme3.asset.CloneableSmartAsset; -import com.jme3.asset.cache.AssetCache; -import com.jme3.asset.cache.SimpleAssetCache; -import com.jme3.asset.cache.WeakRefAssetCache; -import com.jme3.asset.cache.WeakRefCloneAssetCache; -import java.util.ArrayList; -import java.util.List; - -public class TestAssetCache { - - /** - * Counter for asset keys - */ - private static int counter = 0; - - /** - * Dummy data is an asset having 10 KB to put a dent in the garbage collector - */ - private static class DummyData implements CloneableSmartAsset { - - private AssetKey key; - private byte[] data = new byte[10 * 1024]; - - @Override - public DummyData clone(){ - try { - DummyData clone = (DummyData) super.clone(); - clone.data = data.clone(); - return clone; - } catch (CloneNotSupportedException ex) { - throw new AssertionError(); - } - } - - public byte[] getData(){ - return data; - } - - @Override - public AssetKey getKey() { - return key; - } - - @Override - public void setKey(AssetKey key) { - this.key = key; - } - } - - /** - * Dummy key is indexed by a generated ID - */ - private static class DummyKey extends AssetKey implements Cloneable { - - private int id = 0; - - public DummyKey(){ - super("."); - id = counter++; - } - - public DummyKey(int id){ - super("."); - this.id = id; - } - - @Override - public int hashCode(){ - return id; - } - - @Override - public boolean equals(Object other){ - return ((DummyKey)other).id == id; - } - - @Override - public DummyKey clone(){ - return new DummyKey(id); - } - - @Override - public String toString() { - return "ID=" + id; - } - } - - private static void runTest(boolean cloneAssets, boolean smartCache, boolean keepRefs, int limit) { - counter = 0; - List refs = new ArrayList<>(limit); - - AssetCache cache; - AssetProcessor proc = null; - - if (cloneAssets) { - proc = new CloneableAssetProcessor(); - } - - if (smartCache) { - if (cloneAssets) { - cache = new WeakRefCloneAssetCache(); - } else { - cache = new WeakRefAssetCache(); - } - } else { - cache = new SimpleAssetCache(); - } - - System.gc(); - System.gc(); - System.gc(); - System.gc(); - - long memory = Runtime.getRuntime().freeMemory(); - - while (counter < limit){ - // Create a key - DummyKey key = new DummyKey(); - - // Create some data - DummyData data = new DummyData(); - - // Postprocess the data before placing it in the cache. - if (proc != null){ - data = (DummyData) proc.postProcess(key, data); - } - - if (data.key != null){ - // Keeping a hard reference to the key in the cache - // means the asset will never be collected => bug - throw new AssertionError(); - } - - cache.addToCache(key, data); - - // Get the asset from the cache - AssetKey keyToGet = key.clone(); - - // NOTE: Commented out because getFromCache leaks the original key -// DummyData someLoaded = (DummyData) cache.getFromCache(keyToGet); -// if (someLoaded != data){ -// // Failed to get the same asset from the cache => bug -// // Since a hard reference to the key is kept, -// // it cannot be collected at this point. -// throw new AssertionError(); -// } - - // Clone the asset - if (proc != null){ - // Data is now the clone! - data = (DummyData) proc.createClone(data); - if (smartCache) { - // Registering a clone is only needed - // if smart cache is used. - cache.registerAssetClone(keyToGet, data); - // The clone of the asset must have the same key as the original - // otherwise => bug - if (data.key != key){ - throw new AssertionError(); - } - } - } - - // Keep references to the asset => *should* prevent - // collections of the asset in the cache thus causing - // an out of memory error. - if (keepRefs){ - // Prevent the saved references from taking too much memory. - if (cloneAssets) { - data.data = null; - } - refs.add(data); - } - - if ((counter % 1000) == 0){ - long newMem = Runtime.getRuntime().freeMemory(); - System.out.println("Allocated objects: " + counter); - System.out.println("Allocated memory: " + ((memory - newMem)/(1024*1024)) + " MB" ); - memory = newMem; - } - } - } - - public static void main(String[] args){ - // Test cloneable smart asset - System.out.println("====== Running Cloneable Smart Asset Test ======"); - runTest(true, true, false, 100000); - - // Test non-cloneable smart asset - System.out.println("====== Running Non-cloneable Smart Asset Test ======"); - runTest(false, true, false, 100000); - } -} diff --git a/jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java b/jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java deleted file mode 100644 index 0a864a0cda..0000000000 --- a/jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.asset; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; -import com.jme3.ui.Picture; - -/** - * This tests loading a file from a jar stored online. - * @author Kirill Vainer - */ -public class TestOnlineJar extends SimpleApplication { - - public static void main(String[] args){ - TestOnlineJar app = new TestOnlineJar(); - app.start(); - } - - @Override - public void simpleInitApp() { - // create a simple plane/quad - Quad quadMesh = new Quad(1, 1); - quadMesh.updateGeometry(1, 1, true); - - Geometry quad = new Geometry("Textured Quad", quadMesh); - - assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/town.zip", - HttpZipLocator.class); - assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", - HttpZipLocator.class); - - Picture pic1 = new Picture("Picture1"); - pic1.move(0, 0, -1); - pic1.setPosition(0, 0); - pic1.setWidth(128); - pic1.setHeight(128); - pic1.setImage(assetManager, "grass.jpg", false); - guiNode.attachChild(pic1); - - Picture pic2 = new Picture("Picture1"); - pic2.move(0, 0, -1); - pic2.setPosition(128, 0); - pic2.setWidth(128); - pic2.setHeight(128); - pic2.setImage(assetManager, "glasstile2.png", false); - guiNode.attachChild(pic2); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java b/jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java deleted file mode 100644 index 563eb4c7c7..0000000000 --- a/jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.asset; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.asset.plugins.UrlLocator; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; -import com.jme3.texture.Texture; - -/** - * Load an image and display it from the internet using the UrlLocator. - * @author Kirill Vainer - */ -public class TestUrlLoading extends SimpleApplication { - - public static void main(String[] args){ - TestUrlLoading app = new TestUrlLoading(); - app.start(); - } - - @Override - public void simpleInitApp() { - // create a simple plane/quad - Quad quadMesh = new Quad(1, 1); - quadMesh.updateGeometry(1, 1, true); - - Geometry quad = new Geometry("Textured Quad", quadMesh); - - assetManager.registerLocator("https://raw.githubusercontent.com/jMonkeyEngine/BookSamples/master/assets/Textures/", - UrlLocator.class); - TextureKey key = new TextureKey("mucha-window.png", false); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", tex); - quad.setMaterial(mat); - - float aspect = tex.getImage().getWidth() / (float) tex.getImage().getHeight(); - quad.setLocalScale(new Vector3f(aspect * 1.5f, 1.5f, 1)); - quad.center(); - - rootNode.attachChild(quad); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/asset/package-info.java b/jme3-examples/src/main/java/jme3test/asset/package-info.java deleted file mode 100644 index a79bade643..0000000000 --- a/jme3-examples/src/main/java/jme3test/asset/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for asset loading - */ -package jme3test.asset; diff --git a/jme3-examples/src/main/java/jme3test/audio/TestAmbient.java b/jme3-examples/src/main/java/jme3test/audio/TestAmbient.java deleted file mode 100644 index 708fe1c77a..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestAmbient.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.audio; - -import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioData.DataType; -import com.jme3.audio.AudioNode; -import com.jme3.audio.Environment; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -public class TestAmbient extends SimpleApplication { - - public static void main(String[] args) { - TestAmbient test = new TestAmbient(); - test.start(); - } - - @Override - public void simpleInitApp() { - float[] eax = new float[]{15, 38.0f, 0.300f, -1000, -3300, 0, - 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f, 0.00f, - 0.00f, -229, 0.088f, 0.00f, 0.00f, 0.00f, 0.125f, 1.000f, - 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f}; - Environment env = new Environment(eax); - audioRenderer.setEnvironment(env); - - AudioNode waves = new AudioNode(assetManager, - "Sound/Environment/Ocean Waves.ogg", DataType.Buffer); - waves.setPositional(true); - waves.setLocalTranslation(new Vector3f(0, 0,0)); - waves.setMaxDistance(100); - waves.setRefDistance(5); - - AudioNode nature = new AudioNode(assetManager, - "Sound/Environment/Nature.ogg", DataType.Stream); - nature.setPositional(false); - nature.setVolume(3); - - waves.playInstance(); - nature.play(); - - // just a blue box to mark the spot - Box box1 = new Box(.5f, .5f, .5f); - Geometry player = new Geometry("Player", box1); - Material mat1 = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.Blue); - player.setMaterial(mat1); - rootNode.attachChild(player); - } - - @Override - public void simpleUpdate(float tpf) { - } -} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestDoppler.java b/jme3-examples/src/main/java/jme3test/audio/TestDoppler.java deleted file mode 100644 index 1065e1cee9..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestDoppler.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.audio; - -import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioData; -import com.jme3.audio.AudioNode; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Torus; - -/** - * Test Doppler Effect - */ -public class TestDoppler extends SimpleApplication { - - private float pos = -5; - private float vel = 5; - private AudioNode ufoNode; - - public static void main(String[] args){ - TestDoppler test = new TestDoppler(); - test.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10); - - Torus torus = new Torus(10, 6, 1, 3); - Geometry g = new Geometry("Torus Geom", torus); - g.rotate(-FastMath.HALF_PI, 0, 0); - g.center(); - - g.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); -// rootNode.attachChild(g); - - ufoNode = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", AudioData.DataType.Buffer); - ufoNode.setLooping(true); - ufoNode.setPitch(0.5f); - ufoNode.setRefDistance(1); - ufoNode.setMaxDistance(100000000); - ufoNode.setVelocityFromTranslation(true); - ufoNode.play(); - - Geometry ball = new Geometry("Beeper", new Sphere(10, 10, 0.1f)); - ball.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - ufoNode.attachChild(ball); - - rootNode.attachChild(ufoNode); - } - - - @Override - public void simpleUpdate(float tpf) { - pos += tpf * vel; - if (pos < -10 || pos > 10) { - vel *= -1; - } - ufoNode.setLocalTranslation(new Vector3f(pos, 0, 0)); - } -} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java b/jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java deleted file mode 100644 index 134cb18ee9..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ -package jme3test.audio; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.UrlLocator; -import com.jme3.audio.AudioData; -import com.jme3.audio.AudioNode; -import java.util.Random; - -/** - * Stress test to reproduce JME issue #1761 (AssertionError in ALAudioRenderer). - * - *

After some network delay, a song will play, - * albeit slowly and in a broken fashion. - * If the issue is solved, the song will play all the way through. - * If the issue is present, an AssertionError will be thrown, usually within a - * second of the song starting. - */ -public class TestIssue1761 extends SimpleApplication { - - private AudioNode audioNode; - final private Random random = new Random(); - - /** - * Main entry point for the TestIssue1761 application. - * - * @param unused array of command-line arguments - */ - public static void main(String[] unused) { - TestIssue1761 test = new TestIssue1761(); - test.start(); - } - - @Override - public void simpleInitApp() { - assetManager.registerLocator( - "https://web.archive.org/web/20170625151521if_/http://www.vorbis.com/music/", - UrlLocator.class); - audioNode = new AudioNode(assetManager, "Lumme-Badloop.ogg", - AudioData.DataType.Stream); - audioNode.setPositional(false); - audioNode.play(); - } - - @Override - public void simpleUpdate(float tpf) { - /* - * Randomly pause and restart the audio. - */ - if (random.nextInt(2) == 0) { - audioNode.pause(); - } else { - audioNode.play(); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form b/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form deleted file mode 100644 index 2834858a01..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form +++ /dev/null @@ -1,117 +0,0 @@ - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java b/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java deleted file mode 100644 index da6b4e9a2f..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ - -package jme3test.audio; - -import com.jme3.asset.AssetInfo; -import com.jme3.asset.AssetLoader; -import com.jme3.audio.*; -import com.jme3.audio.AudioSource.Status; -import com.jme3.audio.plugins.OGGLoader; -import com.jme3.audio.plugins.WAVLoader; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeSystem; -import com.jme3.system.NativeLibraries; -import com.jme3.system.NativeLibraryLoader; - -import java.io.*; -import javax.swing.JFileChooser; - -public class TestMusicPlayer extends javax.swing.JFrame { - - private AudioRenderer ar; - private AudioData musicData; - private AudioNode musicSource; - private float musicLength = 0; - private float curTime = 0; - final private Listener listener = new Listener(); - - static { - // Load lwjgl and openal natives if lwjgl version 2 is in classpath. - // - // In case of lwjgl 2, natives are loaded when LwjglContext is - // started, but in this test we do not create a LwjglContext, - // so we should handle loading natives ourselves if running - // with lwjgl 2. - NativeLibraryLoader.loadNativeLibrary(NativeLibraries.Lwjgl.getName(), false); - NativeLibraryLoader.loadNativeLibrary(NativeLibraries.OpenAL.getName(), false); - } - - public TestMusicPlayer() { - initComponents(); - setLocationRelativeTo(null); - initAudioPlayer(); - } - - private void initAudioPlayer(){ - AppSettings settings = new AppSettings(true); - settings.setRenderer(null); // disable rendering - settings.setAudioRenderer("LWJGL"); - ar = JmeSystem.newAudioRenderer(settings); - ar.initialize(); - ar.setListener(listener); - AudioContext.setAudioRenderer(ar); - } - - /** This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - pnlButtons = new javax.swing.JPanel(); - sldVolume = new javax.swing.JSlider(); - btnRewind = new javax.swing.JButton(); - btnStop = new javax.swing.JButton(); - btnPlay = new javax.swing.JButton(); - btnFF = new javax.swing.JButton(); - btnOpen = new javax.swing.JButton(); - pnlBar = new javax.swing.JPanel(); - lblTime = new javax.swing.JLabel(); - sldBar = new javax.swing.JSlider(); - - setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); - addWindowListener(new java.awt.event.WindowAdapter() { - @Override - public void windowClosing(java.awt.event.WindowEvent evt) { - formWindowClosing(evt); - } - }); - - pnlButtons.setLayout(new javax.swing.BoxLayout(pnlButtons, javax.swing.BoxLayout.LINE_AXIS)); - - sldVolume.setMajorTickSpacing(20); - sldVolume.setOrientation(javax.swing.JSlider.VERTICAL); - sldVolume.setPaintTicks(true); - sldVolume.setValue(100); - sldVolume.addChangeListener(new javax.swing.event.ChangeListener() { - @Override - public void stateChanged(javax.swing.event.ChangeEvent evt) { - sldVolumeStateChanged(evt); - } - }); - pnlButtons.add(sldVolume); - - btnRewind.setText("<<"); - pnlButtons.add(btnRewind); - - btnStop.setText("[ ]"); - btnStop.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnStopActionPerformed(evt); - } - }); - pnlButtons.add(btnStop); - - btnPlay.setText("II / >"); - btnPlay.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnPlayActionPerformed(evt); - } - }); - pnlButtons.add(btnPlay); - - btnFF.setText(">>"); - btnFF.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnFFActionPerformed(evt); - } - }); - pnlButtons.add(btnFF); - - btnOpen.setText("Open ..."); - btnOpen.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnOpenActionPerformed(evt); - } - }); - pnlButtons.add(btnOpen); - - getContentPane().add(pnlButtons, java.awt.BorderLayout.CENTER); - - pnlBar.setLayout(new javax.swing.BoxLayout(pnlBar, javax.swing.BoxLayout.LINE_AXIS)); - - lblTime.setText("0:00-0:00"); - lblTime.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 3, 3)); - pnlBar.add(lblTime); - - sldBar.setValue(0); - sldBar.addChangeListener(new javax.swing.event.ChangeListener() { - @Override - public void stateChanged(javax.swing.event.ChangeEvent evt) { - sldBarStateChanged(evt); - } - }); - pnlBar.add(sldBar); - - getContentPane().add(pnlBar, java.awt.BorderLayout.PAGE_START); - - pack(); - }// //GEN-END:initComponents - - private void btnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOpenActionPerformed - JFileChooser chooser = new JFileChooser(); - chooser.setAcceptAllFileFilterUsed(true); - chooser.setDialogTitle("Select OGG file"); - chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - chooser.setMultiSelectionEnabled(false); - if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION){ - btnStopActionPerformed(null); - - final File selected = chooser.getSelectedFile(); - AssetLoader loader = null; - if(selected.getName().endsWith(".wav")){ - loader = new WAVLoader(); - }else{ - loader = new OGGLoader(); - } - - AudioKey key = new AudioKey(selected.getName(), true, true); - try{ - musicData = (AudioData) loader.load(new AssetInfo(null, key) { - @Override - public InputStream openStream() { - try{ - return new FileInputStream(selected); - }catch (FileNotFoundException ex){ - ex.printStackTrace(); - } - return null; - } - }); - }catch (IOException ex){ - ex.printStackTrace(); - } - - musicSource = new AudioNode(musicData, key); - // A positional AudioNode would prohibit stereo sound! - musicSource.setPositional(false); - musicLength = musicData.getDuration(); - updateTime(); - } - }//GEN-LAST:event_btnOpenActionPerformed - - private void updateTime(){ - int max = (int) (musicLength * 100); - int pos = (int) (curTime * 100); - sldBar.setMaximum(max); - sldBar.setValue(pos); - - int minutesTotal = (int) (musicLength / 60); - int secondsTotal = (int) (musicLength % 60); - int minutesNow = (int) (curTime / 60); - int secondsNow = (int) (curTime % 60); - String txt = String.format("%01d:%02d-%01d:%02d", minutesNow, secondsNow, - minutesTotal, secondsTotal); - lblTime.setText(txt); - } - - private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayActionPerformed - if (musicSource == null){ - btnOpenActionPerformed(evt); - return; - } - - if (musicSource.getStatus() == Status.Playing){ - musicSource.setPitch(1); - ar.pauseSource(musicSource); - }else{ - musicSource.setPitch(1); - musicSource.play(); - } - }//GEN-LAST:event_btnPlayActionPerformed - - private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing - ar.cleanup(); - }//GEN-LAST:event_formWindowClosing - - private void sldVolumeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldVolumeStateChanged - listener.setVolume(sldVolume.getValue() / 100f); - ar.setListener(listener); - }//GEN-LAST:event_sldVolumeStateChanged - - private void btnStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStopActionPerformed - if (musicSource != null){ - musicSource.setPitch(1); - ar.stopSource(musicSource); - } - }//GEN-LAST:event_btnStopActionPerformed - - private void btnFFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFFActionPerformed - if (musicSource != null && musicSource.getStatus() == Status.Playing) { - musicSource.setPitch(2); - } - }//GEN-LAST:event_btnFFActionPerformed - - private void sldBarStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldBarStateChanged - // do nothing: OGG/Vorbis supports seeking, but only for time = 0! - }//GEN-LAST:event_sldBarStateChanged - - /** - * @param args the command line arguments - */ - public static void main(String args[]) { - java.awt.EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - new TestMusicPlayer().setVisible(true); - } - }); - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton btnFF; - private javax.swing.JButton btnOpen; - private javax.swing.JButton btnPlay; - private javax.swing.JButton btnRewind; - private javax.swing.JButton btnStop; - private javax.swing.JLabel lblTime; - private javax.swing.JPanel pnlBar; - private javax.swing.JPanel pnlButtons; - private javax.swing.JSlider sldBar; - private javax.swing.JSlider sldVolume; - // End of variables declaration//GEN-END:variables - -} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java b/jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java deleted file mode 100644 index 677d6d2483..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.audio; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.UrlLocator; -import com.jme3.audio.AudioData; -import com.jme3.audio.AudioNode; - -public class TestMusicStreaming extends SimpleApplication { - - public static void main(String[] args){ - TestMusicStreaming test = new TestMusicStreaming(); - test.start(); - } - - @Override - public void simpleInitApp(){ - assetManager.registerLocator("https://web.archive.org/web/20170625151521if_/http://www.vorbis.com/music/", UrlLocator.class); - AudioNode audioSource = new AudioNode(assetManager, "Lumme-Badloop.ogg", - AudioData.DataType.Stream); - audioSource.setPositional(false); - audioSource.setReverbEnabled(false); - audioSource.play(); - } - - @Override - public void simpleUpdate(float tpf){} - -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/audio/TestOgg.java b/jme3-examples/src/main/java/jme3test/audio/TestOgg.java deleted file mode 100644 index 3e4099c660..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestOgg.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.audio; - -import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioData.DataType; -import com.jme3.audio.AudioNode; -import com.jme3.audio.AudioSource; -import com.jme3.audio.LowPassFilter; - -public class TestOgg extends SimpleApplication { - - private AudioNode audioSource; - - public static void main(String[] args){ - TestOgg test = new TestOgg(); - test.start(); - } - - @Override - public void simpleInitApp(){ - System.out.println("Playing without filter"); - audioSource = new AudioNode(assetManager, "Sound/Effects/Foot steps.ogg", DataType.Buffer); - audioSource.play(); - } - - @Override - public void simpleUpdate(float tpf){ - if (audioSource.getStatus() != AudioSource.Status.Playing){ - audioRenderer.deleteAudioData(audioSource.getAudioData()); - - System.out.println("Playing with low pass filter"); - audioSource = new AudioNode(assetManager, "Sound/Effects/Foot steps.ogg", DataType.Buffer); - audioSource.setDryFilter(new LowPassFilter(1f, .1f)); - audioSource.setVolume(3); - audioSource.play(); - } - } - -} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestReverb.java b/jme3-examples/src/main/java/jme3test/audio/TestReverb.java deleted file mode 100644 index aff0a2d464..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestReverb.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.audio; - -import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioData; -import com.jme3.audio.AudioNode; -import com.jme3.audio.Environment; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; - -public class TestReverb extends SimpleApplication { - - private AudioNode audioSource; - private float time = 0; - private float nextTime = 1; - - public static void main(String[] args) { - TestReverb test = new TestReverb(); - test.start(); - } - - @Override - public void simpleInitApp() { - audioSource = new AudioNode(assetManager, "Sound/Effects/Bang.wav", - AudioData.DataType.Buffer); - - float[] eax = new float[]{15, 38.0f, 0.300f, -1000, -3300, 0, - 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f, 0.00f, 0.00f, - -229, 0.088f, 0.00f, 0.00f, 0.00f, 0.125f, 1.000f, 0.250f, - 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f}; - audioRenderer.setEnvironment(new Environment(eax)); - Environment env = Environment.Cavern; - audioRenderer.setEnvironment(env); - } - - @Override - public void simpleUpdate(float tpf) { - time += tpf; - - if (time > nextTime) { - Vector3f v = new Vector3f(); - v.setX(FastMath.nextRandomFloat()); - v.setY(FastMath.nextRandomFloat()); - v.setZ(FastMath.nextRandomFloat()); - v.multLocal(40, 2, 40); - v.subtractLocal(20, 1, 20); - - audioSource.setLocalTranslation(v); - audioSource.playInstance(); - time = 0; - nextTime = FastMath.nextRandomFloat() * 2 + 0.5f; - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestWav.java b/jme3-examples/src/main/java/jme3test/audio/TestWav.java deleted file mode 100644 index 70ec211f23..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/TestWav.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.audio; - -import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioData; -import com.jme3.audio.AudioNode; - -public class TestWav extends SimpleApplication { - - private float time = 0; - private AudioNode audioSource; - - public static void main(String[] args) { - TestWav test = new TestWav(); - test.start(); - } - - @Override - public void simpleUpdate(float tpf) { - time += tpf; - if (time > 1f) { - audioSource.playInstance(); - time = 0; - } - - } - - @Override - public void simpleInitApp() { - audioSource = new AudioNode(assetManager, "Sound/Effects/Gun.wav", - AudioData.DataType.Buffer); - audioSource.setLooping(false); - } -} diff --git a/jme3-examples/src/main/java/jme3test/audio/package-info.java b/jme3-examples/src/main/java/jme3test/audio/package-info.java deleted file mode 100644 index d6c39d933d..0000000000 --- a/jme3-examples/src/main/java/jme3test/audio/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for sound effects and music - */ -package jme3test.audio; diff --git a/jme3-examples/src/main/java/jme3test/awt/AppHarness.java b/jme3-examples/src/main/java/jme3test/awt/AppHarness.java deleted file mode 100644 index 0faa1a6507..0000000000 --- a/jme3-examples/src/main/java/jme3test/awt/AppHarness.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.awt; - -import com.jme3.app.LegacyApplication; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeCanvasContext; -import com.jme3.system.JmeSystem; -import java.applet.Applet; -import java.awt.Canvas; -import java.awt.Graphics; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import javax.swing.SwingUtilities; - -/** - * - * @author Kirill - */ -public class AppHarness extends Applet { - - private JmeCanvasContext context; - private Canvas canvas; - private LegacyApplication app; - - private String appClass; - private URL appCfg = null; - - @SuppressWarnings("unchecked") - private void createCanvas(){ - AppSettings settings = new AppSettings(true); - - // load app cfg - if (appCfg != null){ - try { - InputStream in = appCfg.openStream(); - settings.load(in); - in.close(); - } catch (IOException ex){ - ex.printStackTrace(); - } - } - - settings.setWidth(getWidth()); - settings.setHeight(getHeight()); - settings.setAudioRenderer(null); - - JmeSystem.setLowPermissions(true); - - try{ - Class clazz = Class.forName(appClass); - app = (LegacyApplication) clazz.getDeclaredConstructor().newInstance(); - }catch (ClassNotFoundException - | InstantiationException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException - | NoSuchMethodException - | SecurityException ex) { - ex.printStackTrace(); - } - - app.setSettings(settings); - app.createCanvas(); - - context = (JmeCanvasContext) app.getContext(); - canvas = context.getCanvas(); - canvas.setSize(getWidth(), getHeight()); - - add(canvas); - app.startCanvas(); - } - - @Override - public final void update(Graphics g) { - canvas.setSize(getWidth(), getHeight()); - } - - @Override - public void init(){ - appClass = getParameter("AppClass"); - if (appClass == null) - throw new RuntimeException("The required parameter AppClass isn't specified!"); - - try { - appCfg = new URL(getParameter("AppSettingsURL")); - } catch (MalformedURLException ex) { - ex.printStackTrace(); - appCfg = null; - } - - createCanvas(); - System.out.println("applet:init"); - } - - @Override - public void start(){ - context.setAutoFlushFrames(true); - System.out.println("applet:start"); - } - - @Override - public void stop(){ - context.setAutoFlushFrames(false); - System.out.println("applet:stop"); - } - - @Override - public void destroy(){ - System.out.println("applet:destroyStart"); - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - removeAll(); - System.out.println("applet:destroyRemoved"); - } - }); - app.stop(true); - System.out.println("applet:destroyDone"); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/awt/TestApplet.java b/jme3-examples/src/main/java/jme3test/awt/TestApplet.java deleted file mode 100644 index e9e473b852..0000000000 --- a/jme3-examples/src/main/java/jme3test/awt/TestApplet.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.awt; - -import com.jme3.app.LegacyApplication; -import com.jme3.app.SimpleApplication; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeCanvasContext; -import com.jme3.system.JmeSystem; -import java.applet.Applet; -import java.awt.Canvas; -import java.awt.Graphics; -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.Callable; -import javax.swing.SwingUtilities; - -public class TestApplet extends Applet { - - private static JmeCanvasContext context; - private static LegacyApplication app; - private static Canvas canvas; - private static TestApplet applet; - - public TestApplet(){ - } - - @SuppressWarnings("unchecked") - public static void createCanvas(String appClass){ - AppSettings settings = new AppSettings(true); - settings.setWidth(640); - settings.setHeight(480); - settings.setRenderer(AppSettings.LWJGL_OPENGL2); - - JmeSystem.setLowPermissions(true); - - try{ - Class clazz = Class.forName(appClass); - app = (LegacyApplication) clazz.getDeclaredConstructor().newInstance(); - } catch (ClassNotFoundException - | InstantiationException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException - | NoSuchMethodException - | SecurityException ex) { - ex.printStackTrace(); - } - - app.setSettings(settings); - app.createCanvas(); - - context = (JmeCanvasContext) app.getContext(); - canvas = context.getCanvas(); - canvas.setSize(settings.getWidth(), settings.getHeight()); - } - - public static void startApp(){ - applet.add(canvas); - app.startCanvas(); - - app.enqueue(new Callable(){ - @Override - public Void call(){ - if (app instanceof SimpleApplication){ - SimpleApplication simpleApp = (SimpleApplication) app; - simpleApp.getFlyByCamera().setDragToRotate(true); - simpleApp.getInputManager().setCursorVisible(true); - } - return null; - } - }); - } - - public void freezeApp(){ - remove(canvas); - } - - public void unfreezeApp(){ - add(canvas); - } - - @Override - public final void update(Graphics g) { -// canvas.setSize(getWidth(), getHeight()); - } - - @Override - public void init(){ - applet = this; - createCanvas("jme3test.model.shape.TestBox"); - startApp(); - app.setPauseOnLostFocus(false); - System.out.println("applet:init"); - } - - @Override - public void start(){ -// context.setAutoFlushFrames(true); - System.out.println("applet:start"); - } - - @Override - public void stop(){ -// context.setAutoFlushFrames(false); - System.out.println("applet:stop"); - } - - @Override - public void destroy(){ - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - removeAll(); - System.out.println("applet:destroyStart"); - } - }); - app.stop(true); - System.out.println("applet:destroyEnd"); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java b/jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java deleted file mode 100644 index 9dab109021..0000000000 --- a/jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package jme3test.awt; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.system.AppSettings; -import com.jme3.system.awt.AwtPanel; -import com.jme3.system.awt.AwtPanelsContext; -import com.jme3.system.awt.PaintMode; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.concurrent.CountDownLatch; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.JFrame; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; - -public class TestAwtPanels extends SimpleApplication { - - private static final Logger logger = Logger.getLogger(TestAwtPanels.class.getName()); - - final private static CountDownLatch panelsAreReady = new CountDownLatch(1); - private static TestAwtPanels app; - private static AwtPanel panel, panel2; - private static int panelsClosed = 0; - - private static void createWindowForPanel(AwtPanel panel, int location){ - JFrame frame = new JFrame("Render Display " + location); - frame.getContentPane().setLayout(new BorderLayout()); - frame.getContentPane().add(panel, BorderLayout.CENTER); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosed(WindowEvent e) { - if (++panelsClosed == 2){ - app.stop(); - } - } - }); - frame.pack(); - frame.setLocation(location, Toolkit.getDefaultToolkit().getScreenSize().height - 400); - frame.setVisible(true); - } - - public static void main(String[] args){ - Logger.getLogger("com.jme3").setLevel(Level.WARNING); - - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - logger.warning("Could not set native look and feel."); - } - - app = new TestAwtPanels(); - app.setShowSettings(false); - AppSettings settings = new AppSettings(true); - settings.setCustomRenderer(AwtPanelsContext.class); - settings.setFrameRate(60); - app.setSettings(settings); - app.start(); - - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - /* - * Sleep 2 seconds to ensure there's no race condition. - * The sleep is not required for correctness. - */ - try { - Thread.sleep(2000); - } catch (InterruptedException exception) { - return; - } - - final AwtPanelsContext ctx = (AwtPanelsContext) app.getContext(); - panel = ctx.createPanel(PaintMode.Accelerated); - panel.setPreferredSize(new Dimension(400, 300)); - ctx.setInputSource(panel); - - panel2 = ctx.createPanel(PaintMode.Accelerated); - panel2.setPreferredSize(new Dimension(400, 300)); - - createWindowForPanel(panel, 300); - createWindowForPanel(panel2, 700); - /* - * Both panels are ready. - */ - panelsAreReady.countDown(); - } - }); - } - - @Override - public void simpleInitApp() { - flyCam.setDragToRotate(true); - - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - geom.setMaterial(mat); - rootNode.attachChild(geom); - /* - * Wait until both AWT panels are ready. - */ - try { - panelsAreReady.await(); - } catch (InterruptedException exception) { - throw new RuntimeException("Interrupted while waiting for panels", exception); - } - - panel.attachTo(true, viewPort); - guiViewPort.setClearFlags(true, true, true); - panel2.attachTo(false, guiViewPort); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java deleted file mode 100644 index bb4b39ac95..0000000000 --- a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.awt; - -import com.jme3.app.LegacyApplication; -import com.jme3.app.SimpleApplication; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeCanvasContext; -import com.jme3.util.JmeFormatter; -import java.awt.BorderLayout; -import java.awt.Canvas; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.Callable; -import java.util.logging.ConsoleHandler; -import java.util.logging.Handler; -import java.util.logging.Logger; -import javax.swing.*; - -public class TestCanvas { - - private static JmeCanvasContext context; - private static Canvas canvas; - private static LegacyApplication app; - private static JFrame frame; - private static Container canvasPanel1, canvasPanel2; - private static Container currentPanel; - private static JTabbedPane tabbedPane; - private static final String appClass = "jme3test.post.TestRenderToTexture"; - - private static void createTabs(){ - tabbedPane = new JTabbedPane(); - - canvasPanel1 = new JPanel(); - canvasPanel1.setLayout(new BorderLayout()); - tabbedPane.addTab("jME3 Canvas 1", canvasPanel1); - - canvasPanel2 = new JPanel(); - canvasPanel2.setLayout(new BorderLayout()); - tabbedPane.addTab("jME3 Canvas 2", canvasPanel2); - - frame.getContentPane().add(tabbedPane); - - currentPanel = canvasPanel1; - } - - private static void createMenu(){ - JMenuBar menuBar = new JMenuBar(); - frame.setJMenuBar(menuBar); - - JMenu menuTortureMethods = new JMenu("Canvas Torture Methods"); - menuBar.add(menuTortureMethods); - - final JMenuItem itemRemoveCanvas = new JMenuItem("Remove Canvas"); - menuTortureMethods.add(itemRemoveCanvas); - itemRemoveCanvas.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (itemRemoveCanvas.getText().equals("Remove Canvas")){ - currentPanel.remove(canvas); - - itemRemoveCanvas.setText("Add Canvas"); - }else if (itemRemoveCanvas.getText().equals("Add Canvas")){ - currentPanel.add(canvas, BorderLayout.CENTER); - - itemRemoveCanvas.setText("Remove Canvas"); - } - } - }); - - final JMenuItem itemHideCanvas = new JMenuItem("Hide Canvas"); - menuTortureMethods.add(itemHideCanvas); - itemHideCanvas.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (itemHideCanvas.getText().equals("Hide Canvas")){ - canvas.setVisible(false); - itemHideCanvas.setText("Show Canvas"); - }else if (itemHideCanvas.getText().equals("Show Canvas")){ - canvas.setVisible(true); - itemHideCanvas.setText("Hide Canvas"); - } - } - }); - - final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2"); - menuTortureMethods.add(itemSwitchTab); - itemSwitchTab.addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e){ - if (itemSwitchTab.getText().equals("Switch to tab #2")){ - canvasPanel1.remove(canvas); - canvasPanel2.add(canvas, BorderLayout.CENTER); - currentPanel = canvasPanel2; - itemSwitchTab.setText("Switch to tab #1"); - }else if (itemSwitchTab.getText().equals("Switch to tab #1")){ - canvasPanel2.remove(canvas); - canvasPanel1.add(canvas, BorderLayout.CENTER); - currentPanel = canvasPanel1; - itemSwitchTab.setText("Switch to tab #2"); - } - } - }); - - JMenuItem itemSwitchLaf = new JMenuItem("Switch Look and Feel"); - menuTortureMethods.add(itemSwitchLaf); - itemSwitchLaf.addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e){ - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Throwable t){ - t.printStackTrace(); - } - SwingUtilities.updateComponentTreeUI(frame); - frame.pack(); - } - }); - - JMenuItem itemSmallSize = new JMenuItem("Set size to (0, 0)"); - menuTortureMethods.add(itemSmallSize); - itemSmallSize.addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e){ - Dimension preferred = frame.getPreferredSize(); - frame.setPreferredSize(new Dimension(0, 0)); - frame.pack(); - frame.setPreferredSize(preferred); - } - }); - - JMenuItem itemKillCanvas = new JMenuItem("Stop/Start Canvas"); - menuTortureMethods.add(itemKillCanvas); - itemKillCanvas.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - currentPanel.remove(canvas); - app.stop(true); - - createCanvas(appClass); - currentPanel.add(canvas, BorderLayout.CENTER); - frame.pack(); - startApp(); - } - }); - - JMenuItem itemExit = new JMenuItem("Exit"); - menuTortureMethods.add(itemExit); - itemExit.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent ae) { - frame.dispose(); - app.stop(); - } - }); - } - - private static void createFrame(){ - frame = new JFrame("Test"); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.addWindowListener(new WindowAdapter(){ - @Override - public void windowClosed(WindowEvent e) { - app.stop(); - } - }); - - createTabs(); - createMenu(); - } - - @SuppressWarnings("unchecked") - public static void createCanvas(String appClass){ - AppSettings settings = new AppSettings(true); - settings.setWidth(640); - settings.setHeight(480); - - try{ - Class clazz = Class.forName(appClass); - app = (LegacyApplication) clazz.getDeclaredConstructor().newInstance(); - }catch (ClassNotFoundException - | InstantiationException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException - | NoSuchMethodException - | SecurityException ex) { - ex.printStackTrace(); - } - - app.setPauseOnLostFocus(false); - app.setSettings(settings); - app.createCanvas(); - app.startCanvas(); - - context = (JmeCanvasContext) app.getContext(); - canvas = context.getCanvas(); - canvas.setSize(settings.getWidth(), settings.getHeight()); - } - - public static void startApp(){ - app.startCanvas(); - app.enqueue(new Callable(){ - @Override - public Void call(){ - if (app instanceof SimpleApplication){ - SimpleApplication simpleApp = (SimpleApplication) app; - simpleApp.getFlyByCamera().setDragToRotate(true); - } - return null; - } - }); - - } - - public static void main(String[] args){ - JmeFormatter formatter = new JmeFormatter(); - - Handler consoleHandler = new ConsoleHandler(); - consoleHandler.setFormatter(formatter); - - Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]); - Logger.getLogger("").addHandler(consoleHandler); - - createCanvas(appClass); - - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - } - - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - JPopupMenu.setDefaultLightWeightPopupEnabled(false); - - createFrame(); - - currentPanel.add(canvas, BorderLayout.CENTER); - frame.pack(); - startApp(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - } - }); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java deleted file mode 100644 index 5c6940df31..0000000000 --- a/jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java +++ /dev/null @@ -1,68 +0,0 @@ -package jme3test.awt; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeCanvasContext; -import java.awt.Canvas; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import javax.swing.JFrame; - -public class TestSafeCanvas extends SimpleApplication { - - public static void main(String[] args) throws InterruptedException{ - AppSettings settings = new AppSettings(true); - settings.setWidth(640); - settings.setHeight(480); - - final TestSafeCanvas app = new TestSafeCanvas(); - app.setPauseOnLostFocus(false); - app.setSettings(settings); - app.createCanvas(); - app.startCanvas(true); - - JmeCanvasContext context = (JmeCanvasContext) app.getContext(); - Canvas canvas = context.getCanvas(); - canvas.setSize(settings.getWidth(), settings.getHeight()); - - - - Thread.sleep(3000); - - JFrame frame = new JFrame("Test"); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - app.stop(); - } - }); - frame.getContentPane().add(canvas); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - - Thread.sleep(3000); - - frame.getContentPane().remove(canvas); - - Thread.sleep(3000); - - frame.getContentPane().add(canvas); - } - - @Override - public void simpleInitApp() { - flyCam.setDragToRotate(true); - - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - geom.setMaterial(mat); - rootNode.attachChild(geom); - } -} diff --git a/jme3-examples/src/main/java/jme3test/awt/package-info.java b/jme3-examples/src/main/java/jme3test/awt/package-info.java deleted file mode 100644 index 36025141ca..0000000000 --- a/jme3-examples/src/main/java/jme3test/awt/package-info.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for interfacing to the Abstract Window - * Toolkit (AWT) - */ -package jme3test.awt; diff --git a/jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java b/jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java deleted file mode 100644 index c04069ef88..0000000000 --- a/jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.batching; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.BatchNode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.debug.WireFrustum; -import com.jme3.scene.shape.Box; -import com.jme3.system.NanoTimer; -import com.jme3.util.TangentBinormalGenerator; - -/** - * A test to demonstrate the usage and functionality of the {@link BatchNode} - * @author Nehon - */ -public class TestBatchNode extends SimpleApplication { - private BatchNode batch; - private WireFrustum frustum; - private final Vector3f[] points; - private Geometry cube2; - private float time = 0; - private DirectionalLight dl; - private boolean done = false; - - public static void main(String[] args) { - TestBatchNode app = new TestBatchNode(); - app.start(); - } - - public TestBatchNode() { - points = new Vector3f[8]; - for (int i = 0; i < points.length; i++) { - points[i] = new Vector3f(); - } - } - - @Override - public void simpleInitApp() { - timer = new NanoTimer(); - batch = new BatchNode("theBatchNode"); - - /* - * A cube with a color "bleeding" through transparent texture. Uses - * Texture from jme3-testdata library! - */ - Box boxShape4 = new Box(1f, 1f, 1f); - Geometry cube = new Geometry("cube1", boxShape4); - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - cube.setMaterial(mat); - //Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - //mat.setColor("Diffuse", ColorRGBA.Blue); - //mat.setBoolean("UseMaterialColors", true); - /* - * A cube with a color "bleeding" through transparent texture. Uses - * Texture from jme3-testdata library! - */ - Box box = new Box(1f, 1f, 1f); - cube2 = new Geometry("cube2", box); - cube2.setMaterial(mat); - - TangentBinormalGenerator.generate(cube); - TangentBinormalGenerator.generate(cube2); - - batch.attachChild(cube); - // batch.attachChild(cube2); - // batch.setMaterial(mat); - batch.batch(); - rootNode.attachChild(batch); - cube.setLocalTranslation(3, 0, 0); - cube2.setLocalTranslation(0, 20, 0); - - updateBoundingPoints(points); - frustum = new WireFrustum(points); - Geometry frustumMdl = new Geometry("f", frustum); - frustumMdl.setCullHint(Spatial.CullHint.Never); - frustumMdl.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - frustumMdl.getMaterial().getAdditionalRenderState().setWireframe(true); - frustumMdl.getMaterial().setColor("Color", ColorRGBA.Red); - rootNode.attachChild(frustumMdl); - dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White.mult(2)); - dl.setDirection(new Vector3f(1, -1, -1)); - rootNode.addLight(dl); - flyCam.setMoveSpeed(10); - } - - @Override - public void simpleUpdate(float tpf) { - if (!done) { - done = true; - batch.attachChild(cube2); - batch.batch(); - } - updateBoundingPoints(points); - frustum.update(points); - time += tpf; - dl.setDirection(cam.getDirection()); - cube2.setLocalTranslation(FastMath.sin(-time) * 3, FastMath.cos(time) * 3, 0); - cube2.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Z)); - cube2.setLocalScale(Math.max(FastMath.sin(time), 0.5f)); - - // batch.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Z)); - } - - public void updateBoundingPoints(Vector3f[] points) { - BoundingBox bb = (BoundingBox) batch.getWorldBound(); - float xe = bb.getXExtent(); - float ye = bb.getYExtent(); - float ze = bb.getZExtent(); - float x = bb.getCenter().x; - float y = bb.getCenter().y; - float z = bb.getCenter().z; - - points[0].set(new Vector3f(x - xe, y - ye, z - ze)); - points[1].set(new Vector3f(x - xe, y + ye, z - ze)); - points[2].set(new Vector3f(x + xe, y + ye, z - ze)); - points[3].set(new Vector3f(x + xe, y - ye, z - ze)); - - points[4].set(new Vector3f(x + xe, y - ye, z + ze)); - points[5].set(new Vector3f(x - xe, y - ye, z + ze)); - points[6].set(new Vector3f(x - xe, y + ye, z + ze)); - points[7].set(new Vector3f(x + xe, y + ye, z + ze)); - } -} diff --git a/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java b/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java deleted file mode 100644 index 52a87492c4..0000000000 --- a/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.batching; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.scene.*; -import com.jme3.scene.debug.Arrow; -import com.jme3.scene.shape.Box; -import com.jme3.system.AppSettings; -import com.jme3.system.NanoTimer; -import java.util.ArrayList; -import java.util.Random; - -public class TestBatchNodeCluster extends SimpleApplication { - - public static void main(String[] args) { - TestBatchNodeCluster app = new TestBatchNodeCluster(); - settingst = new AppSettings(true); - //settingst.setFrameRate(75); - settingst.setResolution(640, 480); - settingst.setVSync(false); - settingst.setFullscreen(false); - app.setSettings(settingst); - app.setShowSettings(false); - app.start(); - } - final private ActionListener al = new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("Start Game")) { -// randomGenerator(); - } - } - }; - final private Random rand = new Random(); - final private int maxCubes = 2000; - final private int startAt = 0; - final private ArrayList xPosition = new ArrayList<>(); - final private ArrayList yPosition = new ArrayList<>(); - final private ArrayList zPosition = new ArrayList<>(); - final private int yLimitf = 60, yLimits = -20; - private static AppSettings settingst; - final private int lineLength = 50; - private BatchNode batchNode; - private Material mat1; - private Material mat2; - private Material mat3; - private Material mat4; - private Node terrain; -// protected Geometry player; - - @Override - public void simpleInitApp() { - timer = new NanoTimer(); - - batchNode = new SimpleBatchNode("BatchNode"); - - - xPosition.add(0); - yPosition.add(0); - zPosition.add(0); - - mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.White); - mat1.setColor("GlowColor", ColorRGBA.Blue.mult(10)); - - mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat2.setColor("Color", ColorRGBA.White); - mat2.setColor("GlowColor", ColorRGBA.Red.mult(10)); - - mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat3.setColor("Color", ColorRGBA.White); - mat3.setColor("GlowColor", ColorRGBA.Yellow.mult(10)); - - mat4 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat4.setColor("Color", ColorRGBA.White); - mat4.setColor("GlowColor", ColorRGBA.Orange.mult(10)); - - randomGenerator(); - - //rootNode.attachChild(SkyFactory.createSky( - // assetManager, "Textures/SKY02.zip", false)); - inputManager.addMapping("Start Game", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addListener(al, new String[]{"Start Game"}); - - - cam.setLocation(new Vector3f(-34.403286f, 126.65158f, 434.791f)); - cam.setRotation(new Quaternion(0.022630932f, 0.9749435f, -0.18736298f, 0.11776358f)); - - - batchNode.batch(); - - - terrain = new Node("terrain"); - terrain.setLocalTranslation(50, 0, 50); - terrain.attachChild(batchNode); - - flyCam.setMoveSpeed(100); - rootNode.attachChild(terrain); - Vector3f pos = new Vector3f(-40, 0, -40); - batchNode.setLocalTranslation(pos); - - - Arrow a = new Arrow(new Vector3f(0, 50, 0)); - Geometry g = new Geometry("a", a); - g.setLocalTranslation(terrain.getLocalTranslation()); - Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - m.setColor("Color", ColorRGBA.Blue); - g.setMaterial(m); - - - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(new BloomFilter(BloomFilter.GlowMode.Objects)); -// SSAOFilter ssao = new SSAOFilter(8.630104f,22.970434f,2.9299977f,0.2999997f); -// fpp.addFilter(ssao); - viewPort.addProcessor(fpp); - // viewPort.setBackgroundColor(ColorRGBA.DarkGray); - } - - public void randomGenerator() { - for (int i = startAt; i < maxCubes - 1; i++) { - randomize(); - Geometry box = new Geometry("Box" + i, new Box(1, 1, 1)); - box.setLocalTranslation(new Vector3f(xPosition.get(xPosition.size() - 1), - yPosition.get(yPosition.size() - 1), - zPosition.get(zPosition.size() - 1))); - batchNode.attachChild(box); - if (i < 500) { - box.setMaterial(mat1); - } else if (i < 1000) { - - box.setMaterial(mat2); - } else if (i < 1500) { - - box.setMaterial(mat3); - } else { - - box.setMaterial(mat4); - } - - } - } - -// public BatchNode randomBatch() { -// -// int randomn = rand.nextInt(4); -// if (randomn == 0) { -// return blue; -// } else if (randomn == 1) { -// return brown; -// } else if (randomn == 2) { -// return pink; -// } else if (randomn == 3) { -// return orange; -// } -// return null; -// } - public ColorRGBA randomColor() { - ColorRGBA color = ColorRGBA.Black; - int randomn = rand.nextInt(4); - if (randomn == 0) { - color = ColorRGBA.Orange; - } else if (randomn == 1) { - color = ColorRGBA.Blue; - } else if (randomn == 2) { - color = ColorRGBA.Brown; - } else if (randomn == 3) { - color = ColorRGBA.Magenta; - } - return color; - } - - public void randomize() { - int xpos = xPosition.get(xPosition.size() - 1); - int ypos = yPosition.get(yPosition.size() - 1); - int zpos = zPosition.get(zPosition.size() - 1); - int x = 0; - int y = 0; - int z = 0; - boolean unTrue = true; - while (unTrue) { - unTrue = false; - boolean xChanged = false; - x = 0; - y = 0; - z = 0; - if (xpos >= lineLength * 2) { - x = 2; - xChanged = true; - } else { - x = xPosition.get(xPosition.size() - 1) + 2; - } - if (xChanged) { - //y = yPosition.get(yPosition.size() - lineLength) + 2; - } else { - y = rand.nextInt(3); - if (yPosition.size() > lineLength) { - if (yPosition.size() > 51) { - if (y == 0 && ypos < yLimitf && getym(lineLength) > ypos - 2) { - y = ypos + 2; - } else if (y == 1 && ypos > yLimits && getym(lineLength) < ypos + 2) { - y = ypos - 2; - } else if (y == 2 && getym(lineLength) > ypos - 2 && getym(lineLength) < ypos + 2) { - y = ypos; - } else { - if (ypos >= yLimitf) { - y = ypos - 2; - } else if (ypos <= yLimits) { - y = ypos + 2; - } else if (y == 0 && getym(lineLength) >= ypos - 4) { - y = ypos - 2; - } else if (y == 0 && getym(lineLength) >= ypos - 2) { - y = ypos; - } else if (y == 1 && getym(lineLength) >= ypos + 4) { - y = ypos + 2; - } else if (y == 1 && getym(lineLength) >= ypos + 2) { - y = ypos; - } else if (y == 2 && getym(lineLength) <= ypos - 2) { - y = ypos - 2; - } else if (y == 2 && getym(lineLength) >= ypos + 2) { - y = ypos + 2; - } else { - System.out.println("wtf"); - } - } - } else if (yPosition.size() == lineLength) { - if (y == 0 && ypos < yLimitf) { - y = getym(lineLength) + 2; - } else if (y == 1 && ypos > yLimits) { - y = getym(lineLength) - 2; - } - } - } else { - if (y == 0 && ypos < yLimitf) { - y = ypos + 2; - } else if (y == 1 && ypos > yLimits) { - y = ypos - 2; - } else if (y == 2) { - y = ypos; - } else if (y == 0 && ypos >= yLimitf) { - y = ypos - 2; - } else if (y == 1 && ypos <= yLimits) { - y = ypos + 2; - } - } - } - if (xChanged) { - z = zpos + 2; - } else { - z = zpos; - } -// for (int i = 0; i < xPosition.size(); i++) -// { -// if (x - xPosition.get(i) <= 1 && x - xPosition.get(i) >= -1 && -// y - yPosition.get(i) <= 1 && y - yPosition.get(i) >= -1 -// &&z - zPosition.get(i) <= 1 && z - zPosition.get(i) >= -// -1) -// { -// unTrue = true; -// } -// } - } - xPosition.add(x); - yPosition.add(y); - zPosition.add(z); - } - - public int getxm(int i) { - return xPosition.get(xPosition.size() - i); - } - - public int getym(int i) { - return yPosition.get(yPosition.size() - i); - } - - public int getzm(int i) { - return zPosition.get(zPosition.size() - i); - } - - public int getx(int i) { - return xPosition.get(i); - } - - public int gety(int i) { - return yPosition.get(i); - } - - public int getz(int i) { - return zPosition.get(i); - } - private float time = 0; - - @Override - public void simpleUpdate(float tpf) { - time += tpf; - int random = rand.nextInt(2000); - float mult1 = 1.0f; - float mult2 = 1.0f; - if (random < 500) { - mult1 = 1.0f; - mult2 = 1.0f; - } else if (random < 1000) { - mult1 = -1.0f; - mult2 = 1.0f; - } else if (random < 1500) { - mult1 = 1.0f; - mult2 = -1.0f; - } else if (random <= 2000) { - mult1 = -1.0f; - mult2 = -1.0f; - } - Spatial box = batchNode.getChild("Box" + random); - if (box != null) { - Vector3f v = box.getLocalTranslation(); - box.setLocalTranslation(v.x + FastMath.sin(time * mult1) * 20, v.y + (FastMath.sin(time * mult1) * FastMath.cos(time * mult1) * 20), v.z + FastMath.cos(time * mult2) * 20); - } - terrain.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Y)); - - - } -} diff --git a/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java b/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java deleted file mode 100644 index 5f0e603fb5..0000000000 --- a/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.batching; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.font.BitmapText; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.BatchNode; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; -import com.jme3.shadow.CompareMode; -import com.jme3.shadow.DirectionalLightShadowFilter; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.system.AppSettings; -import com.jme3.system.NanoTimer; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import jme3test.bullet.BombControl; - -/** - * - * @author double1984 (tower mod by atom) - */ -public class TestBatchNodeTower extends SimpleApplication { - - final private int bricksPerLayer = 8; - final private int brickLayers = 30; - - final private static float brickWidth = .75f, brickHeight = .25f, brickDepth = .25f; - final private float radius = 3f; - private float angle = 0; - - - private Material mat; - private Material mat2; - private Material mat3; - private Sphere bullet; - private Box brick; - private SphereCollisionShape bulletCollisionShape; - - private BulletAppState bulletAppState; - final private BatchNode batchNode = new BatchNode("batch Node"); - - public static void main(String args[]) { - TestBatchNodeTower f = new TestBatchNodeTower(); - AppSettings s = new AppSettings(true); - f.setSettings(s); - f.start(); - } - - @Override - public void simpleInitApp() { - timer = new NanoTimer(); - bulletAppState = new BulletAppState(); - bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); - // bulletAppState.setEnabled(false); - stateManager.attach(bulletAppState); - bullet = new Sphere(32, 32, 0.4f, true, false); - bullet.setTextureMode(TextureMode.Projected); - bulletCollisionShape = new SphereCollisionShape(0.4f); - - brick = new Box(brickWidth, brickHeight, brickDepth); - brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); - initMaterial(); - initTower(); - initFloor(); - initCrossHairs(); - this.cam.setLocation(new Vector3f(0, 25f, 8f)); - cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0)); - cam.setFrustumFar(80); - inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "shoot"); - rootNode.setShadowMode(ShadowMode.Off); - - batchNode.batch(); - batchNode.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(batchNode); - - DirectionalLightShadowFilter shadowRenderer - = new DirectionalLightShadowFilter(assetManager, 1024, 2); - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - shadowRenderer.setLight(dl); - shadowRenderer.setLambda(0.55f); - shadowRenderer.setShadowIntensity(0.6f); - shadowRenderer.setShadowCompareMode(CompareMode.Hardware); - shadowRenderer.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(shadowRenderer); - viewPort.addProcessor(fpp); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - final private ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("shoot") && !keyPressed) { - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(mat2); - bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); - bulletGeometry.setLocalTranslation(cam.getLocation()); - RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); -// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); - bulletNode.setLinearVelocity(cam.getDirection().mult(25)); - bulletGeometry.addControl(bulletNode); - rootNode.attachChild(bulletGeometry); - getPhysicsSpace().add(bulletNode); - } - } - }; - - public void initTower() { - double tempX = 0; - double tempY = 0; - double tempZ = 0; - angle = 0f; - for (int i = 0; i < brickLayers; i++){ - // Increment rows - if (i != 0) { - tempY += brickHeight * 2; - } else { - tempY = brickHeight; - } - // Alternate brick seams - angle = 360.0f / bricksPerLayer * i/2f; - for (int j = 0; j < bricksPerLayer; j++){ - tempZ = Math.cos(Math.toRadians(angle))*radius; - tempX = Math.sin(Math.toRadians(angle))*radius; - System.out.println("x="+((float)(tempX))+" y="+((float)(tempY))+" z="+(float)(tempZ)); - Vector3f vt = new Vector3f((float)(tempX), (float)(tempY), (float)(tempZ)); - // Add crenelation - if (i==brickLayers-1){ - if (j%2 == 0){ - addBrick(vt); - } - } - // Create main tower - else { - addBrick(vt); - } - angle += 360.0/bricksPerLayer; - } - } - - } - - public void initFloor() { - Box floorBox = new Box(10f, 0.1f, 5f); - floorBox.scaleTextureCoordinates(new Vector2f(3, 6)); - - Geometry floor = new Geometry("floor", floorBox); - floor.setMaterial(mat3); - floor.setShadowMode(ShadowMode.Receive); - floor.setLocalTranslation(0, 0, 0); - floor.addControl(new RigidBodyControl(0)); - this.rootNode.attachChild(floor); - this.getPhysicsSpace().add(floor); - } - - public void initMaterial() { - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - mat.setTexture("ColorMap", tex); - - mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); - key2.setGenerateMips(true); - Texture tex2 = assetManager.loadTexture(key2); - mat2.setTexture("ColorMap", tex2); - - mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); - key3.setGenerateMips(true); - Texture tex3 = assetManager.loadTexture(key3); - tex3.setWrap(WrapMode.Repeat); - mat3.setTexture("ColorMap", tex3); - } - - public void addBrick(Vector3f ori) { - Geometry reBoxg = new Geometry("brick", brick); - reBoxg.setMaterial(mat); - reBoxg.setLocalTranslation(ori); - reBoxg.rotate(0f, (float)Math.toRadians(angle) , 0f ); - reBoxg.addControl(new RigidBodyControl(1.5f)); - reBoxg.setShadowMode(ShadowMode.CastAndReceive); - reBoxg.getControl(RigidBodyControl.class).setFriction(1.6f); - this.batchNode.attachChild(reBoxg); - this.getPhysicsSpace().add(reBoxg); - } - - protected void initCrossHairs() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, - settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); - guiNode.attachChild(ch); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/batching/package-info.java b/jme3-examples/src/main/java/jme3test/batching/package-info.java deleted file mode 100644 index 714fe0ab6e..0000000000 --- a/jme3-examples/src/main/java/jme3test/batching/package-info.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for batching multiple geometries into a - * single Mesh - */ -package jme3test.batching; diff --git a/jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java b/jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java deleted file mode 100644 index 839628407d..0000000000 --- a/jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.bounding; - -import com.jme3.bounding.BoundingBox; -import com.jme3.collision.CollisionResults; -import com.jme3.math.Ray; -import com.jme3.math.Vector3f; - -/** - * Tests picking/collision between bounds and shapes. - */ -public class TestRayCollision { - - public static void main(String[] args){ - Ray r = new Ray(Vector3f.ZERO, Vector3f.UNIT_X); - BoundingBox bbox = new BoundingBox(new Vector3f(5, 0, 0), 1, 1, 1); - - CollisionResults res = new CollisionResults(); - bbox.collideWith(r, res); - - System.out.println("Bounding:" +bbox); - System.out.println("Ray: "+r); - - System.out.println("Num collisions: "+res.size()); - for (int i = 0; i < res.size(); i++){ - System.out.println("--- Collision #"+i+" ---"); - float dist = res.getCollision(i).getDistance(); - Vector3f pt = res.getCollision(i).getContactPoint(); - System.out.println("distance: "+dist); - System.out.println("point: "+pt); - } - } - -} diff --git a/jme3-examples/src/main/java/jme3test/bounding/package-info.java b/jme3-examples/src/main/java/jme3test/bounding/package-info.java deleted file mode 100644 index 6e7428f082..0000000000 --- a/jme3-examples/src/main/java/jme3test/bounding/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for bounding volumes - */ -package jme3test.bounding; diff --git a/jme3-examples/src/main/java/jme3test/bullet/BombControl.java b/jme3-examples/src/main/java/jme3test/bullet/BombControl.java deleted file mode 100644 index 49f9a43982..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/BombControl.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.asset.AssetManager; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.PhysicsTickListener; -import com.jme3.bullet.collision.PhysicsCollisionEvent; -import com.jme3.bullet.collision.PhysicsCollisionListener; -import com.jme3.bullet.collision.PhysicsCollisionObject; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.objects.PhysicsGhostObject; -import com.jme3.bullet.objects.PhysicsRigidBody; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh.Type; -import com.jme3.effect.shapes.EmitterSphereShape; -import com.jme3.export.JmeExporter; -import com.jme3.export.JmeImporter; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import java.io.IOException; -import java.util.Iterator; - -/** - * - * @author normenhansen - */ -public class BombControl extends RigidBodyControl implements PhysicsCollisionListener, PhysicsTickListener { - - private float explosionRadius = 10; - private PhysicsGhostObject ghostObject; - final private Vector3f vector = new Vector3f(); - final private Vector3f vector2 = new Vector3f(); - private float forceFactor = 1; - private ParticleEmitter effect; - final private float fxTime = 0.5f; - final private float maxTime = 4f; - private float curTime = -1.0f; - private float timer; - - public BombControl(CollisionShape shape, float mass) { - super(shape, mass); - createGhostObject(); - } - - public BombControl(AssetManager manager, CollisionShape shape, float mass) { - super(shape, mass); - createGhostObject(); - prepareEffect(manager); - } - - @Override - public void setPhysicsSpace(PhysicsSpace space) { - super.setPhysicsSpace(space); - if (space != null) { - space.addCollisionListener(this); - } - } - - private void prepareEffect(AssetManager assetManager) { - int COUNT_FACTOR = 1; - float COUNT_FACTOR_F = 1f; - effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR); - effect.setSelectRandomImage(true); - effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (1f / COUNT_FACTOR_F))); - effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); - effect.setStartSize(1.3f); - effect.setEndSize(2f); - effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); - effect.setParticlesPerSec(0); - effect.setGravity(0, -5f, 0); - effect.setLowLife(.4f); - effect.setHighLife(.5f); - effect.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, 7, 0)); - effect.getParticleInfluencer().setVelocityVariation(1f); - effect.setImagesX(2); - effect.setImagesY(2); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); - effect.setMaterial(mat); - } - - protected void createGhostObject() { - ghostObject = new PhysicsGhostObject(new SphereCollisionShape(explosionRadius)); - } - - @Override - public void collision(PhysicsCollisionEvent event) { - if (space == null) { - return; - } - if (event.getObjectA() == this || event.getObjectB() == this) { - space.add(ghostObject); - ghostObject.setPhysicsLocation(getPhysicsLocation(vector)); - space.addTickListener(this); - if (effect != null && spatial.getParent() != null) { - curTime = 0; - effect.setLocalTranslation(spatial.getLocalTranslation()); - spatial.getParent().attachChild(effect); - effect.emitAllParticles(); - } - space.remove(this); - spatial.removeFromParent(); - } - } - - @Override - public void prePhysicsTick(PhysicsSpace space, float f) { - space.removeCollisionListener(this); - } - - @Override - public void physicsTick(PhysicsSpace space, float f) { - //get all overlapping objects and apply impulse to them - for (Iterator it = ghostObject.getOverlappingObjects().iterator(); it.hasNext();) { - PhysicsCollisionObject physicsCollisionObject = it.next(); - if (physicsCollisionObject instanceof PhysicsRigidBody) { - PhysicsRigidBody rBody = (PhysicsRigidBody) physicsCollisionObject; - rBody.getPhysicsLocation(vector2); - vector2.subtractLocal(vector); - float force = explosionRadius - vector2.length(); - force *= forceFactor; - force = force > 0 ? force : 0; - vector2.normalizeLocal(); - vector2.multLocal(force); - ((PhysicsRigidBody) physicsCollisionObject).applyImpulse(vector2, Vector3f.ZERO); - } - } - space.removeTickListener(this); - space.remove(ghostObject); - } - - @Override - public void update(float tpf) { - super.update(tpf); - if(enabled){ - timer+=tpf; - if(timer>maxTime){ - if(spatial.getParent()!=null){ - space.removeCollisionListener(this); - space.remove(this); - spatial.removeFromParent(); - } - } - } - if (enabled && curTime >= 0) { - curTime += tpf; - if (curTime > fxTime) { - curTime = -1; - effect.removeFromParent(); - } - } - } - - /** - * @return the explosionRadius - */ - public float getExplosionRadius() { - return explosionRadius; - } - - /** - * @param explosionRadius the explosionRadius to set - */ - public void setExplosionRadius(float explosionRadius) { - this.explosionRadius = explosionRadius; - createGhostObject(); - } - - public float getForceFactor() { - return forceFactor; - } - - public void setForceFactor(float forceFactor) { - this.forceFactor = forceFactor; - } - - - @Override - public void read(JmeImporter im) throws IOException { - throw new UnsupportedOperationException("Reading not supported."); - } - - @Override - public void write(JmeExporter ex) throws IOException { - throw new UnsupportedOperationException("Saving not supported."); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java b/jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java deleted file mode 100644 index 8f38323d26..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.PhysicsTickListener; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.PhysicsControl; -import com.jme3.bullet.objects.PhysicsVehicle; -import com.jme3.export.InputCapsule; -import com.jme3.export.JmeExporter; -import com.jme3.export.JmeImporter; -import com.jme3.export.OutputCapsule; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Spatial; -import com.jme3.scene.control.Control; -import com.jme3.util.clone.Cloner; -import com.jme3.util.clone.JmeCloneable; -import java.io.IOException; - -/** - * PhysicsHoverControl uses a RayCast Vehicle with "slippery wheels" to simulate a hovering tank - * @author normenhansen - */ -public class PhysicsHoverControl extends PhysicsVehicle implements PhysicsControl, PhysicsTickListener, JmeCloneable { - - protected Spatial spatial; - protected boolean enabled = true; - protected PhysicsSpace space = null; - protected float steeringValue = 0; - protected float accelerationValue = 0; - protected int xw = 3; - protected int zw = 5; - protected int yw = 2; - protected Vector3f HOVER_HEIGHT_LF_START = new Vector3f(xw, 1, zw); - protected Vector3f HOVER_HEIGHT_RF_START = new Vector3f(-xw, 1, zw); - protected Vector3f HOVER_HEIGHT_LR_START = new Vector3f(xw, 1, -zw); - protected Vector3f HOVER_HEIGHT_RR_START = new Vector3f(-xw, 1, -zw); - protected Vector3f HOVER_HEIGHT_LF = new Vector3f(xw, -yw, zw); - protected Vector3f HOVER_HEIGHT_RF = new Vector3f(-xw, -yw, zw); - protected Vector3f HOVER_HEIGHT_LR = new Vector3f(xw, -yw, -zw); - protected Vector3f HOVER_HEIGHT_RR = new Vector3f(-xw, -yw, -zw); - protected Vector3f tempVect1 = new Vector3f(0, 0, 0); - protected Vector3f tempVect2 = new Vector3f(0, 0, 0); - protected Vector3f tempVect3 = new Vector3f(0, 0, 0); -// protected float rotationCounterForce = 10000f; -// protected float speedCounterMult = 2000f; -// protected float multiplier = 1000f; - - public PhysicsHoverControl() { - } - - /** - * Creates a new PhysicsNode with the supplied collision shape - * @param shape the desired collision shape - */ - public PhysicsHoverControl(CollisionShape shape) { - super(shape); - createWheels(); - } - - public PhysicsHoverControl(CollisionShape shape, float mass) { - super(shape, mass); - createWheels(); - } - - @Deprecated - @Override - public Control cloneForSpatial(Spatial spatial) { - throw new UnsupportedOperationException(); - } - - @Override - public Object jmeClone() { - throw new UnsupportedOperationException("Not yet implemented."); - } - - @Override - public void cloneFields( Cloner cloner, Object original ) { - throw new UnsupportedOperationException("Not yet implemented."); - } - - @Override - public void setSpatial(Spatial spatial) { - this.spatial = spatial; - setUserObject(spatial); - if (spatial == null) { - return; - } - setPhysicsLocation(spatial.getWorldTranslation()); - setPhysicsRotation(spatial.getWorldRotation().toRotationMatrix()); - } - - @Override - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - public boolean isEnabled() { - return enabled; - } - - private void createWheels() { - addWheel(HOVER_HEIGHT_LF_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); - addWheel(HOVER_HEIGHT_RF_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); - addWheel(HOVER_HEIGHT_LR_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); - addWheel(HOVER_HEIGHT_RR_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); - for (int i = 0; i < 4; i++) { - getWheel(i).setFrictionSlip(0.001f); - } - } - - @Override - public void prePhysicsTick(PhysicsSpace space, float f) { - Vector3f angVel = getAngularVelocity(); - float rotationVelocity = angVel.getY(); - Vector3f dir = getForwardVector(tempVect2).multLocal(1, 0, 1).normalizeLocal(); - getLinearVelocity(tempVect3); - Vector3f linearVelocity = tempVect3.multLocal(1, 0, 1); - float groundSpeed = linearVelocity.length(); - - if (steeringValue != 0) { - if (rotationVelocity < 1 && rotationVelocity > -1) { - applyTorque(tempVect1.set(0, steeringValue, 0)); - } - } else { - // counter the steering value! - if (rotationVelocity > 0.2f) { - applyTorque(tempVect1.set(0, -mass * 20, 0)); - } else if (rotationVelocity < -0.2f) { - applyTorque(tempVect1.set(0, mass * 20, 0)); - } - } - if (accelerationValue > 0) { - // counter force that will adjust velocity - // if we are not going where we want to go. - // this will prevent "drifting" and thus improve control - // of the vehicle - if (groundSpeed > FastMath.ZERO_TOLERANCE) { - float d = dir.dot(linearVelocity.normalize()); - Vector3f counter = dir.project(linearVelocity).normalizeLocal().negateLocal().multLocal(1 - d); - applyForce(counter.multLocal(mass * 10), Vector3f.ZERO); - } - - if (linearVelocity.length() < 30) { - applyForce(dir.multLocal(accelerationValue), Vector3f.ZERO); - } - } else { - // counter the acceleration value - if (groundSpeed > FastMath.ZERO_TOLERANCE) { - linearVelocity.normalizeLocal().negateLocal(); - applyForce(linearVelocity.mult(mass * 10), Vector3f.ZERO); - } - } - } - - @Override - public void physicsTick(PhysicsSpace space, float f) { - } - - @Override - public void update(float tpf) { - if (enabled && spatial != null) { - getMotionState().applyTransform(spatial); - } - } - - @Override - public void render(RenderManager rm, ViewPort vp) { - } - - @Override - public void setPhysicsSpace(PhysicsSpace space) { - createVehicle(space); - if (space == null) { - if (this.space != null) { - this.space.removeCollisionObject(this); - this.space.removeTickListener(this); - } - this.space = space; - } else { - space.addCollisionObject(this); - space.addTickListener(this); - } - this.space = space; - } - - @Override - public PhysicsSpace getPhysicsSpace() { - return space; - } - - @Override - public void write(JmeExporter ex) throws IOException { - super.write(ex); - OutputCapsule oc = ex.getCapsule(this); - oc.write(enabled, "enabled", true); - oc.write(spatial, "spatial", null); - } - - @Override - public void read(JmeImporter im) throws IOException { - super.read(im); - InputCapsule ic = im.getCapsule(this); - enabled = ic.readBoolean("enabled", true); - spatial = (Spatial) ic.readSavable("spatial", null); - } - - /** - * @param steeringValue the steeringValue to set - */ - @Override - public void steer(float steeringValue) { - this.steeringValue = steeringValue * getMass(); - } - - /** - * @param accelerationValue the accelerationValue to set - */ - @Override - public void accelerate(float accelerationValue) { - this.accelerationValue = accelerationValue * getMass(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java b/jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java deleted file mode 100644 index 59d02d64c8..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.Application; -import com.jme3.asset.AssetManager; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.collision.shapes.GImpactCollisionShape; -import com.jme3.bullet.collision.shapes.MeshCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; -import com.jme3.texture.Texture; -import com.jme3.util.BufferUtils; - -/** - * - * @author normenhansen - */ -public class PhysicsTestHelper { - /** - * A private constructor to inhibit instantiation of this class. - */ - private PhysicsTestHelper() { - } - - /** - * creates a simple physics test world with a floor, an obstacle and some test boxes - * - * @param rootNode where lights and geometries should be added - * @param assetManager for loading assets - * @param space where collision objects should be added - */ - public static void createPhysicsTestWorld(Node rootNode, AssetManager assetManager, PhysicsSpace space) { - AmbientLight light = new AmbientLight(); - light.setColor(ColorRGBA.LightGray); - rootNode.addLight(light); - - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - - Box floorBox = new Box(140, 0.25f, 140); - Geometry floorGeometry = new Geometry("Floor", floorBox); - floorGeometry.setMaterial(material); - floorGeometry.setLocalTranslation(0, -5, 0); -// Plane plane = new Plane(); -// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y); -// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0)); - floorGeometry.addControl(new RigidBodyControl(0)); - rootNode.attachChild(floorGeometry); - space.add(floorGeometry); - - //movable boxes - for (int i = 0; i < 12; i++) { - Box box = new Box(0.25f, 0.25f, 0.25f); - Geometry boxGeometry = new Geometry("Box", box); - boxGeometry.setMaterial(material); - boxGeometry.setLocalTranslation(i, 5, -3); - //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh - boxGeometry.addControl(new RigidBodyControl(2)); - rootNode.attachChild(boxGeometry); - space.add(boxGeometry); - } - - //immovable sphere with mesh collision shape - Sphere sphere = new Sphere(8, 8, 1); - Geometry sphereGeometry = new Geometry("Sphere", sphere); - sphereGeometry.setMaterial(material); - sphereGeometry.setLocalTranslation(4, -4, 2); - sphereGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0)); - rootNode.attachChild(sphereGeometry); - space.add(sphereGeometry); - - } - - public static void createPhysicsTestWorldSoccer(Node rootNode, AssetManager assetManager, PhysicsSpace space) { - AmbientLight light = new AmbientLight(); - light.setColor(ColorRGBA.LightGray); - rootNode.addLight(light); - - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - - Box floorBox = new Box(20, 0.25f, 20); - Geometry floorGeometry = new Geometry("Floor", floorBox); - floorGeometry.setMaterial(material); - floorGeometry.setLocalTranslation(0, -0.25f, 0); -// Plane plane = new Plane(); -// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y); -// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0)); - floorGeometry.addControl(new RigidBodyControl(0)); - rootNode.attachChild(floorGeometry); - space.add(floorGeometry); - - //movable spheres - for (int i = 0; i < 5; i++) { - Sphere sphere = new Sphere(16, 16, .5f); - Geometry ballGeometry = new Geometry("Soccer ball", sphere); - ballGeometry.setMaterial(material); - ballGeometry.setLocalTranslation(i, 2, -3); - //RigidBodyControl automatically uses Sphere collision shapes when attached to single geometry with sphere mesh - ballGeometry.addControl(new RigidBodyControl(.001f)); - ballGeometry.getControl(RigidBodyControl.class).setRestitution(1); - rootNode.attachChild(ballGeometry); - space.add(ballGeometry); - } - { - //immovable Box with mesh collision shape - Box box = new Box(1, 1, 1); - Geometry boxGeometry = new Geometry("Box", box); - boxGeometry.setMaterial(material); - boxGeometry.setLocalTranslation(4, 1, 2); - boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0)); - rootNode.attachChild(boxGeometry); - space.add(boxGeometry); - } - { - //immovable Box with mesh collision shape - Box box = new Box(1, 1, 1); - Geometry boxGeometry = new Geometry("Box", box); - boxGeometry.setMaterial(material); - boxGeometry.setLocalTranslation(4, 3, 4); - boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0)); - rootNode.attachChild(boxGeometry); - space.add(boxGeometry); - } - } - - /** - * creates a box geometry with a RigidBodyControl - * - * @param assetManager for loading assets - * @return a new Geometry - */ - public static Geometry createPhysicsTestBox(AssetManager assetManager) { - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Box box = new Box(0.25f, 0.25f, 0.25f); - Geometry boxGeometry = new Geometry("Box", box); - boxGeometry.setMaterial(material); - //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh - boxGeometry.addControl(new RigidBodyControl(2)); - return boxGeometry; - } - - /** - * creates a sphere geometry with a RigidBodyControl - * - * @param assetManager for loading assets - * @return a new Geometry - */ - public static Geometry createPhysicsTestSphere(AssetManager assetManager) { - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Sphere sphere = new Sphere(8, 8, 0.25f); - Geometry boxGeometry = new Geometry("Sphere", sphere); - boxGeometry.setMaterial(material); - //RigidBodyControl automatically uses sphere collision shapes when attached to single geometry with sphere mesh - boxGeometry.addControl(new RigidBodyControl(2)); - return boxGeometry; - } - - /** - * creates an empty node with a RigidBodyControl - * - * @param manager for loading assets - * @param shape a shape for the collision object - * @param mass a mass for rigid body - * @return a new Node - */ - public static Node createPhysicsTestNode(AssetManager manager, CollisionShape shape, float mass) { - Node node = new Node("PhysicsNode"); - RigidBodyControl control = new RigidBodyControl(shape, mass); - node.addControl(control); - return node; - } - - /** - * creates the necessary input listener and action to shoot balls from the camera - * - * @param app the application that's running - * @param rootNode where ball geometries should be added - * @param space where collision objects should be added - */ - public static void createBallShooter(final Application app, final Node rootNode, final PhysicsSpace space) { - ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - Sphere bullet = new Sphere(32, 32, 0.4f, true, false); - bullet.setTextureMode(TextureMode.Projected); - Material mat2 = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); - key2.setGenerateMips(true); - Texture tex2 = app.getAssetManager().loadTexture(key2); - mat2.setTexture("ColorMap", tex2); - if (name.equals("shoot") && !keyPressed) { - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(mat2); - bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); - bulletGeometry.setLocalTranslation(app.getCamera().getLocation()); - RigidBodyControl bulletControl = new RigidBodyControl(10); - bulletGeometry.addControl(bulletControl); - bulletControl.setLinearVelocity(app.getCamera().getDirection().mult(25)); - bulletGeometry.addControl(bulletControl); - rootNode.attachChild(bulletGeometry); - space.add(bulletControl); - } - } - }; - app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - app.getInputManager().addListener(actionListener, "shoot"); - } - - /** - * Creates a curved "floor" with a GImpactCollisionShape provided as the RigidBodyControl's collision - * shape. Surface has four slightly concave corners to allow for multiple tests and minimize falling off - * the edge of the floor. - * - * @param assetManager for loading assets - * @param floorDimensions width/depth of the "floor" (X/Z) - * @param position sets the floor's local translation - * @return a new Geometry - */ - public static Geometry createGImpactTestFloor(AssetManager assetManager, float floorDimensions, Vector3f position) { - Geometry floor = createTestFloor(assetManager, floorDimensions, position, ColorRGBA.Red); - RigidBodyControl floorControl = new RigidBodyControl(new GImpactCollisionShape(floor.getMesh()), 0); - floor.addControl(floorControl); - return floor; - } - - /** - * Creates a curved "floor" with a MeshCollisionShape provided as the RigidBodyControl's collision shape. - * Surface has four slightly concave corners to allow for multiple tests and minimize falling off the edge - * of the floor. - * - * @param assetManager for loading assets - * @param floorDimensions width/depth of the "floor" (X/Z) - * @param position sets the floor's local translation - * @return a new Geometry - */ - public static Geometry createMeshTestFloor(AssetManager assetManager, float floorDimensions, Vector3f position) { - Geometry floor = createTestFloor(assetManager, floorDimensions, position, new ColorRGBA(0.5f, 0.5f, 0.9f, 1)); - RigidBodyControl floorControl = new RigidBodyControl(new MeshCollisionShape(floor.getMesh()), 0); - floor.addControl(floorControl); - return floor; - } - - private static Geometry createTestFloor(AssetManager assetManager, float floorDimensions, Vector3f position, ColorRGBA color) { - Geometry floor = new Geometry("floor", createFloorMesh(20, floorDimensions)); - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.getAdditionalRenderState().setWireframe(true); - material.setColor("Color", color); - floor.setMaterial(material); - floor.setLocalTranslation(position); - return floor; - } - - private static Mesh createFloorMesh(int meshDetail, float floorDimensions) { - if (meshDetail < 10) { - meshDetail = 10; - } - int numVertices = meshDetail * meshDetail * 2 * 3;//width * depth * two tris * 3 verts per tri - - int[] indexBuf = new int[numVertices]; - int i = 0; - for (int x = 0; x < meshDetail; x++) { - for (int z = 0; z < meshDetail; z++) { - indexBuf[i] = i++; - indexBuf[i] = i++; - indexBuf[i] = i++; - indexBuf[i] = i++; - indexBuf[i] = i++; - indexBuf[i] = i++; - } - } - - float[] vertBuf = new float[numVertices * 3]; - float xIncrement = floorDimensions / meshDetail; - float zIncrement = floorDimensions / meshDetail; - int j = 0; - for (int x = 0; x < meshDetail; x++) { - float xPos = x * xIncrement; - for (int z = 0; z < meshDetail; z++) { - float zPos = z * zIncrement; - //First tri - vertBuf[j++] = xPos; - vertBuf[j++] = getY(xPos, zPos, floorDimensions); - vertBuf[j++] = zPos; - vertBuf[j++] = xPos; - vertBuf[j++] = getY(xPos, zPos + zIncrement, floorDimensions); - vertBuf[j++] = zPos + zIncrement; - vertBuf[j++] = xPos + xIncrement; - vertBuf[j++] = getY(xPos + xIncrement, zPos, floorDimensions); - vertBuf[j++] = zPos; - //Second tri - vertBuf[j++] = xPos; - vertBuf[j++] = getY(xPos, zPos + zIncrement, floorDimensions); - vertBuf[j++] = zPos + zIncrement; - vertBuf[j++] = xPos + xIncrement; - vertBuf[j++] = getY(xPos + xIncrement, zPos + zIncrement, floorDimensions); - vertBuf[j++] = zPos + zIncrement; - vertBuf[j++] = xPos + xIncrement; - vertBuf[j++] = getY(xPos + xIncrement, zPos, floorDimensions); - vertBuf[j++] = zPos; - } - } - - Mesh m = new Mesh(); - m.setBuffer(VertexBuffer.Type.Index, 1, BufferUtils.createIntBuffer(indexBuf)); - m.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertBuf)); - m.updateBound(); - return m; - } - - private static float getY(float x, float z, float max) { - float yMaxHeight = 8; - float xv = FastMath.unInterpolateLinear(FastMath.abs(x - (max / 2)), 0, max) * FastMath.TWO_PI; - float zv = FastMath.unInterpolateLinear(FastMath.abs(z - (max / 2)), 0, max) * FastMath.TWO_PI; - - float xComp = (FastMath.sin(xv) + 1) * 0.5f; - float zComp = (FastMath.sin(zv) + 1) * 0.5f; - - return -yMaxHeight * xComp * zComp; - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java b/jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java deleted file mode 100644 index 8c1c712603..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ - -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.CompoundCollisionShape; -import com.jme3.bullet.collision.shapes.MeshCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.control.VehicleControl; -import com.jme3.bullet.joints.SliderJoint; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Cylinder; -import com.jme3.texture.Texture; - -/** - * Tests attaching/detaching nodes via joints - * @author normenhansen - */ -public class TestAttachDriver extends SimpleApplication implements ActionListener { - - private VehicleControl vehicle; - private RigidBodyControl bridge; - private SliderJoint slider; - private final float accelerationForce = 1000.0f; - private final float brakeForce = 100.0f; - private float steeringValue = 0; - private float accelerationValue = 0; - final private Vector3f jumpForce = new Vector3f(0, 3000, 0); - private BulletAppState bulletAppState; - - public static void main(String[] args) { - TestAttachDriver app = new TestAttachDriver(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - setupKeys(); - setupFloor(); - buildPlayer(); - } - - private PhysicsSpace getPhysicsSpace(){ - return bulletAppState.getPhysicsSpace(); - } - - private void setupKeys() { - inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addListener(this, "Lefts"); - inputManager.addListener(this, "Rights"); - inputManager.addListener(this, "Ups"); - inputManager.addListener(this, "Downs"); - inputManager.addListener(this, "Space"); - inputManager.addListener(this, "Reset"); - } - - public void setupFloor() { - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key = new TextureKey("Interface/Logo/Monkey.jpg", true); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - tex.setMinFilter(Texture.MinFilter.Trilinear); - mat.setTexture("ColorMap", tex); - - Box floor = new Box(100, 1f, 100); - Geometry floorGeom = new Geometry("Floor", floor); - floorGeom.setMaterial(mat); - floorGeom.setLocalTranslation(new Vector3f(0f, -3, 0f)); - - floorGeom.addControl(new RigidBodyControl(new MeshCollisionShape(floorGeom.getMesh()), 0)); - rootNode.attachChild(floorGeom); - getPhysicsSpace().add(floorGeom); - } - - private void buildPlayer() { - Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - mat.getAdditionalRenderState().setWireframe(true); - mat.setColor("Color", ColorRGBA.Red); - - //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0 - //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0 - CompoundCollisionShape compoundShape = new CompoundCollisionShape(); - BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f)); - compoundShape.addChildShape(box, new Vector3f(0, 1, 0)); - - //create vehicle node - Node vehicleNode=new Node("vehicleNode"); - vehicle = new VehicleControl(compoundShape, 800); - vehicleNode.addControl(vehicle); - - //setting suspension values for wheels, this can be a bit tricky - //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en - float stiffness = 60.0f;//200=f1 car - float compValue = .3f; //(should be lower than damp) - float dampValue = .4f; - vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); - vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); - vehicle.setSuspensionStiffness(stiffness); - vehicle.setMaxSuspensionForce(10000.0f); - - //Create four wheels and add them at their locations - Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0 - Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0 - float radius = 0.5f; - float restLength = 0.3f; - float yOff = 0.5f; - float xOff = 1f; - float zOff = 2f; - - Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true); - - Node node1 = new Node("wheel 1 node"); - Geometry wheels1 = new Geometry("wheel 1", wheelMesh); - node1.attachChild(wheels1); - wheels1.rotate(0, FastMath.HALF_PI, 0); - wheels1.setMaterial(mat); - vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff), - wheelDirection, wheelAxle, restLength, radius, true); - - Node node2 = new Node("wheel 2 node"); - Geometry wheels2 = new Geometry("wheel 2", wheelMesh); - node2.attachChild(wheels2); - wheels2.rotate(0, FastMath.HALF_PI, 0); - wheels2.setMaterial(mat); - vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff), - wheelDirection, wheelAxle, restLength, radius, true); - - Node node3 = new Node("wheel 3 node"); - Geometry wheels3 = new Geometry("wheel 3", wheelMesh); - node3.attachChild(wheels3); - wheels3.rotate(0, FastMath.HALF_PI, 0); - wheels3.setMaterial(mat); - vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff), - wheelDirection, wheelAxle, restLength, radius, false); - - Node node4 = new Node("wheel 4 node"); - Geometry wheels4 = new Geometry("wheel 4", wheelMesh); - node4.attachChild(wheels4); - wheels4.rotate(0, FastMath.HALF_PI, 0); - wheels4.setMaterial(mat); - vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff), - wheelDirection, wheelAxle, restLength, radius, false); - - vehicleNode.attachChild(node1); - vehicleNode.attachChild(node2); - vehicleNode.attachChild(node3); - vehicleNode.attachChild(node4); - - rootNode.attachChild(vehicleNode); - getPhysicsSpace().add(vehicle); - - //driver - Node driverNode=new Node("driverNode"); - driverNode.setLocalTranslation(0,2,0); - RigidBodyControl driver - = new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,.5f,0.2f))); - driverNode.addControl(driver); - - rootNode.attachChild(driverNode); - getPhysicsSpace().add(driver); - - //joint - slider=new SliderJoint(driver, vehicle, Vector3f.UNIT_Y.negate(), Vector3f.UNIT_Y, true); - slider.setUpperLinLimit(.1f); - slider.setLowerLinLimit(-.1f); - - getPhysicsSpace().add(slider); - - Node pole1Node=new Node("pole1Node"); - Node pole2Node=new Node("pole1Node"); - Node bridgeNode=new Node("pole1Node"); - pole1Node.setLocalTranslation(new Vector3f(-2,-1,4)); - pole2Node.setLocalTranslation(new Vector3f(2,-1,4)); - bridgeNode.setLocalTranslation(new Vector3f(0,1.4f,4)); - - RigidBodyControl pole1=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0); - pole1Node.addControl(pole1); - RigidBodyControl pole2=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0); - pole2Node.addControl(pole2); - bridge=new RigidBodyControl(new BoxCollisionShape(new Vector3f(2.5f,0.2f,0.2f))); - bridgeNode.addControl(bridge); - - rootNode.attachChild(pole1Node); - rootNode.attachChild(pole2Node); - rootNode.attachChild(bridgeNode); - getPhysicsSpace().add(pole1); - getPhysicsSpace().add(pole2); - getPhysicsSpace().add(bridge); - - } - - @Override - public void simpleUpdate(float tpf) { - Quaternion quat=new Quaternion(); - cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Lefts")) { - if (value) { - steeringValue += .5f; - } else { - steeringValue -= .5f; - } - vehicle.steer(steeringValue); - } else if (binding.equals("Rights")) { - if (value) { - steeringValue -= .5f; - } else { - steeringValue += .5f; - } - vehicle.steer(steeringValue); - } else if (binding.equals("Ups")) { - if (value) { - accelerationValue += accelerationForce; - } else { - accelerationValue -= accelerationForce; - } - vehicle.accelerate(accelerationValue); - } else if (binding.equals("Downs")) { - if (value) { - vehicle.brake(brakeForce); - } else { - vehicle.brake(0f); - } - } else if (binding.equals("Space")) { - if (value) { - if (slider != null) { - getPhysicsSpace().remove(slider); - slider.destroy(); - slider = null; - } - vehicle.applyImpulse(jumpForce, Vector3f.ZERO); - } - } else if (binding.equals("Reset")) { - if (value) { - System.out.println("Reset"); - vehicle.setPhysicsLocation(new Vector3f(0, 0, 0)); - vehicle.setPhysicsRotation(new Matrix3f()); - vehicle.setLinearVelocity(Vector3f.ZERO); - vehicle.setAngularVelocity(Vector3f.ZERO); - vehicle.resetSuspension(); - bridge.setPhysicsLocation(new Vector3f(0,1.4f,4)); - bridge.setPhysicsRotation(Matrix3f.IDENTITY); - bridge.setLinearVelocity(Vector3f.ZERO); - bridge.setAngularVelocity(Vector3f.ZERO); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java b/jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java deleted file mode 100644 index f722899363..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.GhostControl; -import com.jme3.bullet.control.PhysicsControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.joints.HingeJoint; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; - -/** - * Tests attaching ghost nodes to physics nodes via the scene graph - * @author normenhansen - */ -public class TestAttachGhostObject extends SimpleApplication implements AnalogListener { - - private HingeJoint joint; - private GhostControl ghostControl; - private Node collisionNode; - private BulletAppState bulletAppState; - - public static void main(String[] args) { - TestAttachGhostObject app = new TestAttachGhostObject(); - app.start(); - } - - private void setupKeys() { - inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this, "Lefts", "Rights", "Space"); - } - - @Override - public void onAnalog(String binding, float value, float tpf) { - if (binding.equals("Lefts")) { - joint.enableMotor(true, 1, .1f); - } else if (binding.equals("Rights")) { - joint.enableMotor(true, -1, .1f); - } else if (binding.equals("Space")) { - joint.enableMotor(false, 0, 0); - } - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - setupKeys(); - setupJoint(); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - public void setupJoint() { - Node holderNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.1f, .1f, .1f)), 0); - holderNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, 0, 0f)); - rootNode.attachChild(holderNode); - getPhysicsSpace().add(holderNode); - - Node hammerNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.3f, .3f, .3f)), 1); - hammerNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -1, 0f)); - rootNode.attachChild(hammerNode); - getPhysicsSpace().add(hammerNode); - - //immovable - collisionNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.3f, .3f, .3f)), 0); - collisionNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(1.8f, 0, 0f)); - rootNode.attachChild(collisionNode); - getPhysicsSpace().add(collisionNode); - - //ghost node - ghostControl = new GhostControl(new SphereCollisionShape(0.7f)); - - hammerNode.addControl(ghostControl); - getPhysicsSpace().add(ghostControl); - - joint = new HingeJoint(holderNode.getControl(RigidBodyControl.class), hammerNode.getControl(RigidBodyControl.class), Vector3f.ZERO, new Vector3f(0f, -1, 0f), Vector3f.UNIT_Z, Vector3f.UNIT_Z); - getPhysicsSpace().add(joint); - } - - @Override - public void simpleUpdate(float tpf) { - if (ghostControl.getOverlappingObjects().contains(collisionNode.getControl(PhysicsControl.class))) { - fpsText.setText("collide"); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java b/jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java deleted file mode 100644 index 25065c484b..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.MeshCollisionShape; -import com.jme3.bullet.control.BetterCharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.scene.CameraNode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.CameraControl.ControlDirection; -import com.jme3.scene.shape.Sphere; -import com.jme3.system.AppSettings; - -/** - * A walking physical character followed by a 3rd person camera. (No animation.) - * - * @author normenhansen, zathras - */ -public class TestBetterCharacter extends SimpleApplication implements ActionListener { - - private BulletAppState bulletAppState; - private BetterCharacterControl physicsCharacter; - private Node characterNode; - private CameraNode camNode; - final private Vector3f walkDirection = new Vector3f(0, 0, 0); - final private Vector3f viewDirection = new Vector3f(0, 0, 1); - private boolean leftStrafe = false, rightStrafe = false, forward = false, backward = false, - leftRotate = false, rightRotate = false; - final private Vector3f normalGravity = new Vector3f(0, -9.81f, 0); - private Geometry planet; - - public static void main(String[] args) { - TestBetterCharacter app = new TestBetterCharacter(); - AppSettings settings = new AppSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL2); - settings.setAudioRenderer(AppSettings.LWJGL_OPENAL); - app.setSettings(settings); - app.start(); - } - - @Override - public void simpleInitApp() { - //setup keyboard mapping - setupKeys(); - - // activate physics - bulletAppState = new BulletAppState() { - @Override - public void prePhysicsTick(PhysicsSpace space, float tpf) { - // Apply radial gravity near the planet, downward gravity elsewhere. - checkPlanetGravity(); - } - }; - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - - // init a physics test scene - PhysicsTestHelper.createPhysicsTestWorldSoccer(rootNode, assetManager, bulletAppState.getPhysicsSpace()); - PhysicsTestHelper.createBallShooter(this, rootNode, bulletAppState.getPhysicsSpace()); - setupPlanet(); - - // Create a node for the character model - characterNode = new Node("character node"); - characterNode.setLocalTranslation(new Vector3f(4, 5, 2)); - - // Add a character control to the node, so we can add other things and - // control the model rotation. - physicsCharacter = new BetterCharacterControl(0.3f, 2.5f, 8f); - characterNode.addControl(physicsCharacter); - getPhysicsSpace().add(physicsCharacter); - - // Load model, attach to character node - Node model = (Node) assetManager.loadModel("Models/Jaime/Jaime.j3o"); - model.setLocalScale(1.50f); - characterNode.attachChild(model); - - // Add character node to the rootNode - rootNode.attachChild(characterNode); - - cam.setLocation(new Vector3f(10f, 6f, -5f)); - - // Set forward camera node that follows the character, only used when - // view is "locked" - camNode = new CameraNode("CamNode", cam); - camNode.setControlDir(ControlDirection.SpatialToCamera); - camNode.setLocalTranslation(new Vector3f(0, 2, -6)); - Quaternion quat = new Quaternion(); - // These coordinates are local, the camNode is attached to the character node! - quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y); - camNode.setLocalRotation(quat); - characterNode.attachChild(camNode); - // Disable by default, can be enabled via keyboard shortcut - camNode.setEnabled(false); - } - - @Override - public void simpleUpdate(float tpf) { - // Get current forward and left vectors of model by using its rotation - // to rotate the unit vectors - Vector3f modelForwardDir = characterNode.getWorldRotation().mult(Vector3f.UNIT_Z); - Vector3f modelLeftDir = characterNode.getWorldRotation().mult(Vector3f.UNIT_X); - - // WalkDirection is global! - // You *can* make your character fly with this. - walkDirection.set(0, 0, 0); - if (leftStrafe) { - walkDirection.addLocal(modelLeftDir.mult(3)); - } else if (rightStrafe) { - walkDirection.addLocal(modelLeftDir.negate().multLocal(3)); - } - if (forward) { - walkDirection.addLocal(modelForwardDir.mult(3)); - } else if (backward) { - walkDirection.addLocal(modelForwardDir.negate().multLocal(3)); - } - physicsCharacter.setWalkDirection(walkDirection); - - // ViewDirection is local to characters physics system! - // The final world rotation depends on the gravity and on the state of - // setApplyPhysicsLocal() - if (leftRotate) { - Quaternion rotateL = new Quaternion().fromAngleAxis(FastMath.PI * tpf, Vector3f.UNIT_Y); - rotateL.multLocal(viewDirection); - } else if (rightRotate) { - Quaternion rotateR = new Quaternion().fromAngleAxis(-FastMath.PI * tpf, Vector3f.UNIT_Y); - rotateR.multLocal(viewDirection); - } - physicsCharacter.setViewDirection(viewDirection); - fpsText.setText("Touch da ground = " + physicsCharacter.isOnGround()); - if (!lockView) { - cam.lookAt(characterNode.getWorldTranslation().add(new Vector3f(0, 2, 0)), Vector3f.UNIT_Y); - } - } - - private void setupPlanet() { - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - //immovable sphere with mesh collision shape - Sphere sphere = new Sphere(64, 64, 20); - planet = new Geometry("Sphere", sphere); - planet.setMaterial(material); - planet.setLocalTranslation(30, -15, 30); - planet.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0)); - rootNode.attachChild(planet); - getPhysicsSpace().add(planet); - } - - private void checkPlanetGravity() { - Vector3f planetDist = planet.getWorldTranslation().subtract(characterNode.getWorldTranslation()); - if (planetDist.length() < 24) { - physicsCharacter.setGravity(planetDist.normalizeLocal().multLocal(9.81f)); - } else { - physicsCharacter.setGravity(normalGravity); - } - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Strafe Left")) { - if (value) { - leftStrafe = true; - } else { - leftStrafe = false; - } - } else if (binding.equals("Strafe Right")) { - if (value) { - rightStrafe = true; - } else { - rightStrafe = false; - } - } else if (binding.equals("Rotate Left")) { - if (value) { - leftRotate = true; - } else { - leftRotate = false; - } - } else if (binding.equals("Rotate Right")) { - if (value) { - rightRotate = true; - } else { - rightRotate = false; - } - } else if (binding.equals("Walk Forward")) { - if (value) { - forward = true; - } else { - forward = false; - } - } else if (binding.equals("Walk Backward")) { - if (value) { - backward = true; - } else { - backward = false; - } - } else if (binding.equals("Jump")) { - physicsCharacter.jump(); - } else if (binding.equals("Duck")) { - if (value) { - physicsCharacter.setDucked(true); - } else { - physicsCharacter.setDucked(false); - } - } else if (binding.equals("Lock View")) { - if (value && lockView) { - lockView = false; - } else if (value && !lockView) { - lockView = true; - } - flyCam.setEnabled(!lockView); - camNode.setEnabled(lockView); - } - } - private boolean lockView = false; - - private void setupKeys() { - inputManager.addMapping("Strafe Left", - new KeyTrigger(KeyInput.KEY_U), - new KeyTrigger(KeyInput.KEY_Z)); - inputManager.addMapping("Strafe Right", - new KeyTrigger(KeyInput.KEY_O), - new KeyTrigger(KeyInput.KEY_X)); - inputManager.addMapping("Rotate Left", - new KeyTrigger(KeyInput.KEY_J), - new KeyTrigger(KeyInput.KEY_LEFT)); - inputManager.addMapping("Rotate Right", - new KeyTrigger(KeyInput.KEY_L), - new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addMapping("Walk Forward", - new KeyTrigger(KeyInput.KEY_I), - new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("Walk Backward", - new KeyTrigger(KeyInput.KEY_K), - new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("Jump", - new KeyTrigger(KeyInput.KEY_F), - new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("Duck", - new KeyTrigger(KeyInput.KEY_G), - new KeyTrigger(KeyInput.KEY_LSHIFT), - new KeyTrigger(KeyInput.KEY_RSHIFT)); - inputManager.addMapping("Lock View", - new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addListener(this, "Strafe Left", "Strafe Right"); - inputManager.addListener(this, "Rotate Left", "Rotate Right"); - inputManager.addListener(this, "Walk Forward", "Walk Backward"); - inputManager.addListener(this, "Jump", "Duck", "Lock View"); - } - - @Override - public void simpleRender(RenderManager rm) { - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java b/jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java deleted file mode 100644 index 538ec8b31c..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.Action; -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.animation.DynamicAnimControl; -import com.jme3.bullet.animation.PhysicsLink; -import com.jme3.bullet.animation.RagdollCollisionListener; -import com.jme3.bullet.collision.PhysicsCollisionEvent; -import com.jme3.bullet.collision.PhysicsCollisionObject; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Transform; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; -import com.jme3.texture.Texture; - -/** - * @author normenhansen - */ -public class TestBoneRagdoll - extends SimpleApplication - implements ActionListener, RagdollCollisionListener { - - private AnimComposer composer; - private DynamicAnimControl ragdoll; - private float bulletSize = 1f; - private Material matBullet; - private Node model; - private PhysicsSpace physicsSpace; - private Sphere bullet; - private SphereCollisionShape bulletCollisionShape; - - public static void main(String[] args) { - TestBoneRagdoll app = new TestBoneRagdoll(); - app.start(); - } - - public void onStandDone() { - composer.setCurrentAction("IdleTop"); - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("boom") && !isPressed) { - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(matBullet); - bulletGeometry.setLocalTranslation(cam.getLocation()); - bulletGeometry.setLocalScale(bulletSize); - bulletCollisionShape = new SphereCollisionShape(bulletSize); - BombControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1f); - bulletNode.setForceFactor(8f); - bulletNode.setExplosionRadius(20f); - bulletNode.setCcdMotionThreshold(0.001f); - bulletNode.setLinearVelocity(cam.getDirection().mult(180f)); - bulletGeometry.addControl(bulletNode); - rootNode.attachChild(bulletGeometry); - physicsSpace.add(bulletNode); - } - if (name.equals("bullet+") && isPressed) { - bulletSize += 0.1f; - } - if (name.equals("bullet-") && isPressed) { - bulletSize -= 0.1f; - } - if (name.equals("shoot") && !isPressed) { - Geometry bulletg = new Geometry("bullet", bullet); - bulletg.setMaterial(matBullet); - bulletg.setLocalTranslation(cam.getLocation()); - bulletg.setLocalScale(bulletSize); - bulletCollisionShape = new SphereCollisionShape(bulletSize); - RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, bulletSize * 10f); - bulletNode.setCcdMotionThreshold(0.001f); - bulletNode.setLinearVelocity(cam.getDirection().mult(80f)); - bulletg.addControl(bulletNode); - rootNode.attachChild(bulletg); - physicsSpace.add(bulletNode); - } - if (name.equals("stop") && isPressed) { - ragdoll.setEnabled(!ragdoll.isEnabled()); - ragdoll.setRagdollMode(); - } - if (name.equals("toggle") && isPressed) { - Vector3f v = new Vector3f(model.getLocalTranslation()); - v.y = 0f; - Quaternion q = new Quaternion(); - float[] angles = new float[3]; - model.getLocalRotation().toAngles(angles); - q.fromAngleAxis(angles[1], Vector3f.UNIT_Y); - Transform endModelTransform - = new Transform(v, q, new Vector3f(1f, 1f, 1f)); - if (angles[0] < 0f) { - composer.setCurrentAction("BackOnce"); - ragdoll.blendToKinematicMode(0.5f, endModelTransform); - } else { - composer.setCurrentAction("FrontOnce"); - ragdoll.blendToKinematicMode(0.5f, endModelTransform); - } - } - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(50f); - cam.setLocation(new Vector3f(0.3f, 6.7f, 22.3f)); - cam.setRotation(new Quaternion(-2E-4f, 0.993025f, -0.1179f, -0.0019f)); - - initCrossHairs(); - initMaterial(); - setupKeys(); - setupLight(); - - BulletAppState bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - //bulletAppState.setDebugEnabled(true); - physicsSpace = bulletAppState.getPhysicsSpace(); - - bullet = new Sphere(32, 32, 1f, true, false); - bullet.setTextureMode(TextureMode.Projected); - bulletCollisionShape = new SphereCollisionShape(1f); - - PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, - physicsSpace); - - model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); - rootNode.attachChild(model); - - composer = model.getControl(AnimComposer.class); - composer.setCurrentAction("Dance"); - - Action standUpFront = composer.action("StandUpFront"); - composer.actionSequence("FrontOnce", - standUpFront, Tweens.callMethod(this, "onStandDone")); - Action standUpBack = composer.action("StandUpBack"); - composer.actionSequence("BackOnce", - standUpBack, Tweens.callMethod(this, "onStandDone")); - - ragdoll = new DynamicAnimControl(); - TestRagdollCharacter.setupSinbad(ragdoll); - model.addControl(ragdoll); - physicsSpace.add(ragdoll); - ragdoll.addCollisionListener(this); - } - - @Override - public void collide(PhysicsLink bone, PhysicsCollisionObject object, - PhysicsCollisionEvent event) { - if (object.getUserObject() != null - && object.getUserObject() instanceof Geometry) { - Geometry geom = (Geometry) object.getUserObject(); - if ("bullet".equals(geom.getName())) { - ragdoll.setRagdollMode(); - } - } - } - - private void initCrossHairs() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2f); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2f - guiFont.getCharSet().getRenderedSize() / 3f * 2f, - settings.getHeight() / 2f + ch.getLineHeight() / 2f, 0f); - guiNode.attachChild(ch); - } - - private void initMaterial() { - matBullet = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); - key2.setGenerateMips(true); - Texture tex2 = assetManager.loadTexture(key2); - matBullet.setTexture("ColorMap", tex2); - } - - private void setupKeys() { - inputManager.addMapping("boom", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); - inputManager.addMapping("bullet+", new KeyTrigger(KeyInput.KEY_PERIOD)); - inputManager.addMapping("bullet-", new KeyTrigger(KeyInput.KEY_COMMA)); - inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - - inputManager.addListener(this, - "boom", "bullet-", "bullet+", "shoot", "stop", "toggle"); - - } - - private void setupLight() { - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1f).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1f)); - rootNode.addLight(dl); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java b/jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java deleted file mode 100644 index a265bdba96..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -/* - * Copyright (c) 2009-2012 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. - */ - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.font.BitmapText; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; - -/** - * - * @author double1984 (tower mod by atom) - */ -public class TestBrickTower extends SimpleApplication { - - final private int bricksPerLayer = 8; - final private int brickLayers = 30; - - final private static float brickWidth = .75f, brickHeight = .25f, brickDepth = .25f; - final private float radius = 3f; - private float angle = 0; - - - private Material mat; - private Material mat2; - private Material mat3; - private Sphere bullet; - private Box brick; - private SphereCollisionShape bulletCollisionShape; - - private BulletAppState bulletAppState; - - public static void main(String args[]) { - TestBrickTower f = new TestBrickTower(); - f.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); - // bulletAppState.setEnabled(false); - stateManager.attach(bulletAppState); - bullet = new Sphere(32, 32, 0.4f, true, false); - bullet.setTextureMode(TextureMode.Projected); - bulletCollisionShape = new SphereCollisionShape(0.4f); - - brick = new Box(brickWidth, brickHeight, brickDepth); - brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); - initMaterial(); - initTower(); - initFloor(); - initCrossHairs(); - this.cam.setLocation(new Vector3f(0, 25f, 8f)); - cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0)); - cam.setFrustumFar(80); - inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "shoot"); - rootNode.setShadowMode(ShadowMode.Off); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - final private ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("shoot") && !keyPressed) { - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(mat2); - bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); - bulletGeometry.setLocalTranslation(cam.getLocation()); - RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); -// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); - bulletNode.setLinearVelocity(cam.getDirection().mult(25)); - bulletGeometry.addControl(bulletNode); - rootNode.attachChild(bulletGeometry); - getPhysicsSpace().add(bulletNode); - } - } - }; - - public void initTower() { - double tempX = 0; - double tempY = 0; - double tempZ = 0; - angle = 0f; - for (int i = 0; i < brickLayers; i++){ - // Increment rows - if(i!=0) - tempY+=brickHeight*2; - else - tempY=brickHeight; - // Alternate brick seams - angle = 360.0f / bricksPerLayer * i/2f; - for (int j = 0; j < bricksPerLayer; j++){ - tempZ = Math.cos(Math.toRadians(angle))*radius; - tempX = Math.sin(Math.toRadians(angle))*radius; - System.out.println("x="+((float)(tempX))+" y="+((float)(tempY))+" z="+(float)(tempZ)); - Vector3f vt = new Vector3f((float)(tempX), (float)(tempY), (float)(tempZ)); - // Add crenelation - if (i==brickLayers-1){ - if (j%2 == 0){ - addBrick(vt); - } - } - // Create main tower - else { - addBrick(vt); - } - angle += 360.0/bricksPerLayer; - } - } - - } - - public void initFloor() { - Box floorBox = new Box(10f, 0.1f, 5f); - floorBox.scaleTextureCoordinates(new Vector2f(3, 6)); - - Geometry floor = new Geometry("floor", floorBox); - floor.setMaterial(mat3); - floor.setShadowMode(ShadowMode.Receive); - floor.setLocalTranslation(0, 0, 0); - floor.addControl(new RigidBodyControl(0)); - this.rootNode.attachChild(floor); - this.getPhysicsSpace().add(floor); - } - - public void initMaterial() { - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - mat.setTexture("ColorMap", tex); - - mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); - key2.setGenerateMips(true); - Texture tex2 = assetManager.loadTexture(key2); - mat2.setTexture("ColorMap", tex2); - - mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); - key3.setGenerateMips(true); - Texture tex3 = assetManager.loadTexture(key3); - tex3.setWrap(WrapMode.Repeat); - mat3.setTexture("ColorMap", tex3); - } - - public void addBrick(Vector3f ori) { - Geometry brickGeometry = new Geometry("brick", brick); - brickGeometry.setMaterial(mat); - brickGeometry.setLocalTranslation(ori); - brickGeometry.rotate(0f, (float)Math.toRadians(angle) , 0f ); - brickGeometry.addControl(new RigidBodyControl(1.5f)); - brickGeometry.setShadowMode(ShadowMode.CastAndReceive); - brickGeometry.getControl(RigidBodyControl.class).setFriction(1.6f); - this.rootNode.attachChild(brickGeometry); - this.getPhysicsSpace().add(brickGeometry); - } - - protected void initCrossHairs() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, - settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); - guiNode.attachChild(ch); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java b/jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java deleted file mode 100644 index d0cbdb2bba..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; - -/** - * - * @author double1984 - */ -public class TestBrickWall extends SimpleApplication { - - final private static float bLength = 0.48f; - final private static float bWidth = 0.24f; - final private static float bHeight = 0.12f; - private Material mat; - private Material mat2; - private Material mat3; - private static Sphere bullet; - private static Box brick; - - private BulletAppState bulletAppState; - - public static void main(String args[]) { - TestBrickWall f = new TestBrickWall(); - f.start(); - } - - @Override - public void simpleInitApp() { - - bulletAppState = new BulletAppState(); - bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); - stateManager.attach(bulletAppState); - - bullet = new Sphere(32, 32, 0.4f, true, false); - bullet.setTextureMode(TextureMode.Projected); - brick = new Box(bLength, bHeight, bWidth); - brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); - - initMaterial(); - initWall(); - initFloor(); - initCrossHairs(); - this.cam.setLocation(new Vector3f(0, 6f, 6f)); - cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0)); - cam.setFrustumFar(15); - inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "shoot"); - inputManager.addMapping("gc", new KeyTrigger(KeyInput.KEY_X)); - inputManager.addListener(actionListener, "gc"); - - rootNode.setShadowMode(ShadowMode.Off); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - final private ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("shoot") && !keyPressed) { - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(mat2); - bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); - bulletGeometry.setLocalTranslation(cam.getLocation()); - - SphereCollisionShape bulletCollisionShape = new SphereCollisionShape(0.4f); - RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); -// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); - bulletNode.setLinearVelocity(cam.getDirection().mult(25)); - bulletGeometry.addControl(bulletNode); - rootNode.attachChild(bulletGeometry); - getPhysicsSpace().add(bulletNode); - } - if (name.equals("gc") && !keyPressed) { - System.gc(); - } - } - }; - - public void initWall() { - float startX = bLength / 4; - float height = 0; - for (int j = 0; j < 15; j++) { - for (int i = 0; i < 4; i++) { - Vector3f vt = new Vector3f(i * bLength * 2 + startX, bHeight + height, 0); - addBrick(vt); - } - startX = -startX; - height += 2 * bHeight; - } - } - - public void initFloor() { - Box floorBox = new Box(10f, 0.1f, 5f); - floorBox.scaleTextureCoordinates(new Vector2f(3, 6)); - - Geometry floor = new Geometry("floor", floorBox); - floor.setMaterial(mat3); - floor.setShadowMode(ShadowMode.Receive); - floor.setLocalTranslation(0, -0.1f, 0); - floor.addControl(new RigidBodyControl(new BoxCollisionShape(new Vector3f(10f, 0.1f, 5f)), 0)); - this.rootNode.attachChild(floor); - this.getPhysicsSpace().add(floor); - } - - public void initMaterial() { - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - mat.setTexture("ColorMap", tex); - - mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); - key2.setGenerateMips(true); - Texture tex2 = assetManager.loadTexture(key2); - mat2.setTexture("ColorMap", tex2); - - mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); - key3.setGenerateMips(true); - Texture tex3 = assetManager.loadTexture(key3); - tex3.setWrap(WrapMode.Repeat); - mat3.setTexture("ColorMap", tex3); - } - - public void addBrick(Vector3f ori) { - - Geometry brickGeometry = new Geometry("brick", brick); - brickGeometry.setMaterial(mat); - brickGeometry.setLocalTranslation(ori); - //for geometry with sphere mesh the physics system automatically uses a sphere collision shape - brickGeometry.addControl(new RigidBodyControl(1.5f)); - brickGeometry.setShadowMode(ShadowMode.CastAndReceive); - brickGeometry.getControl(RigidBodyControl.class).setFriction(0.6f); - this.rootNode.attachChild(brickGeometry); - this.getPhysicsSpace().add(brickGeometry); - } - - protected void initCrossHairs() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, - settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); - guiNode.attachChild(ch); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCcd.java b/jme3-examples/src/main/java/jme3test/bullet/TestCcd.java deleted file mode 100644 index 3c5ff09282..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestCcd.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.MeshCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; - -/** - * - * @author normenhansen - */ -public class TestCcd extends SimpleApplication implements ActionListener { - - private Material mat; - private Material mat2; - private Sphere bullet; - private SphereCollisionShape bulletCollisionShape; - private BulletAppState bulletAppState; - - public static void main(String[] args) { - TestCcd app = new TestCcd(); - app.start(); - } - - private void setupKeys() { - inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addMapping("shoot2", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); - inputManager.addListener(this, "shoot"); - inputManager.addListener(this, "shoot2"); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - bullet = new Sphere(32, 32, 0.4f, true, false); - bullet.setTextureMode(TextureMode.Projected); - bulletCollisionShape = new SphereCollisionShape(0.1f); - setupKeys(); - - mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - mat.getAdditionalRenderState().setWireframe(true); - mat.setColor("Color", ColorRGBA.Green); - - mat2 = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - mat2.getAdditionalRenderState().setWireframe(true); - mat2.setColor("Color", ColorRGBA.Red); - - // An obstacle mesh, does not move (mass=0) - Node node2 = new Node(); - node2.setName("mesh"); - node2.setLocalTranslation(new Vector3f(2.5f, 0, 0f)); - node2.addControl(new RigidBodyControl(new MeshCollisionShape(new Box(4, 4, 0.1f)), 0)); - rootNode.attachChild(node2); - getPhysicsSpace().add(node2); - - // The floor, does not move (mass=0) - Node node3 = new Node(); - node3.setLocalTranslation(new Vector3f(0f, -6, 0f)); - node3.addControl(new RigidBodyControl(new BoxCollisionShape(new Vector3f(100, 1, 100)), 0)); - rootNode.attachChild(node3); - getPhysicsSpace().add(node3); - - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleUpdate(float tpf) { - //TODO: add update code - } - - @Override - public void simpleRender(RenderManager rm) { - //TODO: add render code - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("shoot") && !value) { - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(mat); - bulletGeometry.setName("bullet"); - bulletGeometry.setLocalTranslation(cam.getLocation()); - bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); - bulletGeometry.addControl(new RigidBodyControl(bulletCollisionShape, 1)); - bulletGeometry.getControl(RigidBodyControl.class).setCcdMotionThreshold(0.1f); - bulletGeometry.getControl(RigidBodyControl.class).setLinearVelocity(cam.getDirection().mult(40)); - rootNode.attachChild(bulletGeometry); - getPhysicsSpace().add(bulletGeometry); - } else if (binding.equals("shoot2") && !value) { - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(mat2); - bulletGeometry.setName("bullet"); - bulletGeometry.setLocalTranslation(cam.getLocation()); - bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); - bulletGeometry.addControl(new RigidBodyControl(bulletCollisionShape, 1)); - bulletGeometry.getControl(RigidBodyControl.class).setLinearVelocity(cam.getDirection().mult(40)); - rootNode.attachChild(bulletGeometry); - getPhysicsSpace().add(bulletGeometry); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java deleted file mode 100644 index 516345d47d..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.PhysicsCollisionObject; -import com.jme3.bullet.collision.shapes.MeshCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; - -/** - * - * @author normenhansen - */ -public class TestCollisionGroups extends SimpleApplication { - - private BulletAppState bulletAppState; - - public static void main(String[] args) { - TestCollisionGroups app = new TestCollisionGroups(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - - // Add a physics sphere to the world - Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); - physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); - rootNode.attachChild(physicsSphere); - getPhysicsSpace().add(physicsSphere); - - // Add a physics sphere to the world - Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); - physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); - physicsSphere2.getControl(RigidBodyControl.class).addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_02); - rootNode.attachChild(physicsSphere2); - getPhysicsSpace().add(physicsSphere2); - - // an obstacle mesh, does not move (mass=0) - Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); - node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); - node2.getControl(RigidBodyControl.class).setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02); - node2.getControl(RigidBodyControl.class).setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_02); - rootNode.attachChild(node2); - getPhysicsSpace().add(node2); - - // the floor, does not move (mass=0) - Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Box(100f, 0.2f, 100f)), 0); - node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); - rootNode.attachChild(node3); - getPhysicsSpace().add(node3); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleUpdate(float tpf) { - //TODO: add update code - } - - @Override - public void simpleRender(RenderManager rm) { - //TODO: add render code - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java deleted file mode 100644 index 01714f5b3b..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.PhysicsCollisionEvent; -import com.jme3.bullet.collision.PhysicsCollisionListener; -import com.jme3.renderer.RenderManager; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; - -/** - * - * @author normenhansen - */ -public class TestCollisionListener extends SimpleApplication implements PhysicsCollisionListener { - - private BulletAppState bulletAppState; - - public static void main(String[] args) { - TestCollisionListener app = new TestCollisionListener(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - Sphere bullet = new Sphere(32, 32, 0.4f, true, false); - bullet.setTextureMode(TextureMode.Projected); - - PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); - PhysicsTestHelper.createBallShooter(this, rootNode, bulletAppState.getPhysicsSpace()); - - // add ourselves as collision listener - getPhysicsSpace().addCollisionListener(this); - } - - private PhysicsSpace getPhysicsSpace(){ - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleUpdate(float tpf) { - //TODO: add update code - } - - @Override - public void simpleRender(RenderManager rm) { - //TODO: add render code - } - - @Override - public void collision(PhysicsCollisionEvent event) { - if ("Box".equals(event.getNodeA().getName()) || "Box".equals(event.getNodeB().getName())) { - if ("bullet".equals(event.getNodeA().getName()) || "bullet".equals(event.getNodeB().getName())) { - fpsText.setText("You hit the box!"); - } - } - } - -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java deleted file mode 100644 index 2128149d25..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Cylinder; -import com.jme3.scene.shape.Torus; - -/** - * This is a basic Test of jbullet-jme functions - * - * @author normenhansen - */ -public class TestCollisionShapeFactory extends SimpleApplication { - - private BulletAppState bulletAppState; - private Material mat1; - private Material mat2; - private Material mat3; - - public static void main(String[] args) { - TestCollisionShapeFactory app = new TestCollisionShapeFactory(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - createMaterial(); - - Node node = new Node("node1"); - attachRandomGeometry(node, mat1); - randomizeTransform(node); - - Node node2 = new Node("node2"); - attachRandomGeometry(node2, mat2); - randomizeTransform(node2); - - node.attachChild(node2); - rootNode.attachChild(node); - - RigidBodyControl control = new RigidBodyControl(0); - node.addControl(control); - getPhysicsSpace().add(control); - - //test single geometry too - Geometry myGeom = new Geometry("cylinder", new Cylinder(16, 16, 0.5f, 1)); - myGeom.setMaterial(mat3); - randomizeTransform(myGeom); - rootNode.attachChild(myGeom); - RigidBodyControl control3 = new RigidBodyControl(0); - myGeom.addControl(control3); - getPhysicsSpace().add(control3); - } - - private void attachRandomGeometry(Node node, Material mat) { - Box box = new Box(0.25f, 0.25f, 0.25f); - Torus torus = new Torus(16, 16, 0.2f, 0.8f); - Geometry[] boxes = new Geometry[]{ - new Geometry("box1", box), - new Geometry("box2", box), - new Geometry("box3", box), - new Geometry("torus1", torus), - new Geometry("torus2", torus), - new Geometry("torus3", torus) - }; - for (int i = 0; i < boxes.length; i++) { - Geometry geometry = boxes[i]; - geometry.setLocalTranslation((float) Math.random() * 10 -10, (float) Math.random() * 10 -10, (float) Math.random() * 10 -10); - geometry.setLocalRotation(new Quaternion().fromAngles((float) Math.random() * FastMath.PI, (float) Math.random() * FastMath.PI, (float) Math.random() * FastMath.PI)); - geometry.setLocalScale((float) Math.random() * 10 -10, (float) Math.random() * 10 -10, (float) Math.random() * 10 -10); - geometry.setMaterial(mat); - node.attachChild(geometry); - } - } - - private void randomizeTransform(Spatial spat){ - spat.setLocalTranslation((float) Math.random() * 10, (float) Math.random() * 10, (float) Math.random() * 10); - spat.setLocalTranslation((float) Math.random() * 10, (float) Math.random() * 10, (float) Math.random() * 10); - spat.setLocalScale((float) Math.random() * 2, (float) Math.random() * 2, (float) Math.random() * 2); - } - - private void createMaterial() { - mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.Green); - mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat2.setColor("Color", ColorRGBA.Red); - mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat3.setColor("Color", ColorRGBA.Yellow); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java b/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java deleted file mode 100644 index ce21b1f15b..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.VehicleControl; -import com.jme3.bullet.util.CollisionShapeFactory; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.FastMath; -import com.jme3.math.Matrix3f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; - -public class TestFancyCar extends SimpleApplication implements ActionListener { - - private BulletAppState bulletAppState; - private VehicleControl player; - private float steeringValue = 0; - private float accelerationValue = 0; - private Node carNode; - - public static void main(String[] args) { - TestFancyCar app = new TestFancyCar(); - app.start(); - } - - private void setupKeys() { - inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addListener(this, "Lefts"); - inputManager.addListener(this, "Rights"); - inputManager.addListener(this, "Ups"); - inputManager.addListener(this, "Downs"); - inputManager.addListener(this, "Reset"); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - cam.setFrustumFar(150f); - flyCam.setMoveSpeed(10); - - setupKeys(); - PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, getPhysicsSpace()); - buildPlayer(); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.5f, -1f, -0.3f).normalizeLocal()); - rootNode.addLight(dl); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - private Geometry findGeom(Spatial spatial, String name) { - if (spatial instanceof Node) { - Node node = (Node) spatial; - for (int i = 0; i < node.getQuantity(); i++) { - Spatial child = node.getChild(i); - Geometry result = findGeom(child, name); - if (result != null) { - return result; - } - } - } else if (spatial instanceof Geometry) { - if (spatial.getName().startsWith(name)) { - return (Geometry) spatial; - } - } - return null; - } - - private void buildPlayer() { - float stiffness = 120.0f;//200=f1 car - float compValue = 0.2f; //(lower than damp!) - float dampValue = 0.3f; - final float mass = 400; - - // Load model and get chassis Geometry - carNode = (Node) assetManager.loadModel("Models/Ferrari/Car.scene"); - carNode.setShadowMode(ShadowMode.Cast); - Geometry chassis = findGeom(carNode, "Car"); - - // Create a hull collision shape for the chassis - CollisionShape carHull = CollisionShapeFactory.createDynamicMeshShape(chassis); - - // Create a vehicle control - player = new VehicleControl(carHull, mass); - carNode.addControl(player); - - // Setting default values for wheels - player.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); - player.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); - player.setSuspensionStiffness(stiffness); - player.setMaxSuspensionForce(10000); - - // Create four wheels and add them at their locations. - // Note that our fancy car actually goes backward. - Vector3f wheelDirection = new Vector3f(0, -1, 0); - Vector3f wheelAxle = new Vector3f(-1, 0, 0); - - Geometry wheel_fr = findGeom(carNode, "WheelFrontRight"); - wheel_fr.center(); - BoundingBox box = (BoundingBox) wheel_fr.getModelBound(); - float wheelRadius = box.getYExtent(); - float back_wheel_h = (wheelRadius * 1.7f) - 1f; - float front_wheel_h = (wheelRadius * 1.9f) - 1f; - player.addWheel(wheel_fr.getParent(), box.getCenter().add(0, -front_wheel_h, 0), - wheelDirection, wheelAxle, 0.2f, wheelRadius, true); - - Geometry wheel_fl = findGeom(carNode, "WheelFrontLeft"); - wheel_fl.center(); - box = (BoundingBox) wheel_fl.getModelBound(); - player.addWheel(wheel_fl.getParent(), box.getCenter().add(0, -front_wheel_h, 0), - wheelDirection, wheelAxle, 0.2f, wheelRadius, true); - - Geometry wheel_br = findGeom(carNode, "WheelBackRight"); - wheel_br.center(); - box = (BoundingBox) wheel_br.getModelBound(); - player.addWheel(wheel_br.getParent(), box.getCenter().add(0, -back_wheel_h, 0), - wheelDirection, wheelAxle, 0.2f, wheelRadius, false); - - Geometry wheel_bl = findGeom(carNode, "WheelBackLeft"); - wheel_bl.center(); - box = (BoundingBox) wheel_bl.getModelBound(); - player.addWheel(wheel_bl.getParent(), box.getCenter().add(0, -back_wheel_h, 0), - wheelDirection, wheelAxle, 0.2f, wheelRadius, false); - - player.getWheel(2).setFrictionSlip(4); - player.getWheel(3).setFrictionSlip(4); - - rootNode.attachChild(carNode); - getPhysicsSpace().add(player); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Lefts")) { - if (value) { - steeringValue += .5f; - } else { - steeringValue -= .5f; - } - player.steer(steeringValue); - } else if (binding.equals("Rights")) { - if (value) { - steeringValue -= .5f; - } else { - steeringValue += .5f; - } - player.steer(steeringValue); - } // Note that our fancy car actually goes backward. - else if (binding.equals("Ups")) { - if (value) { - accelerationValue -= 800; - } else { - accelerationValue += 800; - } - player.accelerate(accelerationValue); - } else if (binding.equals("Downs")) { - if (value) { - player.brake(40f); - } else { - player.brake(0f); - } - } else if (binding.equals("Reset")) { - if (value) { - System.out.println("Reset"); - player.setPhysicsLocation(Vector3f.ZERO); - player.setPhysicsRotation(new Matrix3f()); - player.setLinearVelocity(Vector3f.ZERO); - player.setAngularVelocity(Vector3f.ZERO); - player.resetSuspension(); - } - } - } - - @Override - public void simpleUpdate(float tpf) { - cam.lookAt(carNode.getWorldTranslation(), Vector3f.UNIT_Y); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java b/jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java deleted file mode 100644 index 2ea1af0ab2..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.bullet; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.GhostControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; - -/** - * - * @author tim8dev [at] gmail [dot com] - */ -public class TestGhostObject extends SimpleApplication { - - private BulletAppState bulletAppState; - private GhostControl ghostControl; - - public static void main(String[] args) { - Application app = new TestGhostObject(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - - // Mesh to be shared across several boxes. - Box boxGeom = new Box(1f, 1f, 1f); - // CollisionShape to be shared across several boxes. - CollisionShape shape = new BoxCollisionShape(new Vector3f(1, 1, 1)); - - Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, shape, 1); - physicsBox.setName("box0"); - physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); - rootNode.attachChild(physicsBox); - getPhysicsSpace().add(physicsBox); - - Node physicsBox1 = PhysicsTestHelper.createPhysicsTestNode(assetManager, shape, 1); - physicsBox1.setName("box1"); - physicsBox1.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0, 40, 0)); - rootNode.attachChild(physicsBox1); - getPhysicsSpace().add(physicsBox1); - - Node physicsBox2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); - physicsBox2.setName("box0"); - physicsBox2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.5f, 80, -.8f)); - rootNode.attachChild(physicsBox2); - getPhysicsSpace().add(physicsBox2); - - // the floor, does not move (mass=0) - Node node = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(100, 1, 100)), 0); - node.setName("floor"); - node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); - rootNode.attachChild(node); - getPhysicsSpace().add(node); - - initGhostObject(); - } - - private PhysicsSpace getPhysicsSpace(){ - return bulletAppState.getPhysicsSpace(); - } - - private void initGhostObject() { - Vector3f halfExtents = new Vector3f(3, 4.2f, 1); - ghostControl = new GhostControl(new BoxCollisionShape(halfExtents)); - Node node=new Node("Ghost Object"); - node.addControl(ghostControl); - rootNode.attachChild(node); - getPhysicsSpace().add(ghostControl); - } - - @Override - public void simpleUpdate(float tpf) { - fpsText.setText("Overlapping objects: " + ghostControl.getOverlappingObjects().toString()); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java b/jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java deleted file mode 100644 index 3127ec4a68..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.PhysicsCollisionObject; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.util.CollisionShapeFactory; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.renderer.Camera; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Spatial; -import com.jme3.shadow.DirectionalLightShadowRenderer; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; -import java.util.ArrayList; -import java.util.List; - -public class TestHoveringTank extends SimpleApplication implements AnalogListener, - ActionListener { - - private BulletAppState bulletAppState; - private PhysicsHoverControl hoverControl; - private Spatial spaceCraft; - /** - * initial location of the tank (in world/physics-space coordinates) - */ - final private Vector3f startLocation = new Vector3f(-140f, 50f, -23f); - /** - * initial orientation of the tank (in world/physics-space coordinates) - */ - final private Quaternion startOrientation - = new Quaternion(new float[]{0f, 0.01f, 0f}); - - public static void main(String[] args) { - TestHoveringTank app = new TestHoveringTank(); - app.start(); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - private void setupKeys() { - inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addListener(this, "Lefts"); - inputManager.addListener(this, "Rights"); - inputManager.addListener(this, "Ups"); - inputManager.addListener(this, "Downs"); - inputManager.addListener(this, "Space"); - inputManager.addListener(this, "Reset"); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); - stateManager.attach(bulletAppState); - bulletAppState.getPhysicsSpace().setAccuracy(1f/30f); - rootNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", EnvMapType.CubeMap)); - - DirectionalLightShadowRenderer dlsr - = new DirectionalLightShadowRenderer(assetManager, 2048, 3); - dlsr.setLambda(0.55f); - dlsr.setShadowIntensity(0.6f); - dlsr.setEdgeFilteringMode(EdgeFilteringMode.Bilinear); - viewPort.addProcessor(dlsr); - - setupKeys(); - createTerrain(); - buildPlayer(); - - DirectionalLight dl = new DirectionalLight(); - dlsr.setLight(dl); - dl.setColor(new ColorRGBA(1.0f, 0.94f, 0.8f, 1f).multLocal(1.3f)); - dl.setDirection(new Vector3f(-0.5f, -0.3f, -0.3f).normalizeLocal()); - rootNode.addLight(dl); - - Vector3f lightDir2 = new Vector3f(0.70518064f, 0.5902297f, -0.39287305f); - DirectionalLight dl2 = new DirectionalLight(); - dl2.setColor(new ColorRGBA(0.7f, 0.85f, 1.0f, 1f)); - dl2.setDirection(lightDir2); - rootNode.addLight(dl2); - } - - private void buildPlayer() { - spaceCraft = assetManager.loadModel("Models/HoverTank/Tank2.mesh.xml"); - CollisionShape colShape = CollisionShapeFactory.createDynamicMeshShape(spaceCraft); - spaceCraft.setShadowMode(ShadowMode.CastAndReceive); - spaceCraft.setLocalTranslation(startLocation); - spaceCraft.setLocalRotation(startOrientation); - - hoverControl = new PhysicsHoverControl(colShape, 500); - - spaceCraft.addControl(hoverControl); - - - rootNode.attachChild(spaceCraft); - getPhysicsSpace().add(hoverControl); - hoverControl.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02); - - ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); - spaceCraft.addControl(chaseCam); - - flyCam.setEnabled(false); - } - - public void makeMissile() { - Vector3f pos = spaceCraft.getWorldTranslation().clone(); - Quaternion rot = spaceCraft.getWorldRotation(); - Vector3f dir = rot.getRotationColumn(2); - - Spatial missile = assetManager.loadModel("Models/SpaceCraft/Rocket.mesh.xml"); - missile.scale(0.5f); - missile.rotate(0, FastMath.PI, 0); - missile.updateGeometricState(); - - BoundingBox box = (BoundingBox) missile.getWorldBound(); - final Vector3f extent = box.getExtent(null); - - BoxCollisionShape boxShape = new BoxCollisionShape(extent); - - missile.setName("Missile"); - missile.rotate(rot); - missile.setLocalTranslation(pos.addLocal(0, extent.y * 4.5f, 0)); - missile.setLocalRotation(hoverControl.getPhysicsRotation()); - missile.setShadowMode(ShadowMode.Cast); - RigidBodyControl control = new BombControl(assetManager, boxShape, 20); - control.setLinearVelocity(dir.mult(100)); - control.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_03); - missile.addControl(control); - - - rootNode.attachChild(missile); - getPhysicsSpace().add(missile); - } - - @Override - public void onAnalog(String binding, float value, float tpf) { - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Lefts")) { - hoverControl.steer(value ? 50f : 0); - } else if (binding.equals("Rights")) { - hoverControl.steer(value ? -50f : 0); - } else if (binding.equals("Ups")) { - hoverControl.accelerate(value ? 100f : 0); - } else if (binding.equals("Downs")) { - hoverControl.accelerate(value ? -100f : 0); - } else if (binding.equals("Reset")) { - if (value) { - System.out.println("Reset"); - hoverControl.setPhysicsLocation(startLocation); - hoverControl.setPhysicsRotation(startOrientation); - hoverControl.setAngularVelocity(Vector3f.ZERO); - hoverControl.setLinearVelocity(Vector3f.ZERO); - hoverControl.clearForces(); - } else { - } - } else if (binding.equals("Space") && value) { - makeMissile(); - } - } - - public void updateCamera() { - rootNode.updateGeometricState(); - - Vector3f pos = spaceCraft.getWorldTranslation().clone(); - Quaternion rot = spaceCraft.getWorldRotation(); - Vector3f dir = rot.getRotationColumn(2); - - // make it XZ only - Vector3f camPos = new Vector3f(dir); - camPos.setY(0); - camPos.normalizeLocal(); - - // negate and multiply by distance from object - camPos.negateLocal(); - camPos.multLocal(15); - - // add Y distance - camPos.setY(2); - camPos.addLocal(pos); - cam.setLocation(camPos); - - Vector3f lookAt = new Vector3f(dir); - lookAt.multLocal(7); // look at dist - lookAt.addLocal(pos); - cam.lookAt(lookAt, Vector3f.UNIT_Y); - } - - @Override - public void simpleUpdate(float tpf) { - } - - private void createTerrain() { - Material matRock = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - } catch (Exception e) { - e.printStackTrace(); - } - TerrainQuad terrain - = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - List cameras = new ArrayList<>(); - cameras.add(getCamera()); - TerrainLodControl control = new TerrainLodControl(terrain, cameras); - terrain.addControl(control); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(2, 2, 2)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(ShadowMode.CastAndReceive); - terrain.addControl(new RigidBodyControl(0)); - rootNode.attachChild(terrain); - getPhysicsSpace().addAll(terrain); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java deleted file mode 100644 index d374ae5645..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.GImpactCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.debug.BulletDebugAppState; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Cylinder; -import com.jme3.system.AppSettings; -import java.util.ArrayList; -import java.util.List; - -/** - * Test demonstrating a GImpactCollisionShape falling through a curved mesh, when using JBullet. Bullet native - * does not experience this issue at the time this test was created. - * - * @author lou - */ -public class TestIssue1120 extends SimpleApplication { - - private BulletAppState bulletAppState; - private final boolean physicsDebug = true; - private BitmapText speedText; - private final List testObjects = new ArrayList<>(); - private static final boolean SKIP_SETTINGS = false;//Used for repeated runs of this test during dev - private float bulletSpeed = 0.5f; - - public static void main(String[] args) { - TestIssue1120 test = new TestIssue1120(); - test.setSettings(new AppSettings(true)); - test.settings.setFrameRate(60); - if (SKIP_SETTINGS) { - test.settings.setWidth(1920); - test.settings.setHeight(1150); - test.showSettings = !SKIP_SETTINGS; - } - test.start(); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(-7.285349f, -2.2638104f, 4.954474f)); - cam.setRotation(new Quaternion(0.07345789f, 0.92521834f, -0.2876841f, 0.23624739f)); - getFlyByCamera().setMoveSpeed(5); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - dl.setColor(ColorRGBA.Green); - rootNode.addLight(dl); - - //Setup interactive test controls - inputManager.addMapping("restart", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("pause", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addMapping("+", new KeyTrigger(KeyInput.KEY_ADD), new KeyTrigger(KeyInput.KEY_EQUALS)); - inputManager.addMapping("-", new KeyTrigger(KeyInput.KEY_SUBTRACT), new KeyTrigger(KeyInput.KEY_MINUS)); - inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { - if (!isPressed) { - return; - } - switch (name) { - case "restart": - cleanup(); - initializeNewTest(); - break; - case "pause": - bulletAppState.setSpeed(bulletAppState.getSpeed() > 0.1 ? 0 : bulletSpeed); - break; - case "+": - bulletSpeed += 0.1f; - if (bulletSpeed > 1f) { - bulletSpeed = 1f; - } - bulletAppState.setSpeed(bulletSpeed); - break; - case "-": - bulletSpeed -= 0.1f; - if (bulletSpeed < 0.1f) { - bulletSpeed = 0.1f; - } - bulletAppState.setSpeed(bulletSpeed); - break; - } - }, "pause", "restart", "+", "-"); - - guiNode = getGuiNode(); - BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText[] testInfo = new BitmapText[2]; - testInfo[0] = new BitmapText(font); - testInfo[1] = new BitmapText(font); - speedText = new BitmapText(font); - - float lineHeight = testInfo[0].getLineHeight(); - testInfo[0].setText("Camera move: W/A/S/D/Q/Z +/-: Increase/Decrease Speed"); - testInfo[0].setLocalTranslation(5, settings.getHeight(), 0); - guiNode.attachChild(testInfo[0]); - testInfo[1].setText("Left Click: Toggle pause Space: Restart test"); - testInfo[1].setLocalTranslation(5, settings.getHeight() - lineHeight, 0); - guiNode.attachChild(testInfo[1]); - - speedText.setLocalTranslation(202, lineHeight * 1, 0); - guiNode.attachChild(speedText); - - initializeNewTest(); - } - - private void initializeNewTest() { - bulletAppState = new BulletAppState(); - bulletAppState.setDebugEnabled(physicsDebug); - stateManager.attach(bulletAppState); - - bulletAppState.setSpeed(bulletSpeed); - - dropTest(); - - Geometry leftFloor = PhysicsTestHelper.createMeshTestFloor(assetManager, 20, new Vector3f(-11, -5, -10)); - addObject(leftFloor); - - //Hide physics debug visualization for floors - if (physicsDebug) { - BulletDebugAppState bulletDebugAppState = stateManager.getState(BulletDebugAppState.class); - bulletDebugAppState.setFilter((Object obj) -> { - return !(obj.equals(leftFloor.getControl(RigidBodyControl.class))); - }); - } - } - - private void addObject(Spatial s) { - testObjects.add(s); - rootNode.attachChild(s); - physicsSpace().add(s); - } - - private void dropTest() { - attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(0f, 2f, -5f), 2); - attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(-1f, 2f, -5f), 2); - attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(-2f, 2f, -5f), 2); - attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(-3f, 2f, -5f), 2); - } - - private void attachTestObject(Mesh mesh, Vector3f position, float mass) { - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - Geometry g = new Geometry("mesh", mesh); - g.setLocalTranslation(position); - g.setMaterial(material); - - RigidBodyControl control = new RigidBodyControl(new GImpactCollisionShape(mesh), mass); - g.addControl(control); - addObject(g); - } - - private PhysicsSpace physicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleUpdate(float tpf) { - speedText.setText("Speed: " + String.format("%.1f", bulletSpeed)); - } - - private void cleanup() { - stateManager.detach(bulletAppState); - stateManager.detach(stateManager.getState(BulletDebugAppState.class)); - for (Spatial s : testObjects) { - rootNode.detachChild(s); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java deleted file mode 100644 index d39c629f6c..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.util.CollisionShapeFactory; -import com.jme3.font.BitmapText; -import com.jme3.material.Material; -import com.jme3.material.RenderState; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.terrain.geomipmap.TerrainQuad; -import java.util.logging.Logger; - -/** - * Test case for JME issue #1125: heightfield collision shapes don't match - * TerrainQuad. - *

- * If successful, just one set of grid diagonals will be visible. If - * unsuccessful, you'll see both green diagonals (the TerrainQuad) and - * perpendicular blue diagonals (physics debug). - *

- * Use this test with jme3-bullet only; it can yield false success with - * jme3-jbullet due to JME issue #1129. - * - * @author Stephen Gold sgold@sonic.net - */ -public class TestIssue1125 extends SimpleApplication { - // ************************************************************************* - // constants and loggers - - /** - * message logger for this class - */ - final public static Logger logger - = Logger.getLogger(TestIssue1125.class.getName()); - // ************************************************************************* - // fields - - /** - * height array for a small heightfield - */ - final private float[] nineHeights = new float[9]; - /** - * green wireframe material for the TerrainQuad - */ - private Material quadMaterial; - /** - * space for physics simulation - */ - private PhysicsSpace physicsSpace; - // ************************************************************************* - // new methods exposed - - /** - * Main entry point for the TestIssue1125 application. - * - * @param ignored array of command-line arguments (not null) - */ - public static void main(String[] ignored) { - new TestIssue1125().start(); - } - // ************************************************************************* - // SimpleApplication methods - - /** - * Initialize this application. - */ - @Override - public void simpleInitApp() { - configureCamera(); - configureMaterials(); - viewPort.setBackgroundColor(new ColorRGBA(0.5f, 0.2f, 0.2f, 1f)); - configurePhysics(); - initializeHeightData(); - addTerrain(); - showHints(); - } - // ************************************************************************* - // private methods - - /** - * Add 3x3 terrain to the scene and the PhysicsSpace. - */ - private void addTerrain() { - int patchSize = 3; - int mapSize = 3; - TerrainQuad quad - = new TerrainQuad("terrain", patchSize, mapSize, nineHeights); - rootNode.attachChild(quad); - quad.setMaterial(quadMaterial); - - CollisionShape shape = CollisionShapeFactory.createMeshShape(quad); - float massForStatic = 0f; - RigidBodyControl rbc = new RigidBodyControl(shape, massForStatic); - rbc.setPhysicsSpace(physicsSpace); - quad.addControl(rbc); - } - - /** - * Configure the camera during startup. - */ - private void configureCamera() { - float fHeight = cam.getFrustumTop() - cam.getFrustumBottom(); - float fWidth = cam.getFrustumRight() - cam.getFrustumLeft(); - float fAspect = fWidth / fHeight; - float yDegrees = 45f; - float near = 0.02f; - float far = 20f; - cam.setFrustumPerspective(yDegrees, fAspect, near, far); - - flyCam.setMoveSpeed(5f); - - cam.setLocation(new Vector3f(2f, 4.7f, 0.4f)); - cam.setRotation(new Quaternion(0.348f, -0.64f, 0.4f, 0.556f)); - } - - /** - * Configure materials during startup. - */ - private void configureMaterials() { - quadMaterial = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - quadMaterial.setColor("Color", ColorRGBA.Green.clone()); - RenderState ars = quadMaterial.getAdditionalRenderState(); - ars.setWireframe(true); - } - - /** - * Configure physics during startup. - */ - private void configurePhysics() { - BulletAppState bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - physicsSpace = bulletAppState.getPhysicsSpace(); - } - - /** - * Initialize the height data during startup. - */ - private void initializeHeightData() { - nineHeights[0] = 1f; - nineHeights[1] = 0f; - nineHeights[2] = 1f; - nineHeights[3] = 0f; - nineHeights[4] = 0.5f; - nineHeights[5] = 0f; - nineHeights[6] = 1f; - nineHeights[7] = 0f; - nineHeights[8] = 1f; - } - - private void showHints() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - int numLines = 3; - BitmapText lines[] = new BitmapText[numLines]; - for (int i = 0; i < numLines; ++i) { - lines[i] = new BitmapText(guiFont); - } - - String p = "Test for jMonkeyEngine issue #1125"; - if (isNativeBullet()) { - lines[0].setText(p + " with native Bullet"); - } else { - lines[0].setText(p + " with JBullet (may yield false success)"); - } - lines[1].setText("Use W/A/S/D/Q/Z/arrow keys to move the camera."); - lines[2].setText("F5: render stats, C: camera pos, M: mem stats"); - - float textHeight = guiFont.getCharSet().getLineHeight(); - float viewHeight = cam.getHeight(); - float viewWidth = cam.getWidth(); - for (int i = 0; i < numLines; ++i) { - float left = Math.round((viewWidth - lines[i].getLineWidth()) / 2f); - float top = viewHeight - i * textHeight; - lines[i].setLocalTranslation(left, top, 0f); - guiNode.attachChild(lines[i]); - } - } - - /** - * Determine which physics library is in use. - * - * @return true for C++ Bullet, false for JBullet (jme3-jbullet) - */ - private boolean isNativeBullet() { - try { - Class clazz = Class.forName("com.jme3.bullet.util.NativeMeshUtil"); - return clazz != null; - } catch (ClassNotFoundException exception) { - return false; - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java deleted file mode 100644 index aecdc43a6a..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2018-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.joints.HingeJoint; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; - -/** - * Test case for JME issue #877: multiple hinges. Based on code submitted by - * Daniel Martensson. - * - * If successful, all pendulums will swing at the same frequency, and all the - * free-falling objects will fall straight down. - */ -public class TestIssue877 extends SimpleApplication { - - final private BulletAppState bulletAppState = new BulletAppState(); - final private int numPendulums = 6; - final private int numFalling = 6; - final private Node pivots[] = new Node[numPendulums]; - final private Node bobs[] = new Node[numPendulums]; - final private Node falling[] = new Node[numFalling]; - private float timeToNextPrint = 1f; // in seconds - - public static void main(String[] args) { - TestIssue877 app = new TestIssue877(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setEnabled(false); - cam.setLocation(new Vector3f(-4.77f, -7.55f, 16.52f)); - cam.setRotation(new Quaternion(-0.103433f, 0.889420f, 0.368792f, 0.249449f)); - - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - - float pivotY = 14.6214f; - float bobStartY = 3f; - float length = pivotY - bobStartY; - for (int i = 0; i < numPendulums; i++) { - float x = 6f - 2.5f * i; - Vector3f pivotLocation = new Vector3f(x, pivotY, 0f); - pivots[i] = createTestNode(0f, pivotLocation); - - Vector3f bobLocation = new Vector3f(x, bobStartY, 0f); - bobs[i] = createTestNode(1f, bobLocation); - } - - for (int i = 0; i < numFalling; i++) { - float x = -6f - 2.5f * (i + numPendulums); - Vector3f createLocation = new Vector3f(x, bobStartY, 0f); - falling[i] = createTestNode(1f, createLocation); - } - - for (int i = 0; i < numPendulums; i++) { - HingeJoint joint = new HingeJoint( - pivots[i].getControl(RigidBodyControl.class), - bobs[i].getControl(RigidBodyControl.class), - new Vector3f(0f, 0f, 0f), - new Vector3f(length, 0f, 0f), - Vector3f.UNIT_Z.clone(), - Vector3f.UNIT_Z.clone()); - bulletAppState.getPhysicsSpace().add(joint); - } - } - - Node createTestNode(float mass, Vector3f location) { - float size = 0.1f; - Vector3f halfExtents = new Vector3f(size, size, size); - CollisionShape shape = new BoxCollisionShape(halfExtents); - RigidBodyControl control = new RigidBodyControl(shape, mass); - Node node = new Node(); - node.addControl(control); - rootNode.attachChild(node); - bulletAppState.getPhysicsSpace().add(node); - control.setPhysicsLocation(location); - - return node; - } - - @Override - public void simpleUpdate(float tpf) { - if (timeToNextPrint > 0f) { - timeToNextPrint -= tpf; - return; - } - - if (numFalling > 0) { - Vector3f fallingLocation = falling[0].getWorldTranslation(); - System.out.printf(" falling[0] location(x=%f, z=%f)", - fallingLocation.x, fallingLocation.z); - /* - * If an object is falling vertically, its X- and Z-coordinates - * should not change. - */ - } - if (numPendulums > 0) { - Vector3f bobLocation = bobs[0].getWorldTranslation(); - Vector3f pivotLocation = pivots[0].getWorldTranslation(); - float distance = bobLocation.distance(pivotLocation); - System.out.printf(" bob[0] distance=%f", distance); - /* - * If the hinge is working properly, the distance from the - * pivot to the bob should remain roughly constant. - */ - } - System.out.println(); - timeToNextPrint = 1f; - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java deleted file mode 100644 index f0e4aec889..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2018-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; - -/** - * Test case for JME issue #883: extra physicsTicks in ThreadingType.PARALLEL. - * - *

If successful, physics time and frame time will advance at the same rate. - */ -public class TestIssue883 extends SimpleApplication { - - private boolean firstPrint = true; - private float timeToNextPrint = 1f; // in seconds - private double frameTime; // in seconds - private double physicsTime; // in seconds - - public static void main(String[] args) { - TestIssue883 app = new TestIssue883(); - app.start(); - } - - @Override - public void simpleInitApp() { - - BulletAppState bulletAppState = new BulletAppState() { - @Override - public void physicsTick(PhysicsSpace space, float timeStep) { - physicsTime += timeStep; - } - }; - bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); - stateManager.attach(bulletAppState); - } - - @Override - public void simpleUpdate(float tpf) { - frameTime += tpf; - - if (timeToNextPrint > 0f) { - timeToNextPrint -= tpf; - return; - } - - if (firstPrint) { // synchronize - frameTime = 0.; - physicsTime = 0.; - firstPrint = false; - } - - System.out.printf(" frameTime= %s physicsTime= %s%n", - frameTime, physicsTime); - timeToNextPrint = 1f; - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java b/jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java deleted file mode 100644 index f7c0a6811c..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.MeshCollisionShape; -import com.jme3.bullet.collision.shapes.PlaneCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.math.Plane; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; - -/** - * - * @author Nehon - */ -public class TestKinematicAddToPhysicsSpaceIssue extends SimpleApplication { - - public static void main(String[] args) { - TestKinematicAddToPhysicsSpaceIssue app = new TestKinematicAddToPhysicsSpaceIssue(); - app.start(); - } - private BulletAppState bulletAppState; - - @Override - public void simpleInitApp() { - - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - // Add a physics sphere to the world - Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); - physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); - rootNode.attachChild(physicsSphere); - - //Setting the rigidBody to kinematic before adding it to the physics space - physicsSphere.getControl(RigidBodyControl.class).setKinematic(true); - //adding it to the physics space - getPhysicsSpace().add(physicsSphere); - //Making it not kinematic again, it should fall under gravity, it doesn't - physicsSphere.getControl(RigidBodyControl.class).setKinematic(false); - - // Add a physics sphere to the world using the collision shape from sphere one - Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); - physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(5, 6, 0)); - rootNode.attachChild(physicsSphere2); - - //Adding the rigid body to physics space - getPhysicsSpace().add(physicsSphere2); - //making it kinematic - physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false); - //Making it not kinematic again, it works properly, the rigid body is affected by gravity. - physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false); - - - - // an obstacle mesh, does not move (mass=0) - Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); - node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); - rootNode.attachChild(node2); - getPhysicsSpace().add(node2); - - // the floor mesh, does not move (mass=0) - Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); - node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); - rootNode.attachChild(node3); - getPhysicsSpace().add(node3); - - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java b/jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java deleted file mode 100644 index 3835b1ca03..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.*; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.math.Plane; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; - -/** - * This is a basic Test of jbullet-jme functions - * - * @author normenhansen - */ -public class TestLocalPhysics extends SimpleApplication { - - private BulletAppState bulletAppState; - - public static void main(String[] args) { - TestLocalPhysics app = new TestLocalPhysics(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - - // Add a physics sphere to the world - Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); - physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); - physicsSphere.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); - rootNode.attachChild(physicsSphere); - getPhysicsSpace().add(physicsSphere); - - // Add a physics sphere to the world using the collision shape from sphere one - Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, physicsSphere.getControl(RigidBodyControl.class).getCollisionShape(), 1); - physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); - physicsSphere2.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); - rootNode.attachChild(physicsSphere2); - getPhysicsSpace().add(physicsSphere2); - - // Add a physics box to the world - Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); - physicsBox.getControl(RigidBodyControl.class).setFriction(0.1f); - physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); - physicsBox.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); - rootNode.attachChild(physicsBox); - getPhysicsSpace().add(physicsBox); - - // Add a physics cylinder to the world - Node physicsCylinder = PhysicsTestHelper.createPhysicsTestNode(assetManager, new CylinderCollisionShape(new Vector3f(1f, 1f, 1.5f)), 1); - physicsCylinder.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2, 2, 0)); - physicsCylinder.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); - rootNode.attachChild(physicsCylinder); - getPhysicsSpace().add(physicsCylinder); - - // an obstacle mesh, does not move (mass=0) - Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); - node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); - node2.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); - rootNode.attachChild(node2); - getPhysicsSpace().add(node2); - - // the floor mesh, does not move (mass=0) - Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); - node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); - node3.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); - rootNode.attachChild(node3); - getPhysicsSpace().add(node3); - - // Join the physics objects with a Point2Point joint -// PhysicsPoint2PointJoint joint=new PhysicsPoint2PointJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0)); -// PhysicsHingeJoint joint=new PhysicsHingeJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0), Vector3f.UNIT_Z,Vector3f.UNIT_Z); -// getPhysicsSpace().add(joint); - - } - - @Override - public void simpleUpdate(float tpf) { - rootNode.rotate(tpf, 0, 0); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java deleted file mode 100644 index a4db5ca759..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.CompoundCollisionShape; -import com.jme3.bullet.control.VehicleControl; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Matrix3f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Cylinder; - -public class TestPhysicsCar extends SimpleApplication implements ActionListener { - - private BulletAppState bulletAppState; - private VehicleControl vehicle; - private final float accelerationForce = 1000.0f; - private final float brakeForce = 100.0f; - private float steeringValue = 0; - private float accelerationValue = 0; - final private Vector3f jumpForce = new Vector3f(0, 3000, 0); - - public static void main(String[] args) { - TestPhysicsCar app = new TestPhysicsCar(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); - setupKeys(); - buildPlayer(); - } - - private PhysicsSpace getPhysicsSpace(){ - return bulletAppState.getPhysicsSpace(); - } - - private void setupKeys() { - inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addListener(this, "Lefts"); - inputManager.addListener(this, "Rights"); - inputManager.addListener(this, "Ups"); - inputManager.addListener(this, "Downs"); - inputManager.addListener(this, "Space"); - inputManager.addListener(this, "Reset"); - } - - private void buildPlayer() { - Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - mat.getAdditionalRenderState().setWireframe(true); - mat.setColor("Color", ColorRGBA.Red); - - //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0 - //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0 - CompoundCollisionShape compoundShape = new CompoundCollisionShape(); - BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f)); - compoundShape.addChildShape(box, new Vector3f(0, 1, 0)); - - //create vehicle node - Node vehicleNode=new Node("vehicleNode"); - vehicle = new VehicleControl(compoundShape, 400); - vehicleNode.addControl(vehicle); - - //setting suspension values for wheels, this can be a bit tricky - //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en - float stiffness = 60.0f;//200=f1 car - float compValue = .3f; //(should be lower than damp) - float dampValue = .4f; - vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); - vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); - vehicle.setSuspensionStiffness(stiffness); - vehicle.setMaxSuspensionForce(10000.0f); - - //Create four wheels and add them at their locations - Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0 - Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0 - float radius = 0.5f; - float restLength = 0.3f; - float yOff = 0.5f; - float xOff = 1f; - float zOff = 2f; - - Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true); - - Node node1 = new Node("wheel 1 node"); - Geometry wheels1 = new Geometry("wheel 1", wheelMesh); - node1.attachChild(wheels1); - wheels1.rotate(0, FastMath.HALF_PI, 0); - wheels1.setMaterial(mat); - vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff), - wheelDirection, wheelAxle, restLength, radius, true); - - Node node2 = new Node("wheel 2 node"); - Geometry wheels2 = new Geometry("wheel 2", wheelMesh); - node2.attachChild(wheels2); - wheels2.rotate(0, FastMath.HALF_PI, 0); - wheels2.setMaterial(mat); - vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff), - wheelDirection, wheelAxle, restLength, radius, true); - - Node node3 = new Node("wheel 3 node"); - Geometry wheels3 = new Geometry("wheel 3", wheelMesh); - node3.attachChild(wheels3); - wheels3.rotate(0, FastMath.HALF_PI, 0); - wheels3.setMaterial(mat); - vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff), - wheelDirection, wheelAxle, restLength, radius, false); - - Node node4 = new Node("wheel 4 node"); - Geometry wheels4 = new Geometry("wheel 4", wheelMesh); - node4.attachChild(wheels4); - wheels4.rotate(0, FastMath.HALF_PI, 0); - wheels4.setMaterial(mat); - vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff), - wheelDirection, wheelAxle, restLength, radius, false); - - vehicleNode.attachChild(node1); - vehicleNode.attachChild(node2); - vehicleNode.attachChild(node3); - vehicleNode.attachChild(node4); - rootNode.attachChild(vehicleNode); - - getPhysicsSpace().add(vehicle); - } - - @Override - public void simpleUpdate(float tpf) { - cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Lefts")) { - if (value) { - steeringValue += .5f; - } else { - steeringValue -= .5f; - } - vehicle.steer(steeringValue); - } else if (binding.equals("Rights")) { - if (value) { - steeringValue -= .5f; - } else { - steeringValue += .5f; - } - vehicle.steer(steeringValue); - } else if (binding.equals("Ups")) { - if (value) { - accelerationValue += accelerationForce; - } else { - accelerationValue -= accelerationForce; - } - vehicle.accelerate(accelerationValue); - } else if (binding.equals("Downs")) { - if (value) { - vehicle.brake(brakeForce); - } else { - vehicle.brake(0f); - } - } else if (binding.equals("Space")) { - if (value) { - vehicle.applyImpulse(jumpForce, Vector3f.ZERO); - } - } else if (binding.equals("Reset")) { - if (value) { - System.out.println("Reset"); - vehicle.setPhysicsLocation(Vector3f.ZERO); - vehicle.setPhysicsRotation(new Matrix3f()); - vehicle.setLinearVelocity(Vector3f.ZERO); - vehicle.setAngularVelocity(Vector3f.ZERO); - vehicle.resetSuspension(); - } else { - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java deleted file mode 100644 index f0f4d7807d..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; -import com.jme3.bullet.control.CharacterControl; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.scene.CameraNode; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.control.CameraControl.ControlDirection; - -/** - * A walking physical character followed by a 3rd person camera. (No animation.) - * @author normenhansen, zathras - */ -public class TestPhysicsCharacter extends SimpleApplication implements ActionListener { - - private BulletAppState bulletAppState; - private CharacterControl physicsCharacter; - final private Vector3f walkDirection = new Vector3f(0,0,0); - final private Vector3f viewDirection = new Vector3f(0,0,0); - private boolean leftStrafe = false, rightStrafe = false, forward = false, backward = false, - leftRotate = false, rightRotate = false; - - public static void main(String[] args) { - TestPhysicsCharacter app = new TestPhysicsCharacter(); - app.start(); - } - - private void setupKeys() { - inputManager.addMapping("Strafe Left", - new KeyTrigger(KeyInput.KEY_Q), - new KeyTrigger(KeyInput.KEY_Z)); - inputManager.addMapping("Strafe Right", - new KeyTrigger(KeyInput.KEY_E), - new KeyTrigger(KeyInput.KEY_X)); - inputManager.addMapping("Rotate Left", - new KeyTrigger(KeyInput.KEY_A), - new KeyTrigger(KeyInput.KEY_LEFT)); - inputManager.addMapping("Rotate Right", - new KeyTrigger(KeyInput.KEY_D), - new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addMapping("Walk Forward", - new KeyTrigger(KeyInput.KEY_W), - new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("Walk Backward", - new KeyTrigger(KeyInput.KEY_S), - new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("Jump", - new KeyTrigger(KeyInput.KEY_SPACE), - new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addMapping("Shoot", - new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(this, "Strafe Left", "Strafe Right"); - inputManager.addListener(this, "Rotate Left", "Rotate Right"); - inputManager.addListener(this, "Walk Forward", "Walk Backward"); - inputManager.addListener(this, "Jump", "Shoot"); - } - @Override - public void simpleInitApp() { - // activate physics - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - - // init a physical test scene - PhysicsTestHelper.createPhysicsTestWorldSoccer(rootNode, assetManager, bulletAppState.getPhysicsSpace()); - setupKeys(); - - // Add a physics character to the world - physicsCharacter = new CharacterControl(new CapsuleCollisionShape(0.5f, 1.8f), .1f); - physicsCharacter.setPhysicsLocation(new Vector3f(0, 1, 0)); - Node characterNode = new Node("character node"); - Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); - model.scale(0.25f); - characterNode.addControl(physicsCharacter); - getPhysicsSpace().add(physicsCharacter); - rootNode.attachChild(characterNode); - characterNode.attachChild(model); - - // set forward camera node that follows the character - CameraNode camNode = new CameraNode("CamNode", cam); - camNode.setControlDir(ControlDirection.SpatialToCamera); - camNode.setLocalTranslation(new Vector3f(0, 1, -5)); - camNode.lookAt(model.getLocalTranslation(), Vector3f.UNIT_Y); - characterNode.attachChild(camNode); - - //disable the default 1st-person flyCam (don't forget this!!) - flyCam.setEnabled(false); - - } - - @Override - public void simpleUpdate(float tpf) { - Vector3f camDir = cam.getDirection().mult(0.2f); - Vector3f camLeft = cam.getLeft().mult(0.2f); - camDir.y = 0; - camLeft.y = 0; - viewDirection.set(camDir); - walkDirection.set(0, 0, 0); - if (leftStrafe) { - walkDirection.addLocal(camLeft); - } else - if (rightStrafe) { - walkDirection.addLocal(camLeft.negate()); - } - if (leftRotate) { - viewDirection.addLocal(camLeft.mult(tpf)); - } else - if (rightRotate) { - viewDirection.addLocal(camLeft.mult(tpf).negate()); - } - if (forward) { - walkDirection.addLocal(camDir); - } else - if (backward) { - walkDirection.addLocal(camDir.negate()); - } - physicsCharacter.setWalkDirection(walkDirection); - physicsCharacter.setViewDirection(viewDirection); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Strafe Left")) { - if (value) { - leftStrafe = true; - } else { - leftStrafe = false; - } - } else if (binding.equals("Strafe Right")) { - if (value) { - rightStrafe = true; - } else { - rightStrafe = false; - } - } else if (binding.equals("Rotate Left")) { - if (value) { - leftRotate = true; - } else { - leftRotate = false; - } - } else if (binding.equals("Rotate Right")) { - if (value) { - rightRotate = true; - } else { - rightRotate = false; - } - } else if (binding.equals("Walk Forward")) { - if (value) { - forward = true; - } else { - forward = false; - } - } else if (binding.equals("Walk Backward")) { - if (value) { - backward = true; - } else { - backward = false; - } - } else if (binding.equals("Jump")) { - physicsCharacter.jump(); - } - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleRender(RenderManager rm) { - //TODO: add render code - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java deleted file mode 100644 index 12b18af865..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.joints.HingeJoint; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; - -public class TestPhysicsHingeJoint extends SimpleApplication implements AnalogListener { - private BulletAppState bulletAppState; - private HingeJoint joint; - - public static void main(String[] args) { - TestPhysicsHingeJoint app = new TestPhysicsHingeJoint(); - app.start(); - } - - private void setupKeys() { - inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Swing", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this, "Left", "Right", "Swing"); - } - - @Override - public void onAnalog(String binding, float value, float tpf) { - if(binding.equals("Left")){ - joint.enableMotor(true, 1, .1f); - } - else if(binding.equals("Right")){ - joint.enableMotor(true, -1, .1f); - } - else if(binding.equals("Swing")){ - joint.enableMotor(false, 0, 0); - } - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - setupKeys(); - setupJoint(); - } - - private PhysicsSpace getPhysicsSpace(){ - return bulletAppState.getPhysicsSpace(); - } - - public void setupJoint() { - Node holderNode=PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0); - holderNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,0,0f)); - rootNode.attachChild(holderNode); - getPhysicsSpace().add(holderNode); - - Node hammerNode=PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .3f, .3f, .3f)),1); - hammerNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,-1,0f)); - rootNode.attachChild(hammerNode); - getPhysicsSpace().add(hammerNode); - - joint=new HingeJoint(holderNode.getControl(RigidBodyControl.class), hammerNode.getControl(RigidBodyControl.class), Vector3f.ZERO, new Vector3f(0f,-1,0f), Vector3f.UNIT_Z, Vector3f.UNIT_Z); - getPhysicsSpace().add(joint); - } - - @Override - public void simpleUpdate(float tpf) { - - } - - -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java deleted file mode 100644 index 9d3a77350e..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java +++ /dev/null @@ -1,69 +0,0 @@ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.collision.PhysicsCollisionObject; -import com.jme3.bullet.collision.PhysicsRayTestResult; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.util.CollisionShapeFactory; -import com.jme3.font.BitmapText; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import java.util.List; - -/** - * - * @author wezrule - */ -public class TestPhysicsRayCast extends SimpleApplication { - - final private BulletAppState bulletAppState = new BulletAppState(); - - public static void main(String[] args) { - new TestPhysicsRayCast().start(); - } - - @Override - public void simpleInitApp() { - stateManager.attach(bulletAppState); - initCrossHair(); - - Spatial s = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml"); - s.setLocalScale(0.1f); - - CollisionShape collisionShape = CollisionShapeFactory.createMeshShape(s); - Node n = new Node("elephant"); - n.addControl(new RigidBodyControl(collisionShape, 1)); - n.getControl(RigidBodyControl.class).setKinematic(true); - bulletAppState.getPhysicsSpace().add(n); - rootNode.attachChild(n); - bulletAppState.setDebugEnabled(true); - } - - @Override - public void simpleUpdate(float tpf) { - float rayLength = 50f; - Vector3f start = cam.getLocation(); - Vector3f end = cam.getDirection().scaleAdd(rayLength, start); - List rayTest - = bulletAppState.getPhysicsSpace().rayTest(start, end); - if (rayTest.size() > 0) { - PhysicsRayTestResult get = rayTest.get(0); - PhysicsCollisionObject collisionObject = get.getCollisionObject(); - // Display the name of the 1st object in place of FPS. - fpsText.setText(collisionObject.getUserObject().toString()); - } else { - // Provide prompt feedback that no collision object was hit. - fpsText.setText("MISSING"); - } - } - - private void initCrossHair() { - BitmapText bitmapText = new BitmapText(guiFont); - bitmapText.setText("+"); - bitmapText.setLocalTranslation((settings.getWidth() - bitmapText.getLineWidth())*0.5f, (settings.getHeight() + bitmapText.getLineHeight())*0.5f, 0); - guiNode.attachChild(bitmapText); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java deleted file mode 100644 index 13c5133524..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.bullet; - - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.*; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.joints.HingeJoint; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.export.binary.BinaryImporter; -import com.jme3.math.Plane; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This is a basic Test of jbullet-jme functions - * - * @author normenhansen - */ -public class TestPhysicsReadWrite extends SimpleApplication{ - private BulletAppState bulletAppState; - - public static void main(String[] args){ - TestPhysicsReadWrite app = new TestPhysicsReadWrite(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - Node physicsRootNode = new Node("PhysicsRootNode"); - rootNode.attachChild(physicsRootNode); - - // Add a physics sphere to the world - Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); - physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); - rootNode.attachChild(physicsSphere); - getPhysicsSpace().add(physicsSphere); - - // Add a physics sphere to the world using the collision shape from sphere one - Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, physicsSphere.getControl(RigidBodyControl.class).getCollisionShape(), 1); - physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); - rootNode.attachChild(physicsSphere2); - getPhysicsSpace().add(physicsSphere2); - - // Add a physics box to the world - Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); - physicsBox.getControl(RigidBodyControl.class).setFriction(0.1f); - physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); - rootNode.attachChild(physicsBox); - getPhysicsSpace().add(physicsBox); - - // Add a physics cylinder to the world - Node physicsCylinder = PhysicsTestHelper.createPhysicsTestNode(assetManager, new CylinderCollisionShape(new Vector3f(1f, 1f, 1.5f)), 1); - physicsCylinder.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2, 2, 0)); - rootNode.attachChild(physicsCylinder); - getPhysicsSpace().add(physicsCylinder); - - // an obstacle mesh, does not move (mass=0) - Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); - node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); - rootNode.attachChild(node2); - getPhysicsSpace().add(node2); - - // the floor mesh, does not move (mass=0) - Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); - node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); - rootNode.attachChild(node3); - getPhysicsSpace().add(node3); - - // Join the physics objects with a Point2Point joint - HingeJoint joint=new HingeJoint(physicsSphere.getControl(RigidBodyControl.class), physicsBox.getControl(RigidBodyControl.class), new Vector3f(-2,0,0), new Vector3f(2,0,0), Vector3f.UNIT_Z,Vector3f.UNIT_Z); - getPhysicsSpace().add(joint); - - //save and load the physicsRootNode - try { - //remove all physics objects from physics space - getPhysicsSpace().removeAll(physicsRootNode); - physicsRootNode.removeFromParent(); - //export to byte array - ByteArrayOutputStream bout=new ByteArrayOutputStream(); - BinaryExporter.getInstance().save(physicsRootNode, bout); - //import from byte array - ByteArrayInputStream bin=new ByteArrayInputStream(bout.toByteArray()); - BinaryImporter imp=BinaryImporter.getInstance(); - imp.setAssetManager(assetManager); - Node newPhysicsRootNode=(Node)imp.load(bin); - //add all physics objects to physics space - getPhysicsSpace().addAll(newPhysicsRootNode); - rootNode.attachChild(newPhysicsRootNode); - } catch (IOException ex) { - Logger.getLogger(TestPhysicsReadWrite.class.getName()).log(Level.SEVERE, null, ex); - } - - } - - private PhysicsSpace getPhysicsSpace(){ - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleUpdate(float tpf) { - //TODO: add update code - } - - @Override - public void simpleRender(RenderManager rm) { - //TODO: add render code - } - -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java b/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java deleted file mode 100644 index 9146c8d70b..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.asset.plugins.ZipLocator; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.objects.PhysicsCharacter; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.MaterialList; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.plugins.ogre.OgreMeshKey; -import java.io.File; - -public class TestQ3 extends SimpleApplication implements ActionListener { - - private BulletAppState bulletAppState; - private PhysicsCharacter player; - final private Vector3f walkDirection = new Vector3f(); - private static boolean useHttp = false; - private boolean left=false,right=false,up=false,down=false; - - public static void main(String[] args) { - TestQ3 app = new TestQ3(); - app.start(); - } - - @Override - public void simpleInitApp() { - File file = new File("quake3level.zip"); - if (!file.exists()) { - useHttp = true; - } - - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - flyCam.setMoveSpeed(100); - setupKeys(); - - this.cam.setFrustumFar(2000); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White.clone().multLocal(2)); - dl.setDirection(new Vector3f(-1, -1, -1).normalize()); - rootNode.addLight(dl); - - AmbientLight am = new AmbientLight(); - am.setColor(ColorRGBA.White.mult(2)); - rootNode.addLight(am); - - // load the level from zip or http zip - if (useHttp) { - assetManager.registerLocator( - "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/quake3level.zip", - HttpZipLocator.class); - } else { - assetManager.registerLocator("quake3level.zip", ZipLocator.class); - } - - // create the geometry and attach it - MaterialList matList = (MaterialList) assetManager.loadAsset("Scene.material"); - OgreMeshKey key = new OgreMeshKey("main.meshxml", matList); - Node gameLevel = (Node) assetManager.loadAsset(key); - gameLevel.setLocalScale(0.1f); - - // add a physics control, it will generate a MeshCollisionShape based on the gameLevel - gameLevel.addControl(new RigidBodyControl(0)); - - player = new PhysicsCharacter(new SphereCollisionShape(5), .01f); - player.setJumpSpeed(20); - player.setFallSpeed(30); - player.setGravity(30); - - player.setPhysicsLocation(new Vector3f(60, 10, -60)); - - rootNode.attachChild(gameLevel); - - getPhysicsSpace().addAll(gameLevel); - getPhysicsSpace().add(player); - } - - private PhysicsSpace getPhysicsSpace(){ - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleUpdate(float tpf) { - Vector3f camDir = cam.getDirection().clone().multLocal(0.6f); - Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f); - walkDirection.set(0,0,0); - if(left) - walkDirection.addLocal(camLeft); - if(right) - walkDirection.addLocal(camLeft.negate()); - if(up) - walkDirection.addLocal(camDir); - if(down) - walkDirection.addLocal(camDir.negate()); - player.setWalkDirection(walkDirection); - cam.setLocation(player.getPhysicsLocation()); - } - - private void setupKeys() { - inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this,"Lefts"); - inputManager.addListener(this,"Rights"); - inputManager.addListener(this,"Ups"); - inputManager.addListener(this,"Downs"); - inputManager.addListener(this,"Space"); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - - if (binding.equals("Lefts")) { - if(value) - left=true; - else - left=false; - } else if (binding.equals("Rights")) { - if(value) - right=true; - else - right=false; - } else if (binding.equals("Ups")) { - if(value) - up=true; - else - up=false; - } else if (binding.equals("Downs")) { - if(value) - down=true; - else - down=false; - } else if (binding.equals("Space")) { - player.jump(); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java b/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java deleted file mode 100644 index 2c4d81dade..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.joints.ConeJoint; -import com.jme3.bullet.joints.PhysicsJoint; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; - -/** - * - * @author normenhansen - */ -public class TestRagDoll extends SimpleApplication implements ActionListener { - - private BulletAppState bulletAppState; - final private Node ragDoll = new Node(); - private Node shoulders; - final private Vector3f upForce = new Vector3f(0, 200, 0); - private boolean applyForce = false; - - public static void main(String[] args) { - TestRagDoll app = new TestRagDoll(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - inputManager.addMapping("Pull ragdoll up", new MouseButtonTrigger(0)); - inputManager.addListener(this, "Pull ragdoll up"); - PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); - createRagDoll(); - } - - private void createRagDoll() { - shoulders = createLimb(0.2f, 1.0f, new Vector3f(0.00f, 1.5f, 0), true); - Node uArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f, 0.8f, 0), false); - Node uArmR = createLimb(0.2f, 0.5f, new Vector3f(0.75f, 0.8f, 0), false); - Node lArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f, -0.2f, 0), false); - Node lArmR = createLimb(0.2f, 0.5f, new Vector3f(0.75f, -0.2f, 0), false); - Node body = createLimb(0.2f, 1.0f, new Vector3f(0.00f, 0.5f, 0), false); - Node hips = createLimb(0.2f, 0.5f, new Vector3f(0.00f, -0.5f, 0), true); - Node uLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f, -1.2f, 0), false); - Node uLegR = createLimb(0.2f, 0.5f, new Vector3f(0.25f, -1.2f, 0), false); - Node lLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f, -2.2f, 0), false); - Node lLegR = createLimb(0.2f, 0.5f, new Vector3f(0.25f, -2.2f, 0), false); - - join(body, shoulders, new Vector3f(0f, 1.4f, 0)); - join(body, hips, new Vector3f(0f, -0.5f, 0)); - - join(uArmL, shoulders, new Vector3f(-0.75f, 1.4f, 0)); - join(uArmR, shoulders, new Vector3f(0.75f, 1.4f, 0)); - join(uArmL, lArmL, new Vector3f(-0.75f, .4f, 0)); - join(uArmR, lArmR, new Vector3f(0.75f, .4f, 0)); - - join(uLegL, hips, new Vector3f(-.25f, -0.5f, 0)); - join(uLegR, hips, new Vector3f(.25f, -0.5f, 0)); - join(uLegL, lLegL, new Vector3f(-.25f, -1.7f, 0)); - join(uLegR, lLegR, new Vector3f(.25f, -1.7f, 0)); - - ragDoll.attachChild(shoulders); - ragDoll.attachChild(body); - ragDoll.attachChild(hips); - ragDoll.attachChild(uArmL); - ragDoll.attachChild(uArmR); - ragDoll.attachChild(lArmL); - ragDoll.attachChild(lArmR); - ragDoll.attachChild(uLegL); - ragDoll.attachChild(uLegR); - ragDoll.attachChild(lLegL); - ragDoll.attachChild(lLegR); - - rootNode.attachChild(ragDoll); - bulletAppState.getPhysicsSpace().addAll(ragDoll); - } - - private Node createLimb(float width, float height, Vector3f location, boolean rotate) { - int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y; - CapsuleCollisionShape shape = new CapsuleCollisionShape(width, height, axis); - Node node = new Node("Limb"); - RigidBodyControl rigidBodyControl = new RigidBodyControl(shape, 1); - node.setLocalTranslation(location); - node.addControl(rigidBodyControl); - return node; - } - - private PhysicsJoint join(Node A, Node B, Vector3f connectionPoint) { - Vector3f pivotA = A.worldToLocal(connectionPoint, new Vector3f()); - Vector3f pivotB = B.worldToLocal(connectionPoint, new Vector3f()); - ConeJoint joint = new ConeJoint(A.getControl(RigidBodyControl.class), B.getControl(RigidBodyControl.class), pivotA, pivotB); - joint.setLimit(1f, 1f, 0); - return joint; - } - - @Override - public void onAction(String string, boolean bln, float tpf) { - if ("Pull ragdoll up".equals(string)) { - if (bln) { - shoulders.getControl(RigidBodyControl.class).activate(); - applyForce = true; - } else { - applyForce = false; - } - } - } - - @Override - public void simpleUpdate(float tpf) { - if (applyForce) { - shoulders.getControl(RigidBodyControl.class).applyForce(upForce, Vector3f.ZERO); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java b/jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java deleted file mode 100644 index b457e3b15b..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.Action; -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.animation.DynamicAnimControl; -import com.jme3.bullet.animation.RangeOfMotion; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.texture.Texture; - -/** - * @author normenhansen - */ -public class TestRagdollCharacter - extends SimpleApplication - implements ActionListener { - - private AnimComposer composer; - private boolean forward = false, backward = false, - leftRotate = false, rightRotate = false; - private Node model; - private PhysicsSpace physicsSpace; - - public static void main(String[] args) { - TestRagdollCharacter app = new TestRagdollCharacter(); - app.start(); - } - - public void onSliceDone() { - composer.setCurrentAction("IdleTop"); - } - - static void setupSinbad(DynamicAnimControl ragdoll) { - ragdoll.link("Waist", 1f, - new RangeOfMotion(1f, -0.4f, 0.8f, -0.8f, 0.4f, -0.4f)); - ragdoll.link("Chest", 1f, new RangeOfMotion(0.4f, 0f, 0.4f)); - ragdoll.link("Neck", 1f, new RangeOfMotion(0.5f, 1f, 0.7f)); - - ragdoll.link("Clavicle.R", 1f, - new RangeOfMotion(0.3f, -0.6f, 0f, 0f, 0.4f, -0.4f)); - ragdoll.link("Humerus.R", 1f, - new RangeOfMotion(1.6f, -0.8f, 1f, -1f, 1.6f, -1f)); - ragdoll.link("Ulna.R", 1f, new RangeOfMotion(0f, 0f, 1f, -1f, 0f, -2f)); - ragdoll.link("Hand.R", 1f, new RangeOfMotion(0.8f, 0f, 0.2f)); - - ragdoll.link("Clavicle.L", 1f, - new RangeOfMotion(0.6f, -0.3f, 0f, 0f, 0.4f, -0.4f)); - ragdoll.link("Humerus.L", - 1f, new RangeOfMotion(0.8f, -1.6f, 1f, -1f, 1f, -1.6f)); - ragdoll.link("Ulna.L", 1f, new RangeOfMotion(0f, 0f, 1f, -1f, 2f, 0f)); - ragdoll.link("Hand.L", 1f, new RangeOfMotion(0.8f, 0f, 0.2f)); - - ragdoll.link("Thigh.R", 1f, - new RangeOfMotion(0.4f, -1f, 0.4f, -0.4f, 1f, -0.5f)); - ragdoll.link("Calf.R", 1f, new RangeOfMotion(2f, 0f, 0f, 0f, 0f, 0f)); - ragdoll.link("Foot.R", 1f, new RangeOfMotion(0.3f, 0.5f, 0f)); - - ragdoll.link("Thigh.L", 1f, - new RangeOfMotion(0.4f, -1f, 0.4f, -0.4f, 0.5f, -1f)); - ragdoll.link("Calf.L", 1f, new RangeOfMotion(2f, 0f, 0f, 0f, 0f, 0f)); - ragdoll.link("Foot.L", 1f, new RangeOfMotion(0.3f, 0.5f, 0f)); - } - - @Override - public void onAction(String binding, boolean isPressed, float tpf) { - if (binding.equals("Rotate Left")) { - if (isPressed) { - leftRotate = true; - } else { - leftRotate = false; - } - } else if (binding.equals("Rotate Right")) { - if (isPressed) { - rightRotate = true; - } else { - rightRotate = false; - } - } else if (binding.equals("Slice")) { - if (isPressed) { - composer.setCurrentAction("SliceOnce"); - } - } else if (binding.equals("Walk Forward")) { - if (isPressed) { - forward = true; - } else { - forward = false; - } - } else if (binding.equals("Walk Backward")) { - if (isPressed) { - backward = true; - } else { - backward = false; - } - } - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(50f); - cam.setLocation(new Vector3f(-16f, 4.7f, -1.6f)); - cam.setRotation(new Quaternion(0.0484f, 0.804337f, -0.066f, 0.5885f)); - - setupKeys(); - setupLight(); - - BulletAppState bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - //bulletAppState.setDebugEnabled(true); - physicsSpace = bulletAppState.getPhysicsSpace(); - - PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, - physicsSpace); - initWall(2f, 1f, 1f); - - model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); - rootNode.attachChild(model); - model.lookAt(new Vector3f(0f, 0f, -1f), Vector3f.UNIT_Y); - model.setLocalTranslation(4f, 0f, -7f); - - composer = model.getControl(AnimComposer.class); - composer.setCurrentAction("IdleTop"); - - Action slice = composer.action("SliceHorizontal"); - composer.actionSequence("SliceOnce", - slice, Tweens.callMethod(this, "onSliceDone")); - - DynamicAnimControl ragdoll = new DynamicAnimControl(); - setupSinbad(ragdoll); - model.addControl(ragdoll); - physicsSpace.add(ragdoll); - } - - @Override - public void simpleUpdate(float tpf) { - if (forward) { - model.move(model.getLocalRotation().multLocal(new Vector3f(0f, 0f, tpf))); - } else if (backward) { - model.move(model.getLocalRotation().multLocal(new Vector3f(0f, 0f, -tpf))); - } else if (leftRotate) { - model.rotate(0f, tpf, 0f); - } else if (rightRotate) { - model.rotate(0f, -tpf, 0f); - } - } - - private void initWall(float bLength, float bWidth, float bHeight) { - Box brick = new Box(bLength, bHeight, bWidth); - brick.scaleTextureCoordinates(new Vector2f(1f, 0.5f)); - Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - mat2.setTexture("ColorMap", tex); - - float startpt = bLength / 4f; - float height = -5f; - for (int j = 0; j < 15; j++) { - for (int i = 0; i < 4; i++) { - Vector3f ori = new Vector3f(i * bLength * 2f + startpt, bHeight + height, -10f); - Geometry brickGeometry = new Geometry("brick", brick); - brickGeometry.setMaterial(mat2); - brickGeometry.setLocalTranslation(ori); - // for geometry with sphere mesh the physics system automatically uses a sphere collision shape - brickGeometry.addControl(new RigidBodyControl(1.5f)); - brickGeometry.setShadowMode(ShadowMode.CastAndReceive); - brickGeometry.getControl(RigidBodyControl.class).setFriction(0.6f); - this.rootNode.attachChild(brickGeometry); - physicsSpace.add(brickGeometry); - } - startpt = -startpt; - height += 2f * bHeight; - } - } - - private void setupKeys() { - inputManager.addMapping("Rotate Left", - new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("Rotate Right", - new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Walk Backward", - new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("Walk Forward", - new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("Slice", - new KeyTrigger(KeyInput.KEY_SPACE), - new KeyTrigger(KeyInput.KEY_RETURN)); - - inputManager.addListener(this, "Rotate Left", "Rotate Right", "Slice", - "Walk Backward", "Walk Forward"); - } - - private void setupLight() { - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1f).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1f)); - rootNode.addLight(dl); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java b/jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java deleted file mode 100644 index 9cf2808aeb..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.*; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.math.Plane; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; - -/** - * This is a basic Test of jbullet-jme functions - * - * @author normenhansen - */ -public class TestSimplePhysics extends SimpleApplication { - - private BulletAppState bulletAppState; - - public static void main(String[] args) { - TestSimplePhysics app = new TestSimplePhysics(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - bulletAppState.setDebugEnabled(true); - - // Add a physics sphere to the world - Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); - physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); - rootNode.attachChild(physicsSphere); - getPhysicsSpace().add(physicsSphere); - - // Add a physics sphere to the world using the collision shape from sphere one - Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, physicsSphere.getControl(RigidBodyControl.class).getCollisionShape(), 1); - physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); - rootNode.attachChild(physicsSphere2); - getPhysicsSpace().add(physicsSphere2); - - // Add a physics box to the world - Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); - physicsBox.getControl(RigidBodyControl.class).setFriction(0.1f); - physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); - rootNode.attachChild(physicsBox); - getPhysicsSpace().add(physicsBox); - - // Add a physics cylinder to the world - Node physicsCylinder = PhysicsTestHelper.createPhysicsTestNode(assetManager, new CylinderCollisionShape(new Vector3f(1f, 1f, 1.5f)), 1); - physicsCylinder.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2, 2, 0)); - rootNode.attachChild(physicsCylinder); - getPhysicsSpace().add(physicsCylinder); - - // an obstacle mesh, does not move (mass=0) - Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); - node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); - rootNode.attachChild(node2); - getPhysicsSpace().add(node2); - - // the floor mesh, does not move (mass=0) - Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); - node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); - rootNode.attachChild(node3); - getPhysicsSpace().add(node3); - - // Join the physics objects with a Point2Point joint -// PhysicsPoint2PointJoint joint=new PhysicsPoint2PointJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0)); -// PhysicsHingeJoint joint=new PhysicsHingeJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0), Vector3f.UNIT_Z,Vector3f.UNIT_Z); -// getPhysicsSpace().add(joint); - - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java b/jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java deleted file mode 100644 index 5b51b50dad..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package jme3test.bullet; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.collision.PhysicsCollisionObject; -import com.jme3.bullet.collision.PhysicsSweepTestResult; -import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.math.Transform; -import com.jme3.scene.Node; -import java.util.List; - -/** - * - * A spatial moves and sweeps its next movement for obstacles before moving - * there Run this example with Vsync enabled - * - * @author wezrule - */ -public class TestSweepTest extends SimpleApplication { - - final private BulletAppState bulletAppState = new BulletAppState(); - private CapsuleCollisionShape capsuleCollisionShape; - private Node capsule; - final private float dist = .5f; - - public static void main(String[] args) { - new TestSweepTest().start(); - } - - @Override - public void simpleInitApp() { - CapsuleCollisionShape obstacleCollisionShape - = new CapsuleCollisionShape(0.3f, 0.5f); - capsuleCollisionShape = new CapsuleCollisionShape(1f, 1f); - - stateManager.attach(bulletAppState); - - capsule = new Node("capsule"); - capsule.move(-2, 0, 0); - capsule.addControl(new RigidBodyControl(capsuleCollisionShape, 1)); - capsule.getControl(RigidBodyControl.class).setKinematic(true); - bulletAppState.getPhysicsSpace().add(capsule); - rootNode.attachChild(capsule); - - Node obstacle = new Node("obstacle"); - obstacle.move(2, 0, 0); - RigidBodyControl bodyControl = new RigidBodyControl(obstacleCollisionShape, 0); - obstacle.addControl(bodyControl); - bulletAppState.getPhysicsSpace().add(obstacle); - rootNode.attachChild(obstacle); - - bulletAppState.setDebugEnabled(true); - } - - @Override - public void simpleUpdate(float tpf) { - - float move = tpf * 1; - boolean colliding = false; - - List sweepTest = bulletAppState.getPhysicsSpace().sweepTest(capsuleCollisionShape, new Transform(capsule.getWorldTranslation()), new Transform(capsule.getWorldTranslation().add(dist, 0, 0))); - - for (PhysicsSweepTestResult result : sweepTest) { - if (result.getCollisionObject().getCollisionShape() != capsuleCollisionShape) { - PhysicsCollisionObject collisionObject = result.getCollisionObject(); - fpsText.setText("Almost colliding with " + collisionObject.getUserObject().toString()); - colliding = true; - } - } - - if (!colliding) { - // if the sweep is clear then move the spatial - capsule.move(move, 0, 0); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java b/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java deleted file mode 100644 index 61f08d25f2..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.Armature; -import com.jme3.anim.ArmatureMask; -import com.jme3.anim.SkinningControl; -import com.jme3.anim.tween.Tween; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.Action; -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.PhysicsCollisionEvent; -import com.jme3.bullet.collision.PhysicsCollisionListener; -import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.CharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.util.CollisionShapeFactory; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh.Type; -import com.jme3.effect.shapes.EmitterSphereShape; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.renderer.Camera; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.*; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.util.SkyFactory; - -import java.util.ArrayList; -import java.util.List; - -/** - * A walking animated character followed by a 3rd person camera on a terrain with LOD. - * @author normenhansen - */ -public class TestWalkingChar extends SimpleApplication - implements ActionListener, PhysicsCollisionListener { - - private BulletAppState bulletAppState; - //character - private CharacterControl character; - private Node model; - //temp vectors - final private Vector3f walkDirection = new Vector3f(); - //Materials - private Material matBullet; - //animation - private Action standAction; - private Action walkAction; - private AnimComposer composer; - private float airTime = 0; - //camera - private boolean left = false, right = false, up = false, down = false; - //bullet - private Sphere bullet; - private SphereCollisionShape bulletCollisionShape; - //explosion - private ParticleEmitter effect; - //brick wall - private Box brick; - final private float bLength = 0.8f; - final private float bWidth = 0.4f; - final private float bHeight = 0.4f; - - public static void main(String[] args) { - TestWalkingChar app = new TestWalkingChar(); - app.start(); - } - - @Override - public void simpleInitApp() { - bulletAppState = new BulletAppState(); - bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); - stateManager.attach(bulletAppState); - setupKeys(); - prepareBullet(); - prepareEffect(); - createLight(); - createSky(); - createTerrain(); - createWall(); - createCharacter(); - setupChaseCamera(); - setupAnimationController(); - setupFilter(); - } - - private void setupFilter() { - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects); - fpp.addFilter(bloom); - viewPort.addProcessor(fpp); - } - - private PhysicsSpace getPhysicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - private void setupKeys() { - inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addListener(this, "wireframe"); - inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("CharSpace", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this, "CharLeft"); - inputManager.addListener(this, "CharRight"); - inputManager.addListener(this, "CharUp"); - inputManager.addListener(this, "CharDown"); - inputManager.addListener(this, "CharSpace"); - inputManager.addListener(this, "CharShoot"); - } - - private void createWall() { - float xOff = -144; - float zOff = -40; - float startpt = bLength / 4 - xOff; - float height = 6.1f; - brick = new Box(bLength, bHeight, bWidth); - brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); - for (int j = 0; j < 15; j++) { - for (int i = 0; i < 4; i++) { - Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight + height, zOff); - addBrick(vt); - } - startpt = -startpt; - height += 1.01f * bHeight; - } - } - - private void addBrick(Vector3f ori) { - Geometry brickGeometry = new Geometry("brick", brick); - brickGeometry.setMaterial(matBullet); - brickGeometry.setLocalTranslation(ori); - brickGeometry.addControl(new RigidBodyControl(1.5f)); - brickGeometry.setShadowMode(ShadowMode.CastAndReceive); - this.rootNode.attachChild(brickGeometry); - this.getPhysicsSpace().add(brickGeometry); - } - - private void prepareBullet() { - bullet = new Sphere(32, 32, 0.4f, true, false); - bullet.setTextureMode(TextureMode.Projected); - bulletCollisionShape = new SphereCollisionShape(0.4f); - matBullet = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - matBullet.setColor("Color", ColorRGBA.Green); - matBullet.setColor("GlowColor", ColorRGBA.Green); - getPhysicsSpace().addCollisionListener(this); - } - - private void prepareEffect() { - int COUNT_FACTOR = 1; - float COUNT_FACTOR_F = 1f; - effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR); - effect.setSelectRandomImage(true); - effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (1f / COUNT_FACTOR_F))); - effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); - effect.setStartSize(1.3f); - effect.setEndSize(2f); - effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); - effect.setParticlesPerSec(0); - effect.setGravity(0, -5, 0); - effect.setLowLife(.4f); - effect.setHighLife(.5f); - effect.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, 7, 0)); - effect.getParticleInfluencer().setVelocityVariation(1f); - effect.setImagesX(2); - effect.setImagesY(2); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); - effect.setMaterial(mat); -// effect.setLocalScale(100); - rootNode.attachChild(effect); - } - - private void createLight() { - Vector3f direction = new Vector3f(-0.1f, -0.7f, -1).normalizeLocal(); - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(direction); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - } - - private void createSky() { - rootNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - } - - private void createTerrain() { - Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - - } catch (Exception e) { - e.printStackTrace(); - } - - TerrainQuad terrain - = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - List cameras = new ArrayList<>(); - cameras.add(getCamera()); - TerrainLodControl control = new TerrainLodControl(terrain, cameras); - terrain.addControl(control); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(2, 2, 2)); - - RigidBodyControl terrainPhysicsNode - = new RigidBodyControl(CollisionShapeFactory.createMeshShape(terrain), 0); - terrain.addControl(terrainPhysicsNode); - rootNode.attachChild(terrain); - getPhysicsSpace().add(terrainPhysicsNode); - } - - private void createCharacter() { - CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f); - character = new CharacterControl(capsule, 0.01f); - model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - model.addControl(character); - character.setPhysicsLocation(new Vector3f(-140, 40, -10)); - rootNode.attachChild(model); - getPhysicsSpace().add(character); - } - - private void setupChaseCamera() { - flyCam.setEnabled(false); - new ChaseCamera(cam, model, inputManager); - } - - private void setupAnimationController() { - composer = model.getControl(AnimComposer.class); - standAction = composer.action("stand"); - walkAction = composer.action("Walk"); - /* - * Add a "shootOnce" animation action - * that performs the "Dodge" action one time only. - */ - Action dodgeAction = composer.action("Dodge"); - Tween doneTween = Tweens.callMethod(this, "onShootDone"); - composer.actionSequence("shootOnce", dodgeAction, doneTween); - /* - * Define a shooting animation layer - * that animates only the joints of the right arm. - */ - SkinningControl skinningControl - = model.getControl(SkinningControl.class); - Armature armature = skinningControl.getArmature(); - ArmatureMask shootingMask - = ArmatureMask.createMask(armature, "uparm.right"); - composer.makeLayer("shootingLayer", shootingMask); - /* - * Define a walking animation layer - * that animates all joints except those used for shooting. - */ - ArmatureMask walkingMask = new ArmatureMask(); - walkingMask.addBones(armature, "head", "spine", "spinehigh"); - walkingMask.addFromJoint(armature, "hip.left"); - walkingMask.addFromJoint(armature, "hip.right"); - walkingMask.addFromJoint(armature, "uparm.left"); - composer.makeLayer("walkingLayer", walkingMask); - - composer.setCurrentAction("stand", "shootingLayer"); - composer.setCurrentAction("stand", "walkingLayer"); - } - - @Override - public void simpleUpdate(float tpf) { - Vector3f camDir = cam.getDirection().clone().multLocal(0.1f); - Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f); - camDir.y = 0; - camLeft.y = 0; - walkDirection.set(0, 0, 0); - if (left) { - walkDirection.addLocal(camLeft); - } - if (right) { - walkDirection.addLocal(camLeft.negate()); - } - if (up) { - walkDirection.addLocal(camDir); - } - if (down) { - walkDirection.addLocal(camDir.negate()); - } - if (!character.onGround()) { - airTime = airTime + tpf; - } else { - airTime = 0; - } - - Action action = composer.getCurrentAction("walkingLayer"); - if (walkDirection.length() == 0f) { - if (action != standAction) { - composer.setCurrentAction("stand", "walkingLayer"); - } - } else { - character.setViewDirection(walkDirection); - if (airTime > 0.3f) { - if (action != standAction) { - composer.setCurrentAction("stand", "walkingLayer"); - } - } else if (action != walkAction) { - composer.setCurrentAction("Walk", "walkingLayer"); - } - } - character.setWalkDirection(walkDirection); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("CharLeft")) { - if (value) { - left = true; - } else { - left = false; - } - } else if (binding.equals("CharRight")) { - if (value) { - right = true; - } else { - right = false; - } - } else if (binding.equals("CharUp")) { - if (value) { - up = true; - } else { - up = false; - } - } else if (binding.equals("CharDown")) { - if (value) { - down = true; - } else { - down = false; - } - } else if (binding.equals("CharSpace")) { - character.jump(); - } else if (binding.equals("CharShoot") && !value) { - bulletControl(); - } - } - - private void bulletControl() { - composer.setCurrentAction("shootOnce", "shootingLayer"); - - Geometry bulletGeometry = new Geometry("bullet", bullet); - bulletGeometry.setMaterial(matBullet); - bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); - bulletGeometry.setLocalTranslation(character.getPhysicsLocation().add(cam.getDirection().mult(5))); - RigidBodyControl bulletControl = new BombControl(bulletCollisionShape, 1); - bulletControl.setCcdMotionThreshold(0.1f); - bulletControl.setLinearVelocity(cam.getDirection().mult(80)); - bulletGeometry.addControl(bulletControl); - rootNode.attachChild(bulletGeometry); - getPhysicsSpace().add(bulletControl); - } - - @Override - public void collision(PhysicsCollisionEvent event) { - if (event.getObjectA() instanceof BombControl) { - final Spatial node = event.getNodeA(); - effect.killAllParticles(); - effect.setLocalTranslation(node.getLocalTranslation()); - effect.emitAllParticles(); - } else if (event.getObjectB() instanceof BombControl) { - final Spatial node = event.getNodeB(); - effect.killAllParticles(); - effect.setLocalTranslation(node.getLocalTranslation()); - effect.emitAllParticles(); - } - } - - /** - * Callback to indicate that the "shootOnce" animation action has completed. - */ - void onShootDone() { - /* - * Play the "stand" animation action on the shooting layer. - */ - composer.setCurrentAction("stand", "shootingLayer"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/package-info.java b/jme3-examples/src/main/java/jme3test/bullet/package-info.java deleted file mode 100644 index 866ed54fa7..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for Bullet physics - */ -package jme3test.bullet; diff --git a/jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java b/jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java deleted file mode 100644 index f564790411..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.bullet.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.GImpactCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.debug.BulletDebugAppState; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.PQTorus; -import com.jme3.scene.shape.Torus; -import com.jme3.system.AppSettings; -import java.util.ArrayList; -import java.util.List; -import jme3test.bullet.PhysicsTestHelper; - -/** - * This test demonstrates various GImpactCollisionShapes colliding against two identical curved surfaces. The - * left surface is a MeshCollisionShape, right surface is another GImpactCollisionShape. An ideal result is - * for all objects to land and change to a blue colored mesh indicating they are inactive. Falling through the - * floor, or never going inactive (bouncing forever) are failure conditions. - *

- * Observations as of June 2019 (JME v3.3.0-alpha2): - *

    - *
  1. - * With default starting parameters, Native Bullet should pass the test parameters above. JBullet fails due to - * the rocket/MeshCollisionShape never going inactive. - *
  2. - *
  3. - * Native Bullet behaves better than JBullet. JBullet sometimes allows objects to "gain too much energy" after - * a collision, such as the rocket or teapot. Native also does this, to a lesser degree. This generally - * appears to happen at larger object scales. - *
  4. - *
  5. - * JBullet allows some objects to get "stuck" inside the floor, which usually results in a fall-through - * eventually, generally a larger scales for this test. - *
  6. - *
  7. - * Some shapes such as PQTorus and signpost never go inactive at larger scales for both Native and JBullet (test - * at 1.5 and 1.9 scale) - *
  8. - *
- * - * @author lou - */ -public class TestGimpactShape extends SimpleApplication { - - private static TestGimpactShape test; - private BulletAppState bulletAppState; - private int solverNumIterations = 10; - private BitmapText timeElapsedTxt; - private BitmapText solverNumIterationsTxt; - private BitmapText testScale; - private final List testObjects = new ArrayList<>(); - private float testTimer = 0; - private float scaleMod = 1; - private boolean restart = true; - private static final boolean SKIP_SETTINGS = false;//Used for repeated runs of this test during dev - - public static void main(String[] args) { - test = new TestGimpactShape(); - test.setSettings(new AppSettings(true)); - test.settings.setVSync(true); - if (SKIP_SETTINGS) { - test.settings.setWidth(1920); - test.settings.setHeight(1150); - test.showSettings = !SKIP_SETTINGS; - } - test.start(); - } - - @Override - public void simpleInitApp() { - test = this; - getCamera().setLocation(new Vector3f(40, 30, 160)); - getCamera().lookAt(new Vector3f(40, -5, 0), Vector3f.UNIT_Y); - getFlyByCamera().setMoveSpeed(25); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - dl.setColor(ColorRGBA.Green); - rootNode.addLight(dl); - - //Setup test instructions - guiNode = getGuiNode(); - BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText[] testInfo = new BitmapText[2]; - testInfo[0] = new BitmapText(font); - testInfo[1] = new BitmapText(font); - timeElapsedTxt = new BitmapText(font); - solverNumIterationsTxt = new BitmapText(font); - testScale = new BitmapText(font); - - float lineHeight = testInfo[0].getLineHeight(); - testInfo[0].setText("Camera move:W/A/S/D/Q/Z Solver iterations: 1=10, 2=20, 3=30"); - testInfo[0].setLocalTranslation(5, test.settings.getHeight(), 0); - guiNode.attachChild(testInfo[0]); - testInfo[1].setText("P: Toggle pause Inc/Dec object scale: +, - Space: Restart test"); - testInfo[1].setLocalTranslation(5, test.settings.getHeight() - lineHeight, 0); - guiNode.attachChild(testInfo[1]); - - timeElapsedTxt.setLocalTranslation(202, lineHeight * 1, 0); - guiNode.attachChild(timeElapsedTxt); - solverNumIterationsTxt.setLocalTranslation(202, lineHeight * 2, 0); - guiNode.attachChild(solverNumIterationsTxt); - testScale.setLocalTranslation(202, lineHeight * 3, 0); - guiNode.attachChild(testScale); - - //Setup interactive test controls - inputManager.addMapping("restart", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { - restart = true; - }, "restart"); - - inputManager.addMapping("pause", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { - if (!isPressed) { - return; - } - bulletAppState.setSpeed(bulletAppState.getSpeed() > 0.1 ? 0 : 1); - }, "pause"); - - inputManager.addMapping("1", new KeyTrigger(KeyInput.KEY_1)); - inputManager.addMapping("2", new KeyTrigger(KeyInput.KEY_2)); - inputManager.addMapping("3", new KeyTrigger(KeyInput.KEY_3)); - inputManager.addMapping("+", new KeyTrigger(KeyInput.KEY_ADD), new KeyTrigger(KeyInput.KEY_EQUALS)); - inputManager.addMapping("-", new KeyTrigger(KeyInput.KEY_SUBTRACT), new KeyTrigger(KeyInput.KEY_MINUS)); - inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { - if (!isPressed) { - return; - } - switch (name) { - case "1": - solverNumIterations = 10; - break; - case "2": - solverNumIterations = 20; - break; - case "3": - solverNumIterations = 30; - break; - case "+": - scaleMod += scaleMod < 1.9f ? 0.1f : 0; - break; - case "-": - scaleMod -= scaleMod > 0.5f ? 0.1f : 0; - break; - } - restart = true; - }, "1", "2", "3", "+", "-"); - - initializeNewTest(); - } - - private void initializeNewTest() { - testScale.setText("Object scale: " + String.format("%.1f", scaleMod)); - solverNumIterationsTxt.setText("Solver Iterations: " + solverNumIterations); - - bulletAppState = new BulletAppState(); - bulletAppState.setDebugEnabled(true); - stateManager.attach(bulletAppState); - bulletAppState.getPhysicsSpace().setSolverNumIterations(solverNumIterations); - - float floorSize = 80; - //Left side test - GImpact objects collide with MeshCollisionShape floor - Vector3f leftFloorPos = new Vector3f(-41, -5, -10); - Vector3f leftFloorCenter = leftFloorPos.add(floorSize / 2, 0, floorSize / 2); - - dropTest1(leftFloorCenter); - dropTest2(leftFloorCenter); - dropPot(leftFloorCenter); - dropSword(leftFloorCenter); - dropSign(leftFloorCenter); - dropRocket(leftFloorCenter); - - Geometry leftFloor = PhysicsTestHelper.createMeshTestFloor(assetManager, floorSize, leftFloorPos); - addObject(leftFloor); - - //Right side test - GImpact objects collide with GImpact floor - Vector3f rightFloorPos = new Vector3f(41, -5, -10); - Vector3f rightFloorCenter = rightFloorPos.add(floorSize / 2, 0, floorSize / 2); - - dropTest1(rightFloorCenter); - dropTest2(rightFloorCenter); - dropPot(rightFloorCenter); - dropSword(rightFloorCenter); - dropSign(rightFloorCenter); - dropRocket(rightFloorCenter); - - Geometry rightFloor = PhysicsTestHelper.createGImpactTestFloor(assetManager, floorSize, rightFloorPos); - addObject(rightFloor); - - //Hide physics debug visualization for floors - BulletDebugAppState bulletDebugAppState = stateManager.getState(BulletDebugAppState.class); - bulletDebugAppState.setFilter((Object obj) -> { - return !(obj.equals(rightFloor.getControl(RigidBodyControl.class)) - || obj.equals(leftFloor.getControl(RigidBodyControl.class))); - }); - } - - private void addObject(Spatial s) { - testObjects.add(s); - rootNode.attachChild(s); - physicsSpace().add(s); - } - - private void dropTest1(Vector3f offset) { - offset = offset.add(-18, 6, -18); - attachTestObject(new Torus(16, 16, 0.15f, 0.5f), new Vector3f(-12f, 0f, 5f).add(offset), 1); - attachTestObject(new PQTorus(2f, 3f, 0.6f, 0.2f, 48, 16), new Vector3f(0, 0, 0).add(offset), 5); - - } - - private void dropTest2(Vector3f offset) { - offset = offset.add(18, 6, -18); - attachTestObject(new Torus(16, 16, 0.3f, 0.8f), new Vector3f(12f, 0f, 5f).add(offset), 3); - attachTestObject(new PQTorus(3f, 5f, 0.8f, 0.2f, 96, 16), new Vector3f(0, 0, 0).add(offset), 10); - } - - private void dropPot(Vector3f offset) { - drop(offset.add(-12, 7, 15), "Models/Teapot/Teapot.mesh.xml", 1.0f, 2); - } - - private void dropSword(Vector3f offset) { - drop(offset.add(-10, 5, 3), "Models/Sinbad/Sword.mesh.xml", 1.0f, 2); - } - - private void dropSign(Vector3f offset) { - drop(offset.add(9, 15, 5), "Models/Sign Post/Sign Post.mesh.xml", 1.0f, 1); - } - - private void dropRocket(Vector3f offset) { - RigidBodyControl c = drop(offset.add(26, 4, 7), "Models/SpaceCraft/Rocket.mesh.xml", 4.0f, 3); - c.setAngularDamping(0.5f); - c.setLinearDamping(0.5f); - } - - private RigidBodyControl drop(Vector3f offset, String model, float scale, float mass) { - scale *= scaleMod; - Node n = (Node) assetManager.loadModel(model); - n.setLocalTranslation(offset); - n.rotate(0, 0, -FastMath.HALF_PI); - - Geometry tp = ((Geometry) n.getChild(0)); - tp.scale(scale); - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - tp.setMaterial(mat); - - Mesh mesh = tp.getMesh(); - GImpactCollisionShape shape = new GImpactCollisionShape(mesh); - shape.setScale(new Vector3f(scale, scale, scale)); - - RigidBodyControl control = new RigidBodyControl(shape, mass); - n.addControl(control); - addObject(n); - return control; - } - - private void attachTestObject(Mesh mesh, Vector3f position, float mass) { - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Geometry g = new Geometry("mesh", mesh); - g.scale(scaleMod); - g.setLocalTranslation(position); - g.setMaterial(material); - - GImpactCollisionShape shape = new GImpactCollisionShape(mesh); - shape.setScale(new Vector3f(scaleMod, scaleMod, scaleMod)); - RigidBodyControl control = new RigidBodyControl(shape, mass); - g.addControl(control); - addObject(g); - } - - private PhysicsSpace physicsSpace() { - return bulletAppState.getPhysicsSpace(); - } - - @Override - public void simpleUpdate(float tpf) { - testTimer += tpf * bulletAppState.getSpeed(); - - if (restart) { - cleanup(); - initializeNewTest(); - restart = false; - testTimer = 0; - } - timeElapsedTxt.setText("Time Elapsed: " + String.format("%.3f", testTimer)); - } - - private void cleanup() { - stateManager.detach(bulletAppState); - stateManager.detach(stateManager.getState(BulletDebugAppState.class)); - for (Spatial s : testObjects) { - rootNode.detachChild(s); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java b/jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java deleted file mode 100644 index c1adfcb1a4..0000000000 --- a/jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for specific Bullet-physics collision - * shapes - */ -package jme3test.bullet.shape; diff --git a/jme3-examples/src/main/java/jme3test/collision/RayTrace.java b/jme3-examples/src/main/java/jme3test/collision/RayTrace.java deleted file mode 100644 index 6023b6f132..0000000000 --- a/jme3-examples/src/main/java/jme3test/collision/RayTrace.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.collision; - -import com.jme3.collision.CollisionResults; -import com.jme3.math.Ray; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.scene.Spatial; -import java.awt.FlowLayout; -import java.awt.image.BufferedImage; -import javax.swing.ImageIcon; -import javax.swing.JFrame; -import javax.swing.JLabel; - -public class RayTrace { - - final private BufferedImage image; - final private Camera cam; - final private Spatial scene; - final private CollisionResults results = new CollisionResults(); - private JLabel label; - - public RayTrace(Spatial scene, Camera cam, int width, int height){ - image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - this.scene = scene; - this.cam = cam; - } - - public void show(){ - JFrame frame = new JFrame("HDR View"); - label = new JLabel(new ImageIcon(image)); - frame.getContentPane().add(label); - frame.setLayout(new FlowLayout()); - frame.pack(); - frame.setVisible(true); - } - - public void update(){ - int w = image.getWidth(); - int h = image.getHeight(); - - float wr = (float) cam.getWidth() / image.getWidth(); - float hr = (float) cam.getHeight() / image.getHeight(); - - scene.updateGeometricState(); - - for (int y = 0; y < h; y++){ - for (int x = 0; x < w; x++){ - Vector2f v = new Vector2f(x * wr,y * hr); - Vector3f pos = cam.getWorldCoordinates(v, 0.0f); - Vector3f dir = cam.getWorldCoordinates(v, 0.3f); - dir.subtractLocal(pos).normalizeLocal(); - - Ray r = new Ray(pos, dir); - - results.clear(); - scene.collideWith(r, results); - if (results.size() > 0){ - image.setRGB(x, h - y - 1, 0xFFFFFFFF); - }else{ - image.setRGB(x, h - y - 1, 0xFF000000); - } - } - } - - label.repaint(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/collision/TestMousePick.java b/jme3-examples/src/main/java/jme3test/collision/TestMousePick.java deleted file mode 100644 index 9ff54ae532..0000000000 --- a/jme3-examples/src/main/java/jme3test/collision/TestMousePick.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.collision; - -import com.jme3.app.SimpleApplication; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Ray; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.debug.Arrow; -import com.jme3.scene.shape.Box; - -public class TestMousePick extends SimpleApplication { - - public static void main(String[] args) { - TestMousePick app = new TestMousePick(); - app.start(); - } - - private Node shootables; - private Geometry mark; - - @Override - public void simpleInitApp() { - flyCam.setEnabled(false); - initMark(); - - /* Create four colored boxes and a floor to shoot at: */ - shootables = new Node("Shootables"); - rootNode.attachChild(shootables); - shootables.attachChild(makeCube("a Dragon", -2f, 0f, 1f)); - shootables.attachChild(makeCube("a tin can", 1f, -2f, 0f)); - shootables.attachChild(makeCube("the Sheriff", 0f, 1f, -2f)); - shootables.attachChild(makeCube("the Deputy", 1f, 0f, -4f)); - shootables.attachChild(makeFloor()); - shootables.attachChild(makeCharacter()); - } - - @Override - public void simpleUpdate(float tpf){ - Vector3f origin = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f); - Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f); - direction.subtractLocal(origin).normalizeLocal(); - - Ray ray = new Ray(origin, direction); - CollisionResults results = new CollisionResults(); - shootables.collideWith(ray, results); -// System.out.println("----- Collisions? " + results.size() + "-----"); -// for (int i = 0; i < results.size(); i++) { -// // For each hit, we know distance, impact point, name of geometry. -// float dist = results.getCollision(i).getDistance(); -// Vector3f pt = results.getCollision(i).getWorldContactPoint(); -// String hit = results.getCollision(i).getGeometry().getName(); -// System.out.println("* Collision #" + i); -// System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away."); -// } - if (results.size() > 0) { - CollisionResult closest = results.getClosestCollision(); - mark.setLocalTranslation(closest.getContactPoint()); - - Quaternion q = new Quaternion(); - q.lookAt(closest.getContactNormal(), Vector3f.UNIT_Y); - mark.setLocalRotation(q); - - rootNode.attachChild(mark); - } else { - rootNode.detachChild(mark); - } - } - - /** A cube object for target practice */ - private Geometry makeCube(String name, float x, float y, float z) { - Box box = new Box(1, 1, 1); - Geometry cube = new Geometry(name, box); - cube.setLocalTranslation(x, y, z); - Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.randomColor()); - cube.setMaterial(mat1); - return cube; - } - - /** A floor to show that the "shot" can go through several objects. */ - private Geometry makeFloor() { - Box box = new Box(15, .2f, 15); - Geometry floor = new Geometry("the Floor", box); - floor.setLocalTranslation(0, -4, -5); - Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.Gray); - floor.setMaterial(mat1); - return floor; - } - - /** - * A red arrow to mark the spot being picked. - */ - private void initMark() { - Arrow arrow = new Arrow(Vector3f.UNIT_Z.mult(2f)); - mark = new Geometry("BOOM!", arrow); - Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mark_mat.setColor("Color", ColorRGBA.Red); - mark.setMaterial(mark_mat); - } - - private Spatial makeCharacter() { - // load a character from jme3-testdata - Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - golem.scale(0.5f); - golem.setLocalTranslation(-1.0f, -1.5f, -0.6f); - - // We must add a light to make the model visible - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal()); - golem.addLight(sun); - return golem; - } -} diff --git a/jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java b/jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java deleted file mode 100644 index e3c1ba136b..0000000000 --- a/jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.collision; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingSphere; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.scene.Mesh; -import com.jme3.scene.Spatial; -import com.jme3.scene.VertexBuffer.Type; - -public class TestRayCasting extends SimpleApplication { - - private RayTrace tracer; - private Spatial teapot; - - public static void main(String[] args){ - TestRayCasting app = new TestRayCasting(); - app.setPauseOnLostFocus(false); - app.start(); - } - - @Override - public void simpleInitApp() { -// flyCam.setEnabled(false); - - // load material - Material mat = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); - - Mesh q = new Mesh(); - q.setBuffer(Type.Position, 3, new float[] - { - 1, 0, 0, - 0, 1.5f, 0, - -1, 0, 0 - } - ); - q.setBuffer(Type.Index, 3, new int[]{ 0, 1, 2 }); - q.setBound(new BoundingSphere()); - q.updateBound(); -// Geometry teapot = new Geometry("MyGeom", q); - - teapot = assetManager.loadModel("Models/Teapot/Teapot.mesh.xml"); -// teapot.scale(2f, 2f, 2f); -// teapot.move(2f, 2f, -.5f); - teapot.rotate(FastMath.HALF_PI, FastMath.HALF_PI, FastMath.HALF_PI); - teapot.setMaterial(mat); - rootNode.attachChild(teapot); - -// cam.setLocation(cam.getLocation().add(0,1,0)); -// cam.lookAt(teapot.getWorldBound().getCenter(), Vector3f.UNIT_Y); - - tracer = new RayTrace(rootNode, cam, 160, 128); - tracer.show(); - tracer.update(); - } - - @Override - public void simpleUpdate(float tpf){ - teapot.rotate(0,tpf,0); - tracer.update(); - } - -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java b/jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java deleted file mode 100644 index 6d20ea1fc2..0000000000 --- a/jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.collision; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingVolume; -import com.jme3.collision.CollisionResults; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; - -public class TestTriangleCollision extends SimpleApplication { - - private Geometry geom1; - - private Spatial golem; - - public static void main(String[] args) { - TestTriangleCollision app = new TestTriangleCollision(); - app.start(); - } - - @Override - public void simpleInitApp() { - // Create two boxes - Mesh mesh1 = new Box(0.5f, 0.5f, 0.5f); - geom1 = new Geometry("Box", mesh1); - geom1.move(2, 2, -.5f); - Material m1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - m1.setColor("Color", ColorRGBA.Blue); - geom1.setMaterial(m1); - rootNode.attachChild(geom1); - - // load a character from jme3-testdata - golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - golem.scale(0.5f); - golem.setLocalTranslation(-1.0f, -1.5f, -0.6f); - - // We must add a light to make the model visible - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal()); - golem.addLight(sun); - rootNode.attachChild(golem); - - // Create input - inputManager.addMapping("MoveRight", new KeyTrigger(KeyInput.KEY_L)); - inputManager.addMapping("MoveLeft", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("MoveUp", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addMapping("MoveDown", new KeyTrigger(KeyInput.KEY_K)); - - inputManager.addListener(analogListener, new String[]{ - "MoveRight", "MoveLeft", "MoveUp", "MoveDown" - }); - } - final private AnalogListener analogListener = new AnalogListener() { - - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("MoveRight")) { - geom1.move(2 * tpf, 0, 0); - } - - if (name.equals("MoveLeft")) { - geom1.move(-2 * tpf, 0, 0); - } - - if (name.equals("MoveUp")) { - geom1.move(0, 2 * tpf, 0); - } - - if (name.equals("MoveDown")) { - geom1.move(0, -2 * tpf, 0); - } - } - }; - - @Override - public void simpleUpdate(float tpf) { - CollisionResults results = new CollisionResults(); - BoundingVolume bv = geom1.getWorldBound(); - golem.collideWith(bv, results); - - if (results.size() > 0) { - geom1.getMaterial().setColor("Color", ColorRGBA.Red); - }else{ - geom1.getMaterial().setColor("Color", ColorRGBA.Blue); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/collision/package-info.java b/jme3-examples/src/main/java/jme3test/collision/package-info.java deleted file mode 100644 index 10ff40e8f6..0000000000 --- a/jme3-examples/src/main/java/jme3test/collision/package-info.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for picking and non-physics collision - * detection - */ -package jme3test.collision; diff --git a/jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java b/jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java deleted file mode 100644 index 6110469ee0..0000000000 --- a/jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2009-2018 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. - */ - -package jme3test.conversion; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.util.MipMapGenerator; - -public class TestMipMapGen extends SimpleApplication { - - public static void main(String[] args){ - TestMipMapGen app = new TestMipMapGen(); - app.start(); - } - - @Override - public void simpleInitApp() { - BitmapText txt = guiFont.createLabel("Left: HW Mips"); - txt.setLocalTranslation(0, settings.getHeight() - txt.getLineHeight() * 4, 0); - guiNode.attachChild(txt); - - txt = guiFont.createLabel("Right: AWT Mips"); - txt.setLocalTranslation(0, settings.getHeight() - txt.getLineHeight() * 3, 0); - guiNode.attachChild(txt); - - // create a simple plane/quad - Quad quadMesh = new Quad(1, 1); - quadMesh.updateGeometry(1, 1, false); - quadMesh.updateBound(); - - Geometry quad1 = new Geometry("Textured Quad", quadMesh); - Geometry quad2 = new Geometry("Textured Quad 2", quadMesh); - - Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.png"); - tex.setMinFilter(Texture.MinFilter.Trilinear); - - Texture texCustomMip = tex.clone(); - Image imageCustomMip = texCustomMip.getImage().clone(); - MipMapGenerator.generateMipMaps(imageCustomMip); - texCustomMip.setImage(imageCustomMip); - - Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setTexture("ColorMap", tex); - - Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat2.setTexture("ColorMap", texCustomMip); - - quad1.setMaterial(mat1); -// quad1.setLocalTranslation(1, 0, 0); - - quad2.setMaterial(mat2); - quad2.setLocalTranslation(1, 0, 0); - - rootNode.attachChild(quad1); - rootNode.attachChild(quad2); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/conversion/package-info.java b/jme3-examples/src/main/java/jme3test/conversion/package-info.java deleted file mode 100644 index 3a49d4c92d..0000000000 --- a/jme3-examples/src/main/java/jme3test/conversion/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for converting textures - */ -package jme3test.conversion; diff --git a/jme3-examples/src/main/java/jme3test/effect/TestEverything.java b/jme3-examples/src/main/java/jme3test/effect/TestEverything.java deleted file mode 100644 index b579a03601..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/TestEverything.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.effect; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.ToneMapFilter; -import com.jme3.renderer.Caps; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.Spatial.CullHint; -import com.jme3.scene.shape.Box; -import com.jme3.shadow.DirectionalLightShadowRenderer; -import com.jme3.texture.Texture; -import com.jme3.util.SkyFactory; -import com.jme3.util.TangentBinormalGenerator; - -public class TestEverything extends SimpleApplication { - - private DirectionalLightShadowRenderer dlsr; - private ToneMapFilter toneMapFilter; - final private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); - - public static void main(String[] args){ - TestEverything app = new TestEverything(); - app.start(); - } - - public void setupHdr(){ - if (renderer.getCaps().contains(Caps.GLSL100)){ - toneMapFilter = new ToneMapFilter(); - toneMapFilter.setWhitePoint(new Vector3f(3f, 3f, 3f)); - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(toneMapFilter); - viewPort.addProcessor(fpp); - - // setPauseOnLostFocus(false); - } - } - - public void setupBasicShadow(){ - if (renderer.getCaps().contains(Caps.GLSL100)){ - dlsr = new DirectionalLightShadowRenderer(assetManager, 1024, 1); - viewPort.addProcessor(dlsr); - } - } - - public void setupSkyBox(){ - Texture envMap; - if (renderer.getCaps().contains(Caps.FloatTexture)){ - envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.hdr"); - }else{ - envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.jpg"); - } - rootNode.attachChild(SkyFactory.createSky(assetManager, envMap, - new Vector3f(-1,-1,-1), SkyFactory.EnvMapType.SphereMap)); - } - - public void setupLighting(){ - boolean hdr = false; - if (toneMapFilter != null){ - hdr = toneMapFilter.isEnabled(); - } - - DirectionalLight dl = new DirectionalLight(); - if (dlsr != null) { - dlsr.setLight(dl); - } - dl.setDirection(lightDir); - if (hdr){ - dl.setColor(new ColorRGBA(3, 3, 3, 1)); - }else{ - dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); - } - rootNode.addLight(dl); - - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1, 0, -1).normalizeLocal()); - if (hdr){ - dl.setColor(new ColorRGBA(1, 1, 1, 1)); - }else{ - dl.setColor(new ColorRGBA(.4f, .4f, .4f, 1)); - } - rootNode.addLight(dl); - } - - public void setupFloor(){ - Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); - Box floor = new Box(50, 1f, 50); - TangentBinormalGenerator.generate(floor); - floor.scaleTextureCoordinates(new Vector2f(5, 5)); - Geometry floorGeom = new Geometry("Floor", floor); - floorGeom.setMaterial(mat); - floorGeom.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(floorGeom); - } - -// public void setupTerrain(){ -// Material mat = manager.loadMaterial("Textures/Terrain/Rock/Rock.j3m"); -// mat.getTextureParam("DiffuseMap").getValue().setWrap(WrapMode.Repeat); -// mat.getTextureParam("NormalMap").getValue().setWrap(WrapMode.Repeat); -// try{ -// Geomap map = GeomapLoader.fromImage(TestEverything.class.getResource("/textures/heightmap.png")); -// Mesh m = map.createMesh(new Vector3f(0.35f, 0.0005f, 0.35f), new Vector2f(10, 10), true); -// Logger.getLogger(TangentBinormalGenerator.class.getName()).setLevel(Level.SEVERE); -// TangentBinormalGenerator.generate(m); -// Geometry t = new Geometry("Terrain", m); -// t.setLocalTranslation(85, -15, 0); -// t.setMaterial(mat); -// t.updateModelBound(); -// t.setShadowMode(ShadowMode.Receive); -// rootNode.attachChild(t); -// }catch (IOException ex){ -// ex.printStackTrace(); -// } -// -// } - - public void setupRobotGuy(){ - Node model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - Material mat = assetManager.loadMaterial("Models/Oto/Oto.j3m"); - model.getChild(0).setMaterial(mat); -// model.setAnimation("Walk"); - model.setLocalTranslation(30, 10.5f, 30); - model.setLocalScale(2); - model.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(model); - } - - public void setupSignpost(){ - Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); - Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - signpost.setMaterial(mat); - signpost.rotate(0, FastMath.HALF_PI, 0); - signpost.setLocalTranslation(12, 3.5f, 30); - signpost.setLocalScale(4); - signpost.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(signpost); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(-32.295086f, 54.80136f, 79.59805f)); - cam.setRotation(new Quaternion(0.074364014f, 0.92519957f, -0.24794696f, 0.27748522f)); - cam.update(); - - cam.setFrustumFar(300); - flyCam.setMoveSpeed(30); - - rootNode.setCullHint(CullHint.Never); - - setupBasicShadow(); - setupHdr(); - - setupLighting(); - setupSkyBox(); - -// setupTerrain(); - setupFloor(); -// setupRobotGuy(); - setupSignpost(); - - - } - -} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java b/jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java deleted file mode 100644 index 7f6a32bc81..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.effect; - -import com.jme3.app.SimpleApplication; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh.Type; -import com.jme3.effect.shapes.EmitterSphereShape; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; - -public class TestExplosionEffect extends SimpleApplication { - - private float time = 0; - private int state = 0; - final private Node explosionEffect = new Node("explosionFX"); - private ParticleEmitter flame, flash, spark, roundspark, smoketrail, debris, - shockwave; - - - private static final int COUNT_FACTOR = 1; - private static final float COUNT_FACTOR_F = 1f; - - private static final boolean POINT_SPRITE = true; - private static final Type EMITTER_TYPE = POINT_SPRITE ? Type.Point : Type.Triangle; - - public static void main(String[] args){ - TestExplosionEffect app = new TestExplosionEffect(); - app.start(); - } - - private void createFlame(){ - flame = new ParticleEmitter("Flame", EMITTER_TYPE, 32 * COUNT_FACTOR); - flame.setSelectRandomImage(true); - flame.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (1f / COUNT_FACTOR_F))); - flame.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); - flame.setStartSize(1.3f); - flame.setEndSize(2f); - flame.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); - flame.setParticlesPerSec(0); - flame.setGravity(0, -5, 0); - flame.setLowLife(.4f); - flame.setHighLife(.5f); - flame.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 7, 0)); - flame.getParticleInfluencer().setVelocityVariation(1f); - flame.setImagesX(2); - flame.setImagesY(2); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); - mat.setBoolean("PointSprite", POINT_SPRITE); - flame.setMaterial(mat); - explosionEffect.attachChild(flame); - } - - private void createFlash(){ - flash = new ParticleEmitter("Flash", EMITTER_TYPE, 24 * COUNT_FACTOR); - flash.setSelectRandomImage(true); - flash.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1f / COUNT_FACTOR_F)); - flash.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); - flash.setStartSize(.1f); - flash.setEndSize(3.0f); - flash.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); - flash.setParticlesPerSec(0); - flash.setGravity(0, 0, 0); - flash.setLowLife(.2f); - flash.setHighLife(.2f); - flash.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, 5f, 0)); - flash.getParticleInfluencer().setVelocityVariation(1); - flash.setImagesX(2); - flash.setImagesY(2); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flash.png")); - mat.setBoolean("PointSprite", POINT_SPRITE); - flash.setMaterial(mat); - explosionEffect.attachChild(flash); - } - - private void createRoundSpark(){ - roundspark = new ParticleEmitter("RoundSpark", EMITTER_TYPE, 20 * COUNT_FACTOR); - roundspark.setStartColor(new ColorRGBA(1f, 0.29f, 0.34f, (float) (1.0 / COUNT_FACTOR_F))); - roundspark.setEndColor(new ColorRGBA(0, 0, 0, 0.5f / COUNT_FACTOR_F)); - roundspark.setStartSize(1.2f); - roundspark.setEndSize(1.8f); - roundspark.setShape(new EmitterSphereShape(Vector3f.ZERO, 2f)); - roundspark.setParticlesPerSec(0); - roundspark.setGravity(0, -.5f, 0); - roundspark.setLowLife(1.8f); - roundspark.setHighLife(2f); - roundspark.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, 3, 0)); - roundspark.getParticleInfluencer().setVelocityVariation(.5f); - roundspark.setImagesX(1); - roundspark.setImagesY(1); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/roundspark.png")); - mat.setBoolean("PointSprite", POINT_SPRITE); - roundspark.setMaterial(mat); - explosionEffect.attachChild(roundspark); - } - - private void createSpark(){ - spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR); - spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F)); - spark.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); - spark.setStartSize(.5f); - spark.setEndSize(.5f); - spark.setFacingVelocity(true); - spark.setParticlesPerSec(0); - spark.setGravity(0, 5, 0); - spark.setLowLife(1.1f); - spark.setHighLife(1.5f); - spark.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 20, 0)); - spark.getParticleInfluencer().setVelocityVariation(1); - spark.setImagesX(1); - spark.setImagesY(1); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/spark.png")); - spark.setMaterial(mat); - explosionEffect.attachChild(spark); - } - - private void createSmokeTrail(){ - smoketrail = new ParticleEmitter("SmokeTrail", Type.Triangle, 22 * COUNT_FACTOR); - smoketrail.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F)); - smoketrail.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); - smoketrail.setStartSize(.2f); - smoketrail.setEndSize(1f); - -// smoketrail.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); - smoketrail.setFacingVelocity(true); - smoketrail.setParticlesPerSec(0); - smoketrail.setGravity(0, 1, 0); - smoketrail.setLowLife(.4f); - smoketrail.setHighLife(.5f); - smoketrail.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, 12, 0)); - smoketrail.getParticleInfluencer().setVelocityVariation(1); - smoketrail.setImagesX(1); - smoketrail.setImagesY(3); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/smoketrail.png")); - smoketrail.setMaterial(mat); - explosionEffect.attachChild(smoketrail); - } - - private void createDebris(){ - debris = new ParticleEmitter("Debris", Type.Triangle, 15 * COUNT_FACTOR); - debris.setSelectRandomImage(true); - debris.setRandomAngle(true); - debris.setRotateSpeed(FastMath.TWO_PI * 4); - debris.setStartColor(new ColorRGBA(1f, 0.59f, 0.28f, 1.0f / COUNT_FACTOR_F)); - debris.setEndColor(new ColorRGBA(.5f, 0.5f, 0.5f, 0f)); - debris.setStartSize(.2f); - debris.setEndSize(.2f); - -// debris.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); - debris.setParticlesPerSec(0); - debris.setGravity(0, 12f, 0); - debris.setLowLife(1.4f); - debris.setHighLife(1.5f); - debris.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, 15, 0)); - debris.getParticleInfluencer().setVelocityVariation(.60f); - debris.setImagesX(3); - debris.setImagesY(3); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/Debris.png")); - debris.setMaterial(mat); - explosionEffect.attachChild(debris); - } - - private void createShockwave(){ - shockwave = new ParticleEmitter("Shockwave", Type.Triangle, 1 * COUNT_FACTOR); -// shockwave.setRandomAngle(true); - shockwave.setFaceNormal(Vector3f.UNIT_Y); - shockwave.setStartColor(new ColorRGBA(.48f, 0.17f, 0.01f, .8f / COUNT_FACTOR_F)); - shockwave.setEndColor(new ColorRGBA(.48f, 0.17f, 0.01f, 0f)); - - shockwave.setStartSize(0f); - shockwave.setEndSize(7f); - - shockwave.setParticlesPerSec(0); - shockwave.setGravity(0, 0, 0); - shockwave.setLowLife(0.5f); - shockwave.setHighLife(0.5f); - shockwave.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, 0, 0)); - shockwave.getParticleInfluencer().setVelocityVariation(0f); - shockwave.setImagesX(1); - shockwave.setImagesY(1); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/shockwave.png")); - shockwave.setMaterial(mat); - explosionEffect.attachChild(shockwave); - } - - @Override - public void simpleInitApp() { - createFlame(); - createFlash(); - createSpark(); - createRoundSpark(); - createSmokeTrail(); - createDebris(); - createShockwave(); - explosionEffect.setLocalScale(0.5f); - renderManager.preloadScene(explosionEffect); - - cam.setLocation(new Vector3f(0, 3.5135868f, 10)); - cam.setRotation(new Quaternion(1.5714673E-4f, 0.98696727f, -0.16091813f, 9.6381607E-4f)); - - rootNode.attachChild(explosionEffect); - } - - @Override - public void simpleUpdate(float tpf){ - time += tpf / speed; - if (time > 1f && state == 0){ - flash.emitAllParticles(); - spark.emitAllParticles(); - smoketrail.emitAllParticles(); - debris.emitAllParticles(); - shockwave.emitAllParticles(); - state++; - } - if (time > 1f + .05f / speed && state == 1){ - flame.emitAllParticles(); - roundspark.emitAllParticles(); - state++; - } - - // rewind the effect - if (time > 5 / speed && state == 2){ - state = 0; - time = 0; - - flash.killAllParticles(); - spark.killAllParticles(); - smoketrail.killAllParticles(); - debris.killAllParticles(); - flame.killAllParticles(); - roundspark.killAllParticles(); - shockwave.killAllParticles(); - } - } - -} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java b/jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java deleted file mode 100644 index b466815dfb..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package jme3test.effect; - -import com.jme3.animation.LoopMode; -import com.jme3.app.SimpleApplication; -import com.jme3.cinematic.MotionPath; -import com.jme3.cinematic.events.MotionEvent; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh.Type; -import com.jme3.effect.shapes.EmitterMeshVertexShape; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.Trigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.material.Materials; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.post.filters.FXAAFilter; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.CenterQuad; -import com.jme3.scene.shape.Torus; -import com.jme3.shadow.DirectionalLightShadowFilter; -import com.jme3.system.AppSettings; -import com.jme3.texture.Texture; -import java.util.Arrays; - -/** - * Test case for Issue 1773 (Wrong particle position when using - * 'EmitterMeshVertexShape' or 'EmitterMeshFaceShape' and worldSpace - * flag equal to true) - * - * If the test succeeds, the particles will be generated from the vertices - * (for EmitterMeshVertexShape) or from the faces (for EmitterMeshFaceShape) - * of the torus mesh. If the test fails, the particles will appear in the - * center of the torus when worldSpace flag is set to true. - * - * @author capdevon - */ -public class TestIssue1773 extends SimpleApplication implements ActionListener { - - public static void main(String[] args) { - TestIssue1773 app = new TestIssue1773(); - AppSettings settings = new AppSettings(true); - settings.setResolution(1280, 720); - settings.setRenderer(AppSettings.LWJGL_OPENGL32); - app.setSettings(settings); - app.setPauseOnLostFocus(false); - app.setShowSettings(false); - app.start(); - } - - private ParticleEmitter emit; - private Node myModel; - private BitmapText emitUI; - private MotionEvent motionControl; - private boolean playing; - - @Override - public void simpleInitApp() { - - BitmapText hud = createTextUI(ColorRGBA.White, 20, 15); - hud.setText("Play/Pause Motion: KEY_SPACE, InWorldSpace: KEY_I"); - - emitUI = createTextUI(ColorRGBA.Blue, 20, 15 * 2); - - configCamera(); - setupLights(); - setupGround(); - setupCircle(); - createMotionControl(); - setupKeys(); - } - - /** - * Crates particle emitter and adds it to root node. - */ - private void setupCircle() { - myModel = new Node("FieryCircle"); - - Geometry torus = createTorus(1f); - myModel.attachChild(torus); - - emit = createParticleEmitter(torus, true); - myModel.attachChild(emit); - - rootNode.attachChild(myModel); - } - - /** - * Creates torus geometry used for the emitter shape. - */ - private Geometry createTorus(float radius) { - float s = radius / 8f; - Geometry geo = new Geometry("CircleXZ", new Torus(64, 4, s, radius)); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - mat.getAdditionalRenderState().setWireframe(true); - geo.setMaterial(mat); - return geo; - } - - /** - * Creates a particle emitter that will emit the particles from - * the given shape's vertices. - */ - private ParticleEmitter createParticleEmitter(Geometry geo, boolean pointSprite) { - Type type = pointSprite ? Type.Point : Type.Triangle; - ParticleEmitter emitter = new ParticleEmitter("Emitter", type, 1000); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); - mat.setBoolean("PointSprite", pointSprite); - emitter.setMaterial(mat); - emitter.setLowLife(1); - emitter.setHighLife(1); - emitter.setImagesX(15); - emitter.setStartSize(0.04f); - emitter.setEndSize(0.02f); - emitter.setStartColor(ColorRGBA.Orange); - emitter.setEndColor(ColorRGBA.Red); - emitter.setParticlesPerSec(900); - emitter.setGravity(0, 0f, 0); - //emitter.getParticleInfluencer().setVelocityVariation(1); - //emitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, .5f, 0)); - emitter.setShape(new EmitterMeshVertexShape(Arrays.asList(geo.getMesh()))); - //emitter.setShape(new EmitterMeshFaceShape(Arrays.asList(geo.getMesh()))); - return emitter; - } - - /** - * Creates a motion control that will move particle emitter in - * a circular path. - */ - private void createMotionControl() { - - float radius = 5f; - float height = 1.10f; - - MotionPath path = new MotionPath(); - path.setCycle(true); - - for (int i = 0; i < 8; i++) { - float x = FastMath.sin(FastMath.QUARTER_PI * i) * radius; - float z = FastMath.cos(FastMath.QUARTER_PI * i) * radius; - path.addWayPoint(new Vector3f(x, height, z)); - } - //path.enableDebugShape(assetManager, rootNode); - - motionControl = new MotionEvent(myModel, path); - motionControl.setLoopMode(LoopMode.Loop); - //motionControl.setInitialDuration(15f); - //motionControl.setSpeed(2f); - motionControl.setDirectionType(MotionEvent.Direction.Path); - } - - /** - * Use keyboard space key to toggle emitter motion and I key to - * toggle inWorldSpace flag. By default, inWorldSpace flag is on - * and emitter motion is off. - */ - private void setupKeys() { - addMapping("ToggleMotionEvent", new KeyTrigger(KeyInput.KEY_SPACE)); - addMapping("InWorldSpace", new KeyTrigger(KeyInput.KEY_I)); - } - - private void addMapping(String mappingName, Trigger... triggers) { - inputManager.addMapping(mappingName, triggers); - inputManager.addListener(this, mappingName); - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("InWorldSpace") && isPressed) { - boolean worldSpace = emit.isInWorldSpace(); - emit.setInWorldSpace(!worldSpace); - - } else if (name.equals("ToggleMotionEvent") && isPressed) { - if (playing) { - playing = false; - motionControl.pause(); - } else { - playing = true; - motionControl.play(); - } - } - } - - @Override - public void simpleUpdate(float tpf) { - emitUI.setText("InWorldSpace: " + emit.isInWorldSpace()); - } - - private void configCamera() { - flyCam.setDragToRotate(true); - flyCam.setMoveSpeed(10); - - cam.setLocation(new Vector3f(0, 6f, 9.2f)); - cam.lookAt(Vector3f.UNIT_Y, Vector3f.UNIT_Y); - - float aspect = (float) cam.getWidth() / cam.getHeight(); - cam.setFrustumPerspective(45, aspect, 0.1f, 1000f); - } - - /** - * Adds a ground to the scene - */ - private void setupGround() { - CenterQuad quad = new CenterQuad(12, 12); - quad.scaleTextureCoordinates(new Vector2f(2, 2)); - Geometry floor = new Geometry("Floor", quad); - Material mat = new Material(assetManager, Materials.LIGHTING); - Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); - tex.setWrap(Texture.WrapMode.Repeat); - mat.setTexture("DiffuseMap", tex); - floor.setMaterial(mat); - floor.rotate(-FastMath.HALF_PI, 0, 0); - rootNode.attachChild(floor); - } - - /** - * Adds lights and filters - */ - private void setupLights() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - - AmbientLight ambient = new AmbientLight(); - ambient.setColor(ColorRGBA.White); - //rootNode.addLight(ambient); - - DirectionalLight sun = new DirectionalLight(); - sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal()); - sun.setColor(ColorRGBA.White); - rootNode.addLight(sun); - - DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, 4096, 3); - dlsf.setLight(sun); - dlsf.setShadowIntensity(0.4f); - dlsf.setShadowZExtend(256); - - FXAAFilter fxaa = new FXAAFilter(); - BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(bloom); - fpp.addFilter(dlsf); - fpp.addFilter(fxaa); - viewPort.addProcessor(fpp); - } - - /** - * Creates a bitmap test used for displaying debug info. - */ - private BitmapText createTextUI(ColorRGBA color, float xPos, float yPos) { - BitmapFont font = assetManager.loadFont("Interface/Fonts/Console.fnt"); - BitmapText bmp = new BitmapText(font); - bmp.setSize(font.getCharSet().getRenderedSize()); - bmp.setLocalTranslation(xPos, settings.getHeight() - yPos, 0); - bmp.setColor(color); - guiNode.attachChild(bmp); - return bmp; - } -} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java b/jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java deleted file mode 100644 index 7aee885075..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.effect; - -import com.jme3.app.SimpleApplication; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh.Type; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; - -/** - * Particle that moves in a circle. - * - * @author Kirill Vainer - */ -public class TestMovingParticle extends SimpleApplication { - - private ParticleEmitter emit; - private float angle = 0; - - public static void main(String[] args) { - TestMovingParticle app = new TestMovingParticle(); - app.start(); - } - - @Override - public void simpleInitApp() { - emit = new ParticleEmitter("Emitter", Type.Triangle, 300); - emit.setGravity(0, 0, 0); - emit.getParticleInfluencer().setVelocityVariation(1); - emit.setLowLife(1); - emit.setHighLife(1); - emit.getParticleInfluencer() - .setInitialVelocity(new Vector3f(0, .5f, 0)); - emit.setImagesX(15); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); - emit.setMaterial(mat); - - rootNode.attachChild(emit); - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if ("setNum".equals(name) && isPressed) { - emit.setNumParticles(1000); - } - } - }, "setNum"); - - inputManager.addMapping("setNum", new KeyTrigger(KeyInput.KEY_SPACE)); - } - - @Override - public void simpleUpdate(float tpf) { - angle += tpf; - angle %= FastMath.TWO_PI; - float x = FastMath.cos(angle) * 2; - float y = FastMath.sin(angle) * 2; - emit.setLocalTranslation(x, 0, y); - } -} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java b/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java deleted file mode 100644 index 4b75b1e76c..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.effect; - -import com.jme3.app.SimpleApplication; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh.Type; -import com.jme3.effect.shapes.EmitterSphereShape; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; - -public class TestParticleExportingCloning extends SimpleApplication { - - public static void main(String[] args){ - TestParticleExportingCloning app = new TestParticleExportingCloning(); - app.start(); - } - - @Override - public void simpleInitApp() { - ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Triangle, 200); - emit.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); - emit.setGravity(0, 0, 0); - emit.setLowLife(5); - emit.setHighLife(10); - emit.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 0, 0)); - emit.setImagesX(15); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); - emit.setMaterial(mat); - - ParticleEmitter emit2 = emit.clone(); - emit2.move(3, 0, 0); - - rootNode.attachChild(emit); - rootNode.attachChild(emit2); - - ParticleEmitter emit3 = BinaryExporter.saveAndLoad(assetManager, emit); - emit3.move(-3, 0, 0); - rootNode.attachChild(emit3); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java b/jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java deleted file mode 100644 index 8543eba0e1..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.effect; - -import com.jme3.app.SimpleApplication; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh.Type; -import com.jme3.effect.shapes.EmitterBoxShape; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; - -public class TestPointSprite extends SimpleApplication { - - public static void main(String[] args){ - TestPointSprite app = new TestPointSprite(); - app.start(); - } - - @Override - public void simpleInitApp() { - final ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Point, 10000); - emit.setShape(new EmitterBoxShape(new Vector3f(-1.8f, -1.8f, -1.8f), - new Vector3f(1.8f, 1.8f, 1.8f))); - emit.setGravity(0, 0, 0); - emit.setLowLife(60); - emit.setHighLife(60); - emit.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 0, 0)); - emit.setImagesX(15); - emit.setStartSize(0.05f); - emit.setEndSize(0.05f); - emit.setStartColor(ColorRGBA.White); - emit.setEndColor(ColorRGBA.White); - emit.setSelectRandomImage(true); - emit.emitAllParticles(); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setBoolean("PointSprite", true); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); - emit.setMaterial(mat); - - rootNode.attachChild(emit); - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if ("setNum".equals(name) && isPressed) { - emit.setNumParticles(5000); - emit.emitAllParticles(); - } - } - }, "setNum"); - - inputManager.addMapping("setNum", new KeyTrigger(KeyInput.KEY_SPACE)); - - } - -} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java b/jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java deleted file mode 100644 index 1a50a02a6c..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.effect; - -import com.jme3.app.SimpleApplication; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh; -import com.jme3.effect.shapes.EmitterSphereShape; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.TranslucentBucketFilter; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; - -/** - * - * @author Nehon - */ -public class TestSoftParticles extends SimpleApplication { - - private boolean softParticles = true; - private FilterPostProcessor fpp; - private Node particleNode; - - public static void main(String[] args) { - TestSoftParticles app = new TestSoftParticles(); - app.start(); - } - - @Override - public void simpleInitApp() { - - cam.setLocation(new Vector3f(-7.2221026f, 4.1183004f, 7.759811f)); - cam.setRotation(new Quaternion(0.06152846f, 0.91236454f, -0.1492115f, 0.37621948f)); - - flyCam.setMoveSpeed(10); - - - // -------- floor - Box b = new Box(10, 0.1f, 10); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Gray); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - geom.setMaterial(mat); - rootNode.attachChild(geom); - - Box b2 = new Box(1, 1, 1); - Geometry geom2 = new Geometry("Box", b2); - Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat2.setColor("Color", ColorRGBA.DarkGray); - geom2.setMaterial(mat2); - rootNode.attachChild(geom2); - geom2.setLocalScale(0.1f, 0.2f, 1); - - fpp = new FilterPostProcessor(assetManager); - TranslucentBucketFilter tbf = new TranslucentBucketFilter(true); - fpp.addFilter(tbf); - int samples = context.getSettings().getSamples(); - if (samples > 0) { - fpp.setNumSamples(samples); - } - viewPort.addProcessor(fpp); - - particleNode = new Node("particleNode"); - rootNode.attachChild(particleNode); - - createParticles(); - - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if(isPressed && name.equals("toggle")){ - // tbf.setEnabled(!tbf.isEnabled()); - softParticles = !softParticles; - if(softParticles){ - viewPort.addProcessor(fpp); - }else{ - viewPort.removeProcessor(fpp); - } - } - } - }, "toggle"); - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - - // emit again - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if(isPressed && name.equals("refire")) { - //fpp.removeFilter(tbf); // <-- add back in to fix - particleNode.detachAllChildren(); - createParticles(); - //fpp.addFilter(tbf); - } - } - }, "refire"); - inputManager.addMapping("refire", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - } - - private void createParticles() { - - Material material = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - material.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); - material.setFloat("Softness", 3f); // - - //Fire - ParticleEmitter fire = new ParticleEmitter("Fire", ParticleMesh.Type.Triangle, 30); - fire.setMaterial(material); - fire.setShape(new EmitterSphereShape(Vector3f.ZERO, 0.1f)); - fire.setImagesX(2); - fire.setImagesY(2); // 2x2 texture animation - fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f)); // red - fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow - fire.setStartSize(0.6f); - fire.setEndSize(0.01f); - fire.setGravity(0, -0.3f, 0); - fire.setLowLife(0.5f); - fire.setHighLife(3f); - fire.setLocalTranslation(0, 0.2f, 0); - - particleNode.attachChild(fire); - - - ParticleEmitter smoke = new ParticleEmitter("Smoke", ParticleMesh.Type.Triangle, 30); - smoke.setMaterial(material); - smoke.setShape(new EmitterSphereShape(Vector3f.ZERO, 5)); - smoke.setImagesX(1); - smoke.setImagesY(1); // 2x2 texture animation - smoke.setStartColor(new ColorRGBA(0.1f, 0.1f, 0.1f,1f)); // dark gray - smoke.setEndColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 0.3f)); // gray - smoke.setStartSize(3f); - smoke.setEndSize(5f); - smoke.setGravity(0, -0.001f, 0); - smoke.setLowLife(100f); - smoke.setHighLife(100f); - smoke.setLocalTranslation(0, 0.1f, 0); - smoke.emitAllParticles(); - - particleNode.attachChild(smoke); - } - - -} diff --git a/jme3-examples/src/main/java/jme3test/effect/package-info.java b/jme3-examples/src/main/java/jme3test/effect/package-info.java deleted file mode 100644 index 09f2903c48..0000000000 --- a/jme3-examples/src/main/java/jme3test/effect/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for special effects, including particles - */ -package jme3test.effect; diff --git a/jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java b/jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java deleted file mode 100644 index 42e291da25..0000000000 --- a/jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.export; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.MaterialKey; -import com.jme3.asset.ModelKey; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.export.binary.BinaryImporter; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.AssetLinkNode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Sphere; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class TestAssetLinkNode extends SimpleApplication { - - private float angle; - private PointLight pl; - private Spatial lightMdl; - - public static void main(String[] args){ - TestAssetLinkNode app = new TestAssetLinkNode(); - app.start(); - } - - @Override - public void simpleInitApp() { - AssetLinkNode loaderNode=new AssetLinkNode(); - loaderNode.addLinkedChild(new ModelKey("Models/MonkeyHead/MonkeyHead.mesh.xml")); - //load/attach the children (happens automatically on load) -// loaderNode.attachLinkedChildren(assetManager); -// rootNode.attachChild(loaderNode); - - //save and load the loaderNode - try { - //export to byte array - ByteArrayOutputStream bout=new ByteArrayOutputStream(); - BinaryExporter.getInstance().save(loaderNode, bout); - //import from byte array, automatically loads the monkey head from file - ByteArrayInputStream bin=new ByteArrayInputStream(bout.toByteArray()); - BinaryImporter imp=BinaryImporter.getInstance(); - imp.setAssetManager(assetManager); - Node newLoaderNode=(Node)imp.load(bin); - //attach to rootNode - rootNode.attachChild(newLoaderNode); - } catch (IOException ex) { - Logger.getLogger(TestAssetLinkNode.class.getName()).log(Level.SEVERE, null, ex); - } - - - rootNode.attachChild(loaderNode); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadAsset(new MaterialKey("Common/Materials/RedColor.j3m"))); - rootNode.attachChild(lightMdl); - - // fluorescent main light - pl = new PointLight(); - pl.setColor(new ColorRGBA(0.88f, 0.92f, 0.95f, 1.0f)); - rootNode.addLight(pl); - - // sunset light - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal()); - dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f)); - rootNode.addLight(dl); - - // skylight - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal()); - dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f)); - rootNode.addLight(dl); - - // white ambient light - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal()); - dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); - rootNode.addLight(dl); - } - - @Override - public void simpleUpdate(float tpf){ - angle += tpf * 0.25f; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 6f, 3f, FastMath.sin(angle) * 6f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java b/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java deleted file mode 100644 index b94fa7a816..0000000000 --- a/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ -package jme3test.export; - -import com.jme3.app.SimpleApplication; -import com.jme3.export.JmeExporter; -import com.jme3.export.xml.XMLExporter; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Test case for JME issue: #2068 exporting a Map to XML results in a - * DOMException. - * - *

If the issue is unresolved, the application will exit prematurely with an - * uncaught exception. - * - *

If the issue is resolved, the application will complete normally. - * - * @author Stephen Gold sgold@sonic.net - */ -public class TestIssue2068 extends SimpleApplication { - // ************************************************************************* - // constants and loggers - - /** - * message logger for this class - */ - final public static Logger logger - = Logger.getLogger(TestIssue2068.class.getName()); - // ************************************************************************* - // new methods exposed - - /** - * Main entry point for the TestIssue2068 application. - * - * @param args array of command-line arguments (not null) - */ - public static void main(String[] args) { - TestIssue2068 app = new TestIssue2068(); - app.start(); - } - - /** - * Initialize the application. - */ - @Override - public void simpleInitApp() { - Map map = new HashMap<>(); - map.put("key", "value"); - rootNode.setUserData("map", map); - - String outputFilename = "TestIssue2068.xml"; - File xmlFile = new File(outputFilename); - JmeExporter exporter = XMLExporter.getInstance(); - try { - exporter.save(rootNode, xmlFile); - } catch (IOException exception) { - logger.log(Level.SEVERE, exception.getMessage(), exception); - } - stop(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java b/jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java deleted file mode 100644 index 57dba2fb54..0000000000 --- a/jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.export; - -import com.jme3.anim.AnimComposer; -import com.jme3.app.SimpleApplication; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.export.binary.BinaryImporter; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; - -import java.io.*; - -public class TestOgreConvert extends SimpleApplication { - - public static void main(String[] args){ - TestOgreConvert app = new TestOgreConvert(); - app.start(); - } - - @Override - public void simpleInitApp() { - Spatial ogreModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White); - dl.setDirection(new Vector3f(0,-1,-1).normalizeLocal()); - rootNode.addLight(dl); - - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryExporter exp = new BinaryExporter(); - exp.save(ogreModel, baos); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - BinaryImporter imp = new BinaryImporter(); - imp.setAssetManager(assetManager); - Node ogreModelReloaded = (Node) imp.load(bais, null, null); - - AnimComposer composer = ogreModelReloaded.getControl(AnimComposer.class); - composer.setCurrentAction("Walk"); - - rootNode.attachChild(ogreModelReloaded); - } catch (IOException ex){ - ex.printStackTrace(); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/export/package-info.java b/jme3-examples/src/main/java/jme3test/export/package-info.java deleted file mode 100644 index a30a5e6ca0..0000000000 --- a/jme3-examples/src/main/java/jme3test/export/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for asset exporting - */ -package jme3test.export; diff --git a/jme3-examples/src/main/java/jme3test/games/CubeField.java b/jme3-examples/src/main/java/jme3test/games/CubeField.java deleted file mode 100644 index 21d060ce0a..0000000000 --- a/jme3-examples/src/main/java/jme3test/games/CubeField.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.games; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingVolume; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Dome; -import java.util.ArrayList; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Kyle "bonechilla" Williams - */ -public class CubeField extends SimpleApplication implements AnalogListener { - - public static void main(String[] args) { - CubeField app = new CubeField(); - app.start(); - } - - private BitmapFont defaultFont; - - private boolean START; - private int difficulty, Score, colorInt, lowCap; - private Node player; - private Geometry fcube; - private ArrayList cubeField; - private ArrayList obstacleColors; - private float speed, coreTime,coreTime2; - private float camAngle = 0; - private BitmapText fpsScoreText, pressStart; - - private boolean solidBox = true; - private Material playerMaterial; - private Material floorMaterial; - - final private float fpsRate = 1000f / 1f; - - /** - * Initializes game - */ - @Override - public void simpleInitApp() { - Logger.getLogger("com.jme3").setLevel(Level.WARNING); - - flyCam.setEnabled(false); - setDisplayStatView(false); - - Keys(); - - defaultFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - pressStart = new BitmapText(defaultFont); - fpsScoreText = new BitmapText(defaultFont); - - loadText(fpsScoreText, "Current Score: 0", defaultFont, 0, 2, 0); - loadText(pressStart, "PRESS ENTER", defaultFont, 0, 5, 0); - - player = createPlayer(); - rootNode.attachChild(player); - cubeField = new ArrayList(); - obstacleColors = new ArrayList(); - - gameReset(); - } - /** - * Used to reset cubeField - */ - private void gameReset(){ - Score = 0; - lowCap = 10; - colorInt = 0; - difficulty = 40; - - for (Geometry cube : cubeField){ - cube.removeFromParent(); - } - cubeField.clear(); - - if (fcube != null){ - fcube.removeFromParent(); - } - fcube = createFirstCube(); - - obstacleColors.clear(); - obstacleColors.add(ColorRGBA.Orange); - obstacleColors.add(ColorRGBA.Red); - obstacleColors.add(ColorRGBA.Yellow); - renderer.setBackgroundColor(ColorRGBA.White); - speed = lowCap / 400f; - coreTime = 20.0f; - coreTime2 = 10.0f; - player.setLocalTranslation(0,0,0); - } - - @Override - public void simpleUpdate(float tpf) { - camTakeOver(tpf); - if (START){ - gameLogic(tpf); - } - colorLogic(); - } - /** - * Forcefully takes over Camera adding functionality and placing it behind the character - * @param tpf Ticks Per Frame - */ - private void camTakeOver(float tpf) { - cam.setLocation(player.getLocalTranslation().add(-8, 2, 0)); - cam.lookAt(player.getLocalTranslation(), Vector3f.UNIT_Y); - - Quaternion rot = new Quaternion(); - rot.fromAngleNormalAxis(camAngle, Vector3f.UNIT_Z); - cam.setRotation(cam.getRotation().mult(rot)); - camAngle *= FastMath.pow(.99f, fpsRate * tpf); - } - - @Override - public void requestClose(boolean esc) { - if (!esc){ - System.out.println("The game was quit."); - }else{ - System.out.println("Player has Collided. Final Score is " + Score); - } - context.destroy(false); - } - /** - * Randomly Places a cube on the map between 30 and 90 paces away from player - */ - private void randomizeCube() { - Geometry cube = fcube.clone(); - int playerX = (int) player.getLocalTranslation().getX(); - int playerZ = (int) player.getLocalTranslation().getZ(); -// float x = FastMath.nextRandomInt(playerX + difficulty + 10, playerX + difficulty + 150); - float x = FastMath.nextRandomInt(playerX + difficulty + 30, playerX + difficulty + 90); - float z = FastMath.nextRandomInt(playerZ - difficulty - 50, playerZ + difficulty + 50); - cube.getLocalTranslation().set(x, 0, z); - -// playerX+difficulty+30,playerX+difficulty+90 - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - if (!solidBox){ - mat.getAdditionalRenderState().setWireframe(true); - } - mat.setColor("Color", obstacleColors.get(FastMath.nextRandomInt(0, obstacleColors.size() - 1))); - cube.setMaterial(mat); - - rootNode.attachChild(cube); - cubeField.add(cube); - } - - private Geometry createFirstCube() { - Vector3f loc = player.getLocalTranslation(); - loc.addLocal(4, 0, 0); - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - geom.setLocalTranslation(loc); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - geom.setMaterial(mat); - - return geom; - } - - private Node createPlayer() { - Dome b = new Dome(Vector3f.ZERO, 10, 100, 1); - Geometry playerMesh = new Geometry("Box", b); - - playerMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - playerMaterial.setColor("Color", ColorRGBA.Red); - playerMesh.setMaterial(playerMaterial); - playerMesh.setName("player"); - - Box floor = new Box(100, 0, 100); - - Geometry floorMesh = new Geometry("Box", floor); - - Vector3f translation = Vector3f.ZERO.add(playerMesh.getLocalTranslation().getX(), - playerMesh.getLocalTranslation().getY() - 1, 0); - - floorMesh.setLocalTranslation(translation); - - floorMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - floorMaterial.setColor("Color", ColorRGBA.LightGray); - floorMesh.setMaterial(floorMaterial); - floorMesh.setName("floor"); - - Node playerNode = new Node(); - playerNode.attachChild(playerMesh); - playerNode.attachChild(floorMesh); - - return playerNode; - } - - /** - * If Game is Lost display Score and Reset the Game - */ - private void gameLost(){ - START = false; - loadText(pressStart, "You lost! Press enter to try again.", defaultFont, 0, 5, 0); - gameReset(); - } - - /** - * Core Game Logic - */ - private void gameLogic(float tpf){ - //Subtract difficulty level in accordance to speed every 10 seconds - if(timer.getTimeInSeconds()>=coreTime2){ - coreTime2=timer.getTimeInSeconds()+10; - if(difficulty<=lowCap){ - difficulty=lowCap; - } - else if(difficulty>lowCap){ - difficulty-=5; - } - } - - if(speed<.1f){ - speed+=.000001f*tpf*fpsRate; - } - - player.move(speed * tpf * fpsRate, 0, 0); - if (cubeField.size() > difficulty){ - cubeField.remove(0); - }else if (cubeField.size() != difficulty){ - randomizeCube(); - } - - if (cubeField.isEmpty()){ - requestClose(false); - }else{ - for (int i = 0; i < cubeField.size(); i++){ - - //better way to check collision - Geometry playerModel = (Geometry) player.getChild(0); - Geometry cubeModel = cubeField.get(i); - - BoundingVolume pVol = playerModel.getWorldBound(); - BoundingVolume vVol = cubeModel.getWorldBound(); - - if (pVol.intersects(vVol)){ - gameLost(); - return; - } - //Remove cube if 10 world units behind player - if (cubeField.get(i).getLocalTranslation().getX() + 10 < player.getLocalTranslation().getX()){ - cubeField.get(i).removeFromParent(); - cubeField.remove(cubeField.get(i)); - } - - } - } - - Score += fpsRate * tpf; - fpsScoreText.setText("Current Score: "+Score); - } - /** - * Sets up the keyboard bindings - */ - private void Keys() { - inputManager.addMapping("START", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT)); - inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addListener(this, "START", "Left", "Right"); - } - - @Override - public void onAnalog(String binding, float value, float tpf) { - if (binding.equals("START") && !START){ - START = true; - guiNode.detachChild(pressStart); - System.out.println("START"); - }else if (START == true && binding.equals("Left")){ - player.move(0, 0, -(speed / 2f) * value * fpsRate); - camAngle -= value*tpf; - }else if (START == true && binding.equals("Right")){ - player.move(0, 0, (speed / 2f) * value * fpsRate); - camAngle += value*tpf; - } - } - - /** - * Determines the colors of the player, floor, obstacle and background - */ - private void colorLogic() { - if (timer.getTimeInSeconds() >= coreTime){ - - colorInt++; - coreTime = timer.getTimeInSeconds() + 20; - - - switch (colorInt){ - case 1: - obstacleColors.clear(); - solidBox = false; - obstacleColors.add(ColorRGBA.Green); - renderer.setBackgroundColor(ColorRGBA.Black); - playerMaterial.setColor("Color", ColorRGBA.White); - floorMaterial.setColor("Color", ColorRGBA.Black); - break; - case 2: - obstacleColors.set(0, ColorRGBA.Black); - solidBox = true; - renderer.setBackgroundColor(ColorRGBA.White); - playerMaterial.setColor("Color", ColorRGBA.Gray); - floorMaterial.setColor("Color", ColorRGBA.LightGray); - break; - case 3: - obstacleColors.set(0, ColorRGBA.Pink); - break; - case 4: - obstacleColors.set(0, ColorRGBA.Cyan); - obstacleColors.add(ColorRGBA.Magenta); - renderer.setBackgroundColor(ColorRGBA.Gray); - floorMaterial.setColor("Color", ColorRGBA.Gray); - playerMaterial.setColor("Color", ColorRGBA.White); - break; - case 5: - obstacleColors.remove(0); - renderer.setBackgroundColor(ColorRGBA.Pink); - solidBox = false; - playerMaterial.setColor("Color", ColorRGBA.White); - break; - case 6: - obstacleColors.set(0, ColorRGBA.White); - solidBox = true; - renderer.setBackgroundColor(ColorRGBA.Black); - playerMaterial.setColor("Color", ColorRGBA.Gray); - floorMaterial.setColor("Color", ColorRGBA.LightGray); - break; - case 7: - obstacleColors.set(0, ColorRGBA.Green); - renderer.setBackgroundColor(ColorRGBA.Gray); - playerMaterial.setColor("Color", ColorRGBA.Black); - floorMaterial.setColor("Color", ColorRGBA.Orange); - break; - case 8: - obstacleColors.set(0, ColorRGBA.Red); - floorMaterial.setColor("Color", ColorRGBA.Pink); - break; - case 9: - obstacleColors.set(0, ColorRGBA.Orange); - obstacleColors.add(ColorRGBA.Red); - obstacleColors.add(ColorRGBA.Yellow); - renderer.setBackgroundColor(ColorRGBA.White); - playerMaterial.setColor("Color", ColorRGBA.Red); - floorMaterial.setColor("Color", ColorRGBA.Gray); - colorInt=0; - break; - default: - break; - } - } - } - /** - * Sets up a BitmapText to be displayed - * @param txt the Bitmap Text - * @param text the - * @param font the font of the text - * @param x - * @param y - * @param z - */ - private void loadText(BitmapText txt, String text, BitmapFont font, float x, float y, float z) { - txt.setSize(font.getCharSet().getRenderedSize()); - txt.setLocalTranslation(txt.getLineWidth() * x, txt.getLineHeight() * y, z); - txt.setText(text); - guiNode.attachChild(txt); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java b/jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java deleted file mode 100644 index fe47ad43c0..0000000000 --- a/jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.games; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.PhysicsCollisionEvent; -import com.jme3.bullet.collision.PhysicsCollisionListener; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.CompoundCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.GhostControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.DirectionalLightShadowFilter; -import java.util.concurrent.Callable; - -/** - * Physics based marble game. - * - * @author SkidRunner (Mark E. Picknell) - */ -public class RollingTheMonkey extends SimpleApplication implements ActionListener, PhysicsCollisionListener { - - private static final String MESSAGE = "Thanks for Playing!"; - private static final String INFO_MESSAGE = "Collect all the spinning cubes!\nPress the 'R' key any time to reset!"; - - private static final float PLAYER_DENSITY = 1200; // OLK(Java LOL) = 1200, STEEL = 8000, RUBBER = 1000 - private static final float PLAYER_REST = 0.1f; // OLK = 0.1f, STEEL = 0.0f, RUBBER = 1.0f I made these up. - - private static final float PLAYER_RADIUS = 2.0f; - private static final float PLAYER_ACCEL = 1.0f; - - private static final float PICKUP_SIZE = 0.5f; - private static final float PICKUP_RADIUS = 15.0f; - private static final int PICKUP_COUNT = 16; - private static final float PICKUP_SPEED = 5.0f; - - private static final float PLAYER_VOLUME = (FastMath.pow(PLAYER_RADIUS, 3) * FastMath.PI) / 3; // V = 4/3 * PI * R pow 3 - private static final float PLAYER_MASS = PLAYER_DENSITY * PLAYER_VOLUME; - private static final float PLAYER_FORCE = 80000 * PLAYER_ACCEL; // F = M(4m diameter steel ball) * A - private static final Vector3f PLAYER_START = new Vector3f(0.0f, PLAYER_RADIUS * 2, 0.0f); - - private static final String INPUT_MAPPING_FORWARD = "INPUT_MAPPING_FORWARD"; - private static final String INPUT_MAPPING_BACKWARD = "INPUT_MAPPING_BACKWARD"; - private static final String INPUT_MAPPING_LEFT = "INPUT_MAPPING_LEFT"; - private static final String INPUT_MAPPING_RIGHT = "INPUT_MAPPING_RIGHT"; - private static final String INPUT_MAPPING_RESET = "INPUT_MAPPING_RESET"; - - public static void main(String[] args) { - RollingTheMonkey app = new RollingTheMonkey(); - app.start(); - } - - private boolean keyForward; - private boolean keyBackward; - private boolean keyLeft; - private boolean keyRight; - private RigidBodyControl player; - private int score; - - private Node pickUps; - private BitmapText scoreText; - private BitmapText messageText; - - @Override - public void simpleInitApp() { - flyCam.setEnabled(false); - cam.setLocation(new Vector3f(0.0f, 12.0f, 21.0f)); - viewPort.setBackgroundColor(new ColorRGBA(0.2118f, 0.0824f, 0.6549f, 1.0f)); - - // init physics - BulletAppState bulletState = new BulletAppState(); - stateManager.attach(bulletState); - PhysicsSpace space = bulletState.getPhysicsSpace(); - space.addCollisionListener(this); - - // create light - DirectionalLight sun = new DirectionalLight(); - sun.setDirection((new Vector3f(-0.7f, -0.3f, -0.5f)).normalizeLocal()); - System.out.println("Here We Go: " + sun.getDirection()); - sun.setColor(ColorRGBA.White); - rootNode.addLight(sun); - - // create materials - Material materialRed = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - materialRed.setBoolean("UseMaterialColors",true); - materialRed.setBoolean("HardwareShadows", true); - materialRed.setColor("Diffuse", new ColorRGBA(0.9451f, 0.0078f, 0.0314f, 1.0f)); - materialRed.setColor("Specular", ColorRGBA.White); - materialRed.setFloat("Shininess", 64.0f); - - Material materialGreen = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - materialGreen.setBoolean("UseMaterialColors",true); - materialGreen.setBoolean("HardwareShadows", true); - materialGreen.setColor("Diffuse", new ColorRGBA(0.0431f, 0.7725f, 0.0078f, 1.0f)); - materialGreen.setColor("Specular", ColorRGBA.White); - materialGreen.setFloat("Shininess", 64.0f); - - Material logoMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - logoMaterial.setBoolean("UseMaterialColors",true); - logoMaterial.setBoolean("HardwareShadows", true); - logoMaterial.setTexture("DiffuseMap", assetManager.loadTexture("com/jme3/app/Monkey.png")); - logoMaterial.setColor("Diffuse", ColorRGBA.White); - logoMaterial.setColor("Specular", ColorRGBA.White); - logoMaterial.setFloat("Shininess", 32.0f); - - Material materialYellow = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - materialYellow.setBoolean("UseMaterialColors",true); - materialYellow.setBoolean("HardwareShadows", true); - materialYellow.setColor("Diffuse", new ColorRGBA(0.9529f, 0.7843f, 0.0078f, 1.0f)); - materialYellow.setColor("Specular", ColorRGBA.White); - materialYellow.setFloat("Shininess", 64.0f); - - // create level spatial - // TODO: create your own level mesh - Node level = new Node("level"); - level.setShadowMode(ShadowMode.CastAndReceive); - - Geometry floor = new Geometry("floor", new Box(22.0f, 0.5f, 22.0f)); - floor.setShadowMode(ShadowMode.Receive); - floor.setLocalTranslation(0.0f, -0.5f, 0.0f); - floor.setMaterial(materialGreen); - - Geometry wallNorth = new Geometry("wallNorth", new Box(22.0f, 2.0f, 0.5f)); - wallNorth.setLocalTranslation(0.0f, 2.0f, 21.5f); - wallNorth.setMaterial(materialRed); - - Geometry wallSouth = new Geometry("wallSouth", new Box(22.0f, 2.0f, 0.5f)); - wallSouth.setLocalTranslation(0.0f, 2.0f, -21.5f); - wallSouth.setMaterial(materialRed); - - Geometry wallEast = new Geometry("wallEast", new Box(0.5f, 2.0f, 21.0f)); - wallEast.setLocalTranslation(-21.5f, 2.0f, 0.0f); - wallEast.setMaterial(materialRed); - - Geometry wallWest = new Geometry("wallWest", new Box(0.5f, 2.0f, 21.0f)); - wallWest.setLocalTranslation(21.5f, 2.0f, 0.0f); - wallWest.setMaterial(materialRed); - - level.attachChild(floor); - level.attachChild(wallNorth); - level.attachChild(wallSouth); - level.attachChild(wallEast); - level.attachChild(wallWest); - - // The easy way: level.addControl(new RigidBodyControl(0)); - - // create level Shape - CompoundCollisionShape levelShape = new CompoundCollisionShape(); - BoxCollisionShape floorShape = new BoxCollisionShape(new Vector3f(22.0f, 0.5f, 22.0f)); - BoxCollisionShape wallNorthShape = new BoxCollisionShape(new Vector3f(22.0f, 2.0f, 0.5f)); - BoxCollisionShape wallSouthShape = new BoxCollisionShape(new Vector3f(22.0f, 2.0f, 0.5f)); - BoxCollisionShape wallEastShape = new BoxCollisionShape(new Vector3f(0.5f, 2.0f, 21.0f)); - BoxCollisionShape wallWestShape = new BoxCollisionShape(new Vector3f(0.5f, 2.0f, 21.0f)); - - levelShape.addChildShape(floorShape, new Vector3f(0.0f, -0.5f, 0.0f)); - levelShape.addChildShape(wallNorthShape, new Vector3f(0.0f, 2.0f, -21.5f)); - levelShape.addChildShape(wallSouthShape, new Vector3f(0.0f, 2.0f, 21.5f)); - levelShape.addChildShape(wallEastShape, new Vector3f(-21.5f, 2.0f, 0.0f)); - levelShape.addChildShape(wallEastShape, new Vector3f(21.5f, 2.0f, 0.0f)); - - level.addControl(new RigidBodyControl(levelShape, 0)); - - rootNode.attachChild(level); - space.addAll(level); - - // create Pickups - // TODO: create your own pickUp mesh - // create single mesh for all pickups - // HINT: think particles. - pickUps = new Node("pickups"); - - Quaternion rotation = new Quaternion(); - Vector3f translation = new Vector3f(0.0f, PICKUP_SIZE * 1.5f, -PICKUP_RADIUS); - int index = 0; - float amount = FastMath.TWO_PI / PICKUP_COUNT; - for(float angle = 0; angle < FastMath.TWO_PI; angle += amount) { - Geometry pickUp = new Geometry("pickUp" + (index++), new Box(PICKUP_SIZE,PICKUP_SIZE, PICKUP_SIZE)); - pickUp.setShadowMode(ShadowMode.CastAndReceive); - pickUp.setMaterial(materialYellow); - pickUp.setLocalRotation(rotation.fromAngles( - FastMath.rand.nextFloat() * FastMath.TWO_PI, - FastMath.rand.nextFloat() * FastMath.TWO_PI, - FastMath.rand.nextFloat() * FastMath.TWO_PI)); - - rotation.fromAngles(0.0f, angle, 0.0f); - rotation.mult(translation, pickUp.getLocalTranslation()); - pickUps.attachChild(pickUp); - - pickUp.addControl(new GhostControl(new SphereCollisionShape(PICKUP_SIZE))); - - - space.addAll(pickUp); - //space.addCollisionListener(pickUpControl); - } - rootNode.attachChild(pickUps); - - // Create player - // TODO: create your own player mesh - Geometry playerGeometry = new Geometry("player", new Sphere(16, 32, PLAYER_RADIUS)); - playerGeometry.setShadowMode(ShadowMode.CastAndReceive); - playerGeometry.setLocalTranslation(PLAYER_START.clone()); - playerGeometry.setMaterial(logoMaterial); - - // Store control for applying forces - // TODO: create your own player control - player = new RigidBodyControl(new SphereCollisionShape(PLAYER_RADIUS), PLAYER_MASS); - player.setRestitution(PLAYER_REST); - - playerGeometry.addControl(player); - - rootNode.attachChild(playerGeometry); - space.addAll(playerGeometry); - - inputManager.addMapping(INPUT_MAPPING_FORWARD, new KeyTrigger(KeyInput.KEY_UP) - , new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping(INPUT_MAPPING_BACKWARD, new KeyTrigger(KeyInput.KEY_DOWN) - , new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping(INPUT_MAPPING_LEFT, new KeyTrigger(KeyInput.KEY_LEFT) - , new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping(INPUT_MAPPING_RIGHT, new KeyTrigger(KeyInput.KEY_RIGHT) - , new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping(INPUT_MAPPING_RESET, new KeyTrigger(KeyInput.KEY_R)); - inputManager.addListener(this, INPUT_MAPPING_FORWARD, INPUT_MAPPING_BACKWARD - , INPUT_MAPPING_LEFT, INPUT_MAPPING_RIGHT, INPUT_MAPPING_RESET); - - // init UI - BitmapText infoText = new BitmapText(guiFont); - infoText.setText(INFO_MESSAGE); - guiNode.attachChild(infoText); - - scoreText = new BitmapText(guiFont); - scoreText.setText("Score: 0"); - guiNode.attachChild(scoreText); - - messageText = new BitmapText(guiFont); - messageText.setText(MESSAGE); - messageText.setLocalScale(0.0f); - guiNode.attachChild(messageText); - - infoText.setLocalTranslation(0.0f, cam.getHeight(), 0.0f); - scoreText.setLocalTranslation((cam.getWidth() - scoreText.getLineWidth()) / 2.0f, - scoreText.getLineHeight(), 0.0f); - messageText.setLocalTranslation((cam.getWidth() - messageText.getLineWidth()) / 2.0f, - (cam.getHeight() - messageText.getLineHeight()) / 2, 0.0f); - - // init shadows - FilterPostProcessor processor = new FilterPostProcessor(assetManager); - DirectionalLightShadowFilter filter = new DirectionalLightShadowFilter(assetManager, 2048, 1); - filter.setLight(sun); - processor.addFilter(filter); - viewPort.addProcessor(processor); - - } - - @Override - public void simpleUpdate(float tpf) { - // Update and position the score - scoreText.setText("Score: " + score); - scoreText.setLocalTranslation((cam.getWidth() - scoreText.getLineWidth()) / 2.0f, - scoreText.getLineHeight(), 0.0f); - - // Rotate all the pickups - float pickUpSpeed = PICKUP_SPEED * tpf; - for(Spatial pickUp : pickUps.getChildren()) { - pickUp.rotate(pickUpSpeed, pickUpSpeed, pickUpSpeed); - } - - Vector3f centralForce = new Vector3f(); - - if(keyForward) centralForce.addLocal(cam.getDirection()); - if(keyBackward) centralForce.addLocal(cam.getDirection().negate()); - if(keyLeft) centralForce.addLocal(cam.getLeft()); - if(keyRight) centralForce.addLocal(cam.getLeft().negate()); - - if(!Vector3f.ZERO.equals(centralForce)) { - centralForce.setY(0); // stop ball from pushing down or flying up - centralForce.normalizeLocal(); // normalize force - centralForce.multLocal(PLAYER_FORCE); // scale vector to force - - player.applyCentralForce(centralForce); // apply force to player - } - - cam.lookAt(player.getPhysicsLocation(), Vector3f.UNIT_Y); - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - switch(name) { - case INPUT_MAPPING_FORWARD: - keyForward = isPressed; - break; - case INPUT_MAPPING_BACKWARD: - keyBackward = isPressed; - break; - case INPUT_MAPPING_LEFT: - keyLeft = isPressed; - break; - case INPUT_MAPPING_RIGHT: - keyRight = isPressed; - break; - case INPUT_MAPPING_RESET: - enqueue(new Callable() { - @Override - public Void call() { - reset(); - return null; - } - }); - break; - } - } - @Override - public void collision(PhysicsCollisionEvent event) { - Spatial nodeA = event.getNodeA(); - Spatial nodeB = event.getNodeB(); - - String nameA = nodeA == null ? "" : nodeA.getName(); - String nameB = nodeB == null ? "" : nodeB.getName(); - - if(nameA.equals("player") && nameB.startsWith("pickUp")) { - GhostControl pickUpControl = nodeB.getControl(GhostControl.class); - if(pickUpControl != null && pickUpControl.isEnabled()) { - pickUpControl.setEnabled(false); - nodeB.removeFromParent(); - nodeB.setLocalScale(0.0f); - score += 1; - if(score >= PICKUP_COUNT) { - messageText.setLocalScale(1.0f); - } - } - } else if(nameA.startsWith("pickUp") && nameB.equals("player")) { - GhostControl pickUpControl = nodeA.getControl(GhostControl.class); - if(pickUpControl != null && pickUpControl.isEnabled()) { - pickUpControl.setEnabled(false); - nodeA.setLocalScale(0.0f); - score += 1; - if(score >= PICKUP_COUNT) { - messageText.setLocalScale(1.0f); - } - } - } - } - - private void reset() { - // Reset the pickups - for(Spatial pickUp : pickUps.getChildren()) { - GhostControl pickUpControl = pickUp.getControl(GhostControl.class); - if(pickUpControl != null) { - pickUpControl.setEnabled(true); - } - pickUp.setLocalScale(1.0f); - } - // Reset the player - player.setPhysicsLocation(PLAYER_START.clone()); - player.setAngularVelocity(Vector3f.ZERO.clone()); - player.setLinearVelocity(Vector3f.ZERO.clone()); - // Reset the score - score = 0; - // Reset the message - messageText.setLocalScale(0.0f); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/games/WorldOfInception.java b/jme3-examples/src/main/java/jme3test/games/WorldOfInception.java deleted file mode 100644 index 04aca57e8f..0000000000 --- a/jme3-examples/src/main/java/jme3test/games/WorldOfInception.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.games; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.AbstractAppState; -import com.jme3.app.state.AppStateManager; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.collision.shapes.MeshCollisionShape; -import com.jme3.bullet.collision.shapes.SphereCollisionShape; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.debug.DebugTools; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Ray; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.FogFilter; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Sphere; -import java.util.Random; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * WorldOfInception - Find the galaxy center ;) - * - * @author normenhansen - */ -public class WorldOfInception extends SimpleApplication implements AnalogListener { - - //Assumptions: POI radius in world == 1, only one player, vector3f hash describes enough worlds - private static final Logger logger = Logger.getLogger(WorldOfInception.class.getName()); - private static final Random random = new Random(System.currentTimeMillis()); - private static final float scaleDist = 10; - private static final float poiRadius = 100; - private static final int poiCount = 30; - private static Material poiMaterial; - private static Mesh poiMesh; - private static Material ballMaterial; - private static Mesh ballMesh; - private static CollisionShape poiHorizonCollisionShape; - private static CollisionShape poiCollisionShape; - private static CollisionShape ballCollisionShape; - private InceptionLevel currentLevel; - private final Vector3f walkDirection = new Vector3f(); - private static DebugTools debugTools; - - public WorldOfInception() { - //base level vector position hash == seed - super(new InceptionLevel(null, Vector3f.ZERO)); - currentLevel = super.getStateManager().getState(InceptionLevel.class); - currentLevel.takeOverParent(); - currentLevel.getRootNode().setLocalScale(Vector3f.UNIT_XYZ); - currentLevel.getRootNode().setLocalTranslation(Vector3f.ZERO); - } - - public static void main(String[] args) { - WorldOfInception app = new WorldOfInception(); - app.start(); - } - - @Override - public void simpleInitApp() { - //set far frustum only so we see the outer world longer - cam.setFrustumFar(10000); - cam.setLocation(Vector3f.ZERO); - debugTools = new DebugTools(assetManager); - rootNode.attachChild(debugTools.debugNode); - poiMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - poiMaterial.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - poiMesh = new Sphere(16, 16, 1f); - - ballMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - ballMaterial.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - ballMaterial.setColor("Color", ColorRGBA.Red); - ballMesh = new Sphere(16, 16, 1.0f); - - poiHorizonCollisionShape = new MeshCollisionShape(new Sphere(128, 128, poiRadius)); - poiCollisionShape = new SphereCollisionShape(1f); - ballCollisionShape = new SphereCollisionShape(1f); - setupKeys(); - setupDisplay(); - setupFog(); - } - - private void setupKeys() { - inputManager.addMapping("StrafeLeft", new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("StrafeRight", new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("Forward", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("Back", new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("StrafeUp", new KeyTrigger(KeyInput.KEY_Q)); - inputManager.addMapping("StrafeDown", new KeyTrigger(KeyInput.KEY_Z), new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("Return", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addMapping("Esc", new KeyTrigger(KeyInput.KEY_ESCAPE)); - inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT)); - inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addListener(this, "StrafeLeft", "StrafeRight", "Forward", "Back", "StrafeUp", "StrafeDown", "Space", "Reset", "Esc", "Up", "Down", "Left", "Right"); - } - - private void setupDisplay() { - if (fpsText == null) { - fpsText = new BitmapText(guiFont); - } - fpsText.setLocalScale(0.7f, 0.7f, 0.7f); - fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0); - fpsText.setText(""); - fpsText.setCullHint(Spatial.CullHint.Never); - guiNode.attachChild(fpsText); - } - - private void setupFog() { - // use fog to give more sense of depth - FilterPostProcessor fpp; - FogFilter fog; - fpp=new FilterPostProcessor(assetManager); - fog=new FogFilter(); - fog.setFogColor(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)); - fog.setFogDistance(poiRadius); - fog.setFogDensity(2.0f); - fpp.addFilter(fog); - viewPort.addProcessor(fpp); - } - - @Override - public void onAnalog(String name, float value, float tpf) { - Vector3f left = rootNode.getLocalRotation().mult(Vector3f.UNIT_X.negate()); - Vector3f forward = rootNode.getLocalRotation().mult(Vector3f.UNIT_Z.negate()); - Vector3f up = rootNode.getLocalRotation().mult(Vector3f.UNIT_Y); - //TODO: properly scale input based on current scaling level - tpf = tpf * (10 - (9.0f * currentLevel.getCurrentScaleAmount())); - if (name.equals("StrafeLeft") && value > 0) { - walkDirection.addLocal(left.mult(tpf)); - } else if (name.equals("StrafeRight") && value > 0) { - walkDirection.addLocal(left.negate().multLocal(tpf)); - } else if (name.equals("Forward") && value > 0) { - walkDirection.addLocal(forward.mult(tpf)); - } else if (name.equals("Back") && value > 0) { - walkDirection.addLocal(forward.negate().multLocal(tpf)); - } else if (name.equals("StrafeUp") && value > 0) { - walkDirection.addLocal(up.mult(tpf)); - } else if (name.equals("StrafeDown") && value > 0) { - walkDirection.addLocal(up.negate().multLocal(tpf)); - } else if (name.equals("Up") && value > 0) { - //TODO: rotate rootNode, needs to be global - } else if (name.equals("Down") && value > 0) { - } else if (name.equals("Left") && value > 0) { - } else if (name.equals("Right") && value > 0) { - } else if (name.equals("Esc")) { - stop(); - } - } - - @Override - public void simpleUpdate(float tpf) { - currentLevel = currentLevel.getCurrentLevel(); - currentLevel.move(walkDirection); - fpsText.setText("Location: " + currentLevel.getCoordinates()); - walkDirection.set(Vector3f.ZERO); - } - - public static class InceptionLevel extends AbstractAppState { - - private final InceptionLevel parent; - private final Vector3f inParentPosition; - private SimpleApplication application; - private BulletAppState physicsState; - private Node rootNode; - private Vector3f playerPos; - private InceptionLevel currentActiveChild; - private InceptionLevel currentReturnLevel; - private float curScaleAmount = 0; - - public InceptionLevel(InceptionLevel parent, Vector3f inParentPosition) { - this.parent = parent; - this.inParentPosition = inParentPosition; - } - - @Override - public void update(float tpf) { - super.update(tpf); - if (currentReturnLevel != this) { - return; - } - debugTools.setYellowArrow(new Vector3f(0, 0, -2), playerPos.divide(poiRadius)); - float curLocalDist = getPlayerPosition().length(); - // If we are outside the range of one point of interest, move out to - // the next upper level - if (curLocalDist > poiRadius + FastMath.ZERO_TOLERANCE) { //DAFUQ normalize? - if (parent == null) { - //TODO: could add new nodes coming in instead for literally endless space - logger.log(Level.INFO, "Hit event horizon"); - currentReturnLevel = this; - return; - } - //give to parent - logger.log(Level.INFO, "give to parent"); - parent.takeOverChild(inParentPosition.add(playerPos.normalize())); - application.getStateManager().attach(parent); - currentReturnLevel = parent; - return; - } - - AppStateManager stateManager = application.getStateManager(); - // We create child positions based on the parent position hash, so we - // should in practice get the same galaxy w/o too many doubles - // with each run with the same root vector. - Vector3f[] vectors = getPositions(poiCount, inParentPosition.hashCode()); - for (int i = 0; i < vectors.length; i++) { - Vector3f vector3f = vectors[i]; - //negative rootNode location is our actual player position - Vector3f distVect = vector3f.subtract(playerPos); - float distance = distVect.length(); - if (distance <= 1) { - checkActiveChild(vector3f); - float percent = 0; - curScaleAmount = 0; - this.scaleAsParent(percent, playerPos, distVect); - currentActiveChild.scaleAsChild(percent, distVect); - logger.log(Level.INFO, "Give over to child {0}", currentActiveChild); - currentActiveChild.takeOverParent(); - stateManager.detach(this); - currentReturnLevel = currentActiveChild; - return; - } else if (distance <= 1 + scaleDist) { - debugTools.setRedArrow(Vector3f.ZERO, distVect); - checkActiveChild(vector3f); - //TODO: scale percent nicer for less of an "explosion" effect - float percent = 1 - mapValue(distance - 1, 0, scaleDist, 0, 1); - curScaleAmount = percent; - rootNode.getChild(i).setCullHint(Spatial.CullHint.Always); - this.scaleAsParent(percent, playerPos, distVect); - currentActiveChild.scaleAsChild(percent, distVect); - currentReturnLevel = this; - return; - } else if (currentActiveChild != null && currentActiveChild.getPositionInParent().equals(vector3f)) { - //TODO: doing this here causes problems when close to multiple POIs - rootNode.getChild(i).setCullHint(Spatial.CullHint.Inherit); - } - } - checkActiveChild(null); - curScaleAmount = 0; - rootNode.setLocalScale(1); - rootNode.setLocalTranslation(playerPos.negate()); - debugTools.setRedArrow(Vector3f.ZERO, Vector3f.ZERO); - debugTools.setBlueArrow(Vector3f.ZERO, Vector3f.ZERO); - debugTools.setGreenArrow(Vector3f.ZERO, Vector3f.ZERO); - } - - private void checkActiveChild(Vector3f vector3f) { - AppStateManager stateManager = application.getStateManager(); - if(vector3f == null){ - if(currentActiveChild != null){ - logger.log(Level.INFO, "Detach child {0}", currentActiveChild); - stateManager.detach(currentActiveChild); - currentActiveChild = null; - } - return; - } - if (currentActiveChild == null) { - currentActiveChild = new InceptionLevel(this, vector3f); - stateManager.attach(currentActiveChild); - logger.log(Level.INFO, "Attach child {0}", currentActiveChild); - } else if (!currentActiveChild.getPositionInParent().equals(vector3f)) { - logger.log(Level.INFO, "Switching from child {0}", currentActiveChild); - stateManager.detach(currentActiveChild); - currentActiveChild = new InceptionLevel(this, vector3f); - stateManager.attach(currentActiveChild); - logger.log(Level.INFO, "Attach child {0}", currentActiveChild); - } - } - - private void scaleAsChild(float percent, Vector3f dist) { - float childScale = mapValue(percent, 1.0f / poiRadius, 1); - Vector3f distToHorizon = dist.normalize(); - Vector3f scaledDistToHorizon = distToHorizon.mult(childScale * poiRadius); - Vector3f rootOff = dist.add(scaledDistToHorizon); - debugTools.setBlueArrow(Vector3f.ZERO, rootOff); - getRootNode().setLocalScale(childScale); - getRootNode().setLocalTranslation(rootOff); - //prepare player position already - Vector3f playerPosition = dist.normalize().mult(-poiRadius); - setPlayerPosition(playerPosition); - } - - private void scaleAsParent(float percent, Vector3f playerPos, Vector3f dist) { - float scale = mapValue(percent, 1.0f, poiRadius); - Vector3f distToHorizon = dist.subtract(dist.normalize()); - Vector3f offLocation = playerPos.add(distToHorizon); - Vector3f rootOff = offLocation.mult(scale).negate(); - rootOff.addLocal(dist); - debugTools.setGreenArrow(Vector3f.ZERO, offLocation); - getRootNode().setLocalScale(scale); - getRootNode().setLocalTranslation(rootOff); - } - - public void takeOverParent() { - //got playerPos from scaleAsChild before - getPlayerPosition().normalizeLocal().multLocal(poiRadius); - currentReturnLevel = this; - } - - public void takeOverChild(Vector3f playerPos) { - this.playerPos.set(playerPos); - currentReturnLevel = this; - } - - public InceptionLevel getLastLevel(Ray pickRay) { - // TODO: get a level based on positions getting ever more accurate, - // from any given position - return null; - } - - public InceptionLevel getLevel(Vector3f... location) { - // TODO: get a level based on positions getting ever more accurate, - // from any given position - return null; - } - - private void initData() { - getRootNode(); - physicsState = new BulletAppState(); - physicsState.startPhysics(); - physicsState.getPhysicsSpace().setGravity(Vector3f.ZERO); - //horizon - physicsState.getPhysicsSpace().add(new RigidBodyControl(poiHorizonCollisionShape, 0)); - int hashCode = inParentPosition.hashCode(); - Vector3f[] positions = getPositions(poiCount, hashCode); - for (int i = 0; i < positions.length; i++) { - Vector3f vector3f = positions[i]; - Geometry poiGeom = new Geometry("poi", poiMesh); - poiGeom.setLocalTranslation(vector3f); - poiGeom.setMaterial(poiMaterial); - RigidBodyControl control = new RigidBodyControl(poiCollisionShape, 0); - //!!! Important - control.setApplyPhysicsLocal(true); - poiGeom.addControl(control); - physicsState.getPhysicsSpace().add(poiGeom); - rootNode.attachChild(poiGeom); - - } - //add balls after so first 10 geoms == locations - for (int i = 0; i < positions.length; i++) { - Vector3f vector3f = positions[i]; - Geometry ball = getRandomBall(vector3f); - physicsState.getPhysicsSpace().add(ball); - rootNode.attachChild(ball); - } - - } - - private Geometry getRandomBall(Vector3f location) { - Vector3f localLocation = new Vector3f(); - localLocation.set(location); - localLocation.addLocal(new Vector3f(random.nextFloat() - 0.5f, random.nextFloat() - 0.5f, random.nextFloat() - 0.5f).normalize().mult(3)); - Geometry poiGeom = new Geometry("ball", ballMesh); - poiGeom.setLocalTranslation(localLocation); - poiGeom.setMaterial(ballMaterial); - RigidBodyControl control = new RigidBodyControl(ballCollisionShape, 1); - //!!! Important - control.setApplyPhysicsLocal(true); - poiGeom.addControl(control); - float x = (random.nextFloat() - 0.5f) * 100; - float y = (random.nextFloat() - 0.5f) * 100; - float z = (random.nextFloat() - 0.5f) * 100; - control.setLinearVelocity(new Vector3f(x, y, z)); - return poiGeom; - } - - private void cleanupData() { - physicsState.stopPhysics(); - //TODO: remove all objects? - physicsState = null; - rootNode = null; - } - - @Override - public void initialize(AppStateManager stateManager, Application app) { - super.initialize(stateManager, app); - //only generate data and attach node when we are actually attached (or picking) - initData(); - application = (SimpleApplication) app; - application.getRootNode().attachChild(getRootNode()); - application.getStateManager().attach(physicsState); - } - - @Override - public void cleanup() { - super.cleanup(); - //detach everything when we are detached - application.getRootNode().detachChild(rootNode); - application.getStateManager().detach(physicsState); - cleanupData(); - } - - public Node getRootNode() { - if (rootNode == null) { - rootNode = new Node("ZoomLevel"); - if (parent != null) { - rootNode.setLocalScale(1.0f / poiRadius); - } - } - return rootNode; - } - - public Vector3f getPositionInParent() { - return inParentPosition; - } - - public Vector3f getPlayerPosition() { - if (playerPos == null) { - playerPos = new Vector3f(); - } - return playerPos; - } - - public void setPlayerPosition(Vector3f vec) { - if (playerPos == null) { - playerPos = new Vector3f(); - } - playerPos.set(vec); - } - - public void move(Vector3f dir) { - if (playerPos == null) { - playerPos = new Vector3f(); - } - playerPos.addLocal(dir); - } - - public float getCurrentScaleAmount() { - return curScaleAmount; - } - - public InceptionLevel getParent() { - return parent; - } - - public InceptionLevel getCurrentLevel() { - return currentReturnLevel; - } - - public String getCoordinates() { - InceptionLevel cur = this; - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.insert(0, this.getPlayerPosition()); - stringBuilder.insert(0, this.getPositionInParent() + " / "); - cur = cur.getParent(); - while (cur != null) { - stringBuilder.insert(0, cur.getPositionInParent() + " / "); - cur = cur.getParent(); - } - return stringBuilder.toString(); - } - } - - public static Vector3f[] getPositions(int count, long seed) { - Random rnd = new Random(seed); - Vector3f[] vectors = new Vector3f[count]; - for (int i = 0; i < count; i++) { - vectors[i] = new Vector3f((rnd.nextFloat() - 0.5f) * poiRadius, - (rnd.nextFloat() - 0.5f) * poiRadius, - (rnd.nextFloat() - 0.5f) * poiRadius); - } - return vectors; - } - - /** - * Maps a value from 0-1 to a range from min to max. - * - * @param x - * @param min - * @param max - * @return the mapped value - */ - private static float mapValue(float x, float min, float max) { - return mapValue(x, 0, 1, min, max); - } - - /** - * Maps a value from inputMin to inputMax to a range from min to max. - * - * @param x - * @param inputMin - * @param inputMax - * @param min - * @param max - * @return the mapped value - */ - private static float mapValue(float x, float inputMin, float inputMax, float min, float max) { - return (x - inputMin) * (max - min) / (inputMax - inputMin) + min; - } -} diff --git a/jme3-examples/src/main/java/jme3test/games/package-info.java b/jme3-examples/src/main/java/jme3test/games/package-info.java deleted file mode 100644 index 37b6b362a4..0000000000 --- a/jme3-examples/src/main/java/jme3test/games/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * simple example games - */ -package jme3test.games; diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java deleted file mode 100644 index 96bc5db0b6..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.LineWrapMode; -import com.jme3.font.Rectangle; -import com.jme3.input.KeyInput; -import com.jme3.input.RawInputListener; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.event.*; - -public class TestBitmapFont extends SimpleApplication { - - private String txtB = - "ABCDEFGHIKLMNOPQRSTUVWXYZ1234567 890`~!@#$%^&*()-=_+[]\\;',./{}|:<>?"; - - private BitmapText txt; - private BitmapText txt3; - - public static void main(String[] args){ - TestBitmapFont app = new TestBitmapFont(); - app.start(); - } - - @Override - public void simpleInitApp() { - inputManager.addMapping("WordWrap", new KeyTrigger(KeyInput.KEY_TAB)); - inputManager.addListener(keyListener, "WordWrap"); - inputManager.addRawInputListener(textListener); - - BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - txt = new BitmapText(fnt); - txt.setBox(new Rectangle(0, 0, settings.getWidth(), settings.getHeight())); - txt.setSize(fnt.getPreferredSize() * 2f); - txt.setText(txtB); - txt.setLocalTranslation(0, txt.getHeight(), 0); - guiNode.attachChild(txt); - - BitmapText txt2 = new BitmapText(fnt); - txt2.setSize(fnt.getPreferredSize() * 1.2f); - txt2.setText("Text without restriction. \nText without restriction. Text without restriction. Text without restriction"); - txt2.setLocalTranslation(0, txt2.getHeight(), 0); - guiNode.attachChild(txt2); - - txt3 = new BitmapText(fnt); - txt3.setBox(new Rectangle(0, 0, settings.getWidth(), 0)); - txt3.setText("Press Tab to toggle word-wrap. type text and enter to input text"); - txt3.setLocalTranslation(0, settings.getHeight()/2, 0); - guiNode.attachChild(txt3); - } - - private ActionListener keyListener = new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("WordWrap") && !isPressed) { - txt.setLineWrapMode( txt.getLineWrapMode() == LineWrapMode.Word ? - LineWrapMode.NoWrap : LineWrapMode.Word ); - } - } - }; - - final private RawInputListener textListener = new RawInputListener() { - final private StringBuilder str = new StringBuilder(); - - @Override - public void onMouseMotionEvent(MouseMotionEvent evt) { } - - @Override - public void onMouseButtonEvent(MouseButtonEvent evt) { } - - @Override - public void onKeyEvent(KeyInputEvent evt) { - if (evt.isReleased()) - return; - if (evt.getKeyChar() == '\n' || evt.getKeyChar() == '\r') { - txt3.setText(str.toString()); - str.setLength(0); - } else { - str.append(evt.getKeyChar()); - } - } - - @Override - public void onJoyButtonEvent(JoyButtonEvent evt) { } - - @Override - public void onJoyAxisEvent(JoyAxisEvent evt) { } - - @Override - public void endInput() { } - - @Override - public void beginInput() { } - - @Override - public void onTouchEvent(TouchEvent evt) { } - - }; - -} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java deleted file mode 100644 index d6bc143d62..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2009-2019 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. - */ - -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.Rectangle; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; - -public class TestBitmapFontAlignment extends SimpleApplication { - - public static void main(String[] args) { - TestBitmapFontAlignment test = new TestBitmapFontAlignment(); - test.start(); - } - - @Override - public void simpleInitApp() { - int width = getCamera().getWidth(); - int height = getCamera().getHeight(); - - // VAlign.Top - BitmapText labelAlignTop = guiFont.createLabel("This text has VAlign.Top."); - Rectangle textboxAlignTop = new Rectangle(width * 0.2f, height * 0.7f, 120, 120); - labelAlignTop.setBox(textboxAlignTop); - labelAlignTop.setVerticalAlignment(BitmapFont.VAlign.Top); - getGuiNode().attachChild(labelAlignTop); - - Geometry backgroundBoxAlignTop = new Geometry("", new Quad(textboxAlignTop.width, -textboxAlignTop.height)); - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setColor("Color", ColorRGBA.Blue); - backgroundBoxAlignTop.setMaterial(material); - backgroundBoxAlignTop.setLocalTranslation(textboxAlignTop.x, textboxAlignTop.y, -1); - getGuiNode().attachChild(backgroundBoxAlignTop); - - // VAlign.Center - BitmapText labelAlignCenter = guiFont.createLabel("This text has VAlign.Center"); - Rectangle textboxAlignCenter = new Rectangle(width * 0.4f, height * 0.7f, 120, 120); - labelAlignCenter.setBox(textboxAlignCenter); - labelAlignCenter.setVerticalAlignment(BitmapFont.VAlign.Center); - getGuiNode().attachChild(labelAlignCenter); - - Geometry backgroundBoxAlignCenter = backgroundBoxAlignTop.clone(false); - backgroundBoxAlignCenter.setLocalTranslation(textboxAlignCenter.x, textboxAlignCenter.y, -1); - getGuiNode().attachChild(backgroundBoxAlignCenter); - - // VAlign.Bottom - BitmapText labelAlignBottom = guiFont.createLabel("This text has VAlign.Bottom"); - Rectangle textboxAlignBottom = new Rectangle(width * 0.6f, height * 0.7f, 120, 120); - labelAlignBottom.setBox(textboxAlignBottom); - labelAlignBottom.setVerticalAlignment(BitmapFont.VAlign.Bottom); - getGuiNode().attachChild(labelAlignBottom); - - Geometry backgroundBoxAlignBottom = backgroundBoxAlignTop.clone(false); - backgroundBoxAlignBottom.setLocalTranslation(textboxAlignBottom.x, textboxAlignBottom.y, -1); - getGuiNode().attachChild(backgroundBoxAlignBottom); - - // VAlign.Top + Align.Right - BitmapText labelAlignTopRight = guiFont.createLabel("This text has VAlign.Top and Align.Right"); - Rectangle textboxAlignTopRight = new Rectangle(width * 0.2f, height * 0.3f, 120, 120); - labelAlignTopRight.setBox(textboxAlignTopRight); - labelAlignTopRight.setVerticalAlignment(BitmapFont.VAlign.Top); - labelAlignTopRight.setAlignment(BitmapFont.Align.Right); - getGuiNode().attachChild(labelAlignTopRight); - - Geometry backgroundBoxAlignTopRight = backgroundBoxAlignTop.clone(false); - backgroundBoxAlignTopRight.setLocalTranslation(textboxAlignTopRight.x, textboxAlignTopRight.y, -1); - getGuiNode().attachChild(backgroundBoxAlignTopRight); - - // VAlign.Center + Align.Center - BitmapText labelAlignCenterCenter = guiFont.createLabel("This text has VAlign.Center and Align.Center"); - Rectangle textboxAlignCenterCenter = new Rectangle(width * 0.4f, height * 0.3f, 120, 120); - labelAlignCenterCenter.setBox(textboxAlignCenterCenter); - labelAlignCenterCenter.setVerticalAlignment(BitmapFont.VAlign.Center); - labelAlignCenterCenter.setAlignment(BitmapFont.Align.Center); - getGuiNode().attachChild(labelAlignCenterCenter); - - Geometry backgroundBoxAlignCenterCenter = backgroundBoxAlignCenter.clone(false); - backgroundBoxAlignCenterCenter.setLocalTranslation(textboxAlignCenterCenter.x, textboxAlignCenterCenter.y, -1); - getGuiNode().attachChild(backgroundBoxAlignCenterCenter); - - // VAlign.Bottom + Align.Left - BitmapText labelAlignBottomLeft = guiFont.createLabel("This text has VAlign.Bottom and Align.Left"); - Rectangle textboxAlignBottomLeft = new Rectangle(width * 0.6f, height * 0.3f, 120, 120); - labelAlignBottomLeft.setBox(textboxAlignBottomLeft); - labelAlignBottomLeft.setVerticalAlignment(BitmapFont.VAlign.Bottom); - labelAlignBottomLeft.setAlignment(BitmapFont.Align.Left); - getGuiNode().attachChild(labelAlignBottomLeft); - - Geometry backgroundBoxAlignBottomLeft = backgroundBoxAlignBottom.clone(false); - backgroundBoxAlignBottomLeft.setLocalTranslation(textboxAlignBottomLeft.x, textboxAlignBottomLeft.y, -1); - getGuiNode().attachChild(backgroundBoxAlignBottomLeft); - - // Large quad with VAlign.Center and Align.Center - BitmapText label = guiFont.createLabel("This text is centered, both horizontally and vertically."); - Rectangle box = new Rectangle(width * 0.05f, height * 0.95f, width * 0.9f, height * 0.1f); - label.setBox(box); - label.setAlignment(BitmapFont.Align.Center); - label.setVerticalAlignment(BitmapFont.VAlign.Center); - getGuiNode().attachChild(label); - - Geometry background = new Geometry("background", new Quad(box.width, -box.height)); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Green); - background.setMaterial(mat); - background.setLocalTranslation(box.x, box.y, -1); - getGuiNode().attachChild(background); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java deleted file mode 100644 index 6d2ad6f37b..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (c) 2018-2021 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: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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 HOLDER 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. - */ - -package jme3test.gui; - -import java.awt.Color; -import java.awt.Font; -import java.awt.FontFormatException; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.*; - -import com.jme3.app.DebugKeysAppState; -import com.jme3.app.StatsAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.ScreenshotAppState; -import com.jme3.bounding.BoundingBox; -import com.jme3.font.BitmapCharacterSet; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.*; -import com.jme3.scene.debug.WireBox; -import com.jme3.scene.shape.*; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import com.jme3.texture.plugins.AWTLoader; - -/** - * - * @author pspeed42 - */ -public class TestBitmapFontLayout extends SimpleApplication { - - public static final String SCROLL_UP = "scroll up"; - public static final String SCROLL_DOWN = "scroll down"; - public static final String SCROLL_LEFT = "scroll left"; - public static final String SCROLL_RIGHT = "scroll right"; - public static final String ZOOM_IN = "zoom in"; - public static final String ZOOM_OUT = "zoom out"; - public static final String RESET_ZOOM = "reset zoom"; - public static final String RESET_VIEW = "reset view"; - - public static final float ZOOM_SPEED = 0.1f; - public static final float SCROLL_SPEED = 50; - - final private Node testRoot = new Node("test root"); - final private Node scrollRoot = new Node("scroll root"); - final private Vector3f scroll = new Vector3f(0, 0, 0); - final private Vector3f zoom = new Vector3f(0, 0, 0); - - public static void main(String[] args){ - TestBitmapFontLayout app = new TestBitmapFontLayout(); - app.start(); - } - - public TestBitmapFontLayout() { - super(new StatsAppState(), - new DebugKeysAppState(), - new ScreenshotAppState("", System.currentTimeMillis())); - } - - public static Font loadTtf( String resource ) { - try { - return Font.createFont(Font.TRUETYPE_FONT, - TestBitmapFontLayout.class.getResourceAsStream(resource)); - } catch( FontFormatException | IOException e ) { - throw new RuntimeException("Error loading resource:" + resource, e); - } - } - - private Texture renderAwtFont( TestConfig test, int width, int height, BitmapFont bitmapFont ) { - - BitmapCharacterSet charset = bitmapFont.getCharSet(); - - // Create an image at least as big as our JME text - System.out.println("Creating image size:" + width + ", " + height); - BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2 = (Graphics2D)image.getGraphics(); - - g2.setColor(Color.lightGray); - g2.fillRect(0, 0, width, height); - g2.setColor(Color.cyan); - g2.drawRect(0, 0, width, height); - - g2.setColor(new Color(0, 0, 128)); - //g2.drawLine(0, 0, 50, 50); - //g2.drawLine(xFont, yFont, xFont + 30, yFont); - //g2.drawLine(xFont, yFont, xFont, yFont + 30); - - //g2.drawString("Testing", 0, 10); - - Font font = test.awtFont; - System.out.println("Java font:" + font); - - float size = font.getSize2D(); - FontMetrics fm = g2.getFontMetrics(font); - System.out.println("Java font metrics:" + fm); - - String[] lines = test.text.split("\n"); - - g2.setFont(font); - g2.setRenderingHint( - RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - - int y = fm.getLeading() + fm.getMaxAscent(); - for( String s : lines ) { - g2.drawString(s, 0, y); - y += fm.getHeight(); - } - - g2.dispose(); - - Image jmeImage = new AWTLoader().load(image, true); - return new Texture2D(jmeImage); - } - - private Node createVisual( TestConfig test ) { - Node result = new Node(test.name); - - // For reasons I have trouble articulating, I want the visual's 0,0,0 to be - // the same as the JME rendered text. All other things will then be positioned relative - // to that. - // JME BitmapText (currently) renders from what it thinks the top of the letter is - // down. The actual bitmap text bounds may extend upwards... so we need to account - // for that in any labeling we add above it. - // Thus we add and set up the main test text first. - - BitmapFont bitmapFont = assetManager.loadFont(test.jmeFont); - BitmapCharacterSet charset = bitmapFont.getCharSet(); - - System.out.println("Test name:" + test.name); - System.out.println("Charset line height:" + charset.getLineHeight()); - System.out.println(" base:" + charset.getBase()); - System.out.println(" rendered size:" + charset.getRenderedSize()); - System.out.println(" width:" + charset.getWidth() + " height:" + charset.getHeight()); - - BitmapText bitmapText = new BitmapText(bitmapFont); - bitmapText.setText(test.text); - bitmapText.setColor(ColorRGBA.Black); - result.attachChild(bitmapText); - - // And force it to update because BitmapText builds itself lazily. - result.updateLogicalState(0.1f); - BoundingBox bb = (BoundingBox)bitmapText.getWorldBound(); - - BitmapText label = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt")); - label.setText("Test:" + test.name); - // Move the label up by its own size plus whatever extra headspace - // that the test text might have... plus a couple pixels of padding. - float yOffset = Math.max(0, bb.getCenter().y + bb.getYExtent()); - label.move(0, label.getSize() + yOffset + 2, 0); - label.setColor(new ColorRGBA(0, 0.2f, 0, 1f)); - result.attachChild(label); - - - // Bitmap text won't update itself automatically... it's lazy. - // That means it won't be able to tell us its bounding volume, etc... so - // we'll force it to update. - result.updateLogicalState(0.1f); - - // Add a bounding box visual - WireBox box = new WireBox(bb.getXExtent(), bb.getYExtent(), bb.getZExtent()); - Geometry geom = new Geometry(test.name + " bounds", box); - geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - geom.getMaterial().setColor("Color", ColorRGBA.Red); - geom.setLocalTranslation(bb.getCenter()); - result.attachChild(geom); - - // Add a box to show 0,0 + font size - float size = bitmapText.getLineHeight() * 0.5f; - box = new WireBox(size, size, 0); - geom = new Geometry(test.name + " metric", box); - geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - geom.getMaterial().setColor("Color", ColorRGBA.Blue); - geom.setLocalTranslation(size, -size, 0); - result.attachChild(geom); - - float yBaseline = -charset.getBase(); - Line line = new Line(new Vector3f(0, yBaseline, 0), new Vector3f(50, yBaseline, 0)); - geom = new Geometry(test.name + " base", line); - geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - geom.getMaterial().setColor("Color", ColorRGBA.Green); - result.attachChild(geom); - - System.out.println("text bb:" + bb); - // We want the width and the height to cover the whole potential area - // for the font. So it can't just be the rendered bounds but must encompass - // the whole abstract font space... 0, 0, to center + extents. - //int width = (int)Math.round(bb.getCenter().x + bb.getXExtent()); - //int height = (int)Math.round(-bb.getCenter().y + bb.getYExtent()); - // No, that's not right either because in case like this: - // text bb:BoundingBox [Center: (142.0, -15.5, 0.0) xExtent: 142.0 yExtent: 20.5 zExtent: 0.0] - // We get: - // Creating image size:284, 36 - // ...when it should be at least 41 high. - float x1 = bb.getCenter().x - bb.getXExtent(); - float x2 = bb.getCenter().x + bb.getXExtent(); - float y1 = bb.getCenter().y - bb.getYExtent(); - float y2 = bb.getCenter().y + bb.getYExtent(); - System.out.println("xy1:" + x1 + ", " + y1 + " xy2:" + x2 + ", " + y2); - int width = Math.round(x2 - Math.min(0, x1)); - int height = Math.round(y2 - Math.min(0, y1)); - - Texture awtText = renderAwtFont(test, width, height, bitmapFont); - Quad quad = new Quad(width, height); - geom = new Geometry(test.name + " awt1", quad); - geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - geom.getMaterial().setTexture("ColorMap", awtText); - // Quads render from the lower left corner up - geom.move(0, -height, 0); - - // That quad is now positioned directly over where the bitmap text is. - // We'll clone it and move one right and one down - Geometry right = geom.clone(); - right.move(width, 0, 0); - result.attachChild(right); - - Geometry down = geom.clone(); - down.move(0, bb.getCenter().y - bb.getYExtent() - 1, 0); - result.attachChild(down); - - return result; - } - - @Override - public void simpleInitApp() { - setPauseOnLostFocus(false); - setDisplayStatView(false); - setDisplayFps(false); - viewPort.setBackgroundColor(ColorRGBA.LightGray); - - setupTestScene(); - setupUserInput(); - - setupInstructionsNote(); - } - - protected void setupInstructionsNote() { - // Add some instructional text - String instructions = "WASD/Cursor Keys = scroll\n" - + "+/- = zoom\n" - + "space = reset view\n" - + "0 = reset zoom\n"; - BitmapText note = new BitmapText(guiFont); - note.setText(instructions); - note.setColor(new ColorRGBA(0, 0.3f, 0, 1)); - note.updateLogicalState(0.1f); - - BoundingBox bb = (BoundingBox)note.getWorldBound(); - - note.setLocalTranslation(cam.getWidth() - bb.getXExtent() * 2 - 20, - cam.getHeight() - 20, 10); - - guiNode.attachChild(note); - - BitmapText note2 = note.clone(); - note2.setColor(ColorRGBA.Black); - note2.move(1, -1, -2); - guiNode.attachChild(note2); - - BitmapText note3 = note.clone(); - note3.setColor(ColorRGBA.White); - note3.move(-1, 1, -1); - guiNode.attachChild(note3); - - } - - protected void setupTestScene() { - String fox = "The quick brown fox jumps over the lazy dog."; - String loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; - String foxIpsum = fox + "\n" + loremIpsum; - - List tests = new ArrayList<>(); - - - // Note: for some Java fonts we reduce the point size to more closely - // match the pixel size... other than the Java-rendered fonts from Hiero, it will never - // be exact because of different font engines. - tests.add(new TestConfig("Hiero Java FreeSerif-16-Italic", - foxIpsum, - "jme3test/font/FreeSerif16I.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 16f))); - - tests.add(new TestConfig("Hiero FreeType FreeSerif-16-Italic", - foxIpsum, - "jme3test/font/FT-FreeSerif16I.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 14f))); - - tests.add(new TestConfig("Hiero Native FreeSerif-16-Italic", - foxIpsum, - "jme3test/font/Native-FreeSerif16I.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 15f))); - - tests.add(new TestConfig("AngelCode FreeSerif-16-Italic", - foxIpsum, - "jme3test/font/BM-FreeSerif16I.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 12f))); - // It's actually between 12 and 13 but Java rounds up. - - tests.add(new TestConfig("Hiero Padded FreeSerif-16-Italic", - foxIpsum, - "jme3test/font/FreeSerif16Ipad5555.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 16f))); - - tests.add(new TestConfig("AngelCode Padded FreeSerif-16-Italic", - foxIpsum, - "jme3test/font/BM-FreeSerif16Ipad5555.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 12f))); - // It's actually between 12 and 13 but Java rounds up. - - tests.add(new TestConfig("Hiero FreeSerif-32", - foxIpsum, - "jme3test/font/FreeSerif32.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(32f))); - - tests.add(new TestConfig("AngelCode FreeSerif-32", - foxIpsum, - "jme3test/font/BM-FreeSerif32.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(25f))); - - tests.add(new TestConfig("Hiero FreeSerif-64-Italic", - foxIpsum, - "jme3test/font/FreeSerif64I.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 64f))); - - tests.add(new TestConfig("AngelCode FreeSerif-64-Italic", - foxIpsum, - "jme3test/font/BM-FreeSerif64I.fnt", - loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 50f))); - - - /*tests.add(new TestConfig("Japanese", - "\u3042\u3047\u3070\u3090\u309E\u3067\u308A\u3089\n"+ - "\u3042\u3047\u3070\u3090\u309E\u3067\u308A\u3089", - "jme3test/font/DJapaSubset.fnt", - loadTtf("/jme3test/font/DroidSansFallback.ttf").deriveFont(32f)));*/ - - /*tests.add(new TestConfig("DroidSansMono-32", - "Ă㥹ĔĕĖėχψωӮӯ₴₵₹\n"+ - "Ă㥹ĔĕĖėχψωӮӯ₴₵₹", - "jme3test/font/DMono32BI.fnt", - loadTtf("/jme3test/font/DroidSansMono.ttf").deriveFont(32f)));*/ - - /*tests.add(new TestConfig("DroidSansMono-32", - "Ă㥹ĔĕĖėχψωӮӯ\n"+ - "Ă㥹ĔĕĖėχψωӮӯ", - "jme3test/font/DMono32BI.fnt", - loadTtf("/jme3test/font/DroidSansMono.ttf").deriveFont(Font.BOLD | Font.ITALIC, 32f))); - */ - - // Set up the test root node so that y = 0 is the top of the screen - testRoot.setLocalTranslation(0, cam.getHeight(), 0); - testRoot.attachChild(scrollRoot); - guiNode.attachChild(testRoot); - - float y = 0; //cam.getHeight(); - - for( TestConfig test : tests ) { - System.out.println("y:" + y); - - Node vis = createVisual(test); - - BoundingBox bb = (BoundingBox)vis.getWorldBound(); - System.out.println("bb:" + bb); - - // Render it relative to y, projecting down - vis.setLocalTranslation(1 + bb.getCenter().x - bb.getXExtent(), - y - bb.getCenter().y - bb.getYExtent(), - 0); - //vis.setLocalTranslation(1, y, 0); - scrollRoot.attachChild(vis); - - // Position to render the next one - y -= bb.getYExtent() * 2; - - // plus 5 pixels of padding - y -= 5; - } - } - - protected void resetZoom() { - testRoot.setLocalScale(1, 1, 1); - } - - protected void resetView() { - resetZoom(); - scrollRoot.setLocalTranslation(0, 0, 0); - } - - protected void setupUserInput() { - - inputManager.addMapping(SCROLL_UP, new KeyTrigger(KeyInput.KEY_UP), - new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping(SCROLL_DOWN, new KeyTrigger(KeyInput.KEY_DOWN), - new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping(SCROLL_LEFT, new KeyTrigger(KeyInput.KEY_LEFT), - new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping(SCROLL_RIGHT, new KeyTrigger(KeyInput.KEY_RIGHT), - new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping(ZOOM_IN, new KeyTrigger(KeyInput.KEY_ADD), - new KeyTrigger(KeyInput.KEY_EQUALS), - new KeyTrigger(KeyInput.KEY_Q)); - inputManager.addMapping(ZOOM_OUT, new KeyTrigger(KeyInput.KEY_MINUS), - new KeyTrigger(KeyInput.KEY_SUBTRACT), - new KeyTrigger(KeyInput.KEY_Z)); - inputManager.addMapping(RESET_VIEW, new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping(RESET_ZOOM, new KeyTrigger(KeyInput.KEY_0)); - - inputManager.addListener(new KeyStateListener(), - RESET_VIEW, RESET_ZOOM, - SCROLL_UP, SCROLL_DOWN, SCROLL_LEFT, SCROLL_RIGHT, - ZOOM_IN, ZOOM_OUT); - } - - @Override - public void simpleUpdate( float tpf ) { - if( scroll.lengthSquared() != 0 ) { - scrollRoot.move(scroll.mult(tpf)); - } - if( zoom.lengthSquared() != 0 ) { - Vector3f current = testRoot.getLocalScale(); - testRoot.setLocalScale(current.add(zoom.mult(tpf))); - } - } - - private class KeyStateListener implements ActionListener { - @Override - public void onAction(String name, boolean value, float tpf) { - switch( name ) { - case RESET_VIEW: - // Only on the up - if( !value ) { - resetView(); - } - break; - case RESET_ZOOM: - // Only on the up - if( !value ) { - resetZoom(); - } - break; - case ZOOM_IN: - if( value ) { - zoom.set(ZOOM_SPEED, ZOOM_SPEED, 0); - } else { - zoom.set(0, 0, 0); - } - break; - case ZOOM_OUT: - if( value ) { - zoom.set(-ZOOM_SPEED, -ZOOM_SPEED, 0); - } else { - zoom.set(0, 0, 0); - } - break; - case SCROLL_UP: - if( value ) { - scroll.set(0, -SCROLL_SPEED, 0); - } else { - scroll.set(0, 0, 0); - } - break; - case SCROLL_DOWN: - if( value ) { - scroll.set(0, SCROLL_SPEED, 0); - } else { - scroll.set(0, 0, 0); - } - break; - case SCROLL_LEFT: - if( value ) { - scroll.set(SCROLL_SPEED, 0, 0); - } else { - scroll.set(0, 0, 0); - } - break; - case SCROLL_RIGHT: - if( value ) { - scroll.set(-SCROLL_SPEED, 0, 0); - } else { - scroll.set(0, 0, 0); - } - break; - } - } - } - - private class TestConfig { - String name; - String jmeFont; - Font awtFont; - String text; - - public TestConfig( String name, String text, String jmeFont, Font awtFont ) { - this.name = name; - this.text = text; - this.jmeFont = jmeFont; - this.awtFont = awtFont; - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java deleted file mode 100644 index e895cfba75..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.Rectangle; -import com.jme3.renderer.queue.RenderQueue.Bucket; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; - -public class TestBitmapText3D extends SimpleApplication { - - final private String txtB = - "ABCDEFGHIKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()-=_+[]\\;',./{}|:<>?"; - - public static void main(String[] args){ - TestBitmapText3D app = new TestBitmapText3D(); - app.start(); - } - - @Override - public void simpleInitApp() { - Quad q = new Quad(6, 3); - Geometry g = new Geometry("quad", q); - g.setLocalTranslation(0, -3, -0.0001f); - g.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(g); - - BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText txt = new BitmapText(fnt); - txt.setBox(new Rectangle(0, 0, 6, 3)); - txt.setQueueBucket(Bucket.Transparent); - txt.setSize( 0.5f ); - txt.setText(txtB); - rootNode.attachChild(txt); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestCursor.java b/jme3-examples/src/main/java/jme3test/gui/TestCursor.java deleted file mode 100644 index 3ba14216d7..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestCursor.java +++ /dev/null @@ -1,77 +0,0 @@ -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.cursors.plugins.JmeCursor; -import java.util.ArrayList; - -/** - * This test class demonstrate how to change cursor in jME3. - * - * NOTE: This will not work on Android as it does not support cursors. - * - * Cursor test - * @author MadJack - */ -public class TestCursor extends SimpleApplication { - - final private ArrayList cursors = new ArrayList<>(); - private long sysTime; - private int count = 0; - - public static void main(String[] args){ - TestCursor app = new TestCursor(); - - app.setShowSettings(false); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setEnabled(false); - // We need the cursor to be visible. If it is not visible the cursor - // will still be "used" and loaded, you just won't see it on the screen. - inputManager.setCursorVisible(true); - - /* - * To make jME3 use a custom cursor it is as simple as putting the - * .cur/.ico/.ani file in an asset directory. Here we use - * "Textures/GUI/Cursors". - * - * For the purpose of this demonstration we load 3 different cursors and add them - * into an array list and switch cursor every 8 seconds. - * - * The first ico has been made by Sirea and the set can be found here: - * http://www.rw-designer.com/icon-set/nyan-cat - * - * The second cursor has been made by Virum64 and is Public Domain. - * http://www.rw-designer.com/cursor-set/memes-faces-v64 - * - * The animated cursor has been made by Pointer Adic and can be found here: - * http://www.rw-designer.com/cursor-set/monkey - */ - cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/meme.cur")); - cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/nyancat.ico")); - cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/monkey.ani")); - - sysTime = System.currentTimeMillis(); - inputManager.setMouseCursor(cursors.get(count)); - } - - @Override - public void simpleUpdate(float tpf) { - long currentTime = System.currentTimeMillis(); - - if (currentTime - sysTime > 8000) { - count++; - if (count >= cursors.size()) { - count = 0; - } - sysTime = currentTime; - // 8 seconds have passed, - // tell jME3 to switch to a different cursor. - inputManager.setMouseCursor(cursors.get(count)); - } - - } -} - diff --git a/jme3-examples/src/main/java/jme3test/gui/TestOrtho.java b/jme3-examples/src/main/java/jme3test/gui/TestOrtho.java deleted file mode 100644 index dc61e9e2c5..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestOrtho.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.ui.Picture; - -public class TestOrtho extends SimpleApplication { - - public static void main(String[] args){ - TestOrtho app = new TestOrtho(); - app.start(); - } - - @Override - public void simpleInitApp() { - Picture p = new Picture("Picture"); - p.move(0, 0, -1); // make it appear behind stats view - p.setPosition(0, 0); - p.setWidth(settings.getWidth()); - p.setHeight(settings.getHeight()); - p.setImage(assetManager, "Interface/Logo/Monkey.png", false); - - // attach geometry to orthoNode - guiNode.attachChild(p); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java b/jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java deleted file mode 100644 index 0b9ae4bab9..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.app.StatsAppState; -import com.jme3.font.*; - -/** - * Test case for JME issue #1158: BitmapText right to left line wrapping not work - */ -public class TestRtlBitmapText extends SimpleApplication { - - private String text = "This is a test right to left text."; - private BitmapFont fnt; - private BitmapText txt; - - public static void main(String[] args) { - TestRtlBitmapText app = new TestRtlBitmapText(); - app.start(); - } - - @Override - public void simpleInitApp() { - float x = 400; - float y = 500; - getStateManager().detach(stateManager.getState(StatsAppState.class)); - fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - fnt.setRightToLeft(true); - - // A right to left BitmapText - txt = new BitmapText(fnt); - txt.setBox(new Rectangle(0, 0, 150, 0)); - txt.setLineWrapMode(LineWrapMode.Word); - txt.setAlignment(BitmapFont.Align.Right); - txt.setText(text); - - txt.setLocalTranslation(x, y, 0); - guiNode.attachChild(txt); - } -} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java b/jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java deleted file mode 100644 index e1baf0b5c7..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.RawInputListener; -import com.jme3.input.event.*; -import com.jme3.math.FastMath; -import com.jme3.math.Vector2f; -import com.jme3.system.AppSettings; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import com.jme3.ui.Picture; - -public class TestSoftwareMouse extends SimpleApplication { - - private Picture cursor; - - final private RawInputListener inputListener = new RawInputListener() { - - @Override - public void beginInput() { - } - @Override - public void endInput() { - } - @Override - public void onJoyAxisEvent(JoyAxisEvent evt) { - } - @Override - public void onJoyButtonEvent(JoyButtonEvent evt) { - } - @Override - public void onMouseMotionEvent(MouseMotionEvent evt) { - float x = evt.getX(); - float y = evt.getY(); - - // Prevent mouse from leaving screen - AppSettings settings = TestSoftwareMouse.this.settings; - x = FastMath.clamp(x, 0, settings.getWidth()); - y = FastMath.clamp(y, 0, settings.getHeight()); - - // adjust for hotspot - cursor.setPosition(x, y - 64); - } - @Override - public void onMouseButtonEvent(MouseButtonEvent evt) { - } - @Override - public void onKeyEvent(KeyInputEvent evt) { - } - @Override - public void onTouchEvent(TouchEvent evt) { - } - }; - - public static void main(String[] args){ - TestSoftwareMouse app = new TestSoftwareMouse(); - -// AppSettings settings = new AppSettings(true); -// settings.setFrameRate(60); -// app.setSettings(settings); - - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setEnabled(false); -// inputManager.setCursorVisible(false); - - Texture tex = assetManager.loadTexture("Interface/Logo/Cursor.png"); - - cursor = new Picture("cursor"); - cursor.setTexture(assetManager, (Texture2D) tex, true); - cursor.setWidth(64); - cursor.setHeight(64); - guiNode.attachChild(cursor); - /* - * Position the software cursor - * so that its upper-left corner is at the hotspot. - */ - Vector2f initialPosition = inputManager.getCursorPosition(); - cursor.setPosition(initialPosition.x, initialPosition.y - 64f); - - inputManager.addRawInputListener(inputListener); - -// Image img = tex.getImage(); -// ByteBuffer data = img.getData(0); -// IntBuffer image = BufferUtils.createIntBuffer(64 * 64); -// for (int y = 0; y < 64; y++){ -// for (int x = 0; x < 64; x++){ -// int rgba = data.getInt(); -// image.put(rgba); -// } -// } -// image.clear(); -// -// try { -// Cursor cur = new Cursor(64, 64, 2, 62, 1, image, null); -// Mouse.setNativeCursor(cur); -// } catch (LWJGLException ex) { -// Logger.getLogger(TestSoftwareMouse.class.getName()).log(Level.SEVERE, null, ex); -// } - } -} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestZOrder.java b/jme3-examples/src/main/java/jme3test/gui/TestZOrder.java deleted file mode 100644 index 6d9ed9768d..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/TestZOrder.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.gui; - -import com.jme3.app.SimpleApplication; -import com.jme3.ui.Picture; - -public class TestZOrder extends SimpleApplication { - - public static void main(String[] args){ - TestZOrder app = new TestZOrder(); - app.start(); - } - - @Override - public void simpleInitApp() { - Picture p = new Picture("Picture1"); - p.move(0,0,-1); - p.setPosition(100, 100); - p.setWidth(100); - p.setHeight(100); - p.setImage(assetManager, "Interface/Logo/Monkey.png", false); - guiNode.attachChild(p); - - Picture p2 = new Picture("Picture2"); - p2.move(0,0,1.001f); - p2.setPosition(150, 150); - p2.setWidth(100); - p2.setHeight(100); - p2.setImage(assetManager, "Interface/Logo/Monkey.png", false); - guiNode.attachChild(p2); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/gui/package-info.java b/jme3-examples/src/main/java/jme3test/gui/package-info.java deleted file mode 100644 index 33e0fc2cf7..0000000000 --- a/jme3-examples/src/main/java/jme3test/gui/package-info.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for native graphical user-interface - * (GUI) support - */ -package jme3test.gui; diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java deleted file mode 100644 index 5af191916d..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.tween.Tween; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.Action; -import com.jme3.anim.tween.action.BlendSpace; -import com.jme3.anim.tween.action.LinearBlendSpace; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; - -/** - * Sample 7 - Load an OgreXML model and play some of its animations. - */ -public class HelloAnimation extends SimpleApplication { - - private Action advance; - private AnimComposer control; - - public static void main(String[] args) { - HelloAnimation app = new HelloAnimation(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.LightGray); - initKeys(); - - /* Add a light source so we can see the model */ - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -1f, -1).normalizeLocal()); - rootNode.addLight(dl); - - /* Load a model that contains animation */ - Node player = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - player.setLocalScale(0.5f); - rootNode.attachChild(player); - - /* Use the model's AnimComposer to play its "stand" animation clip. */ - control = player.getControl(AnimComposer.class); - control.setCurrentAction("stand"); - - /* Compose an animation action named "halt" - that transitions from "Walk" to "stand" in half a second. */ - BlendSpace quickBlend = new LinearBlendSpace(0f, 0.5f); - Action halt = control.actionBlended("halt", quickBlend, "stand", "Walk"); - halt.setLength(0.5); - - /* Compose an animation action named "advance" - that walks for one cycle, then halts, then invokes onAdvanceDone(). */ - Action walk = control.action("Walk"); - Tween doneTween = Tweens.callMethod(this, "onAdvanceDone"); - advance = control.actionSequence("advance", walk, halt, doneTween); - } - - /** - * Callback to indicate that the "advance" animation action has completed. - */ - void onAdvanceDone() { - /* - * Play the "stand" animation action. - */ - control.setCurrentAction("stand"); - } - - /** - * Map the spacebar to the "Walk" input action, and add a listener to initiate - * the "advance" animation action each time it's pressed. - */ - private void initKeys() { - inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE)); - - ActionListener handler = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (keyPressed && control.getCurrentAction() != advance) { - control.setCurrentAction("advance"); - } - } - }; - inputManager.addListener(handler, "Walk"); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java deleted file mode 100644 index d062ed8e98..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; - -/** Sample 3 - how to load an OBJ model, and OgreXML model, - * a material/texture, or text. */ -public class HelloAssets extends SimpleApplication { - - public static void main(String[] args) { - HelloAssets app = new HelloAssets(); - app.start(); - } - - @Override - public void simpleInitApp() { - - /* Load a teapot model (OBJ file from jme3-testdata) */ - Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); - Material mat_default = new Material( assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - teapot.setMaterial(mat_default); - rootNode.attachChild(teapot); - - /* Create a wall (Box with material and texture from jme3-testdata) */ - Box box = new Box(2.5f, 2.5f, 1.0f); - Spatial wall = new Geometry("Box", box ); - Material mat_brick = new Material( assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat_brick.setTexture("ColorMap", assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg")); - wall.setMaterial(mat_brick); - wall.setLocalTranslation(2.0f,-2.5f,0.0f); - rootNode.attachChild(wall); - - /* Display a line of text (default font from jme3-testdata) */ - setDisplayStatView(false); - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText helloText = new BitmapText(guiFont); - helloText.setSize(guiFont.getCharSet().getRenderedSize()); - helloText.setText("Hello World"); - helloText.setLocalTranslation(300, helloText.getLineHeight(), 0); - guiNode.attachChild(helloText); - - /* Load a Ninja model (OgreXML + material + texture from test_data) */ - Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml"); - ninja.scale(0.05f, 0.05f, 0.05f); - ninja.rotate(0.0f, -3.0f, 0.0f); - ninja.setLocalTranslation(0.0f, -5.0f, -2.0f); - rootNode.attachChild(ninja); - /* You must add a light to make the model visible. */ - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal()); - rootNode.addLight(sun); - } -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java deleted file mode 100644 index 228fc53d83..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java +++ /dev/null @@ -1,84 +0,0 @@ -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioData.DataType; -import com.jme3.audio.AudioNode; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -/** Sample 11 - playing 3D audio. */ -public class HelloAudio extends SimpleApplication { - - private AudioNode audio_gun; - - public static void main(String[] args) { - HelloAudio app = new HelloAudio(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(40); - - /* just a blue box floating in space */ - Box box1 = new Box(1, 1, 1); - Geometry player = new Geometry("Player", box1); - Material mat1 = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.Blue); - player.setMaterial(mat1); - rootNode.attachChild(player); - - /* custom init methods, see below */ - initKeys(); - initAudio(); - } - - /** We create two audio nodes. */ - private void initAudio() { - /* gun shot sound is to be triggered by a mouse click. */ - audio_gun = new AudioNode(assetManager, - "Sound/Effects/Gun.wav", DataType.Buffer); - audio_gun.setPositional(false); - audio_gun.setLooping(false); - audio_gun.setVolume(2); - rootNode.attachChild(audio_gun); - - /* nature sound - keeps playing in a loop. */ - AudioNode audio_nature = new AudioNode(assetManager, - "Sound/Environment/Ocean Waves.ogg", DataType.Stream); - audio_nature.setLooping(true); // activate continuous playing - audio_nature.setPositional(true); - audio_nature.setVolume(3); - rootNode.attachChild(audio_nature); - audio_nature.play(); // play continuously! - } - - /** Declaring "Shoot" action, mapping it to a trigger (mouse left click). */ - private void initKeys() { - inputManager.addMapping("Shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "Shoot"); - } - - /** Defining the "Shoot" action: Play a gun sound. */ - final private ActionListener actionListener = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("Shoot") && !keyPressed) { - audio_gun.playInstance(); // play each instance once! - } - } - }; - - /** Move the listener with the camera - for 3-D audio. */ - @Override - public void simpleUpdate(float tpf) { - listener.setLocation(cam.getLocation()); - listener.setRotation(cam.getRotation()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java deleted file mode 100644 index 518e479b76..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; -import com.jme3.bullet.collision.shapes.CollisionShape; -import com.jme3.bullet.control.CharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.util.CollisionShapeFactory; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; - -/** - * Example 9 - How to make walls and floors solid. - * This collision code uses Physics and a custom Action Listener. - * @author normen, with edits by Zathras - */ -public class HelloCollision extends SimpleApplication - implements ActionListener { - - private CharacterControl player; - final private Vector3f walkDirection = new Vector3f(); - private boolean left = false, right = false, up = false, down = false; - - //Temporary vectors used on each frame. - //They here to avoid instantiating new vectors on each frame - final private Vector3f camDir = new Vector3f(); - final private Vector3f camLeft = new Vector3f(); - - public static void main(String[] args) { - HelloCollision app = new HelloCollision(); - app.start(); - } - - @Override - public void simpleInitApp() { - /* Set up physics */ - BulletAppState bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - - // We re-use the flyby camera for rotation, while positioning is handled by physics - viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); - flyCam.setMoveSpeed(100); - setUpKeys(); - setUpLight(); - - // We load the scene from the zip file and adjust its size. - assetManager.registerLocator( - "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/town.zip", - HttpZipLocator.class); - Spatial sceneModel = assetManager.loadModel("main.scene"); - sceneModel.setLocalScale(2f); - - // We set up collision detection for the scene by creating a - // compound collision shape and a static RigidBodyControl with mass zero. - CollisionShape sceneShape = - CollisionShapeFactory.createMeshShape(sceneModel); - RigidBodyControl landscape = new RigidBodyControl(sceneShape, 0); - sceneModel.addControl(landscape); - - // We set up collision detection for the player by creating - // a capsule collision shape and a CharacterControl. - // The CharacterControl offers extra settings for - // size, step height, jumping, falling, and gravity. - // We also put the player in its starting position. - CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1); - player = new CharacterControl(capsuleShape, 0.05f); - player.setJumpSpeed(20); - player.setFallSpeed(30); - player.setGravity(30); - player.setPhysicsLocation(new Vector3f(0, 10, 0)); - - // We attach the scene and the player to the rootnode and the physics space, - // to make them appear in the game world. - rootNode.attachChild(sceneModel); - bulletAppState.getPhysicsSpace().add(landscape); - bulletAppState.getPhysicsSpace().add(player); - } - - private void setUpLight() { - // We add light so we see the scene - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(1.3f)); - rootNode.addLight(al); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White); - dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal()); - rootNode.addLight(dl); - } - - /** We over-write some navigational key mappings here, so we can - * add physics-controlled walking and jumping: */ - private void setUpKeys() { - inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this, "Left"); - inputManager.addListener(this, "Right"); - inputManager.addListener(this, "Up"); - inputManager.addListener(this, "Down"); - inputManager.addListener(this, "Jump"); - } - - /** These are our custom actions triggered by key presses. - * We do not walk yet, we just keep track of the direction the user pressed. */ - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Left")) { - if (value) { left = true; } else { left = false; } - } else if (binding.equals("Right")) { - if (value) { right = true; } else { right = false; } - } else if (binding.equals("Up")) { - if (value) { up = true; } else { up = false; } - } else if (binding.equals("Down")) { - if (value) { down = true; } else { down = false; } - } else if (binding.equals("Jump")) { - player.jump(); - } - } - - /** - * This is the main event loop--walking happens here. - * We check in which direction the player is walking by interpreting - * the camera direction forward (camDir) and to the side (camLeft). - * The setWalkDirection() command is what lets a physics-controlled player walk. - * We also make sure here that the camera moves with player. - */ - @Override - public void simpleUpdate(float tpf) { - camDir.set(cam.getDirection()).multLocal(0.6f); - camLeft.set(cam.getLeft()).multLocal(0.4f); - walkDirection.set(0, 0, 0); - if (left) { - walkDirection.addLocal(camLeft); - } - if (right) { - walkDirection.addLocal(camLeft.negate()); - } - if (up) { - walkDirection.addLocal(camDir); - } - if (down) { - walkDirection.addLocal(camDir.negate()); - } - player.setWalkDirection(walkDirection); - cam.setLocation(player.getPhysicsLocation()); - } -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java deleted file mode 100644 index 1210c7040e..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; - -/** Sample 11 - how to create fire, water, and explosion effects. */ -public class HelloEffects extends SimpleApplication { - - public static void main(String[] args) { - HelloEffects app = new HelloEffects(); - app.start(); - } - - @Override - public void simpleInitApp() { - ParticleEmitter fire = - new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30); - Material mat_red = new Material(assetManager, - "Common/MatDefs/Misc/Particle.j3md"); - mat_red.setTexture("Texture", assetManager.loadTexture( - "Effects/Explosion/flame.png")); - fire.setMaterial(mat_red); - fire.setImagesX(2); - fire.setImagesY(2); // 2x2 texture animation - fire.setEndColor( new ColorRGBA(1f, 0f, 0f, 1f)); // red - fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow - fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0)); - fire.setStartSize(1.5f); - fire.setEndSize(0.1f); - fire.setGravity(0, 0, 0); - fire.setLowLife(1f); - fire.setHighLife(3f); - fire.getParticleInfluencer().setVelocityVariation(0.3f); - rootNode.attachChild(fire); - - ParticleEmitter debris = - new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10); - Material debris_mat = new Material(assetManager, - "Common/MatDefs/Misc/Particle.j3md"); - debris_mat.setTexture("Texture", assetManager.loadTexture( - "Effects/Explosion/Debris.png")); - debris.setMaterial(debris_mat); - debris.setImagesX(3); - debris.setImagesY(3); // 3x3 texture animation - debris.setSelectRandomImage(true); - debris.setRotateSpeed(4); - debris.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 4, 0)); - debris.setStartColor(ColorRGBA.White); - debris.setGravity(0, 6, 0); - debris.getParticleInfluencer().setVelocityVariation(.60f); - rootNode.attachChild(debris); - debris.emitAllParticles(); - -// ParticleEmitter water = -// new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 20); -// Material mat_blue = new Material(assetManager, -// "Common/MatDefs/Misc/Particle.j3md"); -// mat_blue.setTexture("Texture", assetManager.loadTexture( -// "Effects/Explosion/flame.png")); -// water.setMaterial(mat_blue); -// water.setImagesX(2); -// water.setImagesY(2); // 2x2 texture animation -// water.setStartColor( ColorRGBA.Blue); -// water.setEndColor( ColorRGBA.Cyan); -// water.getParticleInfluencer().setInitialVelocity(new Vector3f(0, -4, 0)); -// water.setStartSize(1f); -// water.setEndSize(1.5f); -// water.setGravity(0,1,0); -// water.setLowLife(1f); -// water.setHighLife(1f); -// water.getParticleInfluencer().setVelocityVariation(0.1f); -// water.setLocalTranslation(0, 6, 0); -// rootNode.attachChild(water); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java deleted file mode 100644 index 0796bd7ce8..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -/** Sample 5 - how to map keys and mouse buttons to actions */ -public class HelloInput extends SimpleApplication { - - public static void main(String[] args) { - HelloInput app = new HelloInput(); - app.start(); - } - private Geometry player; - private Boolean isRunning=true; - - @Override - public void simpleInitApp() { - Box b = new Box(1, 1, 1); - player = new Geometry("Player", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - player.setMaterial(mat); - rootNode.attachChild(player); - initKeys(); // load my custom keybinding - } - - /** Custom Keybinding: Map named actions to inputs. */ - private void initKeys() { - /* You can map one or several inputs to one named mapping. */ - inputManager.addMapping("Pause", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Rotate", new KeyTrigger(KeyInput.KEY_SPACE), // spacebar! - new MouseButtonTrigger(MouseInput.BUTTON_LEFT) ); // left click! - /* Add the named mappings to the action listeners. */ - inputManager.addListener(actionListener,"Pause"); - inputManager.addListener(analogListener,"Left", "Right", "Rotate"); - } - - /** Use this listener for KeyDown/KeyUp events */ - final private ActionListener actionListener = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("Pause") && !keyPressed) { - isRunning = !isRunning; - } - } - }; - - /** Use this listener for continuous events */ - final private AnalogListener analogListener = new AnalogListener() { - @Override - public void onAnalog(String name, float value, float tpf) { - if (isRunning) { - if (name.equals("Rotate")) { - player.rotate(0, value, 0); - } - if (name.equals("Right")) { - player.move((new Vector3f(value, 0,0)) ); - } - if (name.equals("Left")) { - player.move(new Vector3f(-value, 0,0)); - } - } else { - System.out.println("Press P to unpause."); - } - } - }; - -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java deleted file mode 100644 index ba6d075e31..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -/** Sample 1 - how to get started with the most simple JME 3 application. - * Display a blue 3D cube and view from all sides by - * moving the mouse and pressing the WASD keys. */ -public class HelloJME3 extends SimpleApplication { - - public static void main(String[] args){ - HelloJME3 app = new HelloJME3(); - app.start(); // start the game - } - - @Override - public void simpleInitApp() { - Box b = new Box(1, 1, 1); // create cube shape - Geometry geom = new Geometry("Box", b); // create cube geometry from the shape - Material mat = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material - mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue - geom.setMaterial(mat); // set the cube's material - rootNode.attachChild(geom); // make the cube appear in the scene - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java deleted file mode 100644 index 5bdec52016..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -/** Sample 4 - how to trigger repeating actions from the main event loop. - * In this example, you use the loop to make the player character - * rotate continuously. */ -public class HelloLoop extends SimpleApplication { - - public static void main(String[] args){ - HelloLoop app = new HelloLoop(); - app.start(); - } - - private Geometry player; - - @Override - public void simpleInitApp() { - /* This blue box is our player character. */ - Box b = new Box(1, 1, 1); - player = new Geometry("blue cube", b); - Material mat = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - player.setMaterial(mat); - rootNode.attachChild(player); - } - - /* Use the main event loop to trigger repeating actions. */ - @Override - public void simpleUpdate(float tpf) { - // make the player rotate: - player.rotate(0, 2*tpf, 0); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java deleted file mode 100644 index e12fef4569..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.material.RenderState.BlendMode; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.Bucket; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.texture.Texture; -import com.jme3.util.TangentBinormalGenerator; - -/** Sample 6 - how to give an object's surface a material and texture. - * How to make objects transparent. How to make bumpy and shiny surfaces. */ -public class HelloMaterial extends SimpleApplication { - - public static void main(String[] args) { - HelloMaterial app = new HelloMaterial(); - app.start(); - } - - @Override - public void simpleInitApp() { - - /* A simple textured cube -- in good MIP map quality. */ - Box cube1Mesh = new Box( 1f,1f,1f); - Geometry cube1Geo = new Geometry("My Textured Box", cube1Mesh); - cube1Geo.setLocalTranslation(new Vector3f(-3f,1.1f,0f)); - Material cube1Mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - Texture cube1Tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); - cube1Mat.setTexture("ColorMap", cube1Tex); - cube1Geo.setMaterial(cube1Mat); - rootNode.attachChild(cube1Geo); - - /* A translucent/transparent texture, similar to a window frame. */ - Box cube2Mesh = new Box( 1f,1f,0.01f); - Geometry cube2Geo = new Geometry("window frame", cube2Mesh); - Material cube2Mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - cube2Mat.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png")); - cube2Mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); // activate transparency - cube2Geo.setQueueBucket(Bucket.Transparent); - cube2Geo.setMaterial(cube2Mat); - rootNode.attachChild(cube2Geo); - - /* A bumpy rock with a shiny light effect. To make bumpy objects you must create a NormalMap. */ - Sphere sphereMesh = new Sphere(32,32, 2f); - Geometry sphereGeo = new Geometry("Shiny rock", sphereMesh); - sphereMesh.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres - TangentBinormalGenerator.generate(sphereMesh); // for lighting effect - Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - sphereMat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg")); - sphereMat.setTexture("NormalMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png")); - sphereMat.setBoolean("UseMaterialColors",true); - sphereMat.setColor("Diffuse",ColorRGBA.White); - sphereMat.setColor("Specular",ColorRGBA.White); - sphereMat.setFloat("Shininess", 64f); // [0,128] - sphereGeo.setMaterial(sphereMat); - //sphereGeo.setMaterial((Material) assetManager.loadMaterial("Materials/MyCustomMaterial.j3m")); - sphereGeo.setLocalTranslation(0,2,-2); // Move it a bit - sphereGeo.rotate(1.6f, 0, 0); // Rotate it a bit - rootNode.attachChild(sphereGeo); - - /* Must add a light to make the lit object visible! */ - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(1,0,-2).normalizeLocal()); - sun.setColor(ColorRGBA.White); - rootNode.addLight(sun); - } -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java deleted file mode 100644 index 12bf60f950..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; - -/** Sample 2 - How to use nodes as handles to manipulate objects in the scene. - * You can rotate, translate, and scale objects by manipulating their parent nodes. - * The Root Node is special: Only what is attached to the Root Node appears in the scene. */ -public class HelloNode extends SimpleApplication { - - public static void main(String[] args){ - HelloNode app = new HelloNode(); - app.start(); - } - - @Override - public void simpleInitApp() { - - /* create a blue box at coordinates (1,-1,1) */ - Box box1 = new Box(1,1,1); - Geometry blue = new Geometry("Box", box1); - blue.setLocalTranslation(new Vector3f(1,-1,1)); - Material mat1 = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.Blue); - blue.setMaterial(mat1); - - /* create a red box straight above the blue one at (1,3,1) */ - Box box2 = new Box(1,1,1); - Geometry red = new Geometry("Box", box2); - red.setLocalTranslation(new Vector3f(1,3,1)); - Material mat2 = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - mat2.setColor("Color", ColorRGBA.Red); - red.setMaterial(mat2); - - /* Create a pivot node at (0,0,0) and attach it to the root node */ - Node pivot = new Node("pivot"); - rootNode.attachChild(pivot); // put this node in the scene - - /* Attach the two boxes to the *pivot* node. (And transitively to the root node.) */ - pivot.attachChild(blue); - pivot.attachChild(red); - /* Rotate the pivot node: Note that both boxes have rotated! */ - pivot.rotate(.4f,.4f,0f); - } -} - diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java deleted file mode 100644 index ec566e3909..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.font.BitmapText; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Sphere.TextureMode; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; - -/** - * Example 12 - how to give objects physical properties, so they bounce and fall. - * @author base code by double1984, updated by zathras - */ -public class HelloPhysics extends SimpleApplication { - - public static void main(String args[]) { - HelloPhysics app = new HelloPhysics(); - app.start(); - } - - /** Prepare the Physics Application State (jBullet) */ - private BulletAppState bulletAppState; - - /** Prepare Materials */ - private Material wall_mat; - private Material stone_mat; - private Material floor_mat; - - /** Prepare geometries for bricks and cannonballs. */ - private static final Box box; - private static final Sphere sphere; - private static final Box floor; - - /** dimensions used for bricks and wall */ - private static final float brickLength = 0.48f; - private static final float brickWidth = 0.24f; - private static final float brickHeight = 0.12f; - - static { - /* Initialize the cannonball geometry */ - sphere = new Sphere(32, 32, 0.4f, true, false); - sphere.setTextureMode(TextureMode.Projected); - /* Initialize the brick geometry */ - box = new Box(brickLength, brickHeight, brickWidth); - box.scaleTextureCoordinates(new Vector2f(1f, .5f)); - /* Initialize the floor geometry */ - floor = new Box(10f, 0.1f, 5f); - floor.scaleTextureCoordinates(new Vector2f(3, 6)); - } - - @Override - public void simpleInitApp() { - /* Set up Physics Game */ - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - /* Configure cam to look at scene */ - cam.setLocation(new Vector3f(0, 4f, 6f)); - cam.lookAt(new Vector3f(2, 2, 0), Vector3f.UNIT_Y); - /* Initialize the scene, materials, inputs, and physics space */ - initInputs(); - initMaterials(); - initWall(); - initFloor(); - initCrossHairs(); - } - - /** Add InputManager action: Left click triggers shooting. */ - private void initInputs() { - inputManager.addMapping("shoot", - new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "shoot"); - } - - /** - * Every time the shoot action is triggered, a new cannonball is produced. - * The ball is set up to fly from the camera position in the camera direction. - */ - final private ActionListener actionListener = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("shoot") && !keyPressed) { - makeCannonBall(); - } - } - }; - - /** Initialize the materials used in this scene. */ - public void initMaterials() { - wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - wall_mat.setTexture("ColorMap", tex); - - stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); - key2.setGenerateMips(true); - Texture tex2 = assetManager.loadTexture(key2); - stone_mat.setTexture("ColorMap", tex2); - - floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); - key3.setGenerateMips(true); - Texture tex3 = assetManager.loadTexture(key3); - tex3.setWrap(WrapMode.Repeat); - floor_mat.setTexture("ColorMap", tex3); - } - - /** Make a solid floor and add it to the scene. */ - public void initFloor() { - Geometry floor_geo = new Geometry("Floor", floor); - floor_geo.setMaterial(floor_mat); - floor_geo.setLocalTranslation(0, -0.1f, 0); - this.rootNode.attachChild(floor_geo); - /* Make the floor physical with mass 0.0f! */ - RigidBodyControl floor_phy = new RigidBodyControl(0.0f); - floor_geo.addControl(floor_phy); - bulletAppState.getPhysicsSpace().add(floor_phy); - } - - /** This loop builds a wall out of individual bricks. */ - public void initWall() { - float startX = brickLength / 4; - float height = 0; - for (int j = 0; j < 15; j++) { - for (int i = 0; i < 6; i++) { - Vector3f vt = - new Vector3f(i * brickLength * 2 + startX, brickHeight + height, 0); - makeBrick(vt); - } - startX = -startX; - height += 2 * brickHeight; - } - } - - /** Creates one physical brick. */ - private void makeBrick(Vector3f loc) { - /* Create a brick geometry and attach it to the scene graph. */ - Geometry brick_geo = new Geometry("brick", box); - brick_geo.setMaterial(wall_mat); - rootNode.attachChild(brick_geo); - /* Position the brick geometry. */ - brick_geo.setLocalTranslation(loc); - /* Make brick physical with a mass > 0. */ - RigidBodyControl brick_phy = new RigidBodyControl(2f); - /* Add physical brick to physics space. */ - brick_geo.addControl(brick_phy); - bulletAppState.getPhysicsSpace().add(brick_phy); - } - - /** Creates one physical cannonball. - * By default, the ball is accelerated and flies - * from the camera position in the camera direction.*/ - public void makeCannonBall() { - /* Create a cannonball geometry and attach to scene graph. */ - Geometry ball_geo = new Geometry("cannon ball", sphere); - ball_geo.setMaterial(stone_mat); - rootNode.attachChild(ball_geo); - /* Position the cannonball. */ - ball_geo.setLocalTranslation(cam.getLocation()); - /* Make the ball physical with a mass > 0.0f */ - RigidBodyControl ball_phy = new RigidBodyControl(1f); - /* Add physical ball to physics space. */ - ball_geo.addControl(ball_phy); - bulletAppState.getPhysicsSpace().add(ball_phy); - /* Accelerate the physical ball to shoot it. */ - ball_phy.setLinearVelocity(cam.getDirection().mult(25)); - } - - /** A plus sign used as crosshairs to help the player with aiming.*/ - protected void initCrossHairs() { - setDisplayStatView(false); - //guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // fake crosshairs :) - ch.setLocalTranslation( // center - settings.getWidth() / 2, - settings.getHeight() / 2, 0); - guiNode.attachChild(ch); - } -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java deleted file mode 100644 index 90e187a9a9..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Ray; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; - -/** Sample 8 - how to let the user pick (select) objects in the scene - * using the mouse or key presses. Can be used for shooting, opening doors, etc. */ -public class HelloPicking extends SimpleApplication { - - public static void main(String[] args) { - HelloPicking app = new HelloPicking(); - app.start(); - } - private Node shootables; - private Geometry mark; - - @Override - public void simpleInitApp() { - initCrossHairs(); // a "+" in the middle of the screen to help aiming - initKeys(); // load custom key mappings - initMark(); // a red sphere to mark the hit - - /* Create four colored boxes and a floor to shoot at: */ - shootables = new Node("Shootables"); - rootNode.attachChild(shootables); - shootables.attachChild(makeCube("a Dragon", -2f, 0f, 1f)); - shootables.attachChild(makeCube("a tin can", 1f, -2f, 0f)); - shootables.attachChild(makeCube("the Sheriff", 0f, 1f, -2f)); - shootables.attachChild(makeCube("the Deputy", 1f, 0f, -4f)); - shootables.attachChild(makeFloor()); - shootables.attachChild(makeCharacter()); - } - - /** Declaring the "Shoot" action and mapping to its triggers. */ - private void initKeys() { - inputManager.addMapping("Shoot", - new KeyTrigger(KeyInput.KEY_SPACE), // trigger 1: spacebar - new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); // trigger 2: left-button click - inputManager.addListener(actionListener, "Shoot"); - } - /** Defining the "Shoot" action: Determine what was hit and how to respond. */ - final private ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("Shoot") && !keyPressed) { - // 1. Reset results list. - CollisionResults results = new CollisionResults(); - // 2. Aim the ray from cam loc to cam direction. - Ray ray = new Ray(cam.getLocation(), cam.getDirection()); - // 3. Collect intersections between Ray and Shootables in results list. - shootables.collideWith(ray, results); - // 4. Print the results - System.out.println("----- Collisions? " + results.size() + "-----"); - for (int i = 0; i < results.size(); i++) { - // For each hit, we know distance, impact point, name of geometry. - float dist = results.getCollision(i).getDistance(); - Vector3f pt = results.getCollision(i).getContactPoint(); - String hit = results.getCollision(i).getGeometry().getName(); - System.out.println("* Collision #" + i); - System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away."); - } - // 5. Use the results (we mark the hit object) - if (results.size() > 0) { - // The closest collision point is what was truly hit: - CollisionResult closest = results.getClosestCollision(); - // Let's interact - we mark the hit with a red dot. - mark.setLocalTranslation(closest.getContactPoint()); - rootNode.attachChild(mark); - } else { - // No hits? Then remove the red mark. - rootNode.detachChild(mark); - } - } - } - }; - - /** A cube object for target practice */ - private Geometry makeCube(String name, float x, float y, float z) { - Box box = new Box(1, 1, 1); - Geometry cube = new Geometry(name, box); - cube.setLocalTranslation(x, y, z); - Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.randomColor()); - cube.setMaterial(mat1); - return cube; - } - - /** A floor to show that the "shot" can go through several objects. */ - private Geometry makeFloor() { - Box box = new Box(15, .2f, 15); - Geometry floor = new Geometry("the Floor", box); - floor.setLocalTranslation(0, -4, -5); - Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setColor("Color", ColorRGBA.Gray); - floor.setMaterial(mat1); - return floor; - } - - /** A red ball that marks the last spot that was "hit" by the "shot". */ - private void initMark() { - Sphere sphere = new Sphere(30, 30, 0.2f); - mark = new Geometry("BOOM!", sphere); - Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mark_mat.setColor("Color", ColorRGBA.Red); - mark.setMaterial(mark_mat); - } - - /** A centred plus sign to help the player aim. */ - private void initCrossHairs() { - setDisplayStatView(false); - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2 - ch.getLineWidth()/2, settings.getHeight() / 2 + ch.getLineHeight()/2, 0); - guiNode.attachChild(ch); - } - - private Spatial makeCharacter() { - // load a character from jme3-testdata - Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - golem.scale(0.5f); - golem.setLocalTranslation(-1.0f, -1.5f, -0.6f); - - // We must add a light to make the model visible - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f)); - golem.addLight(sun); - return golem; - } -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java deleted file mode 100644 index f6032faf36..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; - -public class HelloTerrain extends SimpleApplication { - - public static void main(String[] args) { - HelloTerrain app = new HelloTerrain(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(50); - - /* 1. Create terrain material and load four textures into it. */ - Material mat_terrain = new Material(assetManager, - "Common/MatDefs/Terrain/Terrain.j3md"); - - /* 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ - mat_terrain.setTexture("Alpha", assetManager.loadTexture( - "Textures/Terrain/splat/alphamap.png")); - - /* 1.2) Add GRASS texture into the red layer (Tex1). */ - Texture grass = assetManager.loadTexture( - "Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("Tex1", grass); - mat_terrain.setFloat("Tex1Scale", 64f); - - /* 1.3) Add DIRT texture into the green layer (Tex2) */ - Texture dirt = assetManager.loadTexture( - "Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("Tex2", dirt); - mat_terrain.setFloat("Tex2Scale", 32f); - - /* 1.4) Add ROAD texture into the blue layer (Tex3) */ - Texture rock = assetManager.loadTexture( - "Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("Tex3", rock); - mat_terrain.setFloat("Tex3Scale", 128f); - - /* 2.a Create a custom height map from an image */ - AbstractHeightMap heightmap = null; - Texture heightMapImage = assetManager.loadTexture( - "Textures/Terrain/splat/mountains512.png"); - heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); - -/* 2.b Create a random height map */ -// HillHeightMap heightmap = null; -// HillHeightMap.NORMALIZE_RANGE = 100; -// try { -// heightmap = new HillHeightMap(513, 1000, 50, 100, (byte) 3); -// } catch (Exception ex) { -// ex.printStackTrace(); -// } - - heightmap.load(); - - /* 3. We have prepared material and heightmap. - * Now we create the actual terrain: - * 3.1) Create a TerrainQuad and name it "my terrain". - * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65. - * 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. - * 3.4) As LOD step scale we supply Vector3f(1,1,1). - * 3.5) We supply the prepared heightmap itself. - */ - int patchSize = 65; - TerrainQuad terrain - = new TerrainQuad("my terrain", patchSize, 513, heightmap.getHeightMap()); - - /* 4. We give the terrain its material, position & scale it, and attach it. */ - terrain.setMaterial(mat_terrain); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(2f, 1f, 2f); - rootNode.attachChild(terrain); - - /* 5. The LOD (level of detail) depends on were the camera is: */ - TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); - control.setLodCalculator( new DistanceLodCalculator(patchSize, 2.7f) ); // patch size, and a multiplier - terrain.addControl(control); - } -} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java deleted file mode 100644 index 739a93ff76..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.helloworld; - -import com.jme3.app.SimpleApplication; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; -import com.jme3.bullet.control.CharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import java.util.ArrayList; -import java.util.List; - -/** - * This demo shows a terrain with collision detection, - * that you can walk around in with a first-person perspective. - * This code combines HelloCollision and HelloTerrain. - */ -public class HelloTerrainCollision extends SimpleApplication - implements ActionListener { - - private BulletAppState bulletAppState; - private CharacterControl player; - final private Vector3f walkDirection = new Vector3f(); - private boolean left = false, right = false, up = false, down = false; - //Temporary vectors used on each frame. - //They here to avoid instantiating new vectors on each frame - final private Vector3f camDir = new Vector3f(); - final private Vector3f camLeft = new Vector3f(); - - public static void main(String[] args) { - HelloTerrainCollision app = new HelloTerrainCollision(); - app.start(); - } - - @Override - public void simpleInitApp() { - /* Set up physics */ - bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - - flyCam.setMoveSpeed(100); - setUpKeys(); - - /* 1. Create terrain material and load four textures into it. */ - Material mat_terrain = new Material(assetManager, - "Common/MatDefs/Terrain/Terrain.j3md"); - - /* 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ - mat_terrain.setTexture("Alpha", assetManager.loadTexture( - "Textures/Terrain/splat/alphamap.png")); - - /* 1.2) Add GRASS texture into the red layer (Tex1). */ - Texture grass = assetManager.loadTexture( - "Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("Tex1", grass); - mat_terrain.setFloat("Tex1Scale", 64f); - - /* 1.3) Add DIRT texture into the green layer (Tex2) */ - Texture dirt = assetManager.loadTexture( - "Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("Tex2", dirt); - mat_terrain.setFloat("Tex2Scale", 32f); - - /* 1.4) Add ROAD texture into the blue layer (Tex3) */ - Texture rock = assetManager.loadTexture( - "Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("Tex3", rock); - mat_terrain.setFloat("Tex3Scale", 128f); - - /* 2. Create the height map */ - AbstractHeightMap heightmap = null; - Texture heightMapImage = assetManager.loadTexture( - "Textures/Terrain/splat/mountains512.png"); - heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); - heightmap.load(); - - /* 3. We have prepared material and heightmap. - * Now we create the actual terrain: - * 3.1) Create a TerrainQuad and name it "my terrain". - * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65. - * 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. - * 3.4) As LOD step scale we supply Vector3f(1,1,1). - * 3.5) We supply the prepared heightmap itself. - */ - TerrainQuad terrain - = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap()); - - /* 4. We give the terrain its material, position & scale it, and attach it. */ - terrain.setMaterial(mat_terrain); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(2f, 1f, 2f); - rootNode.attachChild(terrain); - - /* 5. The LOD (level of detail) depends on were the camera is: */ - List cameras = new ArrayList<>(); - cameras.add(getCamera()); - TerrainLodControl control = new TerrainLodControl(terrain, cameras); - terrain.addControl(control); - - /* 6. Add physics: */ - /* We set up collision detection for the scene by creating a static - * RigidBodyControl with mass zero.*/ - terrain.addControl(new RigidBodyControl(0)); - - // We set up collision detection for the player by creating - // a capsule collision shape and a CharacterControl. - // The CharacterControl offers extra settings for - // size, step height, jumping, falling, and gravity. - // We also put the player in its starting position. - CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1); - player = new CharacterControl(capsuleShape, 0.05f); - player.setJumpSpeed(20); - player.setFallSpeed(30); - player.setGravity(30); - player.setPhysicsLocation(new Vector3f(-10, 10, 10)); - - // We attach the scene and the player to the rootnode and the physics space, - // to make them appear in the game world. - bulletAppState.getPhysicsSpace().add(terrain); - bulletAppState.getPhysicsSpace().add(player); - - } - /** We over-write some navigational key mappings here, so we can - * add physics-controlled walking and jumping: */ - private void setUpKeys() { - inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this, "Left"); - inputManager.addListener(this, "Right"); - inputManager.addListener(this, "Up"); - inputManager.addListener(this, "Down"); - inputManager.addListener(this, "Jump"); - } - - /** These are our custom actions triggered by key presses. - * We do not walk yet, we just keep track of the direction the user pressed. */ - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Left")) { - if (value) { left = true; } else { left = false; } - } else if (binding.equals("Right")) { - if (value) { right = true; } else { right = false; } - } else if (binding.equals("Up")) { - if (value) { up = true; } else { up = false; } - } else if (binding.equals("Down")) { - if (value) { down = true; } else { down = false; } - } else if (binding.equals("Jump")) { - player.jump(); - } - } - - /** - * This is the main event loop--walking happens here. - * We check in which direction the player is walking by interpreting - * the camera direction forward (camDir) and to the side (camLeft). - * The setWalkDirection() command is what lets a physics-controlled player walk. - * We also make sure here that the camera moves with player. - */ - @Override - public void simpleUpdate(float tpf) { - camDir.set(cam.getDirection()).multLocal(0.6f); - camLeft.set(cam.getLeft()).multLocal(0.4f); - walkDirection.set(0, 0, 0); - if (left) { - walkDirection.addLocal(camLeft); - } - if (right) { - walkDirection.addLocal(camLeft.negate()); - } - if (up) { - walkDirection.addLocal(camDir); - } - if (down) { - walkDirection.addLocal(camDir.negate()); - } - player.setWalkDirection(walkDirection); - cam.setLocation(player.getPhysicsLocation()); - } -} - diff --git a/jme3-examples/src/main/java/jme3test/helloworld/package-info.java b/jme3-examples/src/main/java/jme3test/helloworld/package-info.java deleted file mode 100644 index 34b47f9c11..0000000000 --- a/jme3-examples/src/main/java/jme3test/helloworld/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps used in the beginners tutorial - */ -package jme3test.helloworld; diff --git a/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java b/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java deleted file mode 100644 index e4f4d8f263..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.input; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.*; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.CameraNode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.CameraControl.ControlDirection; -import com.jme3.scene.shape.RectangleMesh; -import com.jme3.system.AppSettings; - -/** - * A 3rd-person camera node follows a target (teapot). Follow the teapot with - * WASD keys, rotate by dragging the mouse. - */ -public class TestCameraNode extends SimpleApplication implements AnalogListener, ActionListener { - - private Node teaNode; - private boolean rotate = false; - final private Vector3f direction = new Vector3f(); - - public static void main(String[] args) { - TestCameraNode app = new TestCameraNode(); - AppSettings s = new AppSettings(true); - s.setFrameRate(100); - app.setSettings(s); - app.start(); - } - - @Override - public void simpleInitApp() { - // load a teapot model - Geometry teaGeom - = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - teaGeom.setMaterial(mat); - //create a node to attach the geometry and the camera node - teaNode = new Node("teaNode"); - teaNode.attachChild(teaGeom); - rootNode.attachChild(teaNode); - // create a floor - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Geometry ground = new Geometry("ground", new RectangleMesh( - new Vector3f(-25, -1, 25), - new Vector3f(25, -1, 25), - new Vector3f(-25, -1, -25))); - ground.setMaterial(mat); - rootNode.attachChild(ground); - - //creating the camera Node - CameraNode camNode = new CameraNode("CamNode", cam); - // Set the direction to SpatialToCamera, which means the camera will copy the movements of the Node. - camNode.setControlDir(ControlDirection.SpatialToCamera); - //attaching the camNode to the teaNode - teaNode.attachChild(camNode); - //setting the local translation of the cam node to move it away from the tea Node a bit - camNode.setLocalTranslation(new Vector3f(-10, 0, 0)); - //setting the camNode to look at the teaNode - camNode.lookAt(teaNode.getLocalTranslation(), Vector3f.UNIT_Y); - - //disable the default 1st-person flyCam (don't forget this!!) - flyCam.setEnabled(false); - - registerInput(); - } - - public void registerInput() { - inputManager.addMapping("moveForward", new KeyTrigger(KeyInput.KEY_UP), new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("moveBackward", new KeyTrigger(KeyInput.KEY_DOWN), new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("moveRight", new KeyTrigger(KeyInput.KEY_RIGHT), new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("moveLeft", new KeyTrigger(KeyInput.KEY_LEFT), new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("toggleRotate", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addMapping("rotateRight", new MouseAxisTrigger(MouseInput.AXIS_X, true)); - inputManager.addMapping("rotateLeft", new MouseAxisTrigger(MouseInput.AXIS_X, false)); - inputManager.addListener(this, "moveForward", "moveBackward", "moveRight", "moveLeft"); - inputManager.addListener(this, "rotateRight", "rotateLeft", "toggleRotate"); - } - - @Override - public void onAnalog(String name, float value, float tpf) { - //computing the normalized direction of the cam to move the teaNode - direction.set(cam.getDirection()).normalizeLocal(); - if (name.equals("moveForward")) { - direction.multLocal(5 * tpf); - teaNode.move(direction); - } - if (name.equals("moveBackward")) { - direction.multLocal(-5 * tpf); - teaNode.move(direction); - } - if (name.equals("moveRight")) { - direction.crossLocal(Vector3f.UNIT_Y).multLocal(5 * tpf); - teaNode.move(direction); - } - if (name.equals("moveLeft")) { - direction.crossLocal(Vector3f.UNIT_Y).multLocal(-5 * tpf); - teaNode.move(direction); - } - if (name.equals("rotateRight") && rotate) { - teaNode.rotate(0, 5 * tpf, 0); - } - if (name.equals("rotateLeft") && rotate) { - teaNode.rotate(0, -5 * tpf, 0); - } - - } - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - //toggling rotation on or off - if (name.equals("toggleRotate") && keyPressed) { - rotate = true; - inputManager.setCursorVisible(false); - } - if (name.equals("toggleRotate") && !keyPressed) { - rotate = false; - inputManager.setCursorVisible(true); - } - - } -} diff --git a/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java b/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java deleted file mode 100644 index fc787458cf..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.input; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.RectangleMesh; - -/** A 3rd-person chase camera orbits a target (teapot). - * Follow the teapot with WASD keys, rotate by dragging the mouse. */ -public class TestChaseCamera extends SimpleApplication implements AnalogListener, ActionListener { - - private Geometry teaGeom; - - public static void main(String[] args) { - TestChaseCamera app = new TestChaseCamera(); - app.start(); - } - - @Override - public void simpleInitApp() { - // Load a teapot model - teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - Material mat_tea = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - teaGeom.setMaterial(mat_tea); - rootNode.attachChild(teaGeom); - - // Load a floor model - Material mat_ground = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat_ground.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Geometry ground = new Geometry("ground", new RectangleMesh( - new Vector3f(-25, -1, 25), - new Vector3f(25, -1, 25), - new Vector3f(-25, -1, -25))); - ground.setMaterial(mat_ground); - rootNode.attachChild(ground); - - // Disable the default first-person cam! - flyCam.setEnabled(false); - - // Enable a chase cam - ChaseCamera chaseCam = new ChaseCamera(cam, teaGeom, inputManager); - - //Uncomment this to invert the camera's vertical rotation Axis - //chaseCam.setInvertVerticalAxis(true); - - //Uncomment this to invert the camera's horizontal rotation Axis - //chaseCam.setInvertHorizontalAxis(true); - - //Comment this to disable smooth camera motion - chaseCam.setSmoothMotion(true); - - //Uncomment this to disable trailing of the camera - //WARNING, trailing only works with smooth motion enabled. It is true by default. - //chaseCam.setTrailingEnabled(false); - - //Uncomment this to look 3 world units above the target - //chaseCam.setLookAtOffset(Vector3f.UNIT_Y.mult(3)); - - //Uncomment this to enable rotation when the middle mouse button is pressed (like Blender) - // WARNING: setting this trigger disables the rotation on right and left mouse button click - //chaseCam.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); - - //Uncomment this to set multiple triggers to enable rotation of the cam - // Here spacebar and middle mouse button - //chaseCam.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE),new KeyTrigger(KeyInput.KEY_SPACE)); - - //registering inputs for target's movement - registerInput(); - - } - - public void registerInput() { - inputManager.addMapping("moveForward", new KeyTrigger(KeyInput.KEY_UP), new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("moveBackward", new KeyTrigger(KeyInput.KEY_DOWN), new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("moveRight", new KeyTrigger(KeyInput.KEY_RIGHT), new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("moveLeft", new KeyTrigger(KeyInput.KEY_LEFT), new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("displayPosition", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addListener(this, "moveForward", "moveBackward", "moveRight", "moveLeft"); - inputManager.addListener(this, "displayPosition"); - } - - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("moveForward")) { - teaGeom.move(0, 0, -5 * tpf); - } - if (name.equals("moveBackward")) { - teaGeom.move(0, 0, 5 * tpf); - } - if (name.equals("moveRight")) { - teaGeom.move(5 * tpf, 0, 0); - } - if (name.equals("moveLeft")) { - teaGeom.move(-5 * tpf, 0, 0); - - } - - } - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("displayPosition") && keyPressed) { - teaGeom.move(10, 10, 10); - - } - } - - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - - // teaGeom.move(new Vector3f(0.001f, 0, 0)); - // pivot.rotate(0, 0.00001f, 0); - // rootNode.updateGeometricState(); - } -// public void update() { -// super.update(); -//// render the viewports -// float tpf = timer.getTimePerFrame(); -// state.getRootNode().rotate(0, 0.000001f, 0); -// stateManager.update(tpf); -// stateManager.render(renderManager); -// renderManager.render(tpf); -// } -} diff --git a/jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java b/jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java deleted file mode 100644 index 00dcae46aa..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.input; - -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.FlyCamAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; - -/** A 3rd-person chase camera orbits a target (teapot). - * Follow the teapot with WASD keys, rotate by dragging the mouse. */ -public class TestChaseCameraAppState extends SimpleApplication implements AnalogListener, ActionListener { - - private Geometry teaGeom; - - public static void main(String[] args) { - TestChaseCameraAppState app = new TestChaseCameraAppState(); - app.start(); - } - - @Override - public void simpleInitApp() { - // Load a teapot model - teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - Material mat_tea = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - teaGeom.setMaterial(mat_tea); - rootNode.attachChild(teaGeom); - - // Load a floor model - Material mat_ground = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat_ground.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Geometry ground = new Geometry("ground", new Quad(50, 50)); - ground.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X)); - ground.setLocalTranslation(-25, -1, 25); - ground.setMaterial(mat_ground); - rootNode.attachChild(ground); - - //disable the flyCam - stateManager.detach(stateManager.getState(FlyCamAppState.class)); - - // Enable a chase cam - ChaseCameraAppState chaseCamAS = new ChaseCameraAppState(); - chaseCamAS.setTarget(teaGeom); - stateManager.attach(chaseCamAS); - - //Uncomment this to invert the camera's vertical rotation Axis - //chaseCamAS.setInvertVerticalAxis(true); - - //Uncomment this to invert the camera's horizontal rotation Axis - //chaseCamAS.setInvertHorizontalAxis(true); - - //Uncomment this to enable rotation when the middle mouse button is pressed (like Blender) - // WARNING: setting this trigger disables the rotation on right and left mouse button click - //chaseCamAS.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); - - //Uncomment this to set multiple triggers to enable rotation of the cam - //Here space bar and middle mouse button - //chaseCamAS.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE),new KeyTrigger(KeyInput.KEY_SPACE)); - - //registering inputs for target's movement - registerInput(); - - } - - public void registerInput() { - inputManager.addMapping("moveForward", new KeyTrigger(KeyInput.KEY_UP), new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("moveBackward", new KeyTrigger(KeyInput.KEY_DOWN), new KeyTrigger(KeyInput.KEY_S)); - inputManager.addMapping("moveRight", new KeyTrigger(KeyInput.KEY_RIGHT), new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("moveLeft", new KeyTrigger(KeyInput.KEY_LEFT), new KeyTrigger(KeyInput.KEY_A)); - inputManager.addMapping("displayPosition", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addListener(this, "moveForward", "moveBackward", "moveRight", "moveLeft"); - inputManager.addListener(this, "displayPosition"); - } - - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("moveForward")) { - teaGeom.move(0, 0, -5 * tpf); - } - if (name.equals("moveBackward")) { - teaGeom.move(0, 0, 5 * tpf); - } - if (name.equals("moveRight")) { - teaGeom.move(5 * tpf, 0, 0); - } - if (name.equals("moveLeft")) { - teaGeom.move(-5 * tpf, 0, 0); - - } - - } - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("displayPosition") && keyPressed) { - teaGeom.move(10, 10, 10); - - } - } - - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - - // teaGeom.move(new Vector3f(0.001f, 0, 0)); - // pivot.rotate(0, 0.00001f, 0); - // rootNode.updateGeometricState(); - } -// public void update() { -// super.update(); -//// render the viewports -// float tpf = timer.getTimePerFrame(); -// state.getRootNode().rotate(0, 0.000001f, 0); -// stateManager.update(tpf); -// stateManager.render(renderManager); -// renderManager.render(tpf); -// } -} diff --git a/jme3-examples/src/main/java/jme3test/input/TestControls.java b/jme3-examples/src/main/java/jme3test/input/TestControls.java deleted file mode 100644 index 9f3fa28559..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/TestControls.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.input; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseAxisTrigger; - -public class TestControls extends SimpleApplication { - - final private ActionListener actionListener = new ActionListener(){ - @Override - public void onAction(String name, boolean pressed, float tpf){ - System.out.println(name + " = " + pressed); - } - }; - final private AnalogListener analogListener = new AnalogListener() { - @Override - public void onAnalog(String name, float value, float tpf) { - System.out.println(name + " = " + value); - } - }; - - public static void main(String[] args){ - TestControls app = new TestControls(); - app.start(); - } - - @Override - public void simpleInitApp() { - // Test multiple inputs per mapping - inputManager.addMapping("My Action", - new KeyTrigger(KeyInput.KEY_SPACE), - new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false)); - - // Test multiple listeners per mapping - inputManager.addListener(actionListener, "My Action"); - inputManager.addListener(analogListener, "My Action"); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/input/TestIssue1692.java b/jme3-examples/src/main/java/jme3test/input/TestIssue1692.java deleted file mode 100644 index cb63e3a70a..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/TestIssue1692.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.input; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; - -/** - * A test for issue https://github.com/jMonkeyEngine/jmonkeyengine/pull/1692. - * We are testing to see if disabling then re-enabling the chase camera keeps the correct flags - * set so that we can still rotate without dragging - */ -public class TestIssue1692 extends SimpleApplication implements ActionListener { - - private ChaseCamera chaseCam; - private BitmapText cameraStatus; - - public static void main(String[] args) { - TestIssue1692 app = new TestIssue1692(); - app.start(); - } - - @Override - public void simpleInitApp() { - // Load a teapot model, we will chase this with the camera - Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - Material teapotMaterial = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - teaGeom.setMaterial(teapotMaterial); - rootNode.attachChild(teaGeom); - - // Load a floor model - Material floorMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - floorMaterial.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Geometry ground = new Geometry("ground", new Quad(50, 50)); - ground.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X)); - ground.setLocalTranslation(-25, -1, 25); - ground.setMaterial(floorMaterial); - rootNode.attachChild(ground); - - // Disable the default first-person cam! - flyCam.setEnabled(false); - - // Enable a chase cam - chaseCam = new ChaseCamera(cam, teaGeom, inputManager); - /* - * Explicitly set drag to rotate to false. - * We are testing to see if disabling then re-enabling the camera keeps the correct flags - * set so that we can still rotate without dragging. - */ - chaseCam.setDragToRotate(false); - - // Show instructions - int yTop = settings.getHeight(); - int size = guiFont.getCharSet().getRenderedSize(); - BitmapText hudText = new BitmapText(guiFont); - hudText.setSize(size); - hudText.setColor(ColorRGBA.Blue); - hudText.setText("This test is for issue 1692.\n" - + "We are testing to see if drag to rotate stays disabled" - + "after disabling and re-enabling the chase camera.\n" - + "For this test, use the SPACE key to disable and re-enable the camera."); - hudText.setLocalTranslation(0, yTop - (hudText.getLineHeight() * 3), 0); - guiNode.attachChild(hudText); - - // Show camera status - cameraStatus = new BitmapText(guiFont); - cameraStatus.setSize(size); - cameraStatus.setColor(ColorRGBA.Blue); - cameraStatus.setLocalTranslation(0, yTop - cameraStatus.getLineHeight(), 0); // position - guiNode.attachChild(cameraStatus); - - // Register inputs - registerInput(); - } - - @Override - public void simpleUpdate(float tpf) { - // Update chaseCam status - cameraStatus.setText("chaseCam " + (chaseCam.isEnabled() ? "enabled" : "disabled")); - } - - private void registerInput() { - inputManager.addMapping("toggleCamera", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this, "toggleCamera"); - } - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggleCamera") && keyPressed) { - // Toggle chase camera - chaseCam.setEnabled(!chaseCam.isEnabled()); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/input/TestJoystick.java b/jme3-examples/src/main/java/jme3test/input/TestJoystick.java deleted file mode 100644 index 3f25532d50..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/TestJoystick.java +++ /dev/null @@ -1,493 +0,0 @@ -package jme3test.input; - -import com.jme3.app.SimpleApplication; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.font.BitmapText; -import com.jme3.input.Joystick; -import com.jme3.input.JoystickAxis; -import com.jme3.input.JoystickButton; -import com.jme3.input.MouseInput; -import com.jme3.input.RawInputListener; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.input.event.JoyAxisEvent; -import com.jme3.input.event.JoyButtonEvent; -import com.jme3.input.event.KeyInputEvent; -import com.jme3.input.event.MouseButtonEvent; -import com.jme3.input.event.MouseMotionEvent; -import com.jme3.input.event.TouchEvent; -import com.jme3.material.Material; -import com.jme3.material.RenderState.BlendMode; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Ray; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Quad; -import com.jme3.system.AppSettings; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -public class TestJoystick extends SimpleApplication { - - private Joystick viewedJoystick; - private GamepadView gamepad; - private Node joystickInfo; - private float yInfo = 0; - private JoystickButton lastButton; - - public static void main(String[] args){ - TestJoystick app = new TestJoystick(); - AppSettings settings = new AppSettings(true); - settings.setUseJoysticks(true); - app.setSettings(settings); - app.start(); - } - - @Override - public void simpleInitApp() { - getFlyByCamera().setEnabled(false); - - Joystick[] joysticks = inputManager.getJoysticks(); - if (joysticks == null) - throw new IllegalStateException("Cannot find any joysticks!"); - - try { - PrintWriter out = new PrintWriter( new FileWriter( "joysticks-" + System.currentTimeMillis() + ".txt" ) ); - dumpJoysticks( joysticks, out ); - out.close(); - } catch( IOException e ) { - throw new RuntimeException( "Error writing joystick dump", e ); - } - - - int gamepadSize = cam.getHeight() / 2; - float scale = gamepadSize / 512.0f; - gamepad = new GamepadView(); - gamepad.setLocalTranslation( cam.getWidth() - gamepadSize - (scale * 20), 0, 0 ); - gamepad.setLocalScale( scale, scale, scale ); - guiNode.attachChild(gamepad); - - joystickInfo = new Node( "joystickInfo" ); - joystickInfo.setLocalTranslation( 0, cam.getHeight(), 0 ); - guiNode.attachChild( joystickInfo ); - - // Add a raw listener because it's easier to get all joystick events - // this way. - inputManager.addRawInputListener( new JoystickEventListener() ); - - // add action listener for mouse click - // to all easier custom mapping - inputManager.addMapping("mouseClick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if(isPressed){ - pickGamePad(getInputManager().getCursorPosition()); - } - } - }, "mouseClick"); - } - - protected void dumpJoysticks( Joystick[] joysticks, PrintWriter out ) { - for( Joystick j : joysticks ) { - out.println( "Joystick[" + j.getJoyId() + "]:" + j.getName() ); - out.println( " buttons:" + j.getButtonCount() ); - for( JoystickButton b : j.getButtons() ) { - out.println( " " + b ); - } - - out.println( " axes:" + j.getAxisCount() ); - for( JoystickAxis axis : j.getAxes() ) { - out.println( " " + axis ); - } - } - } - - protected void addInfo( String info, int column ) { - - BitmapText t = new BitmapText(guiFont); - t.setText( info ); - t.setLocalTranslation( column * 200, yInfo, 0 ); - joystickInfo.attachChild(t); - yInfo -= t.getHeight(); - } - - protected void setViewedJoystick( Joystick stick ) { - if( this.viewedJoystick == stick ) - return; - - if( this.viewedJoystick != null ) { - joystickInfo.detachAllChildren(); - } - - this.viewedJoystick = stick; - - if( this.viewedJoystick != null ) { - // Draw the hud - yInfo = 0; - - addInfo( "Joystick:\"" + stick.getName() + "\" id:" + stick.getJoyId(), 0 ); - - yInfo -= 5; - - float ySave = yInfo; - - // Column one for the buttons - addInfo( "Buttons:", 0 ); - for( JoystickButton b : stick.getButtons() ) { - addInfo( " '" + b.getName() + "' id:'" + b.getLogicalId() + "'", 0 ); - } - yInfo = ySave; - - // Column two for the axes - addInfo( "Axes:", 1 ); - for( JoystickAxis a : stick.getAxes() ) { - addInfo( " '" + a.getName() + "' id:'" + a.getLogicalId() + "' analog:" + a.isAnalog(), 1 ); - } - - } - } - - /** - * Easier to watch for all button and axis events with a raw input listener. - */ - protected class JoystickEventListener implements RawInputListener { - - final private Map lastValues = new HashMap<>(); - - @Override - public void onJoyAxisEvent(JoyAxisEvent evt) { - Float last = lastValues.remove(evt.getAxis()); - float value = evt.getValue(); - - // Check the axis dead zone. InputManager normally does this - // by default but not for raw events like we get here. - float effectiveDeadZone = Math.max(inputManager.getAxisDeadZone(), evt.getAxis().getDeadZone()); - if( Math.abs(value) < effectiveDeadZone ) { - if( last == null ) { - // Just skip the event - return; - } - // Else set the value to 0 - lastValues.remove(evt.getAxis()); - value = 0; - } - setViewedJoystick( evt.getAxis().getJoystick() ); - gamepad.setAxisValue( evt.getAxis(), value ); - if( value != 0 ) { - lastValues.put(evt.getAxis(), value); - } - } - - @Override - public void onJoyButtonEvent(JoyButtonEvent evt) { - setViewedJoystick( evt.getButton().getJoystick() ); - gamepad.setButtonValue( evt.getButton(), evt.isPressed() ); - } - - @Override - public void beginInput() {} - @Override - public void endInput() {} - @Override - public void onMouseMotionEvent(MouseMotionEvent evt) {} - @Override - public void onMouseButtonEvent(MouseButtonEvent evt) {} - @Override - public void onKeyEvent(KeyInputEvent evt) {} - @Override - public void onTouchEvent(TouchEvent evt) {} - } - - protected class GamepadView extends Node { - - private float xAxis = 0; - private float yAxis = 0; - private float zAxis = 0; - private float zRotation = 0; - - private float lastPovX = 0; - private float lastPovY = 0; - - final private Geometry leftStick; - final private Geometry rightStick; - - final private Map buttons = new HashMap<>(); - - public GamepadView() { - super( "gamepad" ); - - // Sizes naturally for the texture size. All positions will - // be in that space because it's easier. - int size = 512; - - Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-buttons.png" ) ); - m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); - Geometry buttonPanel = new Geometry( "buttons", new Quad(size, size) ); - buttonPanel.setLocalTranslation( 0, 0, -1 ); - buttonPanel.setMaterial(m); - attachChild(buttonPanel); - - m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-frame.png" ) ); - m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); - Geometry frame = new Geometry( "frame", new Quad(size, size) ); - frame.setMaterial(m); - attachChild(frame); - - m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-stick.png" ) ); - m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); - leftStick = new Geometry( "leftStick", new Quad(64, 64) ); - leftStick.setMaterial(m); - attachChild(leftStick); - rightStick = new Geometry( "rightStick", new Quad(64, 64) ); - rightStick.setMaterial(m); - attachChild(rightStick); - - // A "standard" mapping... fits a majority of my game pads - addButton( JoystickButton.BUTTON_0, 371, 512 - 176, 42, 42 ); - addButton( JoystickButton.BUTTON_1, 407, 512 - 212, 42, 42 ); - addButton( JoystickButton.BUTTON_2, 371, 512 - 248, 42, 42 ); - addButton( JoystickButton.BUTTON_3, 334, 512 - 212, 42, 42 ); - - // Front buttons Some of these have the top ones and the bottoms ones flipped. - addButton( JoystickButton.BUTTON_4, 67, 512 - 111, 95, 21 ); - addButton( JoystickButton.BUTTON_5, 348, 512 - 111, 95, 21 ); - addButton( JoystickButton.BUTTON_6, 67, 512 - 89, 95, 21 ); - addButton( JoystickButton.BUTTON_7, 348, 512 - 89, 95, 21 ); - - // Select and start buttons - addButton( JoystickButton.BUTTON_8, 206, 512 - 198, 48, 30 ); - addButton( JoystickButton.BUTTON_9, 262, 512 - 198, 48, 30 ); - - // Joystick push buttons - addButton( JoystickButton.BUTTON_10, 147, 512 - 300, 75, 70 ); - addButton( JoystickButton.BUTTON_11, 285, 512 - 300, 75, 70 ); - - // Fake button highlights for the POV axes - // - // +Y - // -X +X - // -Y - // - addButton( "POV +Y", 96, 512 - 174, 40, 38 ); - addButton( "POV +X", 128, 512 - 208, 40, 38 ); - addButton( "POV -Y", 96, 512 - 239, 40, 38 ); - addButton( "POV -X", 65, 512 - 208, 40, 38 ); - - resetPositions(); - } - - private void addButton( String name, float x, float y, float width, float height ) { - ButtonView b = new ButtonView(name, x, y, width, height); - attachChild(b); - buttons.put(name, b); - } - - public void setAxisValue( JoystickAxis axis, float value ) { - - System.out.println( "Axis:" + axis.getName() + "(id:" + axis.getLogicalId() + ")=" + value ); - if( axis == axis.getJoystick().getXAxis() ) { - setXAxis(value); - } else if( axis == axis.getJoystick().getYAxis() ) { - setYAxis(-value); - } else if( axis == axis.getJoystick().getAxis(JoystickAxis.Z_AXIS) ) { - // Note: in the above condition, we could check the axis name, but - // I have at least one joystick that reports 2 "Z Axis" axes. - // In this particular case, the first one is the right one so - // a name based lookup will find the proper one. It's a problem - // because the erroneous axis sends a constant stream of values. - setZAxis(value); - } else if( axis == axis.getJoystick().getAxis(JoystickAxis.Z_ROTATION) ) { - setZRotation(-value); - } else if( axis == axis.getJoystick().getAxis(JoystickAxis.LEFT_TRIGGER) ) { - if( axis.getJoystick().getButton(JoystickButton.BUTTON_6) == null ) { - // left/right triggers sometimes only show up as axes - boolean pressed = value != 0; - if( pressed != buttons.get(JoystickButton.BUTTON_6).isDown() ) { - setButtonValue(JoystickButton.BUTTON_6, pressed); - } - } - } else if( axis == axis.getJoystick().getAxis(JoystickAxis.RIGHT_TRIGGER) ) { - if( axis.getJoystick().getButton(JoystickButton.BUTTON_7) == null ) { - // left/right triggers sometimes only show up as axes - boolean pressed = value != 0; - if( pressed != buttons.get(JoystickButton.BUTTON_7).isDown() ) { - setButtonValue(JoystickButton.BUTTON_7, pressed); - } - } - } else if( axis == axis.getJoystick().getPovXAxis() ) { - if( lastPovX < 0 ) { - setButtonValue( "POV -X", false ); - } else if( lastPovX > 0 ) { - setButtonValue( "POV +X", false ); - } - if( value < 0 ) { - setButtonValue( "POV -X", true ); - } else if( value > 0 ) { - setButtonValue( "POV +X", true ); - } - lastPovX = value; - } else if( axis == axis.getJoystick().getPovYAxis() ) { - if( lastPovY < 0 ) { - setButtonValue( "POV -Y", false ); - } else if( lastPovY > 0 ) { - setButtonValue( "POV +Y", false ); - } - if( value < 0 ) { - setButtonValue( "POV -Y", true ); - } else if( value > 0 ) { - setButtonValue( "POV +Y", true ); - } - lastPovY = value; - } - } - - public void setButtonValue( JoystickButton button, boolean isPressed ) { - System.out.println( "Button:" + button.getName() + "=" + (isPressed ? "Down" : "Up") ); - setButtonValue( button.getLogicalId(), isPressed ); - lastButton = button; - } - - protected void setButtonValue( String name, boolean isPressed ) { - ButtonView view = buttons.get(name); - if( view != null ) { - if( isPressed ) { - view.down(); - } else { - view.up(); - } - } - } - - public void setXAxis( float f ) { - xAxis = f; - resetPositions(); - } - - public void setYAxis( float f ) { - yAxis = f; - resetPositions(); - } - - public void setZAxis( float f ) { - zAxis = f; - resetPositions(); - } - - public void setZRotation( float f ) { - zRotation = f; - resetPositions(); - } - - private void resetPositions() { - - float xBase = 155; - float yBase = 212; - - Vector2f dir = new Vector2f(xAxis, yAxis); - float length = Math.min(1, dir.length()); - dir.normalizeLocal(); - - float angle = dir.getAngle(); - float x = FastMath.cos(angle) * length * 10; - float y = FastMath.sin(angle) * length * 10; - leftStick.setLocalTranslation( xBase + x, yBase + y, 0 ); - - - xBase = 291; - dir = new Vector2f(zAxis, zRotation); - length = Math.min(1, dir.length()); - dir.normalizeLocal(); - - angle = dir.getAngle(); - x = FastMath.cos(angle) * length * 10; - y = FastMath.sin(angle) * length * 10; - rightStick.setLocalTranslation( xBase + x, yBase + y, 0 ); - } - } - - protected class ButtonView extends Node { - - private int state = 0; - final private Material material; - final private ColorRGBA hilite = new ColorRGBA( 0.0f, 0.75f, 0.75f, 0.5f ); - - public ButtonView( String name, float x, float y, float width, float height ) { - super( "Button:" + name ); - setLocalTranslation( x, y, -0.5f ); - - material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setColor( "Color", hilite ); - material.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); - - Geometry g = new Geometry( "highlight", new Quad(width, height) ); - g.setMaterial(material); - attachChild(g); - - resetState(); - } - - private void resetState() { - if( state <= 0 ) { - setCullHint( CullHint.Always ); - } else { - setCullHint( CullHint.Dynamic ); - } - - System.out.println( getName() + " state:" + state ); - } - - public boolean isDown() { - return state > 0; - } - - public void down() { - state++; - resetState(); - } - - public void up() { - state--; - resetState(); - } - } - - private void pickGamePad(Vector2f mouseLoc){ - if (lastButton != null) { - CollisionResults results = pick(cam, mouseLoc, gamepad); - for (CollisionResult cr : results) { - Node n = cr.getGeometry().getParent(); - if (n != null && (n instanceof ButtonView)) { - String b = n.getName().substring("Button:".length()); - String name = lastButton.getJoystick().getName().replaceAll(" ", "\\\\ "); - String id = lastButton.getLogicalId().replaceAll(" ", "\\\\ "); - System.out.println(name + "." + id + "=" + b); - return; - } - } - } - } - - private static CollisionResults pick(Camera cam, Vector2f mouseLoc, Node node) { - CollisionResults results = new CollisionResults(); - Ray ray = new Ray(); - Vector3f pos = new Vector3f(mouseLoc.x, mouseLoc.y, -1); - Vector3f dir = new Vector3f(mouseLoc.x, mouseLoc.y, 1); - dir.subtractLocal(pos).normalizeLocal(); - ray.setOrigin(pos); - ray.setDirection(dir); - node.collideWith(ray, results); - return results; - } -} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java b/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java deleted file mode 100644 index 2ad86bef36..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.input.combomoves; - -import java.util.ArrayList; -import java.util.List; - -public class ComboMove { - - public static class ComboMoveState { - - final private String[] pressedMappings; - final private String[] unpressedMappings; - final private float timeElapsed; - - public ComboMoveState(String[] pressedMappings, String[] unpressedMappings, float timeElapsed) { - this.pressedMappings = pressedMappings; - this.unpressedMappings = unpressedMappings; - this.timeElapsed = timeElapsed; - } - - public String[] getUnpressedMappings() { - return unpressedMappings; - } - - public String[] getPressedMappings() { - return pressedMappings; - } - - public float getTimeElapsed() { - return timeElapsed; - } - - } - - final private String moveName; - final private List states = new ArrayList<>(); - private boolean useFinalState = true; - private float priority = 1; - private float castTime = 0.8f; - - private transient String[] pressed, unpressed; - private transient float timeElapsed; - - public ComboMove(String moveName){ - this.moveName = moveName; - } - - public float getPriority() { - return priority; - } - - public void setPriority(float priority) { - this.priority = priority; - } - - public float getCastTime() { - return castTime; - } - - public void setCastTime(float castTime) { - this.castTime = castTime; - } - - public boolean useFinalState() { - return useFinalState; - } - - public void setUseFinalState(boolean useFinalState) { - this.useFinalState = useFinalState; - } - - public ComboMove press(String ... pressedMappings){ - this.pressed = pressedMappings; - return this; - } - - public ComboMove notPress(String ... unpressedMappings){ - this.unpressed = unpressedMappings; - return this; - } - - public ComboMove timeElapsed(float time){ - this.timeElapsed = time; - return this; - } - - public void done(){ - if (pressed == null) - pressed = new String[0]; - - if (unpressed == null) - unpressed = new String[0]; - - states.add(new ComboMoveState(pressed, unpressed, timeElapsed)); - pressed = null; - unpressed = null; - timeElapsed = -1; - } - - public ComboMoveState getState(int num){ - return states.get(num); - } - - public int getNumStates(){ - return states.size(); - } - - public String getMoveName() { - return moveName; - } - -} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java b/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java deleted file mode 100644 index 1e1049ab89..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.input.combomoves; - -import java.util.Arrays; -import java.util.HashSet; -import jme3test.input.combomoves.ComboMove.ComboMoveState; - -public class ComboMoveExecution { - - private static final float TIME_LIMIT = 0.3f; - - final private ComboMove moveDef; - private int state; - private float moveTime; - private boolean finalState = false; - - private String debugString = ""; // for debug only - - public ComboMoveExecution(ComboMove move){ - moveDef = move; - } - - private boolean isStateSatisfied(HashSet pressedMappings, float time, - ComboMoveState state){ - - if (state.getTimeElapsed() != -1f){ - // check if an appropriate amount of time has passed - // if the state requires it - if (moveTime + state.getTimeElapsed() >= time){ - return false; - } - } - for (String mapping : state.getPressedMappings()){ - if (!pressedMappings.contains(mapping)) - return false; - } - for (String mapping : state.getUnpressedMappings()){ - if (pressedMappings.contains(mapping)) - return false; - } - return true; - } - - public String getDebugString(){ - return debugString; - } - - public void updateExpiration(float time){ - if (!finalState && moveTime > 0 && moveTime + TIME_LIMIT < time){ - state = 0; - moveTime = 0; - finalState = false; - - // reset debug string. - debugString = ""; - } - } - - /** - * Check if move needs to be executed. - * @param pressedMappings Which mappings are currently pressed - * @param time Current time since start of app - * @return True if move needs to be executed. - */ - public boolean updateState(HashSet pressedMappings, float time){ - ComboMoveState currentState = moveDef.getState(state); - if (isStateSatisfied(pressedMappings, time, currentState)){ - state ++; - moveTime = time; - - if (state >= moveDef.getNumStates()){ - finalState = false; - state = 0; - - moveTime = time+0.5f; // this is for the reset of the debug string only. - debugString += ", -CASTING " + moveDef.getMoveName().toUpperCase() + "-"; - return true; - } - - // the following for debug only. - if (currentState.getPressedMappings().length > 0){ - if (!debugString.equals("")) - debugString += ", "; - - debugString += Arrays.toString(currentState.getPressedMappings()).replace(", ", "+"); - } - - if (moveDef.useFinalState() && state == moveDef.getNumStates() - 1){ - finalState = true; - } - } - return false; - } - -} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java b/jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java deleted file mode 100644 index f5723434f0..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.input.combomoves; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.math.ColorRGBA; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -public class TestComboMoves extends SimpleApplication implements ActionListener { - - final private HashSet pressedMappings = new HashSet<>(); - - private ComboMove fireball; - private ComboMoveExecution fireballExec; - private BitmapText fireballText; - - private ComboMove shuriken; - private ComboMoveExecution shurikenExec; - private BitmapText shurikenText; - - private ComboMove jab; - private ComboMoveExecution jabExec; - private BitmapText jabText; - - private ComboMove punch; - private ComboMoveExecution punchExec; - private BitmapText punchText; - - private ComboMove currentMove = null; - private float currentMoveCastTime = 0; - private float time = 0; - - public static void main(String[] args){ - TestComboMoves app = new TestComboMoves(); - app.start(); - } - - @Override - public void simpleInitApp() { - setDisplayFps(false); - setDisplayStatView(false); - - // Create debug text - BitmapText helpText = new BitmapText(guiFont); - helpText.setLocalTranslation(0, settings.getHeight(), 0); - helpText.setText("Moves:\n" + - "Fireball: Down, Down+Right, Right\n"+ - "Shuriken: Left, Down, Attack1(Z)\n"+ - "Jab: Attack1(Z)\n"+ - "Punch: Attack1(Z), Attack1(Z)\n"); - guiNode.attachChild(helpText); - - fireballText = new BitmapText(guiFont); - fireballText.setColor(ColorRGBA.Orange); - fireballText.setLocalTranslation(0, fireballText.getLineHeight(), 0); - guiNode.attachChild(fireballText); - - shurikenText = new BitmapText(guiFont); - shurikenText.setColor(ColorRGBA.Cyan); - shurikenText.setLocalTranslation(0, shurikenText.getLineHeight()*2f, 0); - guiNode.attachChild(shurikenText); - - jabText = new BitmapText(guiFont); - jabText.setColor(ColorRGBA.Red); - jabText.setLocalTranslation(0, jabText.getLineHeight()*3f, 0); - guiNode.attachChild(jabText); - - punchText = new BitmapText(guiFont); - punchText.setColor(ColorRGBA.Green); - punchText.setLocalTranslation(0, punchText.getLineHeight()*4f, 0); - guiNode.attachChild(punchText); - - inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT)); - inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("Attack1", new KeyTrigger(KeyInput.KEY_Z)); - inputManager.addListener(this, "Left", "Right", "Up", "Down", "Attack1"); - - fireball = new ComboMove("Fireball"); - fireball.press("Down").notPress("Right").done(); - fireball.press("Right", "Down").done(); - fireball.press("Right").notPress("Down").done(); - fireball.notPress("Right", "Down").done(); - fireball.setUseFinalState(false); // no waiting on final state - - shuriken = new ComboMove("Shuriken"); - shuriken.press("Left").notPress("Down", "Attack1").done(); - shuriken.press("Down").notPress("Attack1").timeElapsed(0.11f).done(); - shuriken.press("Attack1").notPress("Left").timeElapsed(0.11f).done(); - shuriken.notPress("Left", "Down", "Attack1").done(); - - jab = new ComboMove("Jab"); - jab.setPriority(0.5f); // make jab less important than other moves - jab.press("Attack1").done(); - - punch = new ComboMove("Punch"); - punch.press("Attack1").done(); - punch.notPress("Attack1").done(); - punch.press("Attack1").done(); - - fireballExec = new ComboMoveExecution(fireball); - shurikenExec = new ComboMoveExecution(shuriken); - jabExec = new ComboMoveExecution(jab); - punchExec = new ComboMoveExecution(punch); - } - - @Override - public void simpleUpdate(float tpf){ - time += tpf; - - // check every frame if any executions are expired - shurikenExec.updateExpiration(time); - shurikenText.setText("Shuriken Exec: " + shurikenExec.getDebugString()); - - fireballExec.updateExpiration(time); - fireballText.setText("Fireball Exec: " + fireballExec.getDebugString()); - - jabExec.updateExpiration(time); - jabText.setText("Jab Exec: " + jabExec.getDebugString()); - - punchExec.updateExpiration(time); - punchText.setText("Punch Exec: " + punchExec.getDebugString()); - - if (currentMove != null){ - currentMoveCastTime -= tpf; - if (currentMoveCastTime <= 0){ - System.out.println("DONE CASTING " + currentMove.getMoveName()); - currentMoveCastTime = 0; - currentMove = null; - } - } - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed){ - pressedMappings.add(name); - }else{ - pressedMappings.remove(name); - } - - // the pressed mappings was changed. update combo executions - List invokedMoves = new ArrayList<>(); - if (shurikenExec.updateState(pressedMappings, time)){ - invokedMoves.add(shuriken); - } - - if (fireballExec.updateState(pressedMappings, time)){ - invokedMoves.add(fireball); - } - - if (jabExec.updateState(pressedMappings, time)){ - invokedMoves.add(jab); - } - - if (punchExec.updateState(pressedMappings, time)){ - invokedMoves.add(punch); - } - - if (invokedMoves.size() > 0){ - // Choose the move with the highest priority. - float priority = 0; - ComboMove toExec = null; - for (ComboMove move : invokedMoves){ - if (move.getPriority() > priority){ - priority = move.getPriority(); - toExec = move; - } - } - if (currentMove != null && currentMove.getPriority() > toExec.getPriority()){ - return; - } - - currentMove = toExec; - currentMoveCastTime = currentMove.getCastTime(); - //System.out.println("CASTING " + currentMove.getMoveName()); - } - } - -} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java b/jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java deleted file mode 100644 index 287475f74e..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for "combos" (user-input sequences) - */ -package jme3test.input.combomoves; diff --git a/jme3-examples/src/main/java/jme3test/input/package-info.java b/jme3-examples/src/main/java/jme3test/input/package-info.java deleted file mode 100644 index 4fa1b11446..0000000000 --- a/jme3-examples/src/main/java/jme3test/input/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for user input - */ -package jme3test.input; diff --git a/jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java b/jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java deleted file mode 100644 index 9181ca00b0..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.asset.AssetManager; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.input.InputManager; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Node; -import com.jme3.shadow.AbstractShadowFilter; -import com.jme3.shadow.AbstractShadowRenderer; -import com.jme3.shadow.CompareMode; -import com.jme3.shadow.EdgeFilteringMode; - -/** - * - * @author Nehon - */ -public class ShadowTestUIManager implements ActionListener { - - final private BitmapText shadowTypeText; - final private BitmapText shadowCompareText; - final private BitmapText shadowFilterText; - final private BitmapText shadowIntensityText; - private final static String TYPE_TEXT = "(Space) Shadow type : "; - private final static String COMPARE_TEXT = "(enter) Shadow compare "; - private final static String FILTERING_TEXT = "(f) Edge filtering : "; - private final static String INTENSITY_TEXT = "(t:up, g:down) Shadow intensity : "; - private boolean hardwareShadows = true; - final private AbstractShadowRenderer plsr; - final private AbstractShadowFilter plsf; - final private ViewPort viewPort; - private int filteringIndex = 0; - private int renderModeIndex = 0; - - - public ShadowTestUIManager(AssetManager assetManager,AbstractShadowRenderer plsr, AbstractShadowFilter plsf, - Node guiNode, InputManager inputManager, ViewPort viewPort) { - this.plsr = plsr; - this.plsf = plsf; - this.viewPort = viewPort; - BitmapFont guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - shadowTypeText = createText(guiFont); - shadowCompareText = createText(guiFont); - shadowFilterText = createText(guiFont); - shadowIntensityText = createText(guiFont); - - shadowTypeText.setText(TYPE_TEXT + "Processor"); - shadowCompareText.setText(COMPARE_TEXT + (hardwareShadows ? "Hardware" : "Software")); - shadowFilterText.setText(FILTERING_TEXT + plsr.getEdgeFilteringMode().toString()); - shadowIntensityText.setText(INTENSITY_TEXT + plsr.getShadowIntensity()); - - shadowTypeText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 20, 0); - shadowCompareText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 40, 0); - shadowFilterText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 60, 0); - shadowIntensityText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 80, 0); - - guiNode.attachChild(shadowTypeText); - guiNode.attachChild(shadowCompareText); - guiNode.attachChild(shadowFilterText); - guiNode.attachChild(shadowIntensityText); - - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("changeFiltering", new KeyTrigger(KeyInput.KEY_F)); - inputManager.addMapping("ShadowUp", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addMapping("ShadowDown", new KeyTrigger(KeyInput.KEY_G)); - inputManager.addMapping("ThicknessUp", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("ThicknessDown", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("toggleHW", new KeyTrigger(KeyInput.KEY_RETURN)); - - - inputManager.addListener(this, "toggleHW", "toggle", "ShadowUp", "ShadowDown", "ThicknessUp", "ThicknessDown", "changeFiltering"); - - } - - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggle") && keyPressed) { - renderModeIndex += 1; - renderModeIndex %= 3; - - switch (renderModeIndex) { - case 0: - viewPort.addProcessor(plsr); - shadowTypeText.setText(TYPE_TEXT + "Processor"); - break; - case 1: - viewPort.removeProcessor(plsr); - plsf.setEnabled(true); - shadowTypeText.setText(TYPE_TEXT + "Filter"); - break; - case 2: - plsf.setEnabled(false); - shadowTypeText.setText(TYPE_TEXT + "None"); - break; - } - - - - } else if (name.equals("toggleHW") && keyPressed) { - hardwareShadows = !hardwareShadows; - plsr.setShadowCompareMode(hardwareShadows ? CompareMode.Hardware : CompareMode.Software); - plsf.setShadowCompareMode(hardwareShadows ? CompareMode.Hardware : CompareMode.Software); - - shadowCompareText.setText(COMPARE_TEXT + (hardwareShadows ? "Hardware" : "Software")); - } - - - if (name.equals("changeFiltering") && keyPressed) { - filteringIndex = plsr.getEdgeFilteringMode().ordinal(); - filteringIndex = (filteringIndex + 1) % EdgeFilteringMode.values().length; - EdgeFilteringMode m = EdgeFilteringMode.values()[filteringIndex]; - plsr.setEdgeFilteringMode(m); - plsf.setEdgeFilteringMode(m); - shadowFilterText.setText(FILTERING_TEXT + m.toString()); - } - - if (name.equals("ShadowUp") && keyPressed) { - plsr.setShadowIntensity(plsr.getShadowIntensity() + 0.1f); - plsf.setShadowIntensity(plsf.getShadowIntensity() + 0.1f); - - shadowIntensityText.setText(INTENSITY_TEXT + plsr.getShadowIntensity()); - } - if (name.equals("ShadowDown") && keyPressed) { - plsr.setShadowIntensity(plsr.getShadowIntensity() - 0.1f); - plsf.setShadowIntensity(plsf.getShadowIntensity() - 0.1f); - shadowIntensityText.setText(INTENSITY_TEXT + plsr.getShadowIntensity()); - } - if (name.equals("ThicknessUp") && keyPressed) { - plsr.setEdgesThickness(plsr.getEdgesThickness() + 1); - plsf.setEdgesThickness(plsf.getEdgesThickness() + 1); - System.out.println("Shadow thickness : " + plsr.getEdgesThickness()); - } - if (name.equals("ThicknessDown") && keyPressed) { - plsr.setEdgesThickness(plsr.getEdgesThickness() - 1); - plsf.setEdgesThickness(plsf.getEdgesThickness() - 1); - System.out.println("Shadow thickness : " + plsr.getEdgesThickness()); - } - - } - - private BitmapText createText(BitmapFont guiFont) { - BitmapText t = new BitmapText(guiFont); - t.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f); - return t; - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestColorApp.java b/jme3-examples/src/main/java/jme3test/light/TestColorApp.java deleted file mode 100644 index 3db910498a..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestColorApp.java +++ /dev/null @@ -1,88 +0,0 @@ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.light.DirectionalLight; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.shadow.DirectionalLightShadowRenderer; - -public class TestColorApp extends SimpleApplication { - public static void main(String[] args) { - TestColorApp app = new TestColorApp(); - app.start(); - } - - @Override - public void simpleInitApp() { - // Lights - DirectionalLight sun = new DirectionalLight(); - Vector3f sunPosition = new Vector3f(1, -1, 1); - sun.setDirection(sunPosition); - sun.setColor(new ColorRGBA(1f,1f,1f,1f)); - rootNode.addLight(sun); - - //DirectionalLightShadowFilter sun_renderer = new DirectionalLightShadowFilter(assetManager, 2048, 4); - DirectionalLightShadowRenderer sun_renderer = new DirectionalLightShadowRenderer(assetManager, 2048, 1); - sun_renderer.setLight(sun); - viewPort.addProcessor(sun_renderer); - -// FilterPostProcessor fpp = new FilterPostProcessor(assetManager); -// fpp.addFilter(sun_renderer); -// viewPort.addProcessor(fpp); - - rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - - // Camera - viewPort.setBackgroundColor(new ColorRGBA(.6f, .6f, .6f, 1f)); - ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); - - - // Objects - // Ground Object - final Geometry groundBoxWhite = new Geometry("Box", new Box(7.5f, 7.5f, .25f)); - float[] f = {-FastMath.PI / 2, 3 * FastMath.PI / 2, 0f}; - groundBoxWhite.setLocalRotation(new Quaternion(f)); - groundBoxWhite.move(7.5f, -.75f, 7.5f); - final Material groundMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - groundMaterial.setColor("Diffuse", new ColorRGBA(.9f, .9f, .9f, .9f)); - groundBoxWhite.setMaterial(groundMaterial); - groundBoxWhite.addControl(chaseCam); - rootNode.attachChild(groundBoxWhite); - - // Planter - Geometry planterBox = new Geometry("Box", new Box(.5f, .5f, .5f)); - final Material planterMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - planterMaterial.setTexture("DiffuseMap", assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg")); - planterBox.setMaterial(groundMaterial); - planterBox.setLocalTranslation(10, 0, 9); - rootNode.attachChild(planterBox); - - // Action! - inputManager.addMapping("on", new KeyTrigger(KeyInput.KEY_Z)); - inputManager.addMapping("off", new KeyTrigger(KeyInput.KEY_X)); - - inputManager.addListener(new AnalogListener() { - @Override - public void onAnalog(String s, float v, float v1) { - if (s.equals("on")) { - groundBoxWhite.setMaterial(planterMaterial); - } - if (s.equals("off")) { - groundBoxWhite.setMaterial(groundMaterial); - } - } - }, "on", "off"); - - inputEnabled = true; - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java b/jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java deleted file mode 100644 index 0f2605839c..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseAxisTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.renderer.Camera; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.control.LightControl; -import com.jme3.scene.debug.Grid; -import com.jme3.scene.debug.WireFrustum; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Cylinder; -import com.jme3.shadow.ShadowUtil; -import com.jme3.texture.Texture; -import com.jme3.util.TempVars; - -public class TestConeVSFrustum extends SimpleApplication { - - public static void main(String[] args) { - TestConeVSFrustum app = new TestConeVSFrustum(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - frustumCam = cam.clone(); - frustumCam.setFrustumFar(25); - Vector3f[] points = new Vector3f[8]; - for (int i = 0; i < 8; i++) { - points[i] = new Vector3f(); - } - ShadowUtil.updateFrustumPoints2(frustumCam, points); - WireFrustum frustumShape = new WireFrustum(points); - Geometry frustum = new Geometry("frustum", frustumShape); - frustum.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - rootNode.attachChild(frustum); - - rootNode.addLight(new DirectionalLight()); - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.2f)); - rootNode.addLight(al); - - Grid grid = new Grid(50, 50, 5); - Geometry gridGeom = new Geometry("grid", grid); - gridGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - gridGeom.getMaterial().setColor("Color", ColorRGBA.Gray); - rootNode.attachChild(gridGeom); - gridGeom.setLocalTranslation(-125, -25, -125); - -// flyCam.setMoveSpeed(30); -// flyCam.setDragToRotate(true); -// cam.setLocation(new Vector3f(56.182674f, 19.037334f, 7.093905f)); -// cam.setRotation(new Quaternion(0.0816657f, -0.82228005f, 0.12213967f, 0.5497892f)); - spotLight = new SpotLight(); - spotLight.setSpotRange(25); - spotLight.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); - - float radius = FastMath.tan(spotLight.getSpotOuterAngle()) * spotLight.getSpotRange(); - - Cylinder cylinder = new Cylinder(5, 16, 0.01f, radius, spotLight.getSpotRange(), true, false); - geom = new Geometry("light", cylinder); - geom.setMaterial(new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md")); - geom.getMaterial().setColor("Diffuse", ColorRGBA.White); - geom.getMaterial().setColor("Ambient", ColorRGBA.DarkGray); - geom.getMaterial().setBoolean("UseMaterialColors", true); - - final Node ln = new Node("lb"); - LightControl lightControl = new LightControl(spotLight); - ln.addControl(lightControl); - ln.attachChild(geom); - - geom.setLocalTranslation(0, -spotLight.getSpotRange() / 2f, 0); - geom.rotate(-FastMath.HALF_PI, 0, 0); - rootNode.attachChild(ln); -// ln.rotate(FastMath.QUARTER_PI, 0, 0); - // ln.setLocalTranslation(0, 0, -16); - - inputManager.addMapping("click", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); - inputManager.addMapping("shift", new KeyTrigger(KeyInput.KEY_LSHIFT), new KeyTrigger(KeyInput.KEY_RSHIFT)); - inputManager.addMapping("middleClick", new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); - inputManager.addMapping("up", new MouseAxisTrigger(MouseInput.AXIS_Y, false)); - inputManager.addMapping("down", new MouseAxisTrigger(MouseInput.AXIS_Y, true)); - inputManager.addMapping("left", new MouseAxisTrigger(MouseInput.AXIS_X, true)); - inputManager.addMapping("right", new MouseAxisTrigger(MouseInput.AXIS_X, false)); - - - final Node camTarget = new Node("CamTarget"); - rootNode.attachChild(camTarget); - - ChaseCameraAppState chaser = new ChaseCameraAppState(); - chaser.setTarget(camTarget); - chaser.setMaxDistance(150); - chaser.setDefaultDistance(70); - chaser.setDefaultHorizontalRotation(FastMath.HALF_PI); - chaser.setMinVerticalRotation(-FastMath.PI); - chaser.setMaxVerticalRotation(FastMath.PI * 2); - chaser.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - stateManager.attach(chaser); - flyCam.setEnabled(false); - - inputManager.addListener(new AnalogListener() { - @Override - public void onAnalog(String name, float value, float tpf) { - Spatial s = null; - float mult = 1; - if (moving) { - s = ln; - } - if (panning) { - s = camTarget; - mult = -1; - } - if ((moving || panning) && s!=null) { - if (shift) { - if (name.equals("left")) { - tmp.set(cam.getDirection()); - s.rotate(tmpQuat.fromAngleAxis(value, tmp)); - } - if (name.equals("right")) { - tmp.set(cam.getDirection()); - s.rotate(tmpQuat.fromAngleAxis(-value, tmp)); - } - } else { - value *= MOVE_SPEED * mult; - if (name.equals("up")) { - tmp.set(cam.getUp()).multLocal(value); - s.move(tmp); - } - if (name.equals("down")) { - tmp.set(cam.getUp()).multLocal(-value); - s.move(tmp); - } - if (name.equals("left")) { - tmp.set(cam.getLeft()).multLocal(value); - s.move(tmp); - } - if (name.equals("right")) { - tmp.set(cam.getLeft()).multLocal(-value); - s.move(tmp); - } - } - } - } - }, "up", "down", "left", "right"); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("click")) { - if (isPressed) { - moving = true; - } else { - moving = false; - } - } - if (name.equals("middleClick")) { - if (isPressed) { - panning = true; - } else { - panning = false; - } - } - if (name.equals("shift")) { - if (isPressed) { - shift = true; - } else { - shift = false; - } - } - } - }, "click", "middleClick", "shift"); - /* - * An unshaded textured cube. - * Uses texture from jme3-testdata library! - */ - Box boxMesh = new Box(1f, 1f, 1f); - Geometry boxGeo = new Geometry("A Textured Box", boxMesh); - Material boxMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - Texture monkeyTex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); - boxMat.setTexture("ColorMap", monkeyTex); - boxGeo.setMaterial(boxMat); - System.err.println("light " + spotLight.getPosition()); - - } - - private final static float MOVE_SPEED = 60; - final private Vector3f tmp = new Vector3f(); - final private Quaternion tmpQuat = new Quaternion(); - private boolean moving, shift; - private boolean panning; - private Geometry geom; - private SpotLight spotLight; - private Camera frustumCam; - - @Override - public void simpleUpdate(float tpf) { - TempVars vars = TempVars.get(); - boolean intersect = spotLight.intersectsFrustum(frustumCam, vars); - - - if (intersect) { - geom.getMaterial().setColor("Diffuse", ColorRGBA.Green); - } else { - geom.getMaterial().setColor("Diffuse", ColorRGBA.White); - } - Vector3f farPoint = vars.vect1.set(spotLight.getPosition()).addLocal(vars.vect2.set(spotLight.getDirection()).multLocal(spotLight.getSpotRange())); - - //computing the radius of the base disc - float farRadius = (spotLight.getSpotRange() / FastMath.cos(spotLight.getSpotOuterAngle())) * FastMath.sin(spotLight.getSpotOuterAngle()); - //computing the projection direction : perpendicular to the light direction and coplanar with the direction vector and the normal vector - Vector3f perpDirection = vars.vect2.set(spotLight.getDirection()).crossLocal(frustumCam.getWorldPlane(3).getNormal()).normalizeLocal().crossLocal(spotLight.getDirection()); - //projecting the far point on the base disc perimeter - Vector3f projectedPoint = vars.vect3.set(farPoint).addLocal(perpDirection.multLocal(farRadius)); - - - vars.release(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java b/jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java deleted file mode 100644 index 81a268fdf4..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.DirectionalLightShadowFilter; -import com.jme3.shadow.DirectionalLightShadowRenderer; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; -import com.jme3.util.TangentBinormalGenerator; - -public class TestDirectionalLightShadow extends SimpleApplication implements ActionListener, AnalogListener { - - public static final int SHADOWMAP_SIZE = 1024; - private DirectionalLightShadowRenderer dlsr; - private DirectionalLightShadowFilter dlsf; - private Geometry ground; - private Material matGroundU; - private Material matGroundL; - private AmbientLight al; - - public static void main(String[] args) { - TestDirectionalLightShadow app = new TestDirectionalLightShadow(); - app.start(); - } - private float frustumSize = 100; - - @Override - public void onAnalog(String name, float value, float tpf) { - if (cam.isParallelProjection()) { - // Instead of moving closer/farther to object, we zoom in/out. - if (name.equals("Size-")) { - frustumSize += 5f * tpf; - } else { - frustumSize -= 5f * tpf; - } - - float aspect = (float) cam.getWidth() / cam.getHeight(); - cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); - } - } - - public void loadScene() { - Spatial[] obj = new Spatial[2]; - // Setup first view - - - Material[] mat = new Material[2]; - mat[0] = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); - mat[1] = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - mat[1].setBoolean("UseMaterialColors", true); - mat[1].setColor("Ambient", ColorRGBA.White); - mat[1].setColor("Diffuse", ColorRGBA.White.clone()); - - - obj[0] = new Geometry("sphere", new Sphere(30, 30, 2)); - obj[0].setShadowMode(ShadowMode.CastAndReceive); - obj[1] = new Geometry("cube", new Box(1.0f, 1.0f, 1.0f)); - obj[1].setShadowMode(ShadowMode.CastAndReceive); - TangentBinormalGenerator.generate(obj[1]); - TangentBinormalGenerator.generate(obj[0]); - - Spatial t = obj[0].clone(false); - t.setLocalScale(10f); - t.setMaterial(mat[1]); - rootNode.attachChild(t); - t.setLocalTranslation(0, 25, 0); - - for (int i = 0; i < 60; i++) { - t = obj[FastMath.nextRandomInt(0, obj.length - 1)].clone(false); - t.setLocalScale(FastMath.nextRandomFloat() * 10f); - t.setMaterial(mat[FastMath.nextRandomInt(0, mat.length - 1)]); - rootNode.attachChild(t); - t.setLocalTranslation(FastMath.nextRandomFloat() * 200f, FastMath.nextRandomFloat() * 30f + 20, 30f * (i + 2f)); - } - - Box b = new Box(1000, 2, 1000); - b.scaleTextureCoordinates(new Vector2f(10, 10)); - ground = new Geometry("soil", b); - ground.setLocalTranslation(0, 10, 550); - matGroundU = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - matGroundU.setColor("Color", ColorRGBA.Green); - - - matGroundL = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matGroundL.setTexture("DiffuseMap", grass); - - ground.setMaterial(matGroundL); - - ground.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(ground); - - l = new DirectionalLight(); - //l.setDirection(new Vector3f(0.5973172f, -0.16583486f, 0.7846725f).normalizeLocal()); - l.setDirection(new Vector3f(-1, -1, -1)); - rootNode.addLight(l); - - - al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.02f)); - rootNode.addLight(al); - - Spatial sky = SkyFactory.createSky(assetManager, - "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); - sky.setLocalScale(350); - - rootNode.attachChild(sky); - } - private DirectionalLight l; - - @Override - public void simpleInitApp() { - // put the camera in a bad position -// cam.setLocation(new Vector3f(65.25412f, 44.38738f, 9.087874f)); -// cam.setRotation(new Quaternion(0.078139365f, 0.050241485f, -0.003942559f, 0.9956679f)); - - cam.setLocation(new Vector3f(3.3720117f, 42.838284f, -83.43792f)); - cam.setRotation(new Quaternion(0.13833192f, -0.08969371f, 0.012581267f, 0.9862358f)); - - flyCam.setMoveSpeed(100); - - loadScene(); - - dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 3); - dlsr.setLight(l); - dlsr.setLambda(0.55f); - dlsr.setShadowIntensity(0.8f); - dlsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest); - dlsr.displayDebug(); - viewPort.addProcessor(dlsr); - - dlsf = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3); - dlsf.setLight(l); - dlsf.setLambda(0.55f); - dlsf.setShadowIntensity(0.8f); - dlsf.setEdgeFilteringMode(EdgeFilteringMode.Nearest); - dlsf.setEnabled(false); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(dlsf); - - viewPort.addProcessor(fpp); - - initInputs(); - } - - private void initInputs() { - inputManager.addMapping("lambdaUp", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("lambdaDown", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("switchGroundMat", new KeyTrigger(KeyInput.KEY_M)); - inputManager.addMapping("debug", new KeyTrigger(KeyInput.KEY_X)); - inputManager.addMapping("stabilize", new KeyTrigger(KeyInput.KEY_B)); - inputManager.addMapping("distance", new KeyTrigger(KeyInput.KEY_N)); - - - inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_NUMPAD8)); - inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_NUMPAD2)); - inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_NUMPAD6)); - inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_NUMPAD4)); - inputManager.addMapping("fwd", new KeyTrigger(KeyInput.KEY_PGUP)); - inputManager.addMapping("back", new KeyTrigger(KeyInput.KEY_PGDN)); - inputManager.addMapping("pp", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addMapping("backShadows", new KeyTrigger(KeyInput.KEY_K)); - - - inputManager.addListener(this, "lambdaUp", "lambdaDown", - "switchGroundMat", "debug", "up", "down", "right", "left", "fwd", "back", "pp", "stabilize", "distance", "ShadowUp", "ShadowDown", "backShadows"); - - ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, dlsr, dlsf, guiNode, inputManager, viewPort); - - inputManager.addListener(this, "Size+", "Size-"); - inputManager.addMapping("Size+", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("Size-", new KeyTrigger(KeyInput.KEY_S)); - - shadowStabilizationText = new BitmapText(guiFont); - shadowStabilizationText.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f); - shadowStabilizationText.setText("(b:on/off) Shadow stabilization : " + dlsr.isEnabledStabilization()); - shadowStabilizationText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 100, 0); - guiNode.attachChild(shadowStabilizationText); - - - shadowZfarText = new BitmapText(guiFont); - shadowZfarText.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f); - shadowZfarText.setText("(n:on/off) Shadow extend to 500 and fade to 50 : " + (dlsr.getShadowZExtend() > 0)); - shadowZfarText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 120, 0); - guiNode.attachChild(shadowZfarText); - } - private BitmapText shadowStabilizationText; - private BitmapText shadowZfarText; - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - - - if (name.equals("pp") && keyPressed) { - if (cam.isParallelProjection()) { - cam.setFrustumPerspective(45, (float) cam.getWidth() / cam.getHeight(), 1, 1000); - } else { - cam.setParallelProjection(true); - float aspect = (float) cam.getWidth() / cam.getHeight(); - cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); - - } - } - - if (name.equals("lambdaUp") && keyPressed) { - dlsr.setLambda(dlsr.getLambda() + 0.01f); - dlsf.setLambda(dlsr.getLambda() + 0.01f); - System.out.println("Lambda : " + dlsr.getLambda()); - } else if (name.equals("lambdaDown") && keyPressed) { - dlsr.setLambda(dlsr.getLambda() - 0.01f); - dlsf.setLambda(dlsr.getLambda() - 0.01f); - System.out.println("Lambda : " + dlsr.getLambda()); - } - if ((name.equals("ShadowUp") || name.equals("ShadowDown")) && keyPressed) { - al.setColor(ColorRGBA.White.mult((1 - dlsr.getShadowIntensity()) * 0.2f)); - } - - if (name.equals("debug") && keyPressed) { - dlsr.displayFrustum(); - } - - if (name.equals("backShadows") && keyPressed) { - dlsr.setRenderBackFacesShadows(!dlsr.isRenderBackFacesShadows()); - dlsf.setRenderBackFacesShadows(!dlsf.isRenderBackFacesShadows()); - } - - if (name.equals("stabilize") && keyPressed) { - dlsr.setEnabledStabilization(!dlsr.isEnabledStabilization()); - dlsf.setEnabledStabilization(!dlsf.isEnabledStabilization()); - shadowStabilizationText.setText("(b:on/off) Shadow stabilization : " + dlsr.isEnabledStabilization()); - } - if (name.equals("distance") && keyPressed) { - if (dlsr.getShadowZExtend() > 0) { - dlsr.setShadowZExtend(0); - dlsr.setShadowZFadeLength(0); - dlsf.setShadowZExtend(0); - dlsf.setShadowZFadeLength(0); - - } else { - dlsr.setShadowZExtend(500); - dlsr.setShadowZFadeLength(50); - dlsf.setShadowZExtend(500); - dlsf.setShadowZFadeLength(50); - } - shadowZfarText.setText("(n:on/off) Shadow extend to 500 and fade to 50 : " + (dlsr.getShadowZExtend() > 0)); - - } - - if (name.equals("switchGroundMat") && keyPressed) { - if (ground.getMaterial() == matGroundL) { - ground.setMaterial(matGroundU); - } else { - ground.setMaterial(matGroundL); - } - } - - if (name.equals("up")) { - up = keyPressed; - } - if (name.equals("down")) { - down = keyPressed; - } - if (name.equals("right")) { - right = keyPressed; - } - if (name.equals("left")) { - left = keyPressed; - } - if (name.equals("fwd")) { - fwd = keyPressed; - } - if (name.equals("back")) { - back = keyPressed; - } - - } - private boolean up = false; - private boolean down = false; - private boolean left = false; - private boolean right = false; - private boolean fwd = false; - private boolean back = false; - final private float s = 1f; - - @Override - public void simpleUpdate(float tpf) { - if (up) { - Vector3f v = l.getDirection(); - v.y += tpf / s; - setDir(v); - } - if (down) { - Vector3f v = l.getDirection(); - v.y -= tpf / s; - setDir(v); - } - if (right) { - Vector3f v = l.getDirection(); - v.x += tpf / s; - setDir(v); - } - if (left) { - Vector3f v = l.getDirection(); - v.x -= tpf / s; - setDir(v); - } - if (fwd) { - Vector3f v = l.getDirection(); - v.z += tpf / s; - setDir(v); - } - if (back) { - Vector3f v = l.getDirection(); - v.z -= tpf / s; - setDir(v); - } - - } - - private void setDir(Vector3f v) { - l.setDirection(v); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java b/jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java deleted file mode 100644 index 846acfce40..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.input.ChaseCamera; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.texture.Texture; -import com.jme3.util.SkyFactory; - -/** - * test - * @author nehon - */ -public class TestEnvironmentMapping extends SimpleApplication { - - public static void main(String[] args) { - TestEnvironmentMapping app = new TestEnvironmentMapping(); - app.start(); - } - - @Override - public void simpleInitApp() { - final Node buggy = (Node) assetManager.loadModel("Models/Buggy/Buggy.j3o"); - - TextureKey key = new TextureKey("Textures/Sky/Bright/BrightSky.dds", true); - key.setGenerateMips(true); - key.setTextureTypeHint(Texture.Type.CubeMap); - final Texture tex = assetManager.loadTexture(key); - - for (Spatial geom : buggy.getChildren()) { - if (geom instanceof Geometry) { - Material m = ((Geometry) geom).getMaterial(); - m.setTexture("EnvMap", tex); - m.setVector3("FresnelParams", new Vector3f(0.05f, 0.18f, 0.11f)); - } - } - - flyCam.setEnabled(false); - - ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); - chaseCam.setLookAtOffset(new Vector3f(0,0.5f,-1.0f)); - buggy.addControl(chaseCam); - rootNode.attachChild(buggy); - rootNode.attachChild(SkyFactory.createSky(assetManager, tex, - SkyFactory.EnvMapType.CubeMap)); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - BloomFilter bf = new BloomFilter(BloomFilter.GlowMode.Objects); - bf.setBloomIntensity(2.3f); - bf.setExposurePower(0.6f); - - fpp.addFilter(bf); - - DirectionalLight l = new DirectionalLight(); - l.setDirection(new Vector3f(0, -1, -1)); - rootNode.addLight(l); - - viewPort.addProcessor(fpp); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java b/jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java deleted file mode 100644 index 8b2244399f..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; - -/** - * Tests the GLTF scene containing an unlit material. If it works, it should use the - * Common/MatDefs/Misc/Unshaded.j3md material definition for those objects. - * - * @author Markil 3 - * @version 3.3.0-SNAPSHOT - */ -public class TestGltfUnlit extends SimpleApplication { - public static void main(String[] args) { - TestGltfUnlit testUnlit = new TestGltfUnlit(); - testUnlit.start(); - } - - @Override - public void simpleInitApp() { - ColorRGBA skyColor = new ColorRGBA(0.5f, 0.6f, 0.7f, 0.0f); - - flyCam.setMoveSpeed(20); - viewPort.setBackgroundColor(skyColor.mult(0.9f)); - - cam.setLocation(new Vector3f(0, 10, 20)); - rootNode.attachChild(getAssetManager().loadModel("jme3test/scenes/unlit.gltf")); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java b/jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java deleted file mode 100644 index 84d0f651e9..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.LightControl; -import com.jme3.scene.shape.Cylinder; -import com.jme3.scene.shape.Dome; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TempVars; - -/** - * Similar to {@link TestLightControlDirectional}, except that the spatial is controlled by the light this - * time. - * - * @author Markil 3 - */ -public class TestLightControl2Directional extends SimpleApplication { - private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); - private final float[] angles = new float[3]; - - private Node lightNode; - private DirectionalLight direction; - - public static void main(String[] args) { - TestLightControl2Directional app = new TestLightControl2Directional(); - app.start(); - } - - public void setupLighting() { - Geometry lightMdl; - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(2f)); - rootNode.addLight(al); - - direction = new DirectionalLight(); - direction.setColor(ColorRGBA.White.mult(10)); - rootNode.addLight(direction); - - lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); - lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); - rootNode.attachChild(lightMdl); - - /* - * We need this Dome doesn't have a "floor." - */ - Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); - lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightFloor.getMaterial().setColor("Color", ColorRGBA.White); - - lightNode = new Node(); - lightNode.addControl(new LightControl(direction, LightControl.ControlDirection.LightToSpatial)); - lightNode.attachChild(lightMdl); - lightNode.attachChild(lightFloor); - - rootNode.attachChild(lightNode); - } - - public void setupDome() { - Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); - dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); - dome.setLocalTranslation(new Vector3f(0, 0, 0)); - rootNode.attachChild(dome); - } - - @Override - public void simpleInitApp() { - this.cam.setLocation(new Vector3f(-50, 20, 50)); - this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - flyCam.setMoveSpeed(30); - - setupLighting(); - setupDome(); - } - - @Override - public void simpleUpdate(float tpf) { - final Vector3f INIT_DIR = Vector3f.UNIT_Z.negate(); - /* - * In Radians per second - */ - final float ROT_SPEED = FastMath.PI / 2; - /* - * 360 degree rotation - */ - final float FULL_ROT = FastMath.PI * 2; - - TempVars vars = TempVars.get(); - Vector3f lightDirection = vars.vect2, nodeDirection = vars.vect3; - float length; - - angles[0] += rotAxis.x * ROT_SPEED * tpf; - angles[1] += rotAxis.y * ROT_SPEED * tpf; - angles[2] += rotAxis.z * ROT_SPEED * tpf; - direction.setDirection(new Quaternion().fromAngles(angles).mult(INIT_DIR)); - super.simpleUpdate(tpf); - - /* - * Make sure they are equal. - */ - lightDirection.set(direction.getDirection()); - lightDirection.normalizeLocal(); - lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); - nodeDirection.negateLocal().normalizeLocal(); - length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); - length = FastMath.abs(length); - if (length > .1F) { - System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); - } - - if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { - direction.setDirection(INIT_DIR); - angles[0] = 0; - angles[1] = 0; - angles[2] = 0; - if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { - rotAxis.set(0, 1, 0); - } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { - rotAxis.set(0, 0, 1); - } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { - rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); - } else { - rotAxis.set(1, 0, 0); - } - } - - vars.release(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java b/jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java deleted file mode 100644 index 717a397b50..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.LightControl; -import com.jme3.scene.shape.Cylinder; -import com.jme3.scene.shape.Dome; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TempVars; - -/** - * Similar to {@link TestLightControlSpot}, except that the spatial is controlled by the light this - * time. - * - * @author Markil 3 - */ -public class TestLightControl2Spot extends SimpleApplication { - private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); - private final float[] angles = new float[3]; - - private Node lightNode; - private SpotLight spot; - - public static void main(String[] args) { - TestLightControl2Spot app = new TestLightControl2Spot(); - app.start(); - } - - public void setupLighting() { - Geometry lightMdl; - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(2f)); - rootNode.addLight(al); - - spot = new SpotLight(); - spot.setSpotRange(1000); - spot.setSpotInnerAngle(5 * FastMath.DEG_TO_RAD); - spot.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); - spot.setColor(ColorRGBA.White.mult(10)); - rootNode.addLight(spot); - - lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); - lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); - rootNode.attachChild(lightMdl); - - /* - * We need this Dome doesn't have a "floor." - */ - Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); - lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightFloor.getMaterial().setColor("Color", ColorRGBA.White); - - lightNode = new Node(); - lightNode.addControl(new LightControl(spot, LightControl.ControlDirection.LightToSpatial)); - lightNode.attachChild(lightMdl); - lightNode.attachChild(lightFloor); - - rootNode.attachChild(lightNode); - } - - public void setupDome() { - Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); - dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); - dome.setLocalTranslation(new Vector3f(0, 0, 0)); - rootNode.attachChild(dome); - } - - @Override - public void simpleInitApp() { - this.cam.setLocation(new Vector3f(-50, 20, 50)); - this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - flyCam.setMoveSpeed(30); - - setupLighting(); - setupDome(); - } - - @Override - public void simpleUpdate(float tpf) { - final Vector3f INIT_DIR = Vector3f.UNIT_Z.negate(); - /* - * In Radians per second - */ - final float ROT_SPEED = FastMath.PI / 2; - /* - * 360 degree rotation - */ - final float FULL_ROT = FastMath.PI * 2; - - TempVars vars = TempVars.get(); - Vector3f lightPosition = vars.vect1, lightDirection = vars.vect2, nodeDirection = vars.vect3; - float length; - - angles[0] += rotAxis.x * ROT_SPEED * tpf; - angles[1] += rotAxis.y * ROT_SPEED * tpf; - angles[2] += rotAxis.z * ROT_SPEED * tpf; - spot.setDirection(new Quaternion().fromAngles(angles).mult(INIT_DIR)); - super.simpleUpdate(tpf); - - /* - * Make sure they are equal. - */ - lightPosition.set(spot.getPosition()); - lightPosition.subtractLocal(lightNode.getWorldTranslation()); - length = lightPosition.lengthSquared(); - if (length > 0.1F) { - System.err.printf("Translation not equal: is %s (%s), needs to be %s\n", lightNode.getWorldTranslation(), lightNode.getLocalTranslation(), spot.getPosition()); - } - lightDirection.set(spot.getDirection()); - lightDirection.normalizeLocal(); - lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); - nodeDirection.negateLocal().normalizeLocal(); - length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); - length = FastMath.abs(length); - if (length > .1F) { - System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); - } - - if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { - spot.setDirection(INIT_DIR); - angles[0] = 0; - angles[1] = 0; - angles[2] = 0; - if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { - rotAxis.set(0, 1, 0); - } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { - rotAxis.set(0, 0, 1); - } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { - rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); - } else { - rotAxis.set(1, 0, 0); - } - } - - vars.release(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java b/jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java deleted file mode 100644 index 5353403a4e..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.LightControl; -import com.jme3.scene.shape.Cylinder; -import com.jme3.scene.shape.Dome; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TempVars; - -/** - * Creates a directional light controlled by rotating a node. The light will shine on a surrounding sphere. - * The light will rotate on each axis, then on a random axis, then return to the X - * axis. - * - * @author Markil 3 - */ -public class TestLightControlDirectional extends SimpleApplication { - private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); - private final float[] angles = new float[3]; - - private Node lightNode; - private DirectionalLight direction; - - public static void main(String[] args) { - TestLightControlDirectional app = new TestLightControlDirectional(); - app.start(); - } - - public void setupLighting() { - Geometry lightMdl; - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(2f)); - rootNode.addLight(al); - - direction = new DirectionalLight(); - direction.setColor(ColorRGBA.White.mult(10)); - rootNode.addLight(direction); - - lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); - lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); - rootNode.attachChild(lightMdl); - - /* - * We need this Dome doesn't have a "floor." - */ - Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); - lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightFloor.getMaterial().setColor("Color", ColorRGBA.White); - - lightNode = new Node(); - lightNode.addControl(new LightControl(direction)); - lightNode.attachChild(lightMdl); - lightNode.attachChild(lightFloor); - rootNode.attachChild(lightNode); - } - - public void setupDome() { - Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); - dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); - dome.setLocalTranslation(new Vector3f(0, 0, 0)); - rootNode.attachChild(dome); - } - - @Override - public void simpleInitApp() { - this.cam.setLocation(new Vector3f(-50, 20, 50)); - this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - flyCam.setMoveSpeed(30); - - setupLighting(); - setupDome(); - } - - @Override - public void simpleUpdate(float tpf) { - /* - * In Radians per second - */ - final float ROT_SPEED = FastMath.PI / 2; - /* - * 360 degree rotation - */ - final float FULL_ROT = FastMath.PI * 2; - - TempVars vars = TempVars.get(); - Vector3f lightDirection = vars.vect2, nodeDirection = vars.vect3; - float length; - - angles[0] += rotAxis.x * ROT_SPEED * tpf; - angles[1] += rotAxis.y * ROT_SPEED * tpf; - angles[2] += rotAxis.z * ROT_SPEED * tpf; - lightNode.setLocalRotation(new Quaternion().fromAngles(angles)); - super.simpleUpdate(tpf); - - /* - * Make sure they are equal. - */ - lightDirection.set(direction.getDirection()); - lightDirection.normalize(); - lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); - nodeDirection.negateLocal().normalizeLocal(); - length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); - length = FastMath.abs(length); - if (length > .1F) { - System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); - } - - if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { - lightNode.setLocalRotation(Quaternion.DIRECTION_Z); - angles[0] = 0; - angles[1] = 0; - angles[2] = 0; - if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { - rotAxis.set(0, 1, 0); - } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { - rotAxis.set(0, 0, 1); - } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { - rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); - } else { - rotAxis.set(1, 0, 0); - } - } - - vars.release(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java b/jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java deleted file mode 100644 index 2e08481cde..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.LightControl; -import com.jme3.scene.shape.Cylinder; -import com.jme3.scene.shape.Dome; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TempVars; - -/** - * Creates a spotlight controlled by rotating a node. The light will shine on a surrounding sphere. - * The light will rotate on each axis, then on a random axis, then return to the X - * axis. - * - * @author Markil 3 - */ -public class TestLightControlSpot extends SimpleApplication { - private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); - private final float[] angles = new float[3]; - - private Node lightNode; - private SpotLight spot; - - public static void main(String[] args) { - TestLightControlSpot app = new TestLightControlSpot(); - app.start(); - } - - public void setupLighting() { - Geometry lightMdl; - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(2f)); - rootNode.addLight(al); - - spot = new SpotLight(); - - spot.setSpotRange(1000); - spot.setSpotInnerAngle(5 * FastMath.DEG_TO_RAD); - spot.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); - spot.setColor(ColorRGBA.White.mult(10)); - rootNode.addLight(spot); - - lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); - lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); - rootNode.attachChild(lightMdl); - - /* - * We need this Dome doesn't have a "floor." - */ - Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); - lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightFloor.getMaterial().setColor("Color", ColorRGBA.White); - - lightNode = new Node(); - lightNode.addControl(new LightControl(spot)); - lightNode.attachChild(lightMdl); - lightNode.attachChild(lightFloor); - rootNode.attachChild(lightNode); - } - - public void setupDome() { - Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); - dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); - dome.setLocalTranslation(new Vector3f(0, 0, 0)); - rootNode.attachChild(dome); - } - - @Override - public void simpleInitApp() { - this.cam.setLocation(new Vector3f(-50, 20, 50)); - this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - flyCam.setMoveSpeed(30); - - setupLighting(); - setupDome(); - } - - @Override - public void simpleUpdate(float tpf) { - /* - * In Radians per second - */ - final float ROT_SPEED = FastMath.PI / 2; - /* - * 360 degree rotation - */ - final float FULL_ROT = FastMath.PI * 2; - - TempVars vars = TempVars.get(); - Vector3f lightPosition = vars.vect1, lightDirection = vars.vect2, nodeDirection = vars.vect3; - float length; - - angles[0] += rotAxis.x * ROT_SPEED * tpf; - angles[1] += rotAxis.y * ROT_SPEED * tpf; - angles[2] += rotAxis.z * ROT_SPEED * tpf; - lightNode.setLocalRotation(new Quaternion().fromAngles(angles)); - super.simpleUpdate(tpf); - - /* - * Make sure they are equal. - */ - lightPosition.set(spot.getPosition()); - length = lightPosition.subtract(lightNode.getWorldTranslation(), vars.vect4).lengthSquared(); - if (length > 0.1F) { - System.err.printf("Translation not equal: is %s, needs to be %s\n", lightNode.getWorldTranslation(), spot.getPosition()); - } - lightDirection.set(spot.getDirection()); - lightDirection.normalizeLocal(); - lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); - nodeDirection.negateLocal().normalizeLocal(); - length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); - length = FastMath.abs(length); - if (length > .1F) { - System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); - } - - if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { - lightNode.setLocalRotation(Quaternion.DIRECTION_Z); - angles[0] = 0; - angles[1] = 0; - angles[2] = 0; - if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { - rotAxis.set(0, 1, 0); - } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { - rotAxis.set(0, 0, 1); - } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { - rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); - } else { - rotAxis.set(1, 0, 0); - } - } - - vars.release(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightRadius.java b/jme3-examples/src/main/java/jme3test/light/TestLightRadius.java deleted file mode 100644 index 26b56e6610..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestLightRadius.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Sphere; -import com.jme3.scene.shape.Torus; - -public class TestLightRadius extends SimpleApplication { - - private float pos, vel=1; - private PointLight pl; - private Geometry lightMdl; - - public static void main(String[] args){ - TestLightRadius app = new TestLightRadius(); - app.start(); - } - - @Override - public void simpleInitApp() { - Torus torus = new Torus(10, 6, 1, 3); -// Torus torus = new Torus(50, 30, 1, 3); - Geometry g = new Geometry("Torus Geom", torus); - g.rotate(-FastMath.HALF_PI, 0, 0); - g.center(); -// g.move(0, 1, 0); - - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - mat.setFloat("Shininess", 32f); - mat.setBoolean("UseMaterialColors", true); - mat.setColor("Ambient", ColorRGBA.Black); - mat.setColor("Diffuse", ColorRGBA.White); - mat.setColor("Specular", ColorRGBA.White); -// mat.setBoolean("VertexLighting", true); -// mat.setBoolean("LowQuality", true); - g.setMaterial(mat); - - rootNode.attachChild(g); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(lightMdl); - - pl = new PointLight(); - pl.setColor(ColorRGBA.Green); - pl.setRadius(4f); - rootNode.addLight(pl); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.Red); - dl.setDirection(new Vector3f(0, 1, 0)); - rootNode.addLight(dl); - } - - @Override - public void simpleUpdate(float tpf){ -// cam.setLocation(new Vector3f(5.0347548f, 6.6481347f, 3.74853f)); -// cam.setRotation(new Quaternion(-0.19183293f, 0.80776674f, -0.37974006f, -0.40805697f)); - - pos += tpf * vel * 5f; - if (pos > 15){ - vel *= -1; - }else if (pos < -15){ - vel *= -1; - } - - pl.setPosition(new Vector3f(pos, 2, 0)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightingFog.java b/jme3-examples/src/main/java/jme3test/light/TestLightingFog.java deleted file mode 100644 index b142dfc417..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestLightingFog.java +++ /dev/null @@ -1,79 +0,0 @@ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.material.Materials; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Sphere; - -public class TestLightingFog extends SimpleApplication implements ActionListener { - - private Material material; - final private Vector2f linear = new Vector2f(25, 120); - final private float exp = 0.015f; - final private float expsq = 0.02f; - - public static void main(String[] args) { - TestLightingFog testLightingFog = new TestLightingFog(); - testLightingFog.start(); - } - - @Override - public void simpleInitApp() { - - ColorRGBA skyColor = new ColorRGBA(0.5f, 0.6f, 0.7f, 0.0f); - - flyCam.setMoveSpeed(20); - viewPort.setBackgroundColor(skyColor.mult(0.9f)); - - DirectionalLight directionalLight = new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()); - rootNode.addLight(directionalLight); - - material = new Material(assetManager, Materials.LIGHTING); - material.setBoolean("UseFog", true); - material.setColor("FogColor", skyColor); - material.setVector2("LinearFog", linear); - - int distance = -3; - - for (int i = 0; i < 100; i++) { - Geometry geometry = new Geometry("Sphere", new Sphere(32, 32, 2)); - geometry.setMaterial(material); - - geometry.setLocalTranslation((FastMath.nextRandomFloat() - 0.5f) * 45, 0, i * distance); - rootNode.attachChild(geometry); - } - - inputManager.addMapping("Linear", new KeyTrigger(KeyInput.KEY_1)); - inputManager.addMapping("Exponential", new KeyTrigger(KeyInput.KEY_2)); - inputManager.addMapping("ExponentialSquared", new KeyTrigger(KeyInput.KEY_3)); - inputManager.addListener(this, "Linear", "Exponential", "ExponentialSquared"); - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("Linear") && !isPressed) { - material.setVector2("LinearFog", linear); - material.clearParam("ExpFog"); - material.clearParam("ExpSqFog"); - } - else if (name.equals("Exponential") && !isPressed) { - material.clearParam("LinearFog"); - material.setFloat("ExpFog", exp); - material.clearParam("ExpSqFog"); - } - else if (name.equals("ExponentialSquared") && !isPressed) { - material.clearParam("LinearFog"); - material.clearParam("ExpFog"); - material.setFloat("ExpSqFog", expsq); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestManyLights.java b/jme3-examples/src/main/java/jme3test/light/TestManyLights.java deleted file mode 100644 index 644344b023..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestManyLights.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.scene.Node; - -public class TestManyLights extends SimpleApplication { - - public static void main(String[] args){ - TestManyLights app = new TestManyLights(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10); - - Node scene = (Node) assetManager.loadModel("Scenes/ManyLights/Main.scene"); - rootNode.attachChild(scene); -// guiNode.setCullHint(CullHint.Always); - } - -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java b/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java deleted file mode 100644 index ca9365cb88..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.BasicProfilerState; -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.light.Light; -import com.jme3.light.LightList; -import com.jme3.light.PointLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.material.TechniqueDef; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.control.AbstractControl; -import com.jme3.scene.shape.Box; -import com.jme3.util.MaterialDebugAppState; - -public class TestManyLightsSingle extends SimpleApplication { - - public static void main(String[] args) { - TestManyLightsSingle app = new TestManyLightsSingle(); - app.start(); - } - - /** - * Switch mode with space bar at run time - */ - private TechniqueDef.LightMode lm = TechniqueDef.LightMode.SinglePass; - - @Override - public void simpleInitApp() { - renderManager.setPreferredLightMode(lm); - renderManager.setSinglePassLightBatchSize(6); - - flyCam.setMoveSpeed(10); - - Node scene = (Node) assetManager.loadModel("Scenes/ManyLights/Main.scene"); - rootNode.attachChild(scene); - Node n = (Node) rootNode.getChild(0); - final LightList lightList = n.getWorldLightList(); - final Geometry g = (Geometry) n.getChild("Grid-geom-1"); - - g.getMaterial().setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); - - /* A colored lit cube. Needs light source! */ - Box boxMesh = new Box(1f, 1f, 1f); - final Geometry boxGeo = new Geometry("Colored Box", boxMesh); - Material boxMat = g.getMaterial().clone(); - boxMat.clearParam("DiffuseMap"); - boxMat.setBoolean("UseMaterialColors", true); - boxMat.setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); - boxMat.setColor("Diffuse", ColorRGBA.Blue); - boxGeo.setMaterial(boxMat); - - final Node cubeNodes = new Node(); - n.attachChild(cubeNodes); - int nb = 0; - for (Light light : lightList) { - nb++; - PointLight p = (PointLight) light; - if (nb > 60) { - n.removeLight(light); - } else { - int rand = FastMath.nextRandomInt(0, 3); - switch (rand) { - case 0: - light.setColor(ColorRGBA.Red); - break; - case 1: - light.setColor(ColorRGBA.Yellow); - break; - case 2: - light.setColor(ColorRGBA.Green); - break; - case 3: - light.setColor(ColorRGBA.Orange); - break; - } - } - Geometry b = boxGeo.clone(false); - cubeNodes.attachChild(b); - b.setLocalTranslation(p.getPosition().x, 2, p.getPosition().z); - - } - - -// cam.setLocation(new Vector3f(3.1893547f, 17.977385f, 30.8378f)); -// cam.setRotation(new Quaternion(0.14317635f, 0.82302624f, -0.23777823f, 0.49557027f)); - - cam.setLocation(new Vector3f(-1.8901939f, 29.34097f, 73.07533f)); - cam.setRotation(new Quaternion(0.0021000702f, 0.971012f, -0.23886925f, 0.008527749f)); - - - BasicProfilerState profiler = new BasicProfilerState(true); - profiler.setGraphScale(1000f); - - // getStateManager().attach(profiler); -// guiNode.setCullHint(CullHint.Always); - - - flyCam.setDragToRotate(true); - flyCam.setMoveSpeed(50); - - final MaterialDebugAppState debug = new MaterialDebugAppState(); - stateManager.attach(debug); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("toggle") && isPressed) { - if (lm == TechniqueDef.LightMode.SinglePass) { - lm = TechniqueDef.LightMode.MultiPass; - helloText.setText("(Multi pass)"); - } else { - lm = TechniqueDef.LightMode.SinglePass; - helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); - } - renderManager.setPreferredLightMode(lm); - reloadScene(g, boxGeo, cubeNodes); - } - if (name.equals("lightsUp") && isPressed) { - renderManager.setSinglePassLightBatchSize(renderManager.getSinglePassLightBatchSize() + 1); - helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); - } - if (name.equals("lightsDown") && isPressed) { - renderManager.setSinglePassLightBatchSize(renderManager.getSinglePassLightBatchSize() - 1); - helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); - } - if (name.equals("toggleOnOff") && isPressed) { - for (final Light light : lightList) { - if (light instanceof AmbientLight) { - continue; - } - - light.setEnabled(!light.isEnabled()); - } - } - } - }, "toggle", "lightsUp", "lightsDown", "toggleOnOff"); - - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("lightsUp", new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("lightsDown", new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("toggleOnOff", new KeyTrigger(KeyInput.KEY_L)); - - - SpotLight spot = new SpotLight(); - spot.setDirection(new Vector3f(-1f, -1f, -1f).normalizeLocal()); - spot.setColor(ColorRGBA.Blue.mult(5)); - spot.setSpotOuterAngle(FastMath.DEG_TO_RAD * 20); - spot.setSpotInnerAngle(FastMath.DEG_TO_RAD * 5); - spot.setPosition(new Vector3f(10, 10, 20)); - rootNode.addLight(spot); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, 1)); - rootNode.addLight(dl); - - AmbientLight al = new AmbientLight(); - al.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); - rootNode.addLight(al); - - - /* - * Write text on the screen (HUD) - */ - guiNode.detachAllChildren(); - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - helloText = new BitmapText(guiFont); - helloText.setSize(guiFont.getCharSet().getRenderedSize()); - helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); - helloText.setLocalTranslation(300, helloText.getLineHeight(), 0); - guiNode.attachChild(helloText); - } - - protected void reloadScene(Geometry g, Geometry boxGeo, Node cubeNodes) { - MaterialDebugAppState debug = stateManager.getState(MaterialDebugAppState.class); - Material m = debug.reloadMaterial(g.getMaterial()); - if (m != null) { - g.setMaterial(m); - } - m = debug.reloadMaterial(boxGeo.getMaterial()); - if (m != null) { - cubeNodes.setMaterial(m); - } - } - - private BitmapText helloText; - - @Override - public void simpleUpdate(float tpf) { -// if (nbFrames == 4000) { -// startTime = System.nanoTime(); -// } -// if (nbFrames > 4000) { -// time = System.nanoTime(); -// float average = ((float) time - (float) startTime) / ((float) nbFrames - 4000f); -// helloText.setText("Average = " + average); -// } -// nbFrames++; - } - - class MoveControl extends AbstractControl { - - final private float direction; - final private Vector3f origPos = new Vector3f(); - - public MoveControl(float direction) { - this.direction = direction; - } - - @Override - public void setSpatial(Spatial spatial) { - super.setSpatial(spatial); //To change body of generated methods, choose Tools | Templates. - origPos.set(spatial.getLocalTranslation()); - } - private float time = 0; - - @Override - protected void controlUpdate(float tpf) { - time += tpf; - spatial.setLocalTranslation(origPos.x + FastMath.cos(time) * direction, origPos.y, origPos.z + FastMath.sin(time) * direction); - } - - @Override - protected void controlRender(RenderManager rm, ViewPort vp) { - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java b/jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java deleted file mode 100644 index d98619a2b2..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.bounding.BoundingSphere; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.*; -import com.jme3.light.*; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.renderer.Camera; -import com.jme3.scene.*; -import com.jme3.scene.debug.Grid; -import com.jme3.scene.debug.WireFrustum; -import com.jme3.scene.shape.*; -import com.jme3.shadow.ShadowUtil; -import com.jme3.util.TempVars; - - -public class TestObbVsBounds extends SimpleApplication { - - private Node ln; - final private BoundingBox aabb = new BoundingBox(); - final private BoundingSphere sphere = new BoundingSphere(10, new Vector3f(-30, 0, -60)); - - private final static float MOVE_SPEED = 60; - final private Vector3f tmp = new Vector3f(); - final private Quaternion tmpQuat = new Quaternion(); - private boolean moving, shift; - private boolean panning; - - final private OrientedBoxProbeArea area = new OrientedBoxProbeArea(); - private Camera frustumCam; - - private Geometry areaGeom; - private Geometry frustumGeom; - private Geometry aabbGeom; - private Geometry sphereGeom; - - public static void main(String[] args) { - TestObbVsBounds app = new TestObbVsBounds(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - frustumCam = cam.clone(); - frustumCam.setFrustumFar(25); - makeCamFrustum(); - aabb.setCenter(20, 10, -60); - aabb.setXExtent(10); - aabb.setYExtent(5); - aabb.setZExtent(3); - makeBoxWire(aabb); - makeSphereWire(sphere); - - rootNode.addLight(new DirectionalLight()); - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.2f)); - rootNode.addLight(al); - - Grid grid = new Grid(50, 50, 5); - Geometry gridGeom = new Geometry("grid", grid); - gridGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - gridGeom.getMaterial().setColor("Color", ColorRGBA.Gray); - rootNode.attachChild(gridGeom); - gridGeom.setLocalTranslation(-125, -25, -125); - - area.setCenter(Vector3f.ZERO); - area.setExtent(new Vector3f(4, 8, 5)); - makeAreaGeom(); - - ln = new Node("lb"); - ln.setLocalRotation(new Quaternion(-0.18826798f, -0.38304946f, -0.12780227f, 0.895261f)); - ln.attachChild(areaGeom); - ln.setLocalScale(4,8,5); - rootNode.attachChild(ln); - - inputManager.addMapping("click", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); - inputManager.addMapping("shift", new KeyTrigger(KeyInput.KEY_LSHIFT), new KeyTrigger(KeyInput.KEY_RSHIFT)); - inputManager.addMapping("middleClick", new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); - inputManager.addMapping("up", new MouseAxisTrigger(MouseInput.AXIS_Y, false)); - inputManager.addMapping("down", new MouseAxisTrigger(MouseInput.AXIS_Y, true)); - inputManager.addMapping("left", new MouseAxisTrigger(MouseInput.AXIS_X, true)); - inputManager.addMapping("right", new MouseAxisTrigger(MouseInput.AXIS_X, false)); - - - final Node camTarget = new Node("CamTarget"); - rootNode.attachChild(camTarget); - - ChaseCameraAppState chaser = new ChaseCameraAppState(); - chaser.setTarget(camTarget); - chaser.setMaxDistance(150); - chaser.setDefaultDistance(70); - chaser.setDefaultHorizontalRotation(FastMath.HALF_PI); - chaser.setMinVerticalRotation(-FastMath.PI); - chaser.setMaxVerticalRotation(FastMath.PI * 2); - chaser.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - stateManager.attach(chaser); - flyCam.setEnabled(false); - - inputManager.addListener(new AnalogListener() { - @Override - public void onAnalog(String name, float value, float tpf) { - Spatial s = null; - float mult = 1; - if (moving) { - s = ln; - } - if (panning) { - s = camTarget; - mult = -1; - } - if ((moving || panning) && s != null) { - if (shift) { - if (name.equals("left")) { - tmp.set(cam.getDirection()); - s.rotate(tmpQuat.fromAngleAxis(value, tmp)); - } - if (name.equals("right")) { - tmp.set(cam.getDirection()); - s.rotate(tmpQuat.fromAngleAxis(-value, tmp)); - } - } else { - value *= MOVE_SPEED * mult; - if (name.equals("up")) { - tmp.set(cam.getUp()).multLocal(value); - s.move(tmp); - } - if (name.equals("down")) { - tmp.set(cam.getUp()).multLocal(-value); - s.move(tmp); - } - if (name.equals("left")) { - tmp.set(cam.getLeft()).multLocal(value); - s.move(tmp); - } - if (name.equals("right")) { - tmp.set(cam.getLeft()).multLocal(-value); - s.move(tmp); - } - } - } - } - }, "up", "down", "left", "right"); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("click")) { - if (isPressed) { - moving = true; - } else { - moving = false; - } - } - if (name.equals("middleClick")) { - if (isPressed) { - panning = true; - } else { - panning = false; - } - } - if (name.equals("shift")) { - if (isPressed) { - shift = true; - } else { - shift = false; - } - } - } - }, "click", "middleClick", "shift"); - - } - - public void makeAreaGeom() { - - Vector3f[] points = new Vector3f[8]; - - for (int i = 0; i < points.length; i++) { - points[i] = new Vector3f(); - } - - points[0].set(-1, -1, 1); - points[1].set(-1, 1, 1); - points[2].set(1, 1, 1); - points[3].set(1, -1, 1); - - points[4].set(-1, -1, -1); - points[5].set(-1, 1, -1); - points[6].set(1, 1, -1); - points[7].set(1, -1, -1); - - Mesh box = WireFrustum.makeFrustum(points); - areaGeom = new Geometry("light", box); - areaGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - areaGeom.getMaterial().setColor("Color", ColorRGBA.White); - } - - public void makeCamFrustum() { - Vector3f[] points = new Vector3f[8]; - for (int i = 0; i < 8; i++) { - points[i] = new Vector3f(); - } - ShadowUtil.updateFrustumPoints2(frustumCam, points); - WireFrustum frustumShape = new WireFrustum(points); - frustumGeom = new Geometry("frustum", frustumShape); - frustumGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - rootNode.attachChild(frustumGeom); - } - - public void makeBoxWire(BoundingBox box) { - Vector3f[] points = new Vector3f[8]; - for (int i = 0; i < 8; i++) { - points[i] = new Vector3f(); - } - points[0].set(-1, -1, 1); - points[1].set(-1, 1, 1); - points[2].set(1, 1, 1); - points[3].set(1, -1, 1); - - points[4].set(-1, -1, -1); - points[5].set(-1, 1, -1); - points[6].set(1, 1, -1); - points[7].set(1, -1, -1); - - WireFrustum frustumShape = new WireFrustum(points); - aabbGeom = new Geometry("box", frustumShape); - aabbGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - aabbGeom.getMaterial().getAdditionalRenderState().setWireframe(true); - aabbGeom.setLocalTranslation(box.getCenter()); - aabbGeom.setLocalScale(box.getXExtent(), box.getYExtent(), box.getZExtent()); - rootNode.attachChild(aabbGeom); - } - - public void makeSphereWire(BoundingSphere sphere) { - - sphereGeom = new Geometry("box", new Sphere(16, 16, 10)); - sphereGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - sphereGeom.getMaterial().getAdditionalRenderState().setWireframe(true); - sphereGeom.setLocalTranslation(sphere.getCenter()); - rootNode.attachChild(sphereGeom); - } - - - @Override - public void simpleUpdate(float tpf) { - - area.setCenter(ln.getLocalTranslation()); - area.setRotation(ln.getLocalRotation()); - - TempVars vars = TempVars.get(); - boolean intersectBox = area.intersectsBox(aabb, vars); - boolean intersectFrustum = area.intersectsFrustum(frustumCam, vars); - boolean intersectSphere = area.intersectsSphere(sphere, vars); - vars.release(); - - boolean intersect = intersectBox || intersectFrustum || intersectSphere; - - areaGeom.getMaterial().setColor("Color", intersect ? ColorRGBA.Green : ColorRGBA.White); - sphereGeom.getMaterial().setColor("Color", intersectSphere ? ColorRGBA.Cyan : ColorRGBA.White); - frustumGeom.getMaterial().setColor("Color", intersectFrustum ? ColorRGBA.Cyan : ColorRGBA.White); - aabbGeom.getMaterial().setColor("Color", intersectBox ? ColorRGBA.Cyan : ColorRGBA.White); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java b/jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java deleted file mode 100644 index 332c0ae893..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.light.SpotLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.DirectionalLightShadowFilter; -import com.jme3.shadow.DirectionalLightShadowRenderer; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.shadow.PointLightShadowFilter; -import com.jme3.shadow.PointLightShadowRenderer; -import com.jme3.shadow.SpotLightShadowFilter; -import com.jme3.shadow.SpotLightShadowRenderer; - -public class TestPointDirectionalAndSpotLightShadows extends SimpleApplication { - public static final int SHADOWMAP_SIZE = 512; - - public static void main(String[] args) { - TestPointDirectionalAndSpotLightShadows app = new TestPointDirectionalAndSpotLightShadows(); - app.start(); - } - private Node lightNode; - private SpotLight spotLight; - - final private boolean useFilter = false; - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10); - cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f)); - cam.setRotation(new Quaternion(4.3868728E-5f, 0.9999293f, -0.011230096f, 0.0039059948f)); - - - Node scene = (Node) assetManager.loadModel("Models/Test/CornellBox.j3o"); - scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - rootNode.attachChild(scene); - rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive); - lightNode = (Node) rootNode.getChild("Lamp"); - Geometry lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setShadowMode(RenderQueue.ShadowMode.Off); - lightNode.attachChild(lightMdl); - //lightMdl.setLocalTranslation(lightNode.getLocalTranslation()); - - - Geometry box = new Geometry("box", new Box(0.2f, 0.2f, 0.2f)); - //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); - box.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - box.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - rootNode.attachChild(box); - box.setLocalTranslation(-1f, 0.5f, -2); - - scene.getLocalLightList().get(0).setColor(ColorRGBA.Red); - - PointLightShadowRenderer plsr - = new PointLightShadowRenderer(assetManager, SHADOWMAP_SIZE); - plsr.setLight((PointLight) scene.getLocalLightList().get(0)); - plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - - PointLightShadowFilter plsf - = new PointLightShadowFilter(assetManager, SHADOWMAP_SIZE); - plsf.setLight((PointLight) scene.getLocalLightList().get(0)); - plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - plsf.setEnabled(useFilter); - - //DIRECTIONAL LIGHT - DirectionalLight directionalLight = new DirectionalLight(); - rootNode.addLight(directionalLight); - directionalLight.setColor(ColorRGBA.Blue); - directionalLight.setDirection(new Vector3f(-1f, -.2f, 0f)); - - DirectionalLightShadowRenderer dlsr - = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE*2, 4); - dlsr.setLight(directionalLight); - dlsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - - DirectionalLightShadowFilter dlsf - = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE*2, 4); - dlsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - dlsf.setLight(directionalLight); - dlsf.setEnabled(useFilter); - - //SPOT LIGHT - spotLight = new SpotLight(); - spotLight.setDirection(new Vector3f(1f,-1f,0f)); - spotLight.setPosition(new Vector3f(-1f,3f,0f)); - spotLight.setSpotOuterAngle(0.5f); - spotLight.setColor(ColorRGBA.Green); - Sphere sphere = new Sphere(8, 8, .1f); - Geometry sphereGeometry = new Geometry("Sphere", sphere); - sphereGeometry.setLocalTranslation(-1f, 3f, 0f); - sphereGeometry.setMaterial(assetManager.loadMaterial("Common/Materials/WhiteColor.j3m")); - rootNode.attachChild(sphereGeometry); - rootNode.addLight(spotLight); - - SpotLightShadowRenderer slsr - = new SpotLightShadowRenderer(assetManager, SHADOWMAP_SIZE); - slsr.setLight(spotLight); - slsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - - SpotLightShadowFilter slsf - = new SpotLightShadowFilter(assetManager, SHADOWMAP_SIZE); - slsf.setLight(spotLight); - slsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - slsf.setEnabled(useFilter); - - - - if (!useFilter)viewPort.addProcessor(slsr); - if (!useFilter)viewPort.addProcessor(plsr); - if (!useFilter)viewPort.addProcessor(dlsr); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(plsf); - fpp.addFilter(dlsf); - fpp.addFilter(slsf); - viewPort.addProcessor(fpp); - - ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort); - ShadowTestUIManager uiManPls = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort); - ShadowTestUIManager uiManDls = new ShadowTestUIManager(assetManager, dlsr, dlsf, guiNode, inputManager, viewPort); - ShadowTestUIManager uiManSls = new ShadowTestUIManager(assetManager, slsr, slsf, guiNode, inputManager, viewPort); - - } - - private float timeElapsed = 0.0f; - @Override - public void simpleUpdate(float tpf) { - timeElapsed += tpf; - lightNode.setLocalTranslation(FastMath.cos(timeElapsed), lightNode.getLocalTranslation().y, FastMath.sin(timeElapsed)); - spotLight.setDirection(new Vector3f(FastMath.cos(-timeElapsed*.7f), -1.0f, FastMath.sin(-timeElapsed*.7f))); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java b/jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java deleted file mode 100644 index 762e11df4a..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.controls.ActionListener; -import com.jme3.light.AmbientLight; -import com.jme3.light.PointLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.shadow.PointLightShadowFilter; -import com.jme3.shadow.PointLightShadowRenderer; - -public class TestPointLightShadows extends SimpleApplication implements ActionListener{ - public static final int SHADOWMAP_SIZE = 512; - - public static void main(String[] args) { - TestPointLightShadows app = new TestPointLightShadows(); - app.start(); - } - private PointLightShadowRenderer plsr; - private AmbientLight al; - - @Override - public void simpleInitApp () { - flyCam.setMoveSpeed(10); - cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f)); - cam.setRotation(new Quaternion(4.3868728E-5f, 0.9999293f, -0.011230096f, 0.0039059948f)); - - al = new AmbientLight(ColorRGBA.White.mult(0.02f)); - rootNode.addLight(al); - - - - - Node scene = (Node) assetManager.loadModel("Models/Test/CornellBox.j3o"); - scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - rootNode.attachChild(scene); - rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive); - Node lightNode = (Node) rootNode.getChild("Lamp"); - Geometry lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setShadowMode(RenderQueue.ShadowMode.Off); - lightNode.attachChild(lightMdl); - //lightMdl.setLocalTranslation(lightNode.getLocalTranslation()); - - - Geometry box = new Geometry("box", new Box(0.2f, 0.2f, 0.2f)); - //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); - box.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - box.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - rootNode.attachChild(box); - box.setLocalTranslation(-1f, 0.5f, -2); - - - plsr = new PointLightShadowRenderer(assetManager, SHADOWMAP_SIZE); - plsr.setLight((PointLight) scene.getLocalLightList().get(0)); - plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - plsr.setShadowZExtend(15); - plsr.setShadowZFadeLength(5); - plsr.setShadowIntensity(0.9f); - // plsr.setFlushQueues(false); - //plsr.displayFrustum(); - plsr.displayDebug(); - viewPort.addProcessor(plsr); - - PointLightShadowFilter plsf - = new PointLightShadowFilter(assetManager, SHADOWMAP_SIZE); - plsf.setLight((PointLight) scene.getLocalLightList().get(0)); - plsf.setShadowZExtend(15); - plsf.setShadowZFadeLength(5); - plsf.setShadowIntensity(0.8f); - plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - plsf.setEnabled(false); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(plsf); - viewPort.addProcessor(fpp); - inputManager.addListener(this,"ShadowUp","ShadowDown"); - ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort); - - } - - @Override - public void simpleUpdate(float tpf) { - // lightNode.move(FastMath.cos(tpf) * 0.4f, 0, FastMath.sin(tpf) * 0.4f); - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if ((name.equals("ShadowUp") || name.equals("ShadowDown")) && isPressed) { - al.setColor(ColorRGBA.White.mult((1 - plsr.getShadowIntensity()) * 0.2f)); - } - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestShadowBug.java b/jme3-examples/src/main/java/jme3test/light/TestShadowBug.java deleted file mode 100644 index acf2d6df13..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestShadowBug.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2009-2015 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. - */ -package jme3test.light; - - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.shadow.PointLightShadowRenderer; -import com.jme3.shadow.SpotLightShadowRenderer; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; - - -public class TestShadowBug extends SimpleApplication { - public static void main(String[] args) { - TestShadowBug app = new TestShadowBug(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(100f); - rootNode.attachChild(makeFloor()); - - Node characters = new Node("Characters"); - characters.setShadowMode(ShadowMode.Cast); - rootNode.attachChild(characters); - - Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - golem.scale(0.5f); - golem.setLocalTranslation(200.0f, -6f, 200f); - golem.setShadowMode(ShadowMode.CastAndReceive); - characters.attachChild(golem); - - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(-1f, -1f, 1f)); - sun.setColor(ColorRGBA.White.mult(1.3f)); - rootNode.addLight(sun); - characters.addLight(sun); - - SpotLight spot = new SpotLight(); - spot.setSpotRange(13f); // distance - spot.setSpotInnerAngle(15f * FastMath.DEG_TO_RAD); // inner light cone (central beam) - spot.setSpotOuterAngle(20f * FastMath.DEG_TO_RAD); // outer light cone (edge of the light) - spot.setColor(ColorRGBA.White.mult(1.3f)); // light color - spot.setPosition(new Vector3f(192.0f, -1f, 192f)); - spot.setDirection(new Vector3f(1, -0.5f, 1)); - rootNode.addLight(spot); - - PointLight lamp_light = new PointLight(); - lamp_light.setColor(ColorRGBA.Yellow); - lamp_light.setRadius(20f); - lamp_light.setPosition(new Vector3f(210.0f, 0f, 210f)); - rootNode.addLight(lamp_light); - - SpotLightShadowRenderer slsr = new SpotLightShadowRenderer(assetManager, 512); - slsr.setLight(spot); - slsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest); - slsr.setShadowIntensity(0.6f); - viewPort.addProcessor(slsr); - - PointLightShadowRenderer plsr = new PointLightShadowRenderer(assetManager, 512); - plsr.setLight(lamp_light); - plsr.setShadowIntensity(0.6f); - plsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest); - viewPort.addProcessor(plsr); - - viewPort.getCamera().setLocation(new Vector3f(192.0f, 10f, 192f)); - float[] angles = new float[]{3.14f/2, 3.14f/2, 0}; - viewPort.getCamera().setRotation(new Quaternion(angles)); - } - - protected Geometry makeFloor() { - Box box = new Box(220, .2f, 220); - box.scaleTextureCoordinates(new Vector2f(10, 10)); - Geometry floor = new Geometry("the Floor", box); - floor.setLocalTranslation(200, -9, 200); - Material matGroundL = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matGroundL.setTexture("DiffuseMap", grass); - floor.setMaterial(matGroundL); - floor.setShadowMode(ShadowMode.CastAndReceive); - return floor; - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java b/jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java deleted file mode 100644 index 857d4374fe..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.DirectionalLightShadowRenderer; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.util.TangentBinormalGenerator; - -public class TestShadowsPerf extends SimpleApplication { - - public static void main(String[] args) { - TestShadowsPerf app = new TestShadowsPerf(); - app.start(); - } - private Geometry sphere; - private Material mat; - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(50); - flyCam.setEnabled(false); - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - cam.setLocation(new Vector3f(-53.952988f, 27.15874f, -32.875023f)); - cam.setRotation(new Quaternion(0.1564309f, 0.6910534f, -0.15713608f, 0.6879555f)); - -// cam.setLocation(new Vector3f(53.64627f, 130.56f, -11.247704f)); -// cam.setRotation(new Quaternion(-6.5737107E-4f, 0.76819664f, -0.64021313f, -7.886125E-4f)); -//// - cam.setFrustumFar(500); - - mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - - Box b = new Box(800, 1, 700); - b.scaleTextureCoordinates(new Vector2f(50, 50)); - Geometry ground = new Geometry("ground", b); - ground.setMaterial(mat); - rootNode.attachChild(ground); - ground.setShadowMode(ShadowMode.Receive); - - Sphere sphMesh = new Sphere(32, 32, 1); - sphMesh.setTextureMode(Sphere.TextureMode.Projected); - sphMesh.updateGeometry(32, 32, 1, false, false); - TangentBinormalGenerator.generate(sphMesh); - - sphere = new Geometry("Rock Ball", sphMesh); - sphere.setLocalTranslation(0, 5, 0); - sphere.setMaterial(mat); - sphere.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(sphere); - - - - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(0, -1, 0).normalizeLocal()); - dl.setColor(ColorRGBA.White); - rootNode.addLight(dl); - - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.7f)); - rootNode.addLight(al); - //rootNode.setShadowMode(ShadowMode.CastAndReceive); - - createBalls(); - - final DirectionalLightShadowRenderer pssmRenderer = new DirectionalLightShadowRenderer(assetManager, 1024, 4); - viewPort.addProcessor(pssmRenderer); -// -// final PssmShadowFilter pssmRenderer = new PssmShadowFilter(assetManager, 1024, 4); -// FilterPostProcessor fpp = new FilterPostProcessor(assetManager); -// fpp.addFilter(pssmRenderer); -// viewPort.addProcessor(fpp); - - pssmRenderer.setLight(dl); - pssmRenderer.setLambda(0.55f); - pssmRenderer.setShadowIntensity(0.55f); - pssmRenderer.setShadowCompareMode(com.jme3.shadow.CompareMode.Software); - pssmRenderer.setEdgeFilteringMode(EdgeFilteringMode.PCF4); - //pssmRenderer.displayDebug(); - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("display") && isPressed) { - //pssmRenderer.debugFrustrums(); - System.out.println("tetetetet"); - } - if (name.equals("add") && isPressed) { - createBalls(); - } - } - }, "display", "add"); - inputManager.addMapping("display", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("add", new KeyTrigger(KeyInput.KEY_RETURN)); - } - private int val = 0; - - private void createBalls() { - System.out.println((frames / time) + ";" + val); - - - for (int i = val; i < val+1 ; i++) { - - Geometry s = sphere.clone().clone(false); - s.setMaterial(mat); - s.setLocalTranslation(i - 30, 5, (((i) * 2) % 40) - 50); - s.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(s); - } - if (val == 300) { - stop(); - } - val += 1; - time = 0; - frames = 0; - } - private float time; - private float frames = 0; - - @Override - public void simpleUpdate(float tpf) { - time += tpf; - frames++; - if (time > 1) { - createBalls(); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java b/jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java deleted file mode 100644 index 535db645d3..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.MaterialDebugAppState; -import com.jme3.util.TangentBinormalGenerator; - -public class TestSimpleLighting extends SimpleApplication { - - private float angle; - private PointLight pl; - private Geometry lightMdl; - - public static void main(String[] args){ - TestSimpleLighting app = new TestSimpleLighting(); - app.start(); - } - - @Override - public void simpleInitApp() { - Geometry teapot = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - TangentBinormalGenerator.generate(teapot.getMesh(), true); - - teapot.setLocalScale(2f); - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); -// mat.selectTechnique("GBuf"); - mat.setFloat("Shininess", 25); - mat.setBoolean("UseMaterialColors", true); - cam.setLocation(new Vector3f(0.015041917f, 0.4572918f, 5.2874837f)); - cam.setRotation(new Quaternion(-1.8875003E-4f, 0.99882424f, 0.04832061f, 0.0039016632f)); - -// mat.setTexture("ColorRamp", assetManager.loadTexture("Textures/ColorRamp/cloudy.png")); -// -// mat.setBoolean("VTangent", true); -// mat.setBoolean("Minnaert", true); -// mat.setBoolean("WardIso", true); -// mat.setBoolean("VertexLighting", true); -// mat.setBoolean("LowQuality", true); -// mat.setBoolean("HighQuality", true); - - mat.setColor("Ambient", ColorRGBA.Black); - mat.setColor("Diffuse", ColorRGBA.Gray); - mat.setColor("Specular", ColorRGBA.Gray); - - teapot.setMaterial(mat); - rootNode.attachChild(teapot); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.getMesh().setStatic(); - rootNode.attachChild(lightMdl); - - pl = new PointLight(); - pl.setColor(ColorRGBA.White); - pl.setRadius(4f); - rootNode.addLight(pl); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - dl.setColor(ColorRGBA.Green); - rootNode.addLight(dl); - - - MaterialDebugAppState debug = new MaterialDebugAppState(); - debug.registerBinding("Common/ShaderLib/BlinnPhongLighting.glsllib", teapot); - stateManager.attach(debug); - setPauseOnLostFocus(false); - flyCam.setDragToRotate(true); - - } - - @Override - public void simpleUpdate(float tpf){ -// cam.setLocation(new Vector3f(2.0632997f, 1.9493936f, 2.6885238f)); -// cam.setRotation(new Quaternion(-0.053555284f, 0.9407851f, -0.17754152f, -0.28378546f)); - - angle += tpf; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 2f, 0.5f, FastMath.sin(angle) * 2f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSpotLight.java b/jme3-examples/src/main/java/jme3test/light/TestSpotLight.java deleted file mode 100644 index e65c1763da..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestSpotLight.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.util.TangentBinormalGenerator; - -public class TestSpotLight extends SimpleApplication { - - final private Vector3f lightTarget = new Vector3f(12, 3.5f, 30); - - public static void main(String[] args){ - TestSpotLight app = new TestSpotLight(); - app.start(); - } - - private SpotLight spot; - private Geometry lightMdl; - public void setupLighting(){ - AmbientLight al=new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.02f)); - rootNode.addLight(al); - - spot=new SpotLight(); - - spot.setSpotRange(1000); - spot.setSpotInnerAngle(5*FastMath.DEG_TO_RAD); - spot.setSpotOuterAngle(10*FastMath.DEG_TO_RAD); - spot.setPosition(new Vector3f(77.70334f, 34.013165f, 27.1017f)); - spot.setDirection(lightTarget.subtract(spot.getPosition())); - spot.setColor(ColorRGBA.White.mult(2)); - rootNode.addLight(spot); - - -// PointLight pl=new PointLight(); -// pl.setPosition(new Vector3f(77.70334f, 34.013165f, 27.1017f)); -// pl.setRadius(1000); -// pl.setColor(ColorRGBA.White.mult(2)); -// rootNode.addLight(pl); - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setLocalTranslation(new Vector3f(77.70334f, 34.013165f, 27.1017f)); - lightMdl.setLocalScale(5); - rootNode.attachChild(lightMdl); - -// DirectionalLight dl = new DirectionalLight(); -// dl.setDirection(lightTarget.subtract(new Vector3f(77.70334f, 34.013165f, 27.1017f))); -// dl.setColor(ColorRGBA.White.mult(2)); -// rootNode.addLight(dl); - - - } - - public void setupFloor(){ - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat); - mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat); - // mat.getTextureParam("ParallaxMap").getTextureValue().setWrap(WrapMode.Repeat); - mat.setFloat("Shininess",3); - // mat.setBoolean("VertexLighting", true); - - - Box floor = new Box(50, 1f, 50); - TangentBinormalGenerator.generate(floor); - floor.scaleTextureCoordinates(new Vector2f(5, 5)); - Geometry floorGeom = new Geometry("Floor", floor); - floorGeom.setMaterial(mat); - floorGeom.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(floorGeom); - } - - - - public void setupSignpost(){ - Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); - Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - // mat.setBoolean("VertexLighting", true); - signpost.setMaterial(mat); - signpost.rotate(0, FastMath.HALF_PI, 0); - signpost.setLocalTranslation(12, 3.5f, 30); - signpost.setLocalScale(4); - signpost.setShadowMode(ShadowMode.CastAndReceive); - TangentBinormalGenerator.generate(signpost); - rootNode.attachChild(signpost); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(27.492603f, 29.138166f, -13.232513f)); - cam.setRotation(new Quaternion(0.25168246f, -0.10547892f, 0.02760565f, 0.96164864f)); - flyCam.setMoveSpeed(30); - - setupLighting(); - setupFloor(); - setupSignpost(); - - - } - - private float angle; - - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - angle += tpf; - angle %= FastMath.TWO_PI; - - spot.setPosition(new Vector3f(FastMath.cos(angle) * 30f, 34.013165f, FastMath.sin(angle) * 30f)); - lightMdl.setLocalTranslation(spot.getPosition()); - spot.setDirection(lightTarget.subtract(spot.getPosition())); - } - - - -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java b/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java deleted file mode 100644 index 3c6c653102..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.shadow.SpotLightShadowFilter; -import com.jme3.shadow.SpotLightShadowRenderer; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.util.TangentBinormalGenerator; - -public class TestSpotLightShadows extends SimpleApplication { - - final private Vector3f lightTarget = new Vector3f(12, 3.5f, 30); - - public static void main(String[] args) { - TestSpotLightShadows app = new TestSpotLightShadows(); - app.start(); - } - private SpotLight spot; - private Geometry lightMdl; - - public void setupLighting() { - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.02f)); - rootNode.addLight(al); - - rootNode.setShadowMode(ShadowMode.CastAndReceive); - - spot = new SpotLight(); - - spot.setSpotRange(1000); - spot.setSpotInnerAngle(5f * FastMath.DEG_TO_RAD); - spot.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); - spot.setPosition(new Vector3f(70.70334f, 34.013165f, 27.1017f)); - spot.setDirection(lightTarget.subtract(spot.getPosition()).normalizeLocal()); - spot.setColor(ColorRGBA.White.mult(2)); - rootNode.addLight(spot); - - -// PointLight pl=new PointLight(); -// pl.setPosition(new Vector3f(77.70334f, 34.013165f, 27.1017f)); -// pl.setRadius(1000); -// pl.setColor(ColorRGBA.White.mult(2)); -// rootNode.addLight(pl); - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.setLocalTranslation(new Vector3f(77.70334f, 34.013165f, 27.1017f)); - lightMdl.setLocalScale(5); - rootNode.attachChild(lightMdl); - -// DirectionalLight dl = new DirectionalLight(); -// dl.setDirection(lightTarget.subtract(new Vector3f(77.70334f, 34.013165f, 27.1017f))); -// dl.setColor(ColorRGBA.White.mult(0.7f)); -// rootNode.addLight(dl); - - - final SpotLightShadowRenderer slsr = new SpotLightShadowRenderer(assetManager, 512); - slsr.setLight(spot); - slsr.setShadowIntensity(0.5f); - slsr.setShadowZExtend(100); - slsr.setShadowZFadeLength(5); - slsr.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON); - viewPort.addProcessor(slsr); - - SpotLightShadowFilter slsf = new SpotLightShadowFilter(assetManager, 512); - slsf.setLight(spot); - slsf.setShadowIntensity(0.5f); - slsf.setShadowZExtend(100); - slsf.setShadowZFadeLength(5); - slsf.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON); - slsf.setEnabled(false); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(slsf); - viewPort.addProcessor(fpp); - - ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, slsr, slsf, guiNode, inputManager, viewPort); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("stop") && isPressed) { - stop = !stop; - // slsr.displayFrustum(); - System.out.println("pos : " + spot.getPosition()); - System.out.println("dir : " + spot.getDirection()); - } - } - }, "stop"); - - inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_1)); - flyCam.setDragToRotate(true); - } - - public void setupFloor() { - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat); - mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat); - mat.setBoolean("UseMaterialColors", true); - mat.setColor("Diffuse", ColorRGBA.White.clone()); - mat.setColor("Ambient", ColorRGBA.White.clone()); - // mat.setColor("Specular", ColorRGBA.White.clone()); - // mat.getTextureParam("ParallaxMap").getTextureValue().setWrap(WrapMode.Repeat); - mat.setFloat("Shininess", 0); - // mat.setBoolean("VertexLighting", true); - - - Box floor = new Box(50, 1f, 50); - TangentBinormalGenerator.generate(floor); - floor.scaleTextureCoordinates(new Vector2f(5, 5)); - Geometry floorGeom = new Geometry("Floor", floor); - floorGeom.setMaterial(mat); - floorGeom.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(floorGeom); - } - - public void setupSignpost() { - Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); - Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - // mat.setBoolean("VertexLighting", true); - signpost.setMaterial(mat); - signpost.rotate(0, FastMath.HALF_PI, 0); - signpost.setLocalTranslation(12, 3.5f, 30); - signpost.setLocalScale(4); - signpost.setShadowMode(ShadowMode.CastAndReceive); - TangentBinormalGenerator.generate(signpost); - rootNode.attachChild(signpost); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(27.492603f, 29.138166f, -13.232513f)); - cam.setRotation(new Quaternion(0.25168246f, -0.10547892f, 0.02760565f, 0.96164864f)); - flyCam.setMoveSpeed(30); - - setupLighting(); - setupFloor(); - setupSignpost(); - - - } - private float angle; - private boolean stop = true; - - @Override - public void simpleUpdate(float tpf) { - if (!stop) { - super.simpleUpdate(tpf); - angle += tpf; - angle %= FastMath.TWO_PI; - - spot.setPosition(new Vector3f(FastMath.cos(angle) * 30f, 34.013165f, FastMath.sin(angle) * 30f)); - lightMdl.setLocalTranslation(spot.getPosition()); - spot.setDirection(lightTarget.subtract(spot.getPosition())); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java b/jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java deleted file mode 100644 index 9fa5a0ea36..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.light.AmbientLight; -import com.jme3.light.SpotLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.util.SkyFactory; - -/** - * Uses the terrain's lighting texture with normal maps and lights. - * - * @author bowens - */ -public class TestSpotLightTerrain extends SimpleApplication { - - final private float grassScale = 64; - final private float dirtScale = 16; - final private float rockScale = 128; - private SpotLight sl; - - public static void main(String[] args) { - TestSpotLightTerrain app = new TestSpotLightTerrain(); - app.start(); - } - - - @Override - public void simpleInitApp() { - makeTerrain(); - flyCam.setMoveSpeed(50); - - sl = new SpotLight(); - sl.setSpotRange(100); - sl.setSpotOuterAngle(20 * FastMath.DEG_TO_RAD); - sl.setSpotInnerAngle(15 * FastMath.DEG_TO_RAD); - sl.setDirection(new Vector3f(-0.39820394f, -0.73094344f, 0.55421597f)); - sl.setPosition(new Vector3f(-64.61567f, -87.615425f, -202.41328f)); - rootNode.addLight(sl); - - AmbientLight ambLight = new AmbientLight(); - ambLight.setColor(ColorRGBA.Black); - rootNode.addLight(ambLight); - - cam.setLocation(new Vector3f(-41.219646f, 0.8363f, -171.67267f)); - cam.setRotation(new Quaternion(-0.04562731f, 0.89917684f, -0.09668826f, -0.4243236f)); - sl.setDirection(cam.getDirection()); - sl.setPosition(cam.getLocation()); - - } - - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - sl.setDirection(cam.getDirection()); - sl.setPosition(cam.getLocation()); - - } - - private void makeTerrain() { - // TERRAIN TEXTURE material - Material matTerrain = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matTerrain.setBoolean("useTriPlanarMapping", false); - matTerrain.setBoolean("WardIso", true); - - // ALPHA map (for splat textures) - matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); - matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); - - // HEIGHTMAP image (for the terrain heightmap) - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - - - // GRASS texture - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap", grass); - matTerrain.setFloat("DiffuseMap_0_scale", grassScale); - - // DIRT texture - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_1", dirt); - matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); - - // ROCK texture - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_2", rock); - matTerrain.setFloat("DiffuseMap_2_scale", rockScale); - - // BRICK texture - Texture brick = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"); - brick.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_3", brick); - matTerrain.setFloat("DiffuseMap_3_scale", rockScale); - - // RIVER ROCK texture - Texture riverRock = assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"); - riverRock.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_4", riverRock); - matTerrain.setFloat("DiffuseMap_4_scale", rockScale); - - - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matTerrain.setTexture("NormalMap", normalMap0); - matTerrain.setTexture("NormalMap_1", normalMap1); - matTerrain.setTexture("NormalMap_2", normalMap2); - matTerrain.setTexture("NormalMap_4", normalMap2); - - // WIREFRAME material - Material matWire = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - matWire.getAdditionalRenderState().setWireframe(true); - matWire.setColor("Color", ColorRGBA.Green); - - createSky(); - - // CREATE HEIGHTMAP - AbstractHeightMap heightmap = null; - try { - //heightmap = new HillHeightMap(1025, 1000, 50, 100, (byte) 3); - - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f); - heightmap.load(); - - } catch (Exception e) { - e.printStackTrace(); - } - - TerrainQuad terrain - = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations - TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); - control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); - terrain.addControl(control); - terrain.setMaterial(matTerrain); - terrain.setModelBound(new BoundingBox()); - terrain.updateModelBound(); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(1f, 1f, 1f); - rootNode.attachChild(terrain); - } - - private void createSky() { - Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg"); - Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg"); - Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg"); - Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg"); - Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg"); - Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg"); - - Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down); - rootNode.attachChild(sky); - } - - -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentCube.java b/jme3-examples/src/main/java/jme3test/light/TestTangentCube.java deleted file mode 100644 index 13841f986f..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestTangentCube.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2009-2015 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. - */ -package jme3test.light; - -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.util.TangentBinormalGenerator; - -/** - * - * @author Nehon - */ -public class TestTangentCube extends SimpleApplication { - - public static void main(String... args) { - TestTangentCube app = new TestTangentCube(); - app.start(); - } - - @Override - public void simpleInitApp() { - Box aBox = new Box(1, 1, 1); - Geometry aGeometry = new Geometry("Box", aBox); - TangentBinormalGenerator.generate(aBox); - - Material aMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - aMaterial.setTexture("DiffuseMap", - assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg")); - aMaterial.setTexture("NormalMap", - assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall_normal.jpg")); - aMaterial.setBoolean("UseMaterialColors", false); - aMaterial.setColor("Diffuse", ColorRGBA.White); - aMaterial.setColor("Specular", ColorRGBA.White); - aMaterial.setFloat("Shininess", 64f); - aGeometry.setMaterial(aMaterial); - - // Rotate 45 degrees to see multiple faces - aGeometry.rotate(FastMath.QUARTER_PI, FastMath.QUARTER_PI, 0.0f); - rootNode.attachChild(aGeometry); - - /* - * Must add a light to make the lit object visible! - */ - PointLight aLight = new PointLight(); - aLight.setPosition(new Vector3f(0, 3, 3)); - aLight.setColor(ColorRGBA.Red); - rootNode.addLight(aLight); -// -// AmbientLight bLight = new AmbientLight(); -// bLight.setColor(ColorRGBA.Gray); -// rootNode.addLight(bLight); - - - ChaseCameraAppState chaser = new ChaseCameraAppState(); - chaser.setTarget(aGeometry); - getStateManager().attach(chaser); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentGen.java b/jme3-examples/src/main/java/jme3test/light/TestTangentGen.java deleted file mode 100644 index 80fd44084c..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestTangentGen.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Mesh.Mode; -import com.jme3.scene.Spatial; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.scene.shape.Quad; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.BufferUtils; -import com.jme3.util.TangentBinormalGenerator; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - - -public class TestTangentGen extends SimpleApplication { - - public static void main(String[] args){ - TestTangentGen app = new TestTangentGen(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(20); - Sphere sphereMesh = new Sphere(32, 32, 1); - sphereMesh.setTextureMode(Sphere.TextureMode.Projected); - sphereMesh.updateGeometry(32, 32, 1, false, false); - addMesh("Sphere", sphereMesh, new Vector3f(-1, 0, 0)); - - Quad quadMesh = new Quad(1, 1); - quadMesh.updateGeometry(1, 1); - addMesh("Quad", quadMesh, new Vector3f(1, 0, 0)); - - Mesh strip = createTriangleStripMesh(); - addMesh("strip", strip, new Vector3f(0, -3, 0)); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1, -1, -1).normalizeLocal()); - dl.setColor(ColorRGBA.White); - rootNode.addLight(dl); - } - - private void addMesh(String name, Mesh mesh, Vector3f translation) { - TangentBinormalGenerator.generate(mesh); - - Geometry testGeom = new Geometry(name, mesh); - Material mat = assetManager.loadMaterial("Textures/BumpMapTest/Tangent.j3m"); - testGeom.setMaterial(mat); - testGeom.getLocalTranslation().set(translation); - rootNode.attachChild(testGeom); - - Geometry debug = new Geometry( - "Debug " + name, - TangentBinormalGenerator.genTbnLines(mesh, 0.08f) - ); - Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m"); - debug.setMaterial(debugMat); - debug.setCullHint(Spatial.CullHint.Never); - debug.getLocalTranslation().set(translation); - rootNode.attachChild(debug); - } - - @Override - public void simpleUpdate(float tpf){ - } - - private Mesh createTriangleStripMesh() { - Mesh strip = new Mesh(); - strip.setMode(Mode.TriangleStrip); - FloatBuffer vb = BufferUtils.createFloatBuffer(3*3*3); // 3 rows * 3 columns * 3 floats - vb.rewind(); - vb.put(new float[]{0,2,0}); vb.put(new float[]{1,2,0}); vb.put(new float[]{2,2,0}); - vb.put(new float[]{0,1,0}); vb.put(new float[]{1,1,0}); vb.put(new float[]{2,1,0}); - vb.put(new float[]{0,0,0}); vb.put(new float[]{1,0,0}); vb.put(new float[]{2,0,0}); - FloatBuffer nb = BufferUtils.createFloatBuffer(3*3*3); - nb.rewind(); - nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); - nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); - nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); - FloatBuffer tb = BufferUtils.createFloatBuffer(3*3*2); - tb.rewind(); - tb.put(new float[]{0,0}); tb.put(new float[]{0.5f,0}); tb.put(new float[]{1,0}); - tb.put(new float[]{0,0.5f}); tb.put(new float[]{0.5f,0.5f}); tb.put(new float[]{1,0.5f}); - tb.put(new float[]{0,1}); tb.put(new float[]{0.5f,1}); tb.put(new float[]{1,1}); - int[] indexes = new int[]{0,3,1,4,2,5, 5,3, 3,6,4,7,5,8}; - IntBuffer ib = BufferUtils.createIntBuffer(indexes.length); - ib.put(indexes); - strip.setBuffer(Type.Position, 3, vb); - strip.setBuffer(Type.Normal, 3, nb); - strip.setBuffer(Type.TexCoord, 2, tb); - strip.setBuffer(Type.Index, 3, ib); - strip.updateBound(); - return strip; - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java b/jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java deleted file mode 100644 index 9121d09154..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TangentBinormalGenerator; - -public class TestTangentGenBadUV extends SimpleApplication { - - private float angle; - private PointLight pl; - private Geometry lightMdl; - - public static void main(String[] args){ - TestTangentGenBadUV app = new TestTangentGenBadUV(); - app.start(); - } - - @Override - public void simpleInitApp() { - Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); - if (teapot instanceof Geometry){ - Geometry g = (Geometry) teapot; - TangentBinormalGenerator.generate(g.getMesh()); - }else{ - throw new RuntimeException(); - } - teapot.setLocalScale(2f); - Material mat = assetManager.loadMaterial("Textures/BumpMapTest/Tangent.j3m"); - teapot.setMaterial(mat); - rootNode.attachChild(teapot); - - Geometry debug = new Geometry( - "Debug Teapot", - TangentBinormalGenerator.genTbnLines(((Geometry) teapot).getMesh(), 0.03f) - ); - Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m"); - debug.setMaterial(debugMat); - debug.setCullHint(Spatial.CullHint.Never); - debug.getLocalTranslation().set(teapot.getLocalTranslation()); - debug.getLocalScale().set(teapot.getLocalScale()); - rootNode.attachChild(debug); - - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1,-1,-1).normalizeLocal()); - dl.setColor(ColorRGBA.White); - rootNode.addLight(dl); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.getMesh().setStatic(); - rootNode.attachChild(lightMdl); - - pl = new PointLight(); - pl.setColor(ColorRGBA.White); - //pl.setRadius(3f); - rootNode.addLight(pl); - } - - @Override - public void simpleUpdate(float tpf){ - angle += tpf; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 2f, 0.5f, FastMath.sin(angle) * 2f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java b/jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java deleted file mode 100644 index f4cd8c4215..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.*; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.util.TangentBinormalGenerator; -import com.jme3.util.mikktspace.MikktspaceTangentGenerator; - -/** - * test - * - * @author normenhansen - */ -public class TestTangentSpace extends SimpleApplication { - - public static void main(String[] args) { - TestTangentSpace app = new TestTangentSpace(); - app.start(); - } - - final private Node debugNode = new Node("debug"); - - @Override - public void simpleInitApp() { - renderManager.setSinglePassLightBatchSize(2); - renderManager.setPreferredLightMode(TechniqueDef.LightMode.SinglePass); - initView(); - - Spatial s = assetManager.loadModel("Models/Test/BasicCubeLow.obj"); - rootNode.attachChild(s); - - Material m = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - m.setTexture("NormalMap", assetManager.loadTexture("Models/Test/Normal_pixel.png")); - - Geometry g = (Geometry)s; - Geometry g2 = (Geometry) g.deepClone(); - g2.move(5, 0, 0); - g.getParent().attachChild(g2); - - g.setMaterial(m); - g2.setMaterial(m); - - //Regular tangent generation (left geom) - TangentBinormalGenerator.generate(g2.getMesh(), true); - - //MikkTSPace Tangent generation (right geom) - - MikktspaceTangentGenerator.generate(g); - - createDebugTangents(g2); - createDebugTangents(g); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("toggleDebug") && isPressed) { - if (debugNode.getParent() == null) { - rootNode.attachChild(debugNode); - } else { - debugNode.removeFromParent(); - } - } - } - }, "toggleDebug"); - - inputManager.addMapping("toggleDebug", new KeyTrigger(KeyInput.KEY_SPACE)); - - - DirectionalLight dl = new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()); - rootNode.addLight(dl); - } - - private void initView() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - cam.setLocation(new Vector3f(8.569681f, 3.335546f, 5.4372444f)); - cam.setRotation(new Quaternion(-0.07608022f, 0.9086564f, -0.18992864f, -0.3639813f)); - flyCam.setMoveSpeed(10); - } - - private void createDebugTangents(Geometry geom) { - Geometry debug = new Geometry( - "Debug " + geom.getName(), - TangentBinormalGenerator.genTbnLines(geom.getMesh(), 0.8f) - ); - Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m"); - debug.setMaterial(debugMat); - debug.setCullHint(Spatial.CullHint.Never); - debug.getLocalTranslation().set(geom.getWorldTranslation()); - debugNode.attachChild(debug); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java b/jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java deleted file mode 100644 index b013dc6c1d..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -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.scene.shape.RectangleMesh; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.CompareMode; -import com.jme3.shadow.DirectionalLightShadowRenderer; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.util.TangentBinormalGenerator; - -public class TestTransparentShadow extends SimpleApplication { - - public static void main(String[] args){ - TestTransparentShadow app = new TestTransparentShadow(); - app.start(); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(5.700248f, 6.161693f, 5.1404157f)); - cam.setRotation(new Quaternion(-0.09441641f, 0.8993388f, -0.24089815f, -0.35248178f)); - - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - RectangleMesh rm = new RectangleMesh( - new Vector3f(-10, 0, 10), - new Vector3f(10, 0, 10), - new Vector3f(-10, 0, -10) - ); - rm.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10)); - TangentBinormalGenerator.generate(rm); - - Geometry geom = new Geometry("floor", rm); - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - geom.setMaterial(mat); - geom.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(geom); - - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.7f)); - rootNode.addLight(al); - - DirectionalLight dl1 = new DirectionalLight(); - dl1.setDirection(new Vector3f(0, -1, 0.5f).normalizeLocal()); - dl1.setColor(ColorRGBA.White.mult(1.5f)); - rootNode.addLight(dl1); - - // create the geometry and attach it - Spatial tree = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); - tree.setQueueBucket(Bucket.Transparent); - tree.setShadowMode(ShadowMode.CastAndReceive); - - rootNode.attachChild(tree); - - // Uses Texture from jme3-testdata library! - ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30); - Material mat_red = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat_red.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); - fire.setShadowMode(ShadowMode.Cast); - fire.setMaterial(mat_red); - fire.setImagesX(2); - fire.setImagesY(2); // 2x2 texture animation - fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f)); // red - fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow - fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0)); - fire.setStartSize(0.6f); - fire.setEndSize(0.1f); - fire.setGravity(0, 0, 0); - fire.setLowLife(0.5f); - fire.setHighLife(1.5f); - fire.getParticleInfluencer().setVelocityVariation(0.3f); - fire.setLocalTranslation(5.0f, 0, 1.0f); - fire.setLocalScale(0.3f); - fire.setQueueBucket(Bucket.Translucent); - rootNode.attachChild(fire); - - Material mat2 = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); - - Geometry ball = new Geometry("sphere", new Sphere(16, 16, 0.5f)); - ball.setMaterial(mat2); - ball.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(ball); - ball.setLocalTranslation(-1.0f, 1.5f, 1.0f); - - final DirectionalLightShadowRenderer dlsRenderer = new DirectionalLightShadowRenderer(assetManager, 1024, 1); - dlsRenderer.setLight(dl1); - dlsRenderer.setLambda(0.55f); - dlsRenderer.setShadowIntensity(0.8f); - dlsRenderer.setShadowCompareMode(CompareMode.Software); - dlsRenderer.setEdgeFilteringMode(EdgeFilteringMode.Nearest); - dlsRenderer.displayDebug(); - viewPort.addProcessor(dlsRenderer); - inputManager.addMapping("stabilize", new KeyTrigger(KeyInput.KEY_B)); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("stabilize") && isPressed) { - dlsRenderer.setEnabledStabilization(!dlsRenderer.isEnabledStabilization()) ; - } - } - }, "stabilize"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java b/jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java deleted file mode 100644 index e5dfdc754c..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.light; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.material.RenderState; -import com.jme3.material.TechniqueDef; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TangentBinormalGenerator; - -/** - * Checks two-sided lighting capability. - * - * @author Kirill Vainer - */ -public class TestTwoSideLighting extends SimpleApplication { - - private float angle; - private PointLight pl; - private Geometry lightMdl; - - public static void main(String[] args){ - TestTwoSideLighting app = new TestTwoSideLighting(); - app.start(); - } - - @Override - public void simpleInitApp() { - // Two-sided lighting requires single pass. - renderManager.setPreferredLightMode(TechniqueDef.LightMode.SinglePass); - renderManager.setSinglePassLightBatchSize(4); - - cam.setLocation(new Vector3f(5.936224f, 3.3759952f, -3.3202777f)); - cam.setRotation(new Quaternion(0.16265652f, -0.4811838f, 0.09137692f, 0.8565368f)); - - Geometry quadGeom = new Geometry("quad", new Quad(1, 1)); - quadGeom.move(1, 0, 0); - Material mat1 = assetManager.loadMaterial("Textures/BumpMapTest/SimpleBump.j3m"); - - // Display both front and back faces. - mat1.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off); - - quadGeom.setMaterial(mat1); - // SimpleBump material requires tangents. - TangentBinormalGenerator.generate(quadGeom); - rootNode.attachChild(quadGeom); - - Geometry teapot = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - teapot.move(-1, 0, 0); - teapot.setLocalScale(2f); - Material mat2 = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - mat2.setFloat("Shininess", 25); - mat2.setBoolean("UseMaterialColors", true); - mat2.setColor("Ambient", ColorRGBA.Black); - mat2.setColor("Diffuse", ColorRGBA.Gray); - mat2.setColor("Specular", ColorRGBA.Gray); - - // Only display backfaces. - mat2.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Front); - - teapot.setMaterial(mat2); - rootNode.attachChild(teapot); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - lightMdl.getMesh().setStatic(); - rootNode.attachChild(lightMdl); - - pl = new PointLight(); - pl.setColor(ColorRGBA.White); - pl.setRadius(4f); - rootNode.addLight(pl); - } - - @Override - public void simpleUpdate(float tpf){ - angle += tpf; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 3f, 0.5f, FastMath.sin(angle) * 3f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/package-info.java b/jme3-examples/src/main/java/jme3test/light/package-info.java deleted file mode 100644 index a896fc8170..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for lighting - */ -package jme3test.light; diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java b/jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java deleted file mode 100644 index 038fca3fe6..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light.pbr; - -import com.jme3.environment.generation.JobProgressAdapter; -import com.jme3.light.LightProbe; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * A basic logger for environment map rendering progress. - * @author nehon - */ -public class ConsoleProgressReporter extends JobProgressAdapter{ - - private static final Logger logger = Logger.getLogger(ConsoleProgressReporter.class.getName()); - - private long time; - - @Override - public void start() { - time = System.currentTimeMillis(); - logger.log(Level.INFO,"Starting generation"); - } - - @Override - public void progress(double value) { - if (logger.isLoggable(Level.INFO)) { - logger.log(Level.INFO, "Progress : {0}%", (value * 100)); - } - } - - @Override - public void step(String message) { - logger.info(message); - } - - @Override - public void done(LightProbe result) { - long end = System.currentTimeMillis(); - if (logger.isLoggable(Level.INFO)) { - logger.log(Level.INFO, "Generation done in {0}", (end - time) / 1000f); - } - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java b/jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java deleted file mode 100644 index ff32877ad8..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.light.pbr; - -import com.jme3.app.SimpleApplication; -import com.jme3.environment.EnvironmentCamera; -import com.jme3.environment.LightProbeFactory; -import com.jme3.environment.generation.JobProgressAdapter; -import com.jme3.environment.util.EnvMapUtils; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.LightProbe; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.scene.*; -import com.jme3.ui.Picture; -import com.jme3.util.SkyFactory; - -/** - * test - * - * @author nehon - */ -public class RefEnv extends SimpleApplication { - - private Node tex; - private Node ref; - private Picture refImg; - - public static void main(String[] args) { - RefEnv app = new RefEnv(); - app.start(); - } - - @Override - public void simpleInitApp() { - - cam.setLocation(new Vector3f(-17.95047f, 4.917353f, -17.970531f)); - cam.setRotation(new Quaternion(0.11724457f, 0.29356146f, -0.03630452f, 0.94802815f)); -// cam.setLocation(new Vector3f(14.790441f, 7.164179f, 19.720007f)); -// cam.setRotation(new Quaternion(-0.038261678f, 0.9578362f, -0.15233073f, -0.24058504f)); - flyCam.setDragToRotate(true); - flyCam.setMoveSpeed(5); - Spatial sc = assetManager.loadModel("Scenes/PBR/ref/scene.gltf"); - rootNode.attachChild(sc); - Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap); - rootNode.attachChild(sky); - rootNode.getChild(0).setCullHint(Spatial.CullHint.Always); - - ref = new Node("reference pictures"); - refImg = new Picture("refImg"); - refImg.setHeight(cam.getHeight()); - refImg.setWidth(cam.getWidth()); - refImg.setImage(assetManager, "jme3test/light/pbr/ref.png", false); - - ref.attachChild(refImg); - - stateManager.attach(new EnvironmentCamera(256, Vector3f.ZERO)); - - inputManager.addMapping("tex", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("switch", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addMapping("ref", new KeyTrigger(KeyInput.KEY_R)); - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("tex") && isPressed) { - if (tex == null) { - tex = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(stateManager.getState(EnvironmentCamera.class).debugEnv, assetManager); - } - if (tex.getParent() == null) { - guiNode.attachChild(tex); - } else { - tex.removeFromParent(); - } - } - - if (name.equals("switch") && isPressed) { - switchMat(rootNode.getChild("Scene")); - } - if (name.equals("ref") && isPressed) { - if (ref.getParent() == null) { - guiNode.attachChild(ref); - } else { - ref.removeFromParent(); - } - } - } - }, "tex", "switch", "ref"); - - } - - private void switchMat(Spatial s) { - if (s instanceof Node) { - Node n = (Node) s; - for (Spatial children : n.getChildren()) { - switchMat(children); - } - } else if (s instanceof Geometry) { - Geometry g = (Geometry) s; - Material mat = g.getMaterial(); - if (((Float) mat.getParam("Metallic").getValue()) == 1f) { - mat.setFloat("Metallic", 0); - mat.setColor("BaseColor", ColorRGBA.Black); - ref.attachChild(refImg); - } else { - mat.setFloat("Metallic", 1); - mat.setColor("BaseColor", ColorRGBA.White); - refImg.removeFromParent(); - } - } - } - - private int frame = 0; - - @Override - public void simpleUpdate(float tpf) { - frame++; - - EnvironmentCamera eCam = stateManager.getState(EnvironmentCamera.class); - if (frame == 2) { - final LightProbe probe = LightProbeFactory.makeProbe(eCam, rootNode, EnvMapUtils.GenerationType.Fast, new JobProgressAdapter() { - - @Override - public void done(LightProbe result) { - System.err.println("Done rendering env maps"); - tex = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(result.getPrefilteredEnvMap(), assetManager); - rootNode.getChild(0).setCullHint(Spatial.CullHint.Dynamic); - } - }); - probe.getArea().setRadius(100); - rootNode.addLight(probe); - - } - - if (eCam.isBusy()) { - System.out.println("EnvironmentCamera busy as of frame " + frame); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java deleted file mode 100644 index 9a9c79d2eb..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java +++ /dev/null @@ -1,92 +0,0 @@ -package jme3test.light.pbr; - -import com.jme3.anim.SkinningControl; -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.UrlLocator; -import com.jme3.environment.EnvironmentCamera; -import com.jme3.environment.LightProbeFactory; -import com.jme3.environment.generation.JobProgressAdapter; -import com.jme3.light.DirectionalLight; -import com.jme3.light.LightProbe; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.system.AppSettings; - -/** - * This test case validates a shader compilation fix with a model using a PBR material in combination with a - * SkinningControl. When you run this application and don't see a RenderException, the test is successful. - * For a detailed explanation consult the GitHub issue: https://github.com/jMonkeyEngine/jmonkeyengine/issues/1340 - * -rvandoosselaer - */ -public class TestIssue1340 extends SimpleApplication { - - private Spatial model; - private int frame; - - public static void main(String[] args) { - TestIssue1340 testIssue1340 = new TestIssue1340(); - testIssue1340.setSettings(createSettings()); - testIssue1340.start(); - } - - private static AppSettings createSettings() { - AppSettings settings = new AppSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL32); - return settings; - } - - @Override - public void simpleInitApp() { - stateManager.attach(new EnvironmentCamera(32)); - - DirectionalLight light = new DirectionalLight(Vector3f.UNIT_Y.negate(), ColorRGBA.White); - rootNode.addLight(light); - - assetManager.registerLocator("https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/RiggedFigure/", UrlLocator.class); - - model = assetManager.loadModel("/glTF-Embedded/RiggedFigure.gltf"); - SkinningControl skinningControl = getSkinningControl(model); - if (skinningControl == null || !skinningControl.isHardwareSkinningPreferred()) { - throw new IllegalArgumentException("This test case requires a model with a SkinningControl and with Hardware skinning preferred!"); - } - - viewPort.setBackgroundColor(ColorRGBA.LightGray); - } - - @Override - public void simpleUpdate(float tpf) { - frame++; - if (frame == 2) { - LightProbeFactory.makeProbe(stateManager.getState(EnvironmentCamera.class), rootNode, new JobProgressAdapter() { - @Override - public void done(LightProbe result) { - enqueue(() -> { - rootNode.attachChild(model); - rootNode.addLight(result); - }); - } - }); - } - } - - private SkinningControl getSkinningControl(Spatial model) { - SkinningControl control = model.getControl(SkinningControl.class); - if (control != null) { - return control; - } - - if (model instanceof Node) { - for (Spatial child : ((Node) model).getChildren()) { - SkinningControl skinningControl = getSkinningControl(child); - if (skinningControl != null) { - return skinningControl; - } - } - } - - return null; - } - -} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java deleted file mode 100644 index e169d27850..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ -package jme3test.light.pbr; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.LightProbe; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.shape.CenterQuad; -import com.jme3.system.AppSettings; - -/** - * Reproduces an issue where PBR materials render much darker with the Core 3.2 - * profile than with the Compatibility profile. - * - *

This test relies on AppSettings set in main(), so it shouldn't be run - * from the jme3-examples TestChooser! - * - *

Compare the window rendered by this test with that rendered by - * TestIssue1903Core. If they differ, you have reproduced the issue. - * If they are identical, then you haven't reproduced it. - */ -public class TestIssue1903Compat extends SimpleApplication { - /** - * Main entry point for the TestIssue1903Compat application. - * - * @param unused array of command-line arguments - */ - public static void main(String[] unused) { - boolean loadDefaults = true; - AppSettings appSettings = new AppSettings(loadDefaults); - appSettings.setGammaCorrection(true); - appSettings.setRenderer(AppSettings.LWJGL_OPENGL2); // Compatibility profile - appSettings.setTitle("Compatibility"); - - TestIssue1903Compat application = new TestIssue1903Compat(); - application.setSettings(appSettings); - application.setShowSettings(false); // to speed up testing - application.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setEnabled(false); - - // Attach a 9x9 quad at the origin. - Mesh mesh = new CenterQuad(9f, 9f); - Geometry quad = new Geometry("quad", mesh); - rootNode.attachChild(quad); - - // Apply a PBR material to the quad. - String materialAssetPath = "TestIssue1903.j3m"; - Material material = assetManager.loadMaterial(materialAssetPath); - quad.setMaterial(material); - - // Add a LightProbe. - String lightProbePath = "Scenes/LightProbes/quarry_Probe.j3o"; - LightProbe probe = (LightProbe) assetManager.loadAsset(lightProbePath); - rootNode.addLight(probe); - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java deleted file mode 100644 index 22bcc18e26..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2023 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. - */ -package jme3test.light.pbr; - -import com.jme3.app.SimpleApplication; -import com.jme3.system.AppSettings; - -/** - * Reproduces an issue where PBR materials render much darker with the Core 3.2 - * profile than with the Compatibility profile. - * - *

This test relies on AppSettings set in main(), so it shouldn't be run - * from the jme3-examples TestChooser! - * - *

Compare the window rendered by this test with that rendered by - * TestIssue1903Compat. If they differ, you have reproduced the issue. - * If they are identical, then you haven't reproduced it. - */ -public class TestIssue1903Core extends SimpleApplication { - /** - * Main entry point for the TestIssue1903Core application. - * - * @param unused array of command-line arguments - */ - public static void main(String[] unused) { - boolean loadDefaults = true; - AppSettings appSettings = new AppSettings(loadDefaults); - appSettings.setGammaCorrection(true); - appSettings.setRenderer(AppSettings.LWJGL_OPENGL32); // Core 3.2 profile - appSettings.setTitle("Core 3.2"); - - TestIssue1903Compat application = new TestIssue1903Compat(); - application.setSettings(appSettings); - application.setShowSettings(false); // to speed up testing - application.start(); - } - - @Override - public void simpleInitApp() { - throw new AssertionError(); // never reached - } -} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java deleted file mode 100644 index d9f3aef763..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2009-2015 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. - */ -package jme3test.light.pbr; - -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.scene.*; -import com.jme3.scene.shape.Sphere; - -/** - * A test case for PBR lighting. - * Still experimental. - * - * @author nehon - */ -public class TestPBRDirectLighting extends SimpleApplication { - - public static void main(String[] args) { - TestPBRDirectLighting app = new TestPBRDirectLighting(); - app.start(); - } - - private DirectionalLight dl; - - private float roughness = 0.0f; - - @Override - public void simpleInitApp() { - - - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - rootNode.addLight(dl); - dl.setColor(ColorRGBA.White); - - ChaseCameraAppState chaser = new ChaseCameraAppState(); - chaser.setDragToRotate(true); - chaser.setMinVerticalRotation(-FastMath.HALF_PI); - chaser.setMaxDistance(1000); - chaser.setInvertVerticalAxis(true); - getStateManager().attach(chaser); - chaser.setTarget(rootNode); - flyCam.setEnabled(false); - - Geometry sphere = new Geometry("sphere", new Sphere(32, 32, 1)); - final Material m = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md"); - m.setColor("BaseColor", ColorRGBA.Black); - m.setFloat("Metallic", 0f); - m.setFloat("Roughness", roughness); - sphere.setMaterial(m); - rootNode.attachChild(sphere); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - - if (name.equals("rup") && isPressed) { - roughness = FastMath.clamp(roughness + 0.1f, 0.0f, 1.0f); - m.setFloat("Roughness", roughness); - } - if (name.equals("rdown") && isPressed) { - roughness = FastMath.clamp(roughness - 0.1f, 0.0f, 1.0f); - m.setFloat("Roughness", roughness); - } - - if (name.equals("light") && isPressed) { - dl.setDirection(cam.getDirection().normalize()); - } - } - }, "light", "rup", "rdown"); - - - inputManager.addMapping("light", new KeyTrigger(KeyInput.KEY_F)); - inputManager.addMapping("rup", new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("rdown", new KeyTrigger(KeyInput.KEY_DOWN)); - - - } - - @Override - public void simpleUpdate(float tpf) { - } - -} - diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java deleted file mode 100644 index 7de1e456c7..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.light.pbr; - -import com.jme3.app.SimpleApplication; -import com.jme3.environment.EnvironmentCamera; -import com.jme3.environment.LightProbeFactory; -import com.jme3.environment.generation.JobProgressAdapter; -import com.jme3.environment.util.EnvMapUtils; -import com.jme3.environment.util.LightsDebugState; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.*; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.ToneMapFilter; -import com.jme3.scene.*; -import com.jme3.texture.plugins.ktx.KTXLoader; -import com.jme3.util.MaterialDebugAppState; -import com.jme3.util.SkyFactory; -import com.jme3.util.mikktspace.MikktspaceTangentGenerator; - -/** - * A test case for PBR lighting. - * Still experimental. - * - * @author nehon - */ -public class TestPBRLighting extends SimpleApplication { - - public static void main(String[] args) { - TestPBRLighting app = new TestPBRLighting(); - app.start(); - } - - private Node tex; - - private Geometry model; - private DirectionalLight dl; - private Node modelNode; - private int frame = 0; - private Material pbrMat; - private float roughness = 1.0f; - - @Override - public void simpleInitApp() { - assetManager.registerLoader(KTXLoader.class, "ktx"); - - viewPort.setBackgroundColor(ColorRGBA.White); - modelNode = new Node("modelNode"); - model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o"); - MikktspaceTangentGenerator.generate(model); - modelNode.attachChild(model); - - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - rootNode.addLight(dl); - dl.setColor(ColorRGBA.White); - rootNode.attachChild(modelNode); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - int numSamples = context.getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - -// fpp.addFilter(new FXAAFilter()); - fpp.addFilter(new ToneMapFilter(Vector3f.UNIT_XYZ.mult(4.0f))); -// fpp.addFilter(new SSAOFilter(0.5f, 3, 0.2f, 0.2f)); - viewPort.addProcessor(fpp); - - //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Sky_Cloudy.hdr", SkyFactory.EnvMapType.EquirectMap); - Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap); - //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap); - //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/road.hdr", SkyFactory.EnvMapType.EquirectMap); - rootNode.attachChild(sky); - - pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m"); - model.setMaterial(pbrMat); - - - final EnvironmentCamera envCam = new EnvironmentCamera(256, new Vector3f(0, 3f, 0)); - stateManager.attach(envCam); - -// EnvironmentManager envManager = new EnvironmentManager(); -// stateManager.attach(envManager); - - // envManager.setScene(rootNode); - - LightsDebugState debugState = new LightsDebugState(); - stateManager.attach(debugState); - - ChaseCamera chaser = new ChaseCamera(cam, modelNode, inputManager); - chaser.setDragToRotate(true); - chaser.setMinVerticalRotation(-FastMath.HALF_PI); - chaser.setMaxDistance(1000); - chaser.setSmoothMotion(true); - chaser.setRotationSensitivity(10); - chaser.setZoomSensitivity(5); - flyCam.setEnabled(false); - //flyCam.setMoveSpeed(100); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("debug") && isPressed) { - if (tex == null) { - return; - } - if (tex.getParent() == null) { - guiNode.attachChild(tex); - } else { - tex.removeFromParent(); - } - } - - if (name.equals("rup") && isPressed) { - roughness = FastMath.clamp(roughness + 0.1f, 0.0f, 1.0f); - pbrMat.setFloat("Roughness", roughness); - } - if (name.equals("rdown") && isPressed) { - roughness = FastMath.clamp(roughness - 0.1f, 0.0f, 1.0f); - pbrMat.setFloat("Roughness", roughness); - } - - - if (name.equals("up") && isPressed) { - model.move(0, tpf * 100f, 0); - } - - if (name.equals("down") && isPressed) { - model.move(0, -tpf * 100f, 0); - } - if (name.equals("left") && isPressed) { - model.move(0, 0, tpf * 100f); - } - if (name.equals("right") && isPressed) { - model.move(0, 0, -tpf * 100f); - } - if (name.equals("light") && isPressed) { - dl.setDirection(cam.getDirection().normalize()); - } - } - }, "toggle", "light", "up", "down", "left", "right", "debug", "rup", "rdown"); - - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addMapping("light", new KeyTrigger(KeyInput.KEY_F)); - inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT)); - inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addMapping("debug", new KeyTrigger(KeyInput.KEY_D)); - inputManager.addMapping("rup", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addMapping("rdown", new KeyTrigger(KeyInput.KEY_G)); - - - MaterialDebugAppState debug = new MaterialDebugAppState(); - debug.registerBinding("Common/MatDefs/Light/PBRLighting.frag", rootNode); - debug.registerBinding("Common/ShaderLib/PBR.glsllib", rootNode); - getStateManager().attach(debug); - - } - - @Override - public void simpleUpdate(float tpf) { - frame++; - - if (frame == 2) { - modelNode.removeFromParent(); - final LightProbe probe = LightProbeFactory.makeProbe(stateManager.getState(EnvironmentCamera.class), rootNode, new JobProgressAdapter() { - - @Override - public void done(LightProbe result) { - System.err.println("Done rendering env maps"); - tex = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(result.getPrefilteredEnvMap(), assetManager); - } - }); - probe.getArea().setRadius(100); - rootNode.addLight(probe); - //getStateManager().getState(EnvironmentManager.class).addEnvProbe(probe); - - } - if (frame > 10 && modelNode.getParent() == null) { - rootNode.attachChild(modelNode); - } - } - -} - diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/package-info.java b/jme3-examples/src/main/java/jme3test/light/pbr/package-info.java deleted file mode 100644 index 399267e70a..0000000000 --- a/jme3-examples/src/main/java/jme3test/light/pbr/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for physically based rendering (PBR) - */ -package jme3test.light.pbr; diff --git a/jme3-examples/src/main/java/jme3test/material/TestBumpModel.java b/jme3-examples/src/main/java/jme3test/material/TestBumpModel.java deleted file mode 100644 index f71e43ea63..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestBumpModel.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.ogre.OgreMeshKey; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TangentBinormalGenerator; - -public class TestBumpModel extends SimpleApplication { - - private float angle; - private PointLight pl; - private Spatial lightMdl; - - public static void main(String[] args){ - TestBumpModel app = new TestBumpModel(); - app.start(); - } - - @Override - public void simpleInitApp() { - Spatial signpost = assetManager.loadAsset(new OgreMeshKey("Models/Sign Post/Sign Post.mesh.xml")); - signpost.setMaterial(assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m")); - TangentBinormalGenerator.generate(signpost); - rootNode.attachChild(signpost); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(lightMdl); - - // fluorescent main light - pl = new PointLight(); - pl.setColor(new ColorRGBA(0.88f, 0.92f, 0.95f, 1.0f)); - rootNode.addLight(pl); - - // sunset light - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal()); - dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f)); - rootNode.addLight(dl); - - // skylight - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal()); - dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f)); - rootNode.addLight(dl); - - // white ambient light - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal()); - dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); - rootNode.addLight(dl); - } - - @Override - public void simpleUpdate(float tpf){ - angle += tpf * 0.25f; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 6f, 3f, FastMath.sin(angle) * 6f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java b/jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java deleted file mode 100644 index 7f7c50fab0..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.renderer.queue.RenderQueue.Bucket; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; - -public class TestColoredTexture extends SimpleApplication { - - private float time = 0; - private ColorRGBA nextColor; - private ColorRGBA prevColor; - private Material mat; - - public static void main(String[] args){ - TestColoredTexture app = new TestColoredTexture(); - app.start(); - } - - @Override - public void simpleInitApp() { - Quad quadMesh = new Quad(512,512); - Geometry quad = new Geometry("Quad", quadMesh); - quad.setQueueBucket(Bucket.Gui); - - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png")); - quad.setMaterial(mat); - guiNode.attachChildAt(quad, 0); - - nextColor = ColorRGBA.randomColor(); - prevColor = ColorRGBA.Black; - } - - @Override - public void simpleUpdate(float tpf){ - time += tpf; - if (time > 1f){ - time -= 1f; - prevColor = nextColor; - nextColor = ColorRGBA.randomColor(); - } - ColorRGBA currentColor = new ColorRGBA(); - currentColor.interpolateLocal(prevColor, nextColor, time); - - mat.setColor("Color", currentColor); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java b/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java deleted file mode 100644 index 0199d70cc2..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java +++ /dev/null @@ -1,46 +0,0 @@ -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.shape.Sphere; -import com.jme3.system.AppSettings; -import com.jme3.util.BufferUtils; - -/** - * Created by michael on 23.02.15. - */ -public class TestGeometryShader extends SimpleApplication { - @Override - public void simpleInitApp() { - Mesh mesh = new Mesh(); - mesh.setBuffer(VertexBuffer.Type.Index, 1, BufferUtils.createIntBuffer(new int[]{1})); - mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(new float[]{0, 0, 0})); - mesh.setMode(Mesh.Mode.Points); - mesh.setBound(new BoundingBox(new Vector3f(0, 0, 0), 10, 10, 10)); - mesh.updateCounts(); - Geometry geometry = new Geometry("Test", mesh); - geometry.updateGeometricState(); - geometry.setMaterial(new Material(assetManager, "Materials/Geom/SimpleGeom.j3md")); - //geometry.getMaterial().getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off); - //geometry.setMaterial(assetManager.loadMaterial("Materials/Geom/SimpleTess.j3md")); - rootNode.attachChild(geometry); - - Geometry geometry1 = new Geometry("T1", new Sphere(10, 10, 1)); - geometry1.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); - rootNode.attachChild(geometry1); - - } - - public static void main(String[] args) { - TestGeometryShader app = new TestGeometryShader(); - AppSettings settings = new AppSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL33); - app.setSettings(settings); - app.start(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java b/jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java deleted file mode 100644 index 2d599ef2f5..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.MatParamOverride; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector4f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.shader.VarType; - -/** - * Test if {@link MatParamOverride}s are working correctly. - * - * @author Kirill Vainer - */ -public class TestMatParamOverride extends SimpleApplication { - - final private Box box = new Box(1, 1, 1); - final MatParamOverride overrideYellow - = new MatParamOverride(VarType.Vector4, "Color", - ColorRGBA.Yellow); - final MatParamOverride overrideWhite - = new MatParamOverride(VarType.Vector4, "Color", - Vector4f.UNIT_XYZW); - final MatParamOverride overrideGray - = new MatParamOverride(VarType.Vector4, "Color", - new Quaternion(0.5f, 0.5f, 0.5f, 1f)); - - public static void main(String[] args) { - TestMatParamOverride app = new TestMatParamOverride(); - app.start(); - } - - private void createBox(float location, ColorRGBA color) { - Geometry geom = new Geometry("Box", box); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", color); - geom.setMaterial(mat); - geom.move(location, 0, 0); - rootNode.attachChild(geom); - } - - @Override - public void simpleInitApp() { - inputManager.setCursorVisible(true); - - createBox(-3, ColorRGBA.Red); - createBox(0, ColorRGBA.Green); - createBox(3, ColorRGBA.Blue); - - System.out.println("Press G, W, Y, or space bar ..."); - inputManager.addMapping("overrideClear", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("overrideGray", new KeyTrigger(KeyInput.KEY_G)); - inputManager.addMapping("overrideWhite", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("overrideYellow", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - if (name.equals("overrideClear")) { - rootNode.clearMatParamOverrides(); - } else if (name.equals("overrideGray")) { - rootNode.clearMatParamOverrides(); - rootNode.addMatParamOverride(overrideGray); - } else if (name.equals("overrideWhite")) { - rootNode.clearMatParamOverrides(); - rootNode.addMatParamOverride(overrideWhite); - } else if (name.equals("overrideYellow")) { - rootNode.clearMatParamOverrides(); - rootNode.addMatParamOverride(overrideYellow); - } - System.out.println(rootNode.getLocalMatParamOverrides()); - } - } - }, "overrideClear", "overrideGray", "overrideWhite", "overrideYellow"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java b/jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java deleted file mode 100644 index a37855185c..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.material; - -import com.jme3.asset.AssetManager; -import com.jme3.asset.TextureKey; -import com.jme3.material.Material; -import com.jme3.material.RenderState.BlendMode; -import com.jme3.math.ColorRGBA; -import com.jme3.system.JmeSystem; -import com.jme3.texture.Texture; - -public class TestMaterialCompare { - - public static void main(String[] args) { - AssetManager assetManager = JmeSystem.newAssetManager( - TestMaterialCompare.class.getResource("/com/jme3/asset/Desktop.cfg")); - - // Cloned materials - Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat1.setName("mat1"); - mat1.setColor("Color", ColorRGBA.Blue); - - Material mat2 = mat1.clone(); - mat2.setName("mat2"); - testEquality(mat1, mat2, true); - - // Cloned material with different render states - Material mat3 = mat1.clone(); - mat3.setName("mat3"); - mat3.getAdditionalRenderState().setBlendMode(BlendMode.ModulateX2); - testEquality(mat1, mat3, false); - - // Two separately loaded materials - Material mat4 = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - mat4.setName("mat4"); - Material mat5 = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - mat5.setName("mat5"); - testEquality(mat4, mat5, true); - - // Comparing same textures - TextureKey originalKey = (TextureKey) mat4.getTextureParam("DiffuseMap").getTextureValue().getKey(); - TextureKey tex1key = new TextureKey("Models/Sign Post/Sign Post.jpg", false); - tex1key.setGenerateMips(true); - - // Texture keys from the original and the loaded texture - // must be identical, otherwise the resultant textures not identical - // and thus materials are not identical! - if (!originalKey.equals(tex1key)){ - System.out.println("TEXTURE KEYS ARE NOT EQUAL"); - } - - Texture tex1 = assetManager.loadTexture(tex1key); - mat4.setTexture("DiffuseMap", tex1); - testEquality(mat4, mat5, true); - - // Change some stuff on the texture and compare, materials no longer equal - tex1.setWrap(Texture.WrapMode.MirroredRepeat); - testEquality(mat4, mat5, false); - - // Comparing different textures - Texture tex2 = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); - mat4.setTexture("DiffuseMap", tex2); - testEquality(mat4, mat5, false); - - // Two materials created the same way - Material mat6 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat6.setName("mat6"); - mat6.setColor("Color", ColorRGBA.Blue); - testEquality(mat1, mat6, true); - - // Changing a material param - mat6.setColor("Color", ColorRGBA.Green); - testEquality(mat1, mat6, false); - } - - private static void testEquality(Material mat1, Material mat2, boolean expected) { - if (mat2.contentEquals(mat1)) { - System.out.print(mat1.getName() + " == " + mat2.getName()); - if (expected) { - System.out.println(" EQUAL OK"); - } else { - System.out.println(" EQUAL FAIL!"); - } - } else { - System.out.print(mat1.getName() + " != " + mat2.getName()); - if (!expected) { - System.out.println(" EQUAL OK"); - } else { - System.out.println(" EQUAL FAIL!"); - } - } - if (mat2.hashCode() == mat1.hashCode()){ - System.out.print(mat1.getName() + " == " + mat2.getName()); - if (expected) { - System.out.println(" HASH OK"); - } else { - System.out.println(" HASH FAIL!"); - } - } else { - System.out.print(mat1.getName() + " != " + mat2.getName()); - if (!expected) { - System.out.println(" HASH OK"); - } else { - System.out.println(" HASH FAIL!"); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java b/jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java deleted file mode 100644 index e75b33ba58..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TangentBinormalGenerator; - -public class TestNormalMapping extends SimpleApplication { - - private float angle; - private PointLight pl; - private Spatial lightMdl; - - public static void main(String[] args){ - TestNormalMapping app = new TestNormalMapping(); - app.start(); - } - - @Override - public void simpleInitApp() { - Sphere sphMesh = new Sphere(32, 32, 1); - sphMesh.setTextureMode(Sphere.TextureMode.Projected); - sphMesh.updateGeometry(32, 32, 1, false, false); - TangentBinormalGenerator.generate(sphMesh); - - Geometry sphere = new Geometry("Rock Ball", sphMesh); - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - sphere.setMaterial(mat); - rootNode.attachChild(sphere); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(lightMdl); - - pl = new PointLight(); - pl.setColor(ColorRGBA.White); - pl.setPosition(new Vector3f(0f, 0f, 4f)); - rootNode.addLight(pl); - -// DirectionalLight dl = new DirectionalLight(); -// dl.setDirection(new Vector3f(1,-1,1).normalizeLocal()); -// dl.setColor(new ColorRGBA(0.22f, 0.15f, 0.1f, 1.0f)); -// rootNode.addLight(dl); - } - - @Override - public void simpleUpdate(float tpf){ - angle += tpf * 0.25f; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 4f, 0.5f, FastMath.sin(angle) * 4f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestParallax.java b/jme3-examples/src/main/java/jme3test/material/TestParallax.java deleted file mode 100644 index 80afeaf382..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestParallax.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.RectangleMesh; -import com.jme3.util.SkyFactory; -import com.jme3.util.TangentBinormalGenerator; - -public class TestParallax extends SimpleApplication { - - private final Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); - - public static void main(String[] args) { - TestParallax app = new TestParallax(); - app.start(); - } - - public void setupSkyBox() { - rootNode.attachChild(SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", SkyFactory.EnvMapType.CubeMap)); - } - - public void setupLighting() { - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(lightDir); - dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); - rootNode.addLight(dl); - } - private Material mat; - - public void setupFloor() { - mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); - - RectangleMesh rm = new RectangleMesh( - new Vector3f(-50, 22, 60), - new Vector3f(50, 22, 60), - new Vector3f(-50, 22, -40)); - rm.scaleTextureCoordinates(new Vector2f(10, 10)); - - Geometry floorGeom = new Geometry("floorGeom", rm); - TangentBinormalGenerator.generate(floorGeom); - floorGeom.setMaterial(mat); - - rootNode.attachChild(floorGeom); - } - - public void setupSignpost() { - Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); - Material matSp = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - TangentBinormalGenerator.generate(signpost); - signpost.setMaterial(matSp); - signpost.rotate(0, FastMath.HALF_PI, 0); - signpost.setLocalTranslation(12, 23.5f, 30); - signpost.setLocalScale(4); - signpost.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(signpost); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(-15.445636f, 30.162927f, 60.252777f)); - cam.setRotation(new Quaternion(0.05173137f, 0.92363626f, -0.13454558f, 0.35513034f)); - flyCam.setMoveSpeed(30); - - setupLighting(); - setupSkyBox(); - setupFloor(); - setupSignpost(); - - inputManager.addListener(new AnalogListener() { - - @Override - public void onAnalog(String name, float value, float tpf) { - if ("heightUP".equals(name)) { - parallaxHeight += 0.01; - mat.setFloat("ParallaxHeight", parallaxHeight); - } - if ("heightDown".equals(name)) { - parallaxHeight -= 0.01; - parallaxHeight = Math.max(parallaxHeight, 0); - mat.setFloat("ParallaxHeight", parallaxHeight); - } - - } - }, "heightUP", "heightDown"); - inputManager.addMapping("heightUP", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addMapping("heightDown", new KeyTrigger(KeyInput.KEY_K)); - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed && "toggleSteep".equals(name)) { - steep = !steep; - mat.setBoolean("SteepParallax", steep); - } - } - }, "toggleSteep"); - inputManager.addMapping("toggleSteep", new KeyTrigger(KeyInput.KEY_SPACE)); - } - private float parallaxHeight = 0.05f; - private boolean steep = false; - - @Override - public void simpleUpdate(float tpf) { -// time+=tpf; -// lightDir.set(FastMath.sin(time), -1, FastMath.cos(time)); -// bsr.setDirection(lightDir); -// dl.setDirection(lightDir); - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java b/jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java deleted file mode 100644 index aca2282634..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.RectangleMesh; -import com.jme3.util.SkyFactory; -import com.jme3.util.TangentBinormalGenerator; - -public class TestParallaxPBR extends SimpleApplication { - - final private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); - - public static void main(String[] args) { - TestParallaxPBR app = new TestParallaxPBR(); - app.start(); - } - - public void setupSkyBox() { - rootNode.attachChild(SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", SkyFactory.EnvMapType.CubeMap)); - } - private DirectionalLight dl; - - public void setupLighting() { - - dl = new DirectionalLight(); - dl.setDirection(lightDir); - dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); - rootNode.addLight(dl); - } - private Material mat; - - public void setupFloor() { - mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWallPBR.j3m"); - //mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWallPBR2.j3m"); - - RectangleMesh rm = new RectangleMesh( - new Vector3f(-50, 22, 60), - new Vector3f(50, 22, 60), - new Vector3f(-50, 22, -40)); - rm.scaleTextureCoordinates(new Vector2f(10, 10)); - - Geometry floorGeom = new Geometry("floorGeom", rm); - TangentBinormalGenerator.generate(floorGeom); - //floorGeom.setLocalScale(100); - - floorGeom.setMaterial(mat); - rootNode.attachChild(floorGeom); - } - - public void setupSignpost() { - Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); - Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - TangentBinormalGenerator.generate(signpost); - signpost.setMaterial(mat); - signpost.rotate(0, FastMath.HALF_PI, 0); - signpost.setLocalTranslation(12, 23.5f, 30); - signpost.setLocalScale(4); - signpost.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(signpost); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(-15.445636f, 30.162927f, 60.252777f)); - cam.setRotation(new Quaternion(0.05173137f, 0.92363626f, -0.13454558f, 0.35513034f)); - flyCam.setMoveSpeed(30); - - - setupLighting(); - setupSkyBox(); - setupFloor(); - setupSignpost(); - - inputManager.addListener(new AnalogListener() { - - @Override - public void onAnalog(String name, float value, float tpf) { - if ("heightUP".equals(name)) { - parallaxHeight += 0.01; - mat.setFloat("ParallaxHeight", parallaxHeight); - } - if ("heightDown".equals(name)) { - parallaxHeight -= 0.01; - parallaxHeight = Math.max(parallaxHeight, 0); - mat.setFloat("ParallaxHeight", parallaxHeight); - } - - } - }, "heightUP", "heightDown"); - inputManager.addMapping("heightUP", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addMapping("heightDown", new KeyTrigger(KeyInput.KEY_K)); - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed && "toggleSteep".equals(name)) { - steep = !steep; - mat.setBoolean("SteepParallax", steep); - } - } - }, "toggleSteep"); - inputManager.addMapping("toggleSteep", new KeyTrigger(KeyInput.KEY_SPACE)); - } - private float parallaxHeight = 0.05f; - private boolean steep = false; - - @Override - public void simpleUpdate(float tpf) { -// time+=tpf; -// lightDir.set(FastMath.sin(time), -1, FastMath.cos(time)); -// bsr.setDirection(lightDir); -// dl.setDirection(lightDir); - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java b/jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java deleted file mode 100644 index 592663efeb..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java +++ /dev/null @@ -1,43 +0,0 @@ -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.material.Technique; -import com.jme3.material.TechniqueDef; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.shader.Shader; -import com.jme3.texture.Texture; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class TestShaderNodes extends SimpleApplication { - - public static void main(String[] args) { - TestShaderNodes app = new TestShaderNodes(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(20); - Logger.getLogger("com.jme3").setLevel(Level.WARNING); - Box boxShape1 = new Box(1f, 1f, 1f); - Geometry cube_tex = new Geometry("A Textured Box", boxShape1); - Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md"); - mat.selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager); - Technique t = mat.getActiveTechnique(); - - for (Shader.ShaderSource shaderSource : t.getDef().getShader(assetManager, renderer.getCaps(), t.getDynamicDefines()).getSources()) { - System.out.println(shaderSource.getSource()); - } - - mat.setColor("Color", ColorRGBA.Yellow); - mat.setTexture("ColorMap", tex); - cube_tex.setMaterial(mat); - rootNode.attachChild(cube_tex); - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java b/jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java deleted file mode 100644 index 4185e1caf7..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TangentBinormalGenerator; - -// phong cutoff for light to normal angle > 90? -public class TestSimpleBumps extends SimpleApplication { - - private float angle; - private PointLight pl; - private Spatial lightMdl; - - public static void main(String[] args){ - TestSimpleBumps app = new TestSimpleBumps(); - app.start(); - } - - @Override - public void simpleInitApp() { - Quad quadMesh = new Quad(1, 1); - - Geometry sphere = new Geometry("Rock Ball", quadMesh); - Material mat = assetManager.loadMaterial("Textures/BumpMapTest/SimpleBump.j3m"); - sphere.setMaterial(mat); - TangentBinormalGenerator.generate(sphere); - rootNode.attachChild(sphere); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(lightMdl); - - pl = new PointLight(); - pl.setColor(ColorRGBA.White); - pl.setPosition(new Vector3f(0f, 0f, 4f)); - rootNode.addLight(pl); - -// DirectionalLight dl = new DirectionalLight(); -// dl.setDirection(new Vector3f(1, -1, -1).normalizeLocal()); -// dl.setColor(new ColorRGBA(0.22f, 0.15f, 0.1f, 1.0f)); -// rootNode.addLight(dl); - } - - @Override - public void simpleUpdate(float tpf){ - angle += tpf * 0.25f; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 4f, 0.5f, FastMath.sin(angle) * 4f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java b/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java deleted file mode 100644 index a5af58bfc5..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java +++ /dev/null @@ -1,73 +0,0 @@ -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.shape.Quad; -import com.jme3.system.AppSettings; -import com.jme3.util.BufferUtils; - -import java.util.concurrent.Callable; - -/** - * Created by michael on 28.02.15. - */ -public class TestTessellationShader extends SimpleApplication { - private Material tessellationMaterial; - private int tessFactor=5; - @Override - public void simpleInitApp() { - tessellationMaterial = new Material(getAssetManager(), "Materials/Tess/SimpleTess.j3md"); - tessellationMaterial.setInt("TessellationFactor", tessFactor); - tessellationMaterial.getAdditionalRenderState().setWireframe(true); - Quad quad = new Quad(10, 10); - quad.clearBuffer(VertexBuffer.Type.Index); - quad.setBuffer(VertexBuffer.Type.Index, 4, BufferUtils.createIntBuffer(0, 1, 2, 3)); - quad.setMode(Mesh.Mode.Patch); - quad.setPatchVertexCount(4); - Geometry geometry = new Geometry("tessTest", quad); - geometry.setMaterial(tessellationMaterial); - rootNode.attachChild(geometry); - - getInputManager().addMapping("TessUp", new KeyTrigger(KeyInput.KEY_O)); - getInputManager().addMapping("TessDo", new KeyTrigger(KeyInput.KEY_L)); - getInputManager().addListener(new AnalogListener() { - @Override - public void onAnalog(String name, float value, float tpf) { - if(name.equals("TessUp")){ - tessFactor++; - enqueue(new Callable() { - @Override - public Boolean call() throws Exception { - tessellationMaterial.setInt("TessellationFactor",tessFactor); - return true; - } - }); - } - if(name.equals("TessDo")){ - tessFactor--; - enqueue(new Callable() { - @Override - public Boolean call() throws Exception { - tessellationMaterial.setInt("TessellationFactor",tessFactor); - return true; - } - }); - } - } - },"TessUp","TessDo"); - } - - public static void main(String[] args) { - TestTessellationShader app = new TestTessellationShader(); - AppSettings settings = new AppSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL40); - app.setSettings(settings); - app.start(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java b/jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java deleted file mode 100644 index 826ef448d0..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java +++ /dev/null @@ -1,44 +0,0 @@ -package jme3test.material; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TangentBinormalGenerator; - -public class TestUnshadedModel extends SimpleApplication { - - public static void main(String[] args){ - TestUnshadedModel app = new TestUnshadedModel(); - app.start(); - } - - @Override - public void simpleInitApp() { - Sphere sphMesh = new Sphere(32, 32, 1); - sphMesh.setTextureMode(Sphere.TextureMode.Projected); - sphMesh.updateGeometry(32, 32, 1, false, false); - TangentBinormalGenerator.generate(sphMesh); - - Geometry sphere = new Geometry("Rock Ball", sphMesh); - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - mat.setColor("Ambient", ColorRGBA.DarkGray); - mat.setColor("Diffuse", ColorRGBA.White); - mat.setBoolean("UseMaterialColors", true); - sphere.setMaterial(mat); - rootNode.attachChild(sphere); - - PointLight pl = new PointLight(); - pl.setColor(ColorRGBA.White); - pl.setPosition(new Vector3f(4f, 0f, 0f)); - rootNode.addLight(pl); - - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White); - rootNode.addLight(al); - } -} diff --git a/jme3-examples/src/main/java/jme3test/material/package-info.java b/jme3-examples/src/main/java/jme3test/material/package-info.java deleted file mode 100644 index a90750386a..0000000000 --- a/jme3-examples/src/main/java/jme3test/material/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for materials - */ -package jme3test.material; diff --git a/jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java b/jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java deleted file mode 100644 index 1bd9361bb7..0000000000 --- a/jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.math; - -import com.jme3.math.FastMath; -import java.util.Scanner; - -public class TestHalfFloat { - public static void main(String[] args){ - Scanner scan = new Scanner(System.in); - while (true){ - System.out.println("Enter float to convert or 'x' to exit: "); - String s = scan.nextLine(); - if (s.equals("x")) - break; - - float flt = Float.valueOf(s); - short half = FastMath.convertFloatToHalf(flt); - float flt2 = FastMath.convertHalfToFloat(half); - - System.out.println("Input float: "+flt); - System.out.println("Result float: "+flt2); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/math/package-info.java b/jme3-examples/src/main/java/jme3test/math/package-info.java deleted file mode 100644 index 0dd99ffacb..0000000000 --- a/jme3-examples/src/main/java/jme3test/math/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for arithmetic - */ -package jme3test.math; diff --git a/jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java b/jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java deleted file mode 100644 index bbf03a8348..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ -package jme3test.model; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.SkinningControl; -import com.jme3.app.*; -import com.jme3.asset.plugins.FileLocator; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.math.*; -import com.jme3.renderer.Limits; -import com.jme3.scene.*; -import com.jme3.scene.control.Control; -import com.jme3.scene.debug.custom.ArmatureDebugAppState; -import com.jme3.scene.plugins.gltf.GltfModelKey; -import jme3test.model.anim.EraseTimer; - -import java.util.*; - -public class TestGltfLoading extends SimpleApplication { - - final private Node autoRotate = new Node("autoRotate"); - final private List assets = new ArrayList<>(); - private Node probeNode; - private float time = 0; - private int assetIndex = 0; - private boolean useAutoRotate = false; - private final static String indentString = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; - final private int duration = 1; - private boolean playAnim = true; - - public static void main(String[] args) { - TestGltfLoading app = new TestGltfLoading(); - app.start(); - } - - /* - WARNING this test case can't work without the assets, and considering their size, they are not pushed into the repo - you can find them here : - https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0 - https://sketchfab.com/features/gltf - You have to copy them in Model/gltf folder in the jme3-testdata project. - */ - @Override - public void simpleInitApp() { - - ArmatureDebugAppState armatureDebugappState = new ArmatureDebugAppState(); - getStateManager().attach(armatureDebugappState); - setTimer(new EraseTimer()); - - String folder = System.getProperty("user.home"); - assetManager.registerLocator(folder, FileLocator.class); - - // cam.setLocation(new Vector3f(4.0339394f, 2.645184f, 6.4627485f)); - // cam.setRotation(new Quaternion(-0.013950467f, 0.98604023f, -0.119502485f, -0.11510504f)); - cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.1f, 100f); - renderer.setDefaultAnisotropicFilter(Math.min(renderer.getLimits().get(Limits.TextureAnisotropy), 8)); - setPauseOnLostFocus(false); - - flyCam.setMoveSpeed(5); - flyCam.setDragToRotate(true); - flyCam.setEnabled(false); - viewPort.setBackgroundColor(new ColorRGBA().setAsSrgb(0.2f, 0.2f, 0.2f, 1.0f)); - rootNode.attachChild(autoRotate); - probeNode = (Node) assetManager.loadModel("Scenes/defaultProbe.j3o"); - autoRotate.attachChild(probeNode); - -// DirectionalLight dl = new DirectionalLight(); -// dl.setDirection(new Vector3f(-1f, -1.0f, -1f).normalizeLocal()); -// dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); -// rootNode.addLight(dl); - -// DirectionalLight dl2 = new DirectionalLight(); -// dl2.setDirection(new Vector3f(1f, 1.0f, 1f).normalizeLocal()); -// dl2.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); -// rootNode.addLight(dl2); - -// PointLight pl = new PointLight(new Vector3f(5.0f, 5.0f, 5.0f), ColorRGBA.White, 30); -// rootNode.addLight(pl); -// PointLight pl1 = new PointLight(new Vector3f(-5.0f, -5.0f, -5.0f), ColorRGBA.White.mult(0.5f), 50); -// rootNode.addLight(pl1); - - //loadModel("Models/gltf/polly/project_polly.gltf", new Vector3f(0, 0, 0), 0.5f); - //loadModel("Models/gltf/zophrac/scene.gltf", new Vector3f(0, 0, 0), 0.01f); - // loadModel("Models/gltf/scifigirl/scene.gltf", new Vector3f(0, -1, 0), 0.1f); - //loadModel("Models/gltf/man/scene.gltf", new Vector3f(0, -1, 0), 0.1f); - //loadModel("Models/gltf/torus/scene.gltf", new Vector3f(0, -1, 0), 0.1f); - //loadModel("Models/gltf/morph/scene.gltf", new Vector3f(0, 0, 0), 0.2f); -// loadModel("Models/gltf/AnimatedMorphCube/glTF/AnimatedMorphCube.gltf", new Vector3f(0, 0, 0), 1f); -// loadModel("Models/gltf/SimpleMorph/glTF/SimpleMorph.gltf", new Vector3f(0, 0, 0), 0.1f); - //loadModel("Models/gltf/nier/scene.gltf", new Vector3f(0, -1.5f, 0), 0.01f); - //loadModel("Models/gltf/izzy/scene.gltf", new Vector3f(0, -1, 0), 0.01f); - //loadModel("Models/gltf/darth/scene.gltf", new Vector3f(0, -1, 0), 0.01f); - //loadModel("Models/gltf/mech/scene.gltf", new Vector3f(0, -1, 0), 0.01f); - //loadModel("Models/gltf/elephant/scene.gltf", new Vector3f(0, -1, 0), 0.01f); - //loadModel("Models/gltf/buffalo/scene.gltf", new Vector3f(0, -1, 0), 0.1f); - //loadModel("Models/gltf/war/scene.gltf", new Vector3f(0, -1, 0), 0.1f); - //loadModel("Models/gltf/ganjaarl/scene.gltf", new Vector3f(0, -1, 0), 0.01f); - //loadModel("Models/gltf/hero/scene.gltf", new Vector3f(0, -1, 0), 0.1f); - //loadModel("Models/gltf/mercy/scene.gltf", new Vector3f(0, -1, 0), 0.01f); - //loadModel("Models/gltf/crab/scene.gltf", Vector3f.ZERO, 1); - //loadModel("Models/gltf/manta/scene.gltf", Vector3f.ZERO, 0.2f); - //loadModel("Models/gltf/bone/scene.gltf", Vector3f.ZERO, 0.1f); -// loadModel("Models/gltf/box/box.gltf", Vector3f.ZERO, 1); - loadModel("Models/gltf/duck/Duck.gltf", new Vector3f(0, -1, 0), 1); -// loadModel("Models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf", Vector3f.ZERO, 1); -// loadModel("Models/gltf/hornet/scene.gltf", new Vector3f(0, -0.5f, 0), 0.4f); -//// loadModel("Models/gltf/adamHead/adamHead.gltf", Vector3f.ZERO, 0.6f); - //loadModel("Models/gltf/busterDrone/busterDrone.gltf", new Vector3f(0, 0f, 0), 0.8f); -// loadModel("Models/gltf/AnimatedCube/glTF/AnimatedCube.gltf", Vector3f.ZERO, 0.5f); -// loadModel("Models/gltf/BoxAnimated/glTF/BoxAnimated.gltf", new Vector3f(0, 0f, 0), 0.8f); -// loadModel("Models/gltf/RiggedSimple/glTF/RiggedSimple.gltf", new Vector3f(0, -0.3f, 0), 0.2f); -// loadModel("Models/gltf/RiggedFigure/glTF/RiggedFigure.gltf", new Vector3f(0, -1f, 0), 1f); -// loadModel("Models/gltf/CesiumMan/glTF/CesiumMan.gltf", new Vector3f(0, -1, 0), 1f); -// loadModel("Models/gltf/BrainStem/glTF/BrainStem.gltf", new Vector3f(0, -1, 0), 1f); - //loadModel("Models/gltf/Jaime/Jaime.gltf", new Vector3f(0, -1, 0), 1f); - // loadModel("Models/gltf/GiantWorm/GiantWorm.gltf", new Vector3f(0, -1, 0), 1f); - //loadModel("Models/gltf/RiggedFigure/WalkingLady.gltf", new Vector3f(0, -0.f, 0), 1f); - //loadModel("Models/gltf/Monster/Monster.gltf", Vector3f.ZERO, 0.03f); - -// loadModel("Models/gltf/Corset/glTF/Corset.gltf", new Vector3f(0, -1, 0), 20f); -// loadModel("Models/gltf/BoxInterleaved/glTF/BoxInterleaved.gltf", new Vector3f(0, 0, 0), 1f); - - - probeNode.attachChild(assets.get(0)); - - // setMorphTarget(morphIndex); - - ChaseCameraAppState chaseCam = new ChaseCameraAppState(); - chaseCam.setTarget(probeNode); - getStateManager().attach(chaseCam); - chaseCam.setInvertHorizontalAxis(true); - chaseCam.setInvertVerticalAxis(true); - chaseCam.setZoomSpeed(0.5f); - chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); - chaseCam.setRotationSpeed(3); - chaseCam.setDefaultDistance(3); - chaseCam.setDefaultVerticalRotation(0.3f); - - inputManager.addMapping("autorotate", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - useAutoRotate = !useAutoRotate; - } - } - }, "autorotate"); - - inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - playAnim = !playAnim; - if (playAnim) { - playFirstAnim(rootNode); - } else { - stopAnim(rootNode); - } - } - } - }, "toggleAnim"); - inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed && composer != null) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - } - } - }, "nextAnim"); - - dumpScene(rootNode, 0); - - // stateManager.attach(new DetailedProfilerState()); - } - - private T findControl(Spatial s, Class controlClass) { - T ctrl = s.getControl(controlClass); - if (ctrl != null) { - return ctrl; - } - if (s instanceof Node) { - Node n = (Node) s; - for (Spatial spatial : n.getChildren()) { - ctrl = findControl(spatial, controlClass); - if (ctrl != null) { - return ctrl; - } - } - } - return null; - } - - private void loadModel(String path, Vector3f offset, float scale) { - GltfModelKey k = new GltfModelKey(path); - //k.setKeepSkeletonPose(true); - Spatial s = assetManager.loadModel(k); - s.scale(scale); - s.move(offset); - assets.add(s); - if (playAnim) { - playFirstAnim(s); - } - - SkinningControl ctrl = findControl(s, SkinningControl.class); - - // ctrl.getSpatial().removeControl(ctrl); - if (ctrl == null) { - return; - } - //System.err.println(ctrl.getArmature().toString()); - //ctrl.setHardwareSkinningPreferred(false); - // getStateManager().getState(ArmatureDebugAppState.class).addArmatureFrom(ctrl); -// AnimControl aCtrl = findControl(s, AnimControl.class); -// //ctrl.getSpatial().removeControl(ctrl); -// if (aCtrl == null) { -// return; -// } -// if (aCtrl.getArmature() != null) { -// getStateManager().getState(SkeletonDebugAppState.class).addSkeleton(aCtrl.getArmature(), aCtrl.getSpatial(), true); -// } - - } - - final private Queue anims = new LinkedList<>(); - private AnimComposer composer; - - private void playFirstAnim(Spatial s) { - - AnimComposer control = s.getControl(AnimComposer.class); - if (control != null) { - anims.clear(); - for (String name : control.getAnimClipsNames()) { - anims.add(name); - } - if (anims.isEmpty()) { - return; - } - String anim = anims.poll(); - anims.add(anim); - control.setCurrentAction(anim); - composer = control; - } - if (s instanceof Node) { - Node n = (Node) s; - for (Spatial spatial : n.getChildren()) { - playFirstAnim(spatial); - } - } - } - - private void stopAnim(Spatial s) { - - AnimComposer control = s.getControl(AnimComposer.class); - if (control != null) { - control.reset(); - } - if (s instanceof Node) { - Node n = (Node) s; - for (Spatial spatial : n.getChildren()) { - stopAnim(spatial); - } - } - } - - @Override - public void simpleUpdate(float tpf) { - if (!useAutoRotate) { - return; - } - time += tpf; - // autoRotate.rotate(0, tpf * 0.5f, 0); - if (time > duration) { - // morphIndex++; - // setMorphTarget(morphIndex); - assets.get(assetIndex).removeFromParent(); - assetIndex = (assetIndex + 1) % assets.size(); -// if (assetIndex == 0) { -// duration = 10; -// } - probeNode.attachChild(assets.get(assetIndex)); - time = 0; - } - } - - private void dumpScene(Spatial s, int indent) { - System.err.println(indentString.substring(0, indent) + s.getName() + " (" + s.getClass().getSimpleName() + ") / " + - s.getLocalTransform().getTranslation().toString() + ", " + - s.getLocalTransform().getRotation().toString() + ", " + - s.getLocalTransform().getScale().toString()); - if (s instanceof Node) { - Node n = (Node) s; - for (Spatial spatial : n.getChildren()) { - dumpScene(spatial, indent + 1); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/TestHoverTank.java b/jme3-examples/src/main/java/jme3test/model/TestHoverTank.java deleted file mode 100644 index 648f7390df..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/TestHoverTank.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.model; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.ChaseCamera; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.LodControl; -import jme3test.post.BloomUI; - -/** - * - * @author Nehon - */ -public class TestHoverTank extends SimpleApplication { - - public static void main(String[] args) { - TestHoverTank app = new TestHoverTank(); - app.start(); - } - - @Override - public void simpleInitApp() { - Node tank = (Node) assetManager.loadModel("Models/HoverTank/Tank2.mesh.xml"); - - flyCam.setEnabled(false); - ChaseCamera chaseCam = new ChaseCamera(cam, tank, inputManager); - chaseCam.setSmoothMotion(true); - chaseCam.setMaxDistance(100000); - chaseCam.setMinVerticalRotation(-FastMath.PI / 2); - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - Geometry tankGeom = (Geometry) tank.getChild(0); - LodControl control = new LodControl(); - tankGeom.addControl(control); - rootNode.attachChild(tank); - - Vector3f lightDir = new Vector3f(-0.8719428f, -0.46824604f, 0.14304268f); - DirectionalLight dl = new DirectionalLight(); - dl.setColor(new ColorRGBA(1.0f, 0.92f, 0.75f, 1f)); - dl.setDirection(lightDir); - - Vector3f lightDir2 = new Vector3f(0.70518064f, 0.5902297f, -0.39287305f); - DirectionalLight dl2 = new DirectionalLight(); - dl2.setColor(new ColorRGBA(0.7f, 0.85f, 1.0f, 1f)); - dl2.setDirection(lightDir2); - - rootNode.addLight(dl); - rootNode.addLight(dl2); - rootNode.attachChild(tank); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - BloomFilter bf = new BloomFilter(BloomFilter.GlowMode.Objects); - bf.setBloomIntensity(2.0f); - bf.setExposurePower(1.3f); - fpp.addFilter(bf); - BloomUI bui = new BloomUI(inputManager, bf); - viewPort.addProcessor(fpp); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java b/jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java deleted file mode 100644 index f97a71b3c0..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.model; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Sphere; - -public class TestMonkeyHead extends SimpleApplication { - - private float angle; - private PointLight pl; - private Spatial lightMdl; - - public static void main(String[] args){ - TestMonkeyHead app = new TestMonkeyHead(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - Spatial bumpy = assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml"); - rootNode.attachChild(bumpy); - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(lightMdl); - - // fluorescent main light - pl = new PointLight(); - pl.setColor(new ColorRGBA(0.88f, 0.92f, 0.95f, 1.0f)); - rootNode.addLight(pl); - - // sunset light - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal()); - dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f)); - rootNode.addLight(dl); - - // skylight - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal()); - dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f)); - rootNode.addLight(dl); - - // white ambient light - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal()); - dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); - rootNode.addLight(dl); - } - - @Override - public void simpleUpdate(float tpf){ - angle += tpf * 0.25f; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 6f, 3f, FastMath.sin(angle) * 6f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java b/jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java deleted file mode 100644 index fb81e69382..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.ModelKey; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.Rectangle; -import com.jme3.light.AmbientLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Ray; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; - -public class TestObjGroupsLoading extends SimpleApplication { - - public static void main(String[] args) { - TestObjGroupsLoading app = new TestObjGroupsLoading(); - app.start(); - } - - private BitmapText pointerDisplay; - - @Override - public void simpleInitApp() { - - // load scene with following structure: - // Chair 1 (just mesh without name) and named groups: Chair 2, Pillow 2, Podium - Spatial scene = assetManager.loadModel(new ModelKey("OBJLoaderTest/TwoChairs.obj")); - // add light to make it visible - scene.addLight(new AmbientLight(ColorRGBA.White)); - // attach scene to the root - rootNode.attachChild(scene); - - // configure camera for best scene viewing - cam.setLocation(new Vector3f(-3, 4, 3)); - cam.lookAtDirection(new Vector3f(0, -0.5f, -1), Vector3f.UNIT_Y); - flyCam.setMoveSpeed(10); - - // create display to indicate pointed geometry name - pointerDisplay = new BitmapText(guiFont); - pointerDisplay.setBox(new Rectangle(0, settings.getHeight(), settings.getWidth(), settings.getHeight()/2)); - pointerDisplay.setAlignment(BitmapFont.Align.Center); - pointerDisplay.setVerticalAlignment(BitmapFont.VAlign.Center); - guiNode.attachChild(pointerDisplay); - - initCrossHairs(); - } - - @Override - public void simpleUpdate(final float tpf) { - - // ray to the center of the screen from the camera - Ray ray = new Ray(cam.getLocation(), cam.getDirection()); - - // find object at the center of the screen - - final CollisionResults results = new CollisionResults(); - rootNode.collideWith(ray, results); - - CollisionResult result = results.getClosestCollision(); - if (result == null) { - pointerDisplay.setText(""); - } else { - // display pointed geometry and it's parents names - StringBuilder sb = new StringBuilder(); - for (Spatial node = result.getGeometry(); node != null; node = node.getParent()) { - if (sb.length() > 0) { - sb.append(" < "); - } - sb.append(node.getName()); - } - pointerDisplay.setText(sb); - } - } - - private void initCrossHairs() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, - settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); - guiNode.attachChild(ch); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/TestObjLoading.java b/jme3-examples/src/main/java/jme3test/model/TestObjLoading.java deleted file mode 100644 index 2788f12891..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/TestObjLoading.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.model; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; - -/** - * Tests OBJ format loading - */ -public class TestObjLoading extends SimpleApplication { - - public static void main(String[] args){ - TestObjLoading app = new TestObjLoading(); - app.start(); - } - - @Override - public void simpleInitApp() { - // create the geometry and attach it - Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - - // show normals as material - Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - teaGeom.setMaterial(mat); - - rootNode.attachChild(teaGeom); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java b/jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java deleted file mode 100644 index c3bc78f479..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.light.PointLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Sphere; - -public class TestOgreLoading extends SimpleApplication { - - private float angle1; - private float angle2; - private PointLight pl; - private PointLight p2; - private Spatial lightMdl; - private Spatial lightMd2; - - public static void main(String[] args) { - TestOgreLoading app = new TestOgreLoading(); - app.start(); - } - - @Override - public void simpleInitApp() { -// PointLight pl = new PointLight(); -// pl.setPosition(new Vector3f(10, 10, -10)); -// rootNode.addLight(pl); - flyCam.setMoveSpeed(10f); - - // sunset light - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, 1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - - - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(lightMdl); - - lightMd2 = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMd2.setMaterial(assetManager.loadMaterial("Common/Materials/WhiteColor.j3m")); - rootNode.attachChild(lightMd2); - - - pl = new PointLight(); - pl.setColor(new ColorRGBA(1, 0.9f, 0.9f, 0)); - pl.setPosition(new Vector3f(0f, 0f, 4f)); - rootNode.addLight(pl); - - p2 = new PointLight(); - p2.setColor(new ColorRGBA(0.9f, 1, 0.9f, 0)); - p2.setPosition(new Vector3f(0f, 0f, 3f)); - rootNode.addLight(p2); - - - // create the geometry and attach it - Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml"); - float scale = 0.05f; - elephant.scale(scale, scale, scale); - rootNode.attachChild(elephant); - } - - @Override - public void simpleUpdate(float tpf) { - angle1 += tpf * 0.25f; - angle1 %= FastMath.TWO_PI; - - angle2 += tpf * 0.50f; - angle2 %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle1) * 4f, 0.5f, FastMath.sin(angle1) * 4f)); - p2.setPosition(new Vector3f(FastMath.cos(angle2) * 4f, 0.5f, FastMath.sin(angle2) * 4f)); - lightMdl.setLocalTranslation(pl.getPosition()); - lightMd2.setLocalTranslation(p2.getPosition()); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java b/jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java deleted file mode 100644 index 6e7b1ee82d..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.system.Timer; - -/** - * @author Nehon - */ -public class EraseTimer extends Timer { - - - //private static final long TIMER_RESOLUTION = 1000L; - //private static final float INVERSE_TIMER_RESOLUTION = 1f/1000L; - private static final long TIMER_RESOLUTION = 1000000000L; - private static final float INVERSE_TIMER_RESOLUTION = 1f / 1000000000L; - - private long startTime; - private long previousTime; - private float tpf; - private float fps; - - public EraseTimer() { - //startTime = System.currentTimeMillis(); - startTime = System.nanoTime(); - } - - /** - * Returns the time in seconds. The timer starts - * at 0.0 seconds. - * - * @return the current time in seconds - */ - @Override - public float getTimeInSeconds() { - return getTime() * INVERSE_TIMER_RESOLUTION; - } - - @Override - public long getTime() { - //return System.currentTimeMillis() - startTime; - return System.nanoTime() - startTime; - } - - @Override - public long getResolution() { - return TIMER_RESOLUTION; - } - - @Override - public float getFrameRate() { - return fps; - } - - @Override - public float getTimePerFrame() { - return tpf; - } - - @Override - public void update() { - tpf = (getTime() - previousTime) * (1.0f / TIMER_RESOLUTION); - if (tpf >= 0.2) { - // The frame lasted more than 200ms, so we erase its time to 16ms. - tpf = 0.016666f; - } else { - fps = 1.0f / tpf; - } - previousTime = getTime(); - } - - @Override - public void reset() { - //startTime = System.currentTimeMillis(); - startTime = System.nanoTime(); - previousTime = getTime(); - } - - -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java deleted file mode 100644 index 18b09edbf2..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2017-2022 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.*; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.*; -import com.jme3.anim.util.AnimMigrationUtils; -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.*; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.debug.custom.ArmatureDebugAppState; - -import java.util.LinkedList; - -/** - * Created by Nehon on 18/12/2017. - */ -public class TestAnimMigration extends SimpleApplication { - - private ArmatureDebugAppState debugAppState; - private AnimComposer composer; - final private LinkedList anims = new LinkedList<>(); - private boolean playAnim = false; - private BlendAction action; - private float blendValue = 1f; - - public static void main(String... argv) { - TestAnimMigration app = new TestAnimMigration(); - app.start(); - } - - @Override - public void simpleInitApp() { - setTimer(new EraseTimer()); - cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.1f, 100f); - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); - rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); - - Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); - // Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml").scale(0.2f).move(0, 1, 0); - //Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); - //Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml").scale(0.02f); - - AnimMigrationUtils.migrate(model); - - rootNode.attachChild(model); - - - debugAppState = new ArmatureDebugAppState(); - stateManager.attach(debugAppState); - - setupModel(model); - - flyCam.setEnabled(false); - - Node target = new Node("CamTarget"); - //target.setLocalTransform(model.getLocalTransform()); - target.move(0, 1, 0); - ChaseCameraAppState chaseCam = new ChaseCameraAppState(); - chaseCam.setTarget(target); - getStateManager().attach(chaseCam); - chaseCam.setInvertHorizontalAxis(true); - chaseCam.setInvertVerticalAxis(true); - chaseCam.setZoomSpeed(0.5f); - chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); - chaseCam.setRotationSpeed(3); - chaseCam.setDefaultDistance(3); - chaseCam.setMinDistance(0.01f); - chaseCam.setZoomSpeed(0.01f); - chaseCam.setDefaultVerticalRotation(0.3f); - - initInputs(); - } - - public void initInputs() { - inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - playAnim = !playAnim; - if (playAnim) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } else { - composer.reset(); - } - } - } - }, "toggleAnim"); - inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed && composer != null) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } - } - }, "nextAnim"); - inputManager.addMapping("toggleArmature", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - debugAppState.setEnabled(!debugAppState.isEnabled()); - } - } - }, "toggleArmature"); - - inputManager.addMapping("mask", new KeyTrigger(KeyInput.KEY_M)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - ((BlendableAction)composer.setCurrentAction("Wave", "LeftArm", false)).setMaxTransitionWeight(0.9); - } - } - - }, "mask"); - - inputManager.addMapping("blendUp", new KeyTrigger(KeyInput.KEY_UP)); - inputManager.addMapping("blendDown", new KeyTrigger(KeyInput.KEY_DOWN)); - - inputManager.addListener(new AnalogListener() { - - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("blendUp")) { - blendValue += value; - blendValue = FastMath.clamp(blendValue, 1, 4); - action.getBlendSpace().setValue(blendValue); - //action.setSpeed(blendValue); - } - if (name.equals("blendDown")) { - blendValue -= value; - blendValue = FastMath.clamp(blendValue, 1, 4); - action.getBlendSpace().setValue(blendValue); - //action.setSpeed(blendValue); - } - //System.err.println(blendValue); - } - }, "blendUp", "blendDown"); - - inputManager.addMapping("maxTransitionWeightInc", new KeyTrigger(KeyInput.KEY_ADD)); - inputManager.addMapping("maxTransitionWeightDec", new KeyTrigger(KeyInput.KEY_SUBTRACT)); - - inputManager.addListener(new AnalogListener() { - - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("maxTransitionWeightInc")) { - Action action = composer.getCurrentAction(); - if (action instanceof BlendableAction) { - BlendableAction ba = (BlendableAction) action; - ba.setMaxTransitionWeight(Math.min(ba.getMaxTransitionWeight() + 0.01, 1.0)); - System.out.println("MaxTransitionWeight=" + ba.getMaxTransitionWeight()); - } - } - if (name.equals("maxTransitionWeightDec")) { - Action action = composer.getCurrentAction(); - if (action instanceof BlendableAction) { - BlendableAction ba = (BlendableAction) action; - ba.setMaxTransitionWeight(Math.max(ba.getMaxTransitionWeight() - 0.01, 0.0)); - System.out.println("MaxTransitionWeight=" + ba.getMaxTransitionWeight()); - } - } - //System.err.println(blendValue); - } - }, "maxTransitionWeightInc", "maxTransitionWeightDec"); - } - - private void setupModel(Spatial model) { - if (composer != null) { - return; - } - composer = model.getControl(AnimComposer.class); - if (composer != null) { - - SkinningControl sc = model.getControl(SkinningControl.class); - debugAppState.addArmatureFrom(sc); - - anims.clear(); - for (String name : composer.getAnimClipsNames()) { - anims.add(name); - } - composer.actionSequence("Sequence1", - composer.makeAction("Walk"), - composer.makeAction("Run"), - composer.makeAction("Jumping")).setSpeed(1); - - composer.actionSequence("Sequence2", - composer.makeAction("Walk"), - composer.makeAction("Run"), - composer.makeAction("Jumping")).setSpeed(-1); - - action = composer.actionBlended("Blend", new LinearBlendSpace(1, 4), - "Walk", "Run"); - - action.getBlendSpace().setValue(1); - - composer.action("Walk").setSpeed(-1); - - composer.addAction("WalkCycle", new BaseAction(Tweens.cycle(composer.makeAction("Walk")))); - - composer.makeLayer("LeftArm", ArmatureMask.createMask(sc.getArmature(), "shoulder.L")); - - anims.addFirst("WalkCycle"); - anims.addFirst("Blend"); - anims.addFirst("Sequence2"); - anims.addFirst("Sequence1"); - - if (anims.isEmpty()) { - return; - } - if (playAnim) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } - - } else { - if (model instanceof Node) { - Node n = (Node) model; - for (Spatial child : n.getChildren()) { - setupModel(child); - } - } - } - - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java deleted file mode 100644 index 30306429da..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2017-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.*; -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.FileLocator; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.math.*; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.debug.custom.ArmatureDebugAppState; -import com.jme3.system.JmeSystem; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedList; -import java.util.Queue; - -/** - * Created by Nehon on 18/12/2017. - */ -public class TestAnimMorphSerialization extends SimpleApplication { - - private ArmatureDebugAppState debugAppState; - private AnimComposer composer; - final private Queue anims = new LinkedList<>(); - private boolean playAnim = true; - private File file; - - public static void main(String... argv) { - TestAnimMorphSerialization app = new TestAnimMorphSerialization(); - app.start(); - } - - @Override - public void simpleInitApp() { - setTimer(new EraseTimer()); - //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - //rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); - //rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); - Node probeNode = (Node) assetManager.loadModel("Scenes/defaultProbe.j3o"); - rootNode.attachChild(probeNode); - Spatial model = assetManager.loadModel("Models/gltf/zophrac/scene.gltf"); - - File storageFolder = JmeSystem.getStorageFolder(); - file = new File(storageFolder.getPath() + File.separator + "zophrac.j3o"); - BinaryExporter be = new BinaryExporter(); - try { - be.save(model, file); - } catch (IOException e) { - e.printStackTrace(); - } - - assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); - Spatial model2 = assetManager.loadModel("zophrac.j3o"); - model2.setLocalScale(0.1f); - probeNode.attachChild(model2); - - debugAppState = new ArmatureDebugAppState(); - stateManager.attach(debugAppState); - - setupModel(model2); - - flyCam.setEnabled(false); - - Node target = new Node("CamTarget"); - //target.setLocalTransform(model.getLocalTransform()); - target.move(0, 0, 0); - ChaseCameraAppState chaseCam = new ChaseCameraAppState(); - chaseCam.setTarget(target); - getStateManager().attach(chaseCam); - chaseCam.setInvertHorizontalAxis(true); - chaseCam.setInvertVerticalAxis(true); - chaseCam.setZoomSpeed(0.5f); - chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); - chaseCam.setRotationSpeed(3); - chaseCam.setDefaultDistance(3); - chaseCam.setMinDistance(0.01f); - chaseCam.setZoomSpeed(0.01f); - chaseCam.setDefaultVerticalRotation(0.3f); - - initInputs(); - } - - public void initInputs() { - inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - playAnim = !playAnim; - if (playAnim) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } else { - composer.reset(); - } - } - } - }, "toggleAnim"); - inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed && composer != null) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } - } - }, "nextAnim"); - } - - private void setupModel(Spatial model) { - if (composer != null) { - return; - } - composer = model.getControl(AnimComposer.class); - if (composer != null) { -// model.getControl(SkinningControl.class).setEnabled(false); -// model.getControl(MorphControl.class).setEnabled(false); -// composer.setEnabled(false); - - - SkinningControl sc = model.getControl(SkinningControl.class); - debugAppState.addArmatureFrom(sc); - - anims.clear(); - for (String name : composer.getAnimClipsNames()) { - anims.add(name); - } - if (anims.isEmpty()) { - return; - } - if (playAnim) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } - - } else { - if (model instanceof Node) { - Node n = (Node) model; - for (Spatial child : n.getChildren()) { - setupModel(child); - } - } - } - - } - - - @Override - public void destroy() { - super.destroy(); - file.delete(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java deleted file mode 100644 index 512946bd01..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2017-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.SkinningControl; -import com.jme3.anim.util.AnimMigrationUtils; -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.FileLocator; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.*; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.debug.custom.ArmatureDebugAppState; -import com.jme3.system.JmeSystem; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedList; -import java.util.Queue; - -/** - * Created by Nehon on 18/12/2017. - */ -public class TestAnimSerialization extends SimpleApplication { - - private ArmatureDebugAppState debugAppState; - private AnimComposer composer; - final private Queue anims = new LinkedList<>(); - private boolean playAnim = true; - private File file; - - public static void main(String... argv) { - TestAnimSerialization app = new TestAnimSerialization(); - app.start(); - } - - @Override - public void simpleInitApp() { - setTimer(new EraseTimer()); - //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); - rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); - - Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); - - AnimMigrationUtils.migrate(model); - - File storageFolder = JmeSystem.getStorageFolder(); - file = new File(storageFolder.getPath() + File.separator + "newJaime.j3o"); - BinaryExporter be = new BinaryExporter(); - try { - be.save(model, file); - } catch (IOException e) { - e.printStackTrace(); - } - - assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); - model = assetManager.loadModel("newJaime.j3o"); - - rootNode.attachChild(model); - - debugAppState = new ArmatureDebugAppState(); - stateManager.attach(debugAppState); - - setupModel(model); - - flyCam.setEnabled(false); - - Node target = new Node("CamTarget"); - //target.setLocalTransform(model.getLocalTransform()); - target.move(0, 1, 0); - ChaseCameraAppState chaseCam = new ChaseCameraAppState(); - chaseCam.setTarget(target); - getStateManager().attach(chaseCam); - chaseCam.setInvertHorizontalAxis(true); - chaseCam.setInvertVerticalAxis(true); - chaseCam.setZoomSpeed(0.5f); - chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); - chaseCam.setRotationSpeed(3); - chaseCam.setDefaultDistance(3); - chaseCam.setMinDistance(0.01f); - chaseCam.setZoomSpeed(0.01f); - chaseCam.setDefaultVerticalRotation(0.3f); - - initInputs(); - } - - public void initInputs() { - inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - playAnim = !playAnim; - if (playAnim) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } else { - composer.reset(); - } - } - } - }, "toggleAnim"); - inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed && composer != null) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } - } - }, "nextAnim"); - } - - private void setupModel(Spatial model) { - if (composer != null) { - return; - } - composer = model.getControl(AnimComposer.class); - if (composer != null) { - - SkinningControl sc = model.getControl(SkinningControl.class); - - debugAppState.addArmatureFrom(sc); - anims.clear(); - for (String name : composer.getAnimClipsNames()) { - anims.add(name); - } - if (anims.isEmpty()) { - return; - } - if (playAnim) { - String anim = anims.poll(); - anims.add(anim); - composer.setCurrentAction(anim); - System.err.println(anim); - } - - } else { - if (model instanceof Node) { - Node n = (Node) model; - for (Spatial child : n.getChildren()) { - setupModel(child); - } - } - } - - } - - - @Override - public void destroy() { - super.destroy(); - file.delete(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java deleted file mode 100644 index e09500e248..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -package jme3test.model.anim; - -import com.jme3.anim.AnimClip; -import com.jme3.anim.AnimComposer; -import com.jme3.anim.AnimFactory; -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; -import com.jme3.util.TangentBinormalGenerator; - -public class TestAnimationFactory extends SimpleApplication { - - public static void main(String[] args) { - TestAnimationFactory app = new TestAnimationFactory(); - app.start(); - } - - @Override - public void simpleInitApp() { - - AmbientLight al = new AmbientLight(); - rootNode.addLight(al); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(Vector3f.UNIT_XYZ.negate()); - rootNode.addLight(dl); - - // Create model - Box box = new Box(1, 1, 1); - Geometry geom = new Geometry("box", box); - geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); - Node model = new Node("model"); - model.attachChild(geom); - - Box child = new Box(0.5f, 0.5f, 0.5f); - Geometry childGeom = new Geometry("box", child); - childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); - Node childModel = new Node("child model"); - childModel.setLocalTranslation(2, 2, 2); - childModel.attachChild(childGeom); - model.attachChild(childModel); - TangentBinormalGenerator.generate(model); - - // Construct a complex animation using AnimFactory: - // 6 seconds in duration, named "anim", running at 25 frames per second - AnimFactory animationFactory = new AnimFactory(6f, "anim", 25f); - - // Create a translation keyFrame at time = 3 with a translation on the X axis of 5 WU. - animationFactory.addTimeTranslation(3, new Vector3f(5, 0, 0)); - //resetting the translation to the start position at time = 6 - animationFactory.addTimeTranslation(6, new Vector3f(0, 0, 0)); - - //Creating a scale keyFrame at time = 2 with the unit scale. - animationFactory.addTimeScale(2, new Vector3f(1, 1, 1)); - //Creating a scale keyFrame at time = 4 scaling to 1.5 - animationFactory.addTimeScale(4, new Vector3f(1.5f, 1.5f, 1.5f)); - //resetting the scale to the start value at time = 5 - animationFactory.addTimeScale(5, new Vector3f(1, 1, 1)); - - - //Creating a rotation keyFrame at time = 0.5 of quarter PI around the Z axis - animationFactory.addTimeRotation(0.5f,new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Z)); - //rotating back to initial rotation value at time = 1 - animationFactory.addTimeRotation(1,Quaternion.IDENTITY); - /* - * Perform a 360-degree rotation around the X axis between t=1 and t=2. - */ - for (int i = 1; i <= 3; ++i) { - float rotTime = i / 3f; - float xAngle = FastMath.TWO_PI * rotTime; - animationFactory.addTimeRotation(1f + rotTime, xAngle, 0f, 0f); - } - - AnimClip clip = animationFactory.buildAnimation(model); - AnimComposer control = new AnimComposer(); - control.addAnimClip(clip); - model.addControl(control); - - rootNode.attachChild(model); - - //run animation - control.setCurrentAction("anim"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java b/jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java deleted file mode 100644 index 6c71144286..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2017-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.*; -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.scene.*; -import com.jme3.scene.debug.custom.ArmatureDebugAppState; -import com.jme3.scene.shape.Cylinder; - -import java.nio.FloatBuffer; -import java.nio.ShortBuffer; - -/** - * Created by Nehon on 18/12/2017. - */ -public class TestArmature extends SimpleApplication { - - public static void main(String... argv) { - TestArmature app = new TestArmature(); - app.start(); - } - - @Override - public void simpleInitApp() { - setTimer(new EraseTimer()); - renderManager.setSinglePassLightBatchSize(2); - //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - //create armature - Joint root = new Joint("Root_Joint"); - Joint j1 = new Joint("Joint_1"); - Joint j2 = new Joint("Joint_2"); - Joint j3 = new Joint("Joint_3"); - root.addChild(j1); - j1.addChild(j2); - j2.addChild(j3); - root.setLocalTranslation(new Vector3f(0, 0, 0.5f)); - j1.setLocalTranslation(new Vector3f(0, 0.0f, -0.5f)); - j2.setLocalTranslation(new Vector3f(0, 0.0f, -0.3f)); - j3.setLocalTranslation(new Vector3f(0, 0, -0.2f)); - Joint[] joints = new Joint[]{root, j1, j2, j3}; - - final Armature armature = new Armature(joints); - //armature.setModelTransformClass(SeparateJointModelTransform.class); - armature.saveBindPose(); - - //create animations - AnimClip clip = new AnimClip("anim"); - float[] times = new float[]{0, 2, 4}; - Quaternion[] rotations = new Quaternion[]{ - new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X), - new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X), - new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X) - }; - Vector3f[] translations = new Vector3f[]{ - new Vector3f(0, 0.2f, 0), - new Vector3f(0, 1.0f, 0), - new Vector3f(0, 0.2f, 0), - }; - Vector3f[] scales = new Vector3f[]{ - new Vector3f(1, 1, 1), - new Vector3f(1, 1, 2), - new Vector3f(1, 1, 1), - }; - Vector3f[] scales2 = new Vector3f[]{ - new Vector3f(1, 1, 1), - new Vector3f(1, 1, 0.5f), - new Vector3f(1, 1, 1), - }; - - TransformTrack track1 = new TransformTrack(j1, times, null, rotations, scales); - TransformTrack track2 = new TransformTrack(j2, times, null, rotations, null); - - clip.setTracks(new TransformTrack[]{track1, track2}); - - //create the animComposer control - final AnimComposer composer = new AnimComposer(); - composer.addAnimClip(clip); - - //create the SkinningControl - SkinningControl ac = new SkinningControl(armature); - ac.setHardwareSkinningPreferred(false); - Node node = new Node("Test Armature"); - - rootNode.attachChild(node); - - //Create the mesh to deform. - Geometry cylinder = new Geometry("cylinder", createMesh()); - Material m = new Material(assetManager, "Common/MatDefs/Misc/fakeLighting.j3md"); - m.setColor("Color", ColorRGBA.randomColor()); - cylinder.setMaterial(m); - node.attachChild(cylinder); - node.addControl(composer); - node.addControl(ac); - - composer.setCurrentAction("anim"); - - ArmatureDebugAppState debugAppState = new ArmatureDebugAppState(); - debugAppState.addArmatureFrom(ac); - stateManager.attach(debugAppState); - - flyCam.setEnabled(false); - - ChaseCameraAppState chaseCam = new ChaseCameraAppState(); - chaseCam.setTarget(node); - getStateManager().attach(chaseCam); - chaseCam.setInvertHorizontalAxis(true); - chaseCam.setInvertVerticalAxis(true); - chaseCam.setZoomSpeed(0.5f); - chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); - chaseCam.setRotationSpeed(3); - chaseCam.setDefaultDistance(3); - chaseCam.setMinDistance(0.01f); - chaseCam.setZoomSpeed(0.01f); - chaseCam.setDefaultVerticalRotation(0.3f); - - - inputManager.addMapping("bind", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - composer.reset(); - armature.applyBindPose(); - - } else { - composer.setCurrentAction("anim"); - } - } - }, "bind"); - } - - private Mesh createMesh() { - Cylinder c = new Cylinder(30, 16, 0.1f, 1, true); - - ShortBuffer jointIndex = (ShortBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.UnsignedShort, 4, c.getVertexCount()); - jointIndex.rewind(); - c.setMaxNumWeights(1); - FloatBuffer jointWeight = (FloatBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.Float, 4, c.getVertexCount()); - jointWeight.rewind(); - VertexBuffer vb = c.getBuffer(VertexBuffer.Type.Position); - FloatBuffer fvb = (FloatBuffer) vb.getData(); - fvb.rewind(); - for (int i = 0; i < c.getVertexCount(); i++) { - fvb.get(); - fvb.get(); - float z = fvb.get(); - int index = 0; - if (z > 0) { - index = 0; - } else if (z > -0.2) { - index = 1; - } else { - index = 2; - } - jointIndex.put((short) index).put((short) 0).put((short) 0).put((short) 0); - jointWeight.put(1f).put(0f).put(0f).put(0f); - - } - c.setBuffer(VertexBuffer.Type.BoneIndex, 4, jointIndex); - c.setBuffer(VertexBuffer.Type.BoneWeight, 4, jointWeight); - - c.updateCounts(); - c.updateBound(); - - VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight); - VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex); - - indicesHW.setUsage(VertexBuffer.Usage.CpuOnly); - weightsHW.setUsage(VertexBuffer.Usage.CpuOnly); - c.setBuffer(weightsHW); - c.setBuffer(indicesHW); - c.generateBindPose(); - - c.prepareForAnim(false); - - return c; - } - - -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java deleted file mode 100644 index 78d81f558c..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.SkinningControl; -import com.jme3.anim.tween.Tween; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.Action; -import com.jme3.anim.util.AnimMigrationUtils; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; - -/** - * Simple application to test an attachments node on the Jaime model. - * - * Derived from {@link jme3test.model.anim.TestOgreAnim}. - */ -public class TestAttachmentsNode extends SimpleApplication - implements ActionListener { - - private Action punchesOnce; - private AnimComposer control; - - public static void main(String[] args) { - TestAttachmentsNode app = new TestAttachmentsNode(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10f); - cam.setLocation(new Vector3f(6.4f, 7.5f, 12.8f)); - cam.setRotation(new Quaternion(-0.060740203f, 0.93925786f, -0.2398315f, -0.2378785f)); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(ColorRGBA.White); - rootNode.addLight(dl); - /* - * Load the Jaime model and convert it - * from the old animation system to the new one. - */ - Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); - AnimMigrationUtils.migrate(model); - /* - * Play the "Idle" animation at half speed. - */ - control = model.getControl(AnimComposer.class); - control.setCurrentAction("Idle"); - control.setGlobalSpeed(0.5f); - /* - * Define a "PunchesOnce" action sequence to play the "Punches" - * animation for one cycle before returning to idle. - */ - Action punches = control.action("Punches"); - Tween doneTween - = Tweens.callMethod(control, "setCurrentAction", "Idle"); - punchesOnce = control.actionSequence("PunchesOnce", punches, doneTween); - - model.center(); - model.setLocalScale(5f); - - Box box = new Box(0.3f, 0.02f, 0.02f); - Geometry saber = new Geometry("saber", box); - saber.move(0.4f, 0.05f, 0.01f); - Material red = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); - saber.setMaterial(red); - /* - * Create an attachments node for Jaime's right hand, - * and attach the saber to that Node. - */ - SkinningControl skeletonControl = model.getControl(SkinningControl.class); - Node n = skeletonControl.getAttachmentsNode("hand.R"); - n.attachChild(saber); - rootNode.attachChild(model); - - inputManager.addListener(this, "Attack"); - inputManager.addMapping("Attack", new KeyTrigger(KeyInput.KEY_SPACE)); - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (value && binding.equals("Attack") - && control.getCurrentAction() != punchesOnce) { - control.setCurrentAction("PunchesOnce"); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java b/jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java deleted file mode 100644 index 5a5934142c..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2017-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.*; -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.FileLocator; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.scene.*; -import com.jme3.scene.debug.custom.ArmatureDebugAppState; -import com.jme3.scene.shape.Cylinder; -import com.jme3.system.JmeSystem; - -import java.io.File; -import java.io.IOException; -import java.nio.FloatBuffer; -import java.nio.ShortBuffer; - -/** - * Created by Nehon on 18/12/2017. - */ -public class TestBaseAnimSerialization extends SimpleApplication { - - private AnimComposer composer; - private Armature armature; - private File file; - - public static void main(String... argv) { - TestBaseAnimSerialization app = new TestBaseAnimSerialization(); - app.start(); - } - - @Override - public void simpleInitApp() { - setTimer(new EraseTimer()); - renderManager.setSinglePassLightBatchSize(2); - //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - //create armature - Joint root = new Joint("Root_Joint"); - Joint j1 = new Joint("Joint_1"); - Joint j2 = new Joint("Joint_2"); - Joint j3 = new Joint("Joint_3"); - root.addChild(j1); - j1.addChild(j2); - j2.addChild(j3); - root.setLocalTranslation(new Vector3f(0, 0, 0.5f)); - j1.setLocalTranslation(new Vector3f(0, 0.0f, -0.5f)); - j2.setLocalTranslation(new Vector3f(0, 0.0f, -0.3f)); - j3.setLocalTranslation(new Vector3f(0, 0, -0.2f)); - Joint[] joints = new Joint[]{root, j1, j2, j3}; - - armature = new Armature(joints); - //armature.setModelTransformClass(SeparateJointModelTransform.class); - armature.saveBindPose(); - - //create animations - AnimClip clip = new AnimClip("anim"); - float[] times = new float[]{0, 2, 4}; - Quaternion[] rotations = new Quaternion[]{ - new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X), - new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X), - new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X) - }; - Vector3f[] translations = new Vector3f[]{ - new Vector3f(0, 0.2f, 0), - new Vector3f(0, 1.0f, 0), - new Vector3f(0, 0.2f, 0), - }; - Vector3f[] scales = new Vector3f[]{ - new Vector3f(1, 1, 1), - new Vector3f(1, 1, 2), - new Vector3f(1, 1, 1), - }; - Vector3f[] scales2 = new Vector3f[]{ - new Vector3f(1, 1, 1), - new Vector3f(1, 1, 0.5f), - new Vector3f(1, 1, 1), - }; - - TransformTrack track1 = new TransformTrack(j1, times, null, rotations, scales); - TransformTrack track2 = new TransformTrack(j2, times, null, rotations, null); - - clip.setTracks(new TransformTrack[]{track1, track2}); - - //create the animComposer control - composer = new AnimComposer(); - composer.addAnimClip(clip); - - //create the SkinningControl - SkinningControl ac = new SkinningControl(armature); - Node node = new Node("Test Armature"); - - //Create the mesh to deform. - Geometry cylinder = new Geometry("cylinder", createMesh()); - Material m = new Material(assetManager, "Common/MatDefs/Misc/fakeLighting.j3md"); - m.setColor("Color", ColorRGBA.randomColor()); - cylinder.setMaterial(m); - node.attachChild(cylinder); - node.addControl(composer); - node.addControl(ac); - - File storageFolder = JmeSystem.getStorageFolder(); - file = new File(storageFolder.getPath() + File.separator + "test.j3o"); - BinaryExporter be = new BinaryExporter(); - try { - be.save(node, file); - } catch (IOException e) { - e.printStackTrace(); - } - - assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); - Node newNode = (Node) assetManager.loadModel("test.j3o"); - - rootNode.attachChild(newNode); - - composer = newNode.getControl(AnimComposer.class); - ac = newNode.getControl(SkinningControl.class); - ac.setHardwareSkinningPreferred(false); - armature = ac.getArmature(); - composer.setCurrentAction("anim"); - - ArmatureDebugAppState debugAppState = new ArmatureDebugAppState(); - debugAppState.addArmatureFrom(ac); - stateManager.attach(debugAppState); - - flyCam.setEnabled(false); - - ChaseCameraAppState chaseCam = new ChaseCameraAppState(); - chaseCam.setTarget(node); - getStateManager().attach(chaseCam); - chaseCam.setInvertHorizontalAxis(true); - chaseCam.setInvertVerticalAxis(true); - chaseCam.setZoomSpeed(0.5f); - chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); - chaseCam.setRotationSpeed(3); - chaseCam.setDefaultDistance(3); - chaseCam.setMinDistance(0.01f); - chaseCam.setZoomSpeed(0.01f); - chaseCam.setDefaultVerticalRotation(0.3f); - - - inputManager.addMapping("bind", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - composer.reset(); - armature.applyBindPose(); - - } else { - composer.setCurrentAction("anim"); - } - } - }, "bind"); - } - - private Mesh createMesh() { - Cylinder c = new Cylinder(30, 16, 0.1f, 1, true); - - ShortBuffer jointIndex = (ShortBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.UnsignedShort, 4, c.getVertexCount()); - jointIndex.rewind(); - c.setMaxNumWeights(1); - FloatBuffer jointWeight = (FloatBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.Float, 4, c.getVertexCount()); - jointWeight.rewind(); - VertexBuffer vb = c.getBuffer(VertexBuffer.Type.Position); - FloatBuffer fvb = (FloatBuffer) vb.getData(); - fvb.rewind(); - for (int i = 0; i < c.getVertexCount(); i++) { - fvb.get(); - fvb.get(); - float z = fvb.get(); - int index = 0; - if (z > 0) { - index = 0; - } else if (z > -0.2) { - index = 1; - } else { - index = 2; - } - jointIndex.put((short) index).put((short) 0).put((short) 0).put((short) 0); - jointWeight.put(1f).put(0f).put(0f).put(0f); - - } - c.setBuffer(VertexBuffer.Type.BoneIndex, 4, jointIndex); - c.setBuffer(VertexBuffer.Type.BoneWeight, 4, jointWeight); - - c.updateCounts(); - c.updateBound(); - - VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight); - VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex); - - indicesHW.setUsage(VertexBuffer.Usage.CpuOnly); - weightsHW.setUsage(VertexBuffer.Usage.CpuOnly); - c.setBuffer(weightsHW); - c.setBuffer(indicesHW); - c.generateBindPose(); - - c.prepareForAnim(false); - - return c; - } - - @Override - public void destroy() { - super.destroy(); - file.delete(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java deleted file mode 100644 index 6c4b230f01..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.model.anim; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; - -import com.jme3.anim.Armature; -import com.jme3.anim.Joint; -import com.jme3.anim.SkinningControl; -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.Quaternion; -import com.jme3.math.Transform; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.VertexBuffer.Format; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.scene.VertexBuffer.Usage; -import com.jme3.scene.shape.Box; - -public class TestCustomAnim extends SimpleApplication { - - private Joint bone; - private Armature armature; - final private Quaternion rotation = new Quaternion(); - - public static void main(String[] args) { - TestCustomAnim app = new TestCustomAnim(); - app.start(); - } - - @Override - public void simpleInitApp() { - - AmbientLight al = new AmbientLight(); - rootNode.addLight(al); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(Vector3f.UNIT_XYZ.negate()); - rootNode.addLight(dl); - - Box box = new Box(1, 1, 1); - - VertexBuffer weightsHW = new VertexBuffer(Type.HWBoneWeight); - VertexBuffer indicesHW = new VertexBuffer(Type.HWBoneIndex); - indicesHW.setUsage(Usage.CpuOnly); - weightsHW.setUsage(Usage.CpuOnly); - box.setBuffer(weightsHW); - box.setBuffer(indicesHW); - - // Setup bone weight buffer - FloatBuffer weights = FloatBuffer.allocate(box.getVertexCount() * 4); - VertexBuffer weightsBuf = new VertexBuffer(Type.BoneWeight); - weightsBuf.setupData(Usage.CpuOnly, 4, Format.Float, weights); - box.setBuffer(weightsBuf); - - // Setup bone index buffer - ByteBuffer indices = ByteBuffer.allocate(box.getVertexCount() * 4); - VertexBuffer indicesBuf = new VertexBuffer(Type.BoneIndex); - indicesBuf.setupData(Usage.CpuOnly, 4, Format.UnsignedByte, indices); - box.setBuffer(indicesBuf); - - // Create bind pose buffers - box.generateBindPose(); - - // Create skeleton - bone = new Joint("root"); - bone.setLocalTransform(new Transform(Vector3f.ZERO, Quaternion.IDENTITY, Vector3f.UNIT_XYZ)); - armature = new Armature(new Joint[] { bone }); - - // Assign all vertices to bone 0 with weight 1 - for (int i = 0; i < box.getVertexCount() * 4; i += 4) { - // assign vertex to bone index 0 - indices.array()[i + 0] = 0; - indices.array()[i + 1] = 0; - indices.array()[i + 2] = 0; - indices.array()[i + 3] = 0; - - // set weight to 1 only for first entry - weights.array()[i + 0] = 1; - weights.array()[i + 1] = 0; - weights.array()[i + 2] = 0; - weights.array()[i + 3] = 0; - } - - // Maximum number of weights per bone is 1 - box.setMaxNumWeights(1); - - // Create model - Geometry geom = new Geometry("box", box); - geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); - Node model = new Node("model"); - model.attachChild(geom); - - // Create skeleton control - SkinningControl skinningControl = new SkinningControl(armature); - model.addControl(skinningControl); - - rootNode.attachChild(model); - } - - @Override - public void simpleUpdate(float tpf) { - // Rotate around X axis - Quaternion rotate = new Quaternion(); - rotate.fromAngleAxis(tpf, Vector3f.UNIT_X); - - // Combine rotation with previous - rotation.multLocal(rotate); - - // Set new rotation into bone - bone.setLocalTransform(new Transform(Vector3f.ZERO, rotation, Vector3f.UNIT_XYZ)); - - // After changing skeleton transforms, must update world data - armature.update(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java b/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java deleted file mode 100644 index bf882bf1a1..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.SkinningControl; -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.*; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; - -import java.util.ArrayList; -import java.util.List; - -public class TestHWSkinning extends SimpleApplication implements ActionListener{ - - - // private AnimComposer composer; - final private String[] animNames = {"Dodge", "Walk", "pull", "push"}; - private final static int SIZE = 40; - private boolean hwSkinningEnable = true; - final private List skControls = new ArrayList<>(); - private BitmapText hwsText; - - public static void main(String[] args) { - TestHWSkinning app = new TestHWSkinning(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10f); - flyCam.setDragToRotate(true); - setPauseOnLostFocus(false); - cam.setLocation(new Vector3f(38.76639f, 14.744472f, 45.097454f)); - cam.setRotation(new Quaternion(-0.06086266f, 0.92303723f, -0.1639443f, -0.34266636f)); - - makeHudText(); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - - Spatial models[] = new Spatial[4]; - for (int i = 0; i < 4; i++) { - models[i] =loadModel(i); - } - - for (int i = 0; i < SIZE; i++) { - for (int j = 0; j < SIZE; j++) { - Node model = (Node)models[(i + j) % 4]; - Spatial s = model.getChild(0).clone(); - model.attachChild(s); - float x = (i - SIZE / 2) / 0.1f; - float z = (j - SIZE / 2) / 0.1f; - s.setLocalTranslation(x, 0, z); - } - } - - inputManager.addListener(this, "toggleHWS"); - inputManager.addMapping("toggleHWS", new KeyTrigger(KeyInput.KEY_SPACE)); - - } - - private Spatial loadModel(int i) { - Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - model.setLocalScale(0.1f); - AnimComposer composer = model.getControl(AnimComposer.class); - - composer.setCurrentAction(animNames[i]); - SkinningControl skinningControl = model.getControl(SkinningControl.class); - skinningControl.setHardwareSkinningPreferred(hwSkinningEnable); - skControls.add(skinningControl); - rootNode.attachChild(model); - return model; - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if(isPressed && name.equals("toggleHWS")){ - hwSkinningEnable = !hwSkinningEnable; - for (SkinningControl control : skControls) { - control.setHardwareSkinningPreferred(hwSkinningEnable); - hwsText.setText("HWS : "+ hwSkinningEnable); - } - } - } - - private void makeHudText() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - hwsText = new BitmapText(guiFont); - hwsText.setSize(guiFont.getCharSet().getRenderedSize()); - hwsText.setText("HWS : "+ hwSkinningEnable); - hwsText.setLocalTranslation(0, cam.getHeight(), 0); - guiNode.attachChild(hwsText); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java b/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java deleted file mode 100644 index d5c5cbd7e0..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.animation.*; -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.*; -import com.jme3.scene.Spatial; - -import java.util.ArrayList; -import java.util.List; - -public class TestHWSkinningOld extends SimpleApplication implements ActionListener { - - final private String[] animNames = {"Dodge", "Walk", "pull", "push"}; - private final static int SIZE = 50; - private boolean hwSkinningEnable = true; - final private List skControls = new ArrayList<>(); - private BitmapText hwsText; - - public static void main(String[] args) { - TestHWSkinningOld app = new TestHWSkinningOld(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10f); - flyCam.setDragToRotate(true); - setPauseOnLostFocus(false); - cam.setLocation(new Vector3f(24.746134f, 13.081396f, 32.72753f)); - cam.setRotation(new Quaternion(-0.06867662f, 0.92435044f, -0.19981281f, -0.31770203f)); - makeHudText(); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - - for (int i = 0; i < SIZE; i++) { - for (int j = 0; j < SIZE; j++) { - Spatial model = assetManager.loadModel("Models/Oto/OtoOldAnim.j3o"); - model.setLocalScale(0.1f); - model.setLocalTranslation(i - SIZE / 2, 0, j - SIZE / 2); - AnimControl control = model.getControl(AnimControl.class); - AnimChannel channel = control.createChannel(); - channel.setAnim(animNames[(i + j) % 4]); - SkeletonControl skeletonControl = model.getControl(SkeletonControl.class); - skeletonControl.setHardwareSkinningPreferred(hwSkinningEnable); - skControls.add(skeletonControl); - rootNode.attachChild(model); - } - } - - inputManager.addListener(this, "toggleHWS"); - inputManager.addMapping("toggleHWS", new KeyTrigger(KeyInput.KEY_SPACE)); - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed && name.equals("toggleHWS")) { - hwSkinningEnable = !hwSkinningEnable; - for (SkeletonControl control : skControls) { - control.setHardwareSkinningPreferred(hwSkinningEnable); - hwsText.setText("HWS : " + hwSkinningEnable); - } - } - } - - private void makeHudText() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - hwsText = new BitmapText(guiFont); - hwsText.setSize(guiFont.getCharSet().getRenderedSize()); - hwsText.setText("HWS : " + hwSkinningEnable); - hwsText.setLocalTranslation(0, cam.getHeight(), 0); - guiNode.attachChild(hwsText); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java b/jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java deleted file mode 100644 index f0e8bd3a6b..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.SkinningControl; -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; - -/** - * Test case for Issue 1395 (OGRE Importer should call saveInitialPose, to be - * consistent with GLTF) - * - * If the test succeeds, the humanoid Oto model will appear in a standing - * position. If the test fails, the model will appear rolled up into a tight - * bundle. - * - * @author sgold - */ -public class TestIssue1395 extends SimpleApplication { - - public static void main(String[] args) { - TestIssue1395 app = new TestIssue1395(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(new ColorRGBA(1f, 1f, 1f, 1f)); - - flyCam.setMoveSpeed(10f); - cam.setLocation(new Vector3f(6.4013605f, 7.488437f, 12.843031f)); - cam.setRotation(new Quaternion(-0.06f, 0.939258f, -0.2399f, -0.2379f)); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1f)); - rootNode.addLight(dl); - - Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - rootNode.attachChild(model); - model.center(); - - SkinningControl skinningControl - = model.getControl(SkinningControl.class); - skinningControl.getArmature().applyInitialPose(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java b/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java deleted file mode 100644 index 7795753b9d..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009-2015 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.AnimComposer; -import com.jme3.app.SimpleApplication; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; - -public class TestModelExportingCloning extends SimpleApplication { - - public static void main(String[] args) { - TestModelExportingCloning app = new TestModelExportingCloning(); - app.start(); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(10f, 3f, 40f)); - cam.lookAtDirection(Vector3f.UNIT_Z.negate(), Vector3f.UNIT_Y); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - - AnimComposer composer; - - Spatial originalModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - composer = originalModel.getControl(AnimComposer.class); - composer.setCurrentAction("Walk"); - composer.setGlobalSpeed(1.5f); - rootNode.attachChild(originalModel); - - Spatial clonedModel = originalModel.clone(); - clonedModel.move(10, 0, 0); - composer = clonedModel.getControl(AnimComposer.class); - composer.setCurrentAction("push"); - System.out.println("clonedModel: globalSpeed=" + composer.getGlobalSpeed()); - rootNode.attachChild(clonedModel); - - Spatial exportedModel = BinaryExporter.saveAndLoad(assetManager, originalModel); - exportedModel.move(20, 0, 0); - composer = exportedModel.getControl(AnimComposer.class); - composer.setCurrentAction("pull"); - System.out.println("exportedModel: globalSpeed=" + composer.getGlobalSpeed()); - rootNode.attachChild(exportedModel); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java b/jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java deleted file mode 100644 index f0b2161528..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java +++ /dev/null @@ -1,149 +0,0 @@ -package jme3test.model.anim; - -import com.jme3.anim.MorphControl; -import com.jme3.app.ChaseCameraAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.material.RenderState; -import com.jme3.scene.Geometry; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.mesh.MorphTarget; -import com.jme3.scene.shape.Box; -import com.jme3.util.BufferUtils; -import com.jme3.util.clone.Cloner; -import java.nio.FloatBuffer; - -public class TestMorph extends SimpleApplication { - - final private float[] weights = new float[2]; - - public static void main(String... args) { - TestMorph app = new TestMorph(); - app.start(); - } - - @Override - public void simpleInitApp() { - BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText text = new BitmapText(font); - text.setText("Press U-Y-I-J to vary weights. Drag LMB to orbit camera."); - text.setLocalTranslation(10f, cam.getHeight() - 10f, 0f); - guiNode.attachChild(text); - - final Box box = new Box(1, 1, 1); - /* - * Add a morph target that increases X coordinates of the "right" face. - */ - FloatBuffer buffer = BufferUtils.createVector3Buffer(box.getVertexCount()); - - float[] d = new float[box.getVertexCount() * 3]; - for (int i = 0; i < d.length; i++) { - d[i] = 0; - } - - d[12] = 3f; - d[15] = 3f; - d[18] = 3f; - d[21] = 3f; - - buffer.put(d); - buffer.rewind(); - - MorphTarget target = new MorphTarget(); - target.setBuffer(VertexBuffer.Type.Position, buffer); - box.addMorphTarget(target); - /* - * Add a morph target that increases Y coordinates of the "right" face. - */ - buffer = BufferUtils.createVector3Buffer(box.getVertexCount()); - - for (int i = 0; i < d.length; i++) { - d[i] = 0; - } - - d[13] = 3f; - d[16] = 3f; - d[19] = 3f; - d[22] = 3f; - - buffer.put(d); - buffer.rewind(); - - final MorphTarget target2 = new MorphTarget(); - target2.setBuffer(VertexBuffer.Type.Position, buffer); - box.addMorphTarget(target2); - - final Geometry g = new Geometry("box", box); - Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - g.setMaterial(m); - m.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off); - m.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - m.setInt("NumberOfMorphTargets", 2); - - rootNode.attachChild(g); - - g.setMorphState(weights); - g.addControl(new MorphControl()); - /* - * Attach a clone of the morphing box model, in order to test cloning. - */ - Geometry g2 = Cloner.deepClone(g); - g2.move(-4f, 0f, 0f); - rootNode.attachChild(g2); - /* - * Attach a saveAndLoad() copy of the morphing box model, - * in order to test serialization. - */ - Geometry g3 = BinaryExporter.saveAndLoad(assetManager, g); - g3.move(-4f, 4f, 0f); - rootNode.attachChild(g3); - - ChaseCameraAppState chase = new ChaseCameraAppState(); - chase.setTarget(rootNode); - getStateManager().attach(chase); - flyCam.setEnabled(false); - - inputManager.addMapping("morphright", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addMapping("morphleft", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("morphup", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("morphdown", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("change", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(new AnalogListener() { - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("morphleft")) { - weights[0] -= tpf; - } - if (name.equals("morphright")) { - weights[0] += tpf; - } - if (name.equals("morphup")) { - weights[1] += tpf; - } - if (name.equals("morphdown")) { - weights[1] -= tpf; - } - weights[0] = Math.max(0f, weights[0]); - weights[1] = Math.max(0f, weights[1]); - g.setMorphState(weights); - - } - }, "morphup", "morphdown", "morphleft", "morphright"); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("change") && isPressed) { - box.setBuffer(VertexBuffer.Type.MorphTarget0, 3, target2.getBuffer(VertexBuffer.Type.Position)); - } - } - }, "change"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java deleted file mode 100644 index fbd9524d80..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.model.anim; - -import com.jme3.anim.AnimClip; -import com.jme3.anim.AnimComposer; -import com.jme3.anim.SkinningControl; -import com.jme3.anim.tween.Tween; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.Action; -import com.jme3.anim.tween.action.BaseAction; -import com.jme3.anim.tween.action.LinearBlendSpace; -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; - -public class TestOgreAnim extends SimpleApplication implements ActionListener { - - private AnimComposer animComposer; - private static Action currentAction; - - public static void main(String[] args) { - TestOgreAnim app = new TestOgreAnim(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10f); - cam.setLocation(new Vector3f(6.4013605f, 7.488437f, 12.843031f)); - cam.setRotation(new Quaternion(-0.060740203f, 0.93925786f, -0.2398315f, -0.2378785f)); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - - Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - model.center(); - - animComposer = model.getControl(AnimComposer.class); - animComposer.actionBlended("Attack", new LinearBlendSpace(0f, 0.5f), "Dodge"); - for (AnimClip animClip : animComposer.getAnimClips()) { - Action action = animComposer.action(animClip.getName()); - if(!"stand".equals(animClip.getName())) { - action = new BaseAction(Tweens.sequence(action, Tweens.callMethod(this, "backToStand", animComposer))); - } - animComposer.addAction(animClip.getName(), action); - } - currentAction = animComposer.setCurrentAction("stand"); // Walk, pull, Dodge, stand, push - - SkinningControl skinningControl = model.getControl(SkinningControl.class); - skinningControl.setHardwareSkinningPreferred(false); - - Box b = new Box(.25f, 3f, .25f); - Geometry item = new Geometry("Item", b); - item.move(0, 1.5f, 0); - item.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - Node n = skinningControl.getAttachmentsNode("hand.right"); - n.attachChild(item); - - rootNode.attachChild(model); - - inputManager.addListener(this, "Attack"); - inputManager.addMapping("Attack", new KeyTrigger(KeyInput.KEY_SPACE)); - } - - public Tween backToStand(AnimComposer animComposer) { - currentAction = animComposer.setCurrentAction("stand"); - return currentAction; - } - - @Override - public void onAction(String binding, boolean value, float tpf) { - if (binding.equals("Attack") && value) { - if (currentAction != null && !currentAction.equals(animComposer.getAction("Dodge"))) { - currentAction = animComposer.setCurrentAction("Dodge"); - currentAction.setSpeed(0.1f); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java deleted file mode 100644 index aac2c1f970..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.model.anim; - -import com.jme3.anim.AnimComposer; -import com.jme3.anim.ArmatureMask; -import com.jme3.anim.Joint; -import com.jme3.anim.SkinningControl; -import com.jme3.anim.tween.action.Action; -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.scene.debug.custom.ArmatureDebugger; - -public class TestOgreComplexAnim extends SimpleApplication { - - private SkinningControl skinningControl; - - private float angle = 0; - private float rate = 1; - - public static void main(String[] args) { - TestOgreComplexAnim app = new TestOgreComplexAnim(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10f); - cam.setLocation(new Vector3f(6.4013605f, 7.488437f, 12.843031f)); - cam.setRotation(new Quaternion(-0.060740203f, 0.93925786f, -0.2398315f, -0.2378785f)); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - - Node model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - - skinningControl = model.getControl(SkinningControl.class); - AnimComposer ac = model.getControl(AnimComposer.class); - - ArmatureMask feet = ArmatureMask.createMask(skinningControl.getArmature(), "hip.right", "hip.left"); - Action dodgeAction = ac.action("Dodge"); - dodgeAction.setMask(feet); - dodgeAction.setSpeed(2f); - Action walkAction = ac.action("Walk"); - walkAction.setMask(feet); - walkAction.setSpeed(0.25f); - - ArmatureMask rightHand = ArmatureMask.createMask(skinningControl.getArmature(), "uparm.right"); - Action pullAction = ac.action("pull"); - pullAction.setMask(rightHand); - pullAction.setSpeed(0.5f); - Action standAction = ac.action("stand"); - standAction.setMask(rightHand); - standAction.setSpeed(0.5f); - - ac.actionSequence("complexAction", - ac.actionSequence("feetAction", dodgeAction, walkAction), - ac.actionSequence("rightHandAction", pullAction, standAction)); - - ac.setCurrentAction("complexAction"); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.getAdditionalRenderState().setWireframe(true); - mat.setColor("Color", ColorRGBA.Green); - mat.setFloat("PointSize", 7f); // Bug ? do not change size of debug points ? - mat.getAdditionalRenderState().setDepthTest(false); - - ArmatureDebugger armatureDebug = new ArmatureDebugger("armature", skinningControl.getArmature(), - skinningControl.getArmature().getJointList()); - armatureDebug.setMaterial(mat); - model.attachChild(armatureDebug); - - rootNode.attachChild(model); - } - - @Override - public void simpleUpdate(float tpf) { - Joint j = skinningControl.getArmature().getJoint("spinehigh"); - Joint j2 = skinningControl.getArmature().getJoint("uparm.left"); - - angle += tpf * rate; - if (angle > FastMath.HALF_PI / 2f) { - angle = FastMath.HALF_PI / 2f; - rate = -1; - } else if (angle < -FastMath.HALF_PI / 2f) { - angle = -FastMath.HALF_PI / 2f; - rate = 1; - } - - Quaternion q = new Quaternion(); - q.fromAngles(0, angle, 0); - - j.setLocalRotation(j.getInitialTransform().getRotation().mult(q)); - j2.setLocalScale(j.getInitialTransform().getScale().mult(new Vector3f(1 + angle, 1 + angle, 1 + angle))); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java b/jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java deleted file mode 100644 index 3761858166..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model.anim; - -import com.jme3.anim.AnimClip; -import com.jme3.anim.AnimComposer; -import com.jme3.anim.SkinningControl; -import com.jme3.anim.tween.Tweens; -import com.jme3.anim.tween.action.Action; -import com.jme3.anim.tween.action.BaseAction; -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.ssao.SSAOFilter; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; -import com.jme3.shadow.DirectionalLightShadowFilter; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Nehon - */ -public class TestSkeletonControlRefresh extends SimpleApplication implements ActionListener{ - - private final static int SIZE = 10; - private boolean hwSkinningEnable = true; - final private List skinningControls = new ArrayList<>(); - private BitmapText hwsText; - - public static void main(String[] args) { - TestSkeletonControlRefresh app = new TestSkeletonControlRefresh(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.White); - flyCam.setMoveSpeed(10f); - cam.setLocation(new Vector3f(3.8664846f, 6.2704787f, 9.664585f)); - cam.setRotation(new Quaternion(-0.054774776f, 0.94064945f, -0.27974048f, -0.18418397f)); - makeHudText(); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); - rootNode.addLight(dl); - Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey k = new TextureKey("Models/Oto/Oto.jpg", false); - m.setTexture("ColorMap", assetManager.loadTexture(k)); - - for (int i = 0; i < SIZE; i++) { - for (int j = 0; j < SIZE; j++) { - Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - //setting a different material - model.setMaterial(m.clone()); - model.setLocalScale(0.1f); - model.setLocalTranslation(i - SIZE / 2, 0, j - SIZE / 2); - - AnimComposer animComposer - = model.getControl(AnimComposer.class); - for (AnimClip animClip : animComposer.getAnimClips()) { - Action action = animComposer.action(animClip.getName()); - animComposer.addAction(animClip.getName(), new BaseAction( - Tweens.sequence(action, Tweens.callMethod(animComposer, "removeCurrentAction", AnimComposer.DEFAULT_LAYER)))); - } - animComposer.setCurrentAction(new ArrayList<>(animComposer.getAnimClips()).get((i + j) % 4).getName()); - - SkinningControl skinningControl = model.getControl(SkinningControl.class); - skinningControl.setHardwareSkinningPreferred(hwSkinningEnable); - skinningControls.add(skinningControl); - - rootNode.attachChild(model); - } - } - - rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - setupFloor(); - - inputManager.addListener(this, "toggleHWS"); - inputManager.addMapping("toggleHWS", new KeyTrigger(KeyInput.KEY_SPACE)); - -// DirectionalLightShadowRenderer pssm = new DirectionalLightShadowRenderer(assetManager, 1024, 2); -// pssm.setLight(dl); -// viewPort.addProcessor(pssm); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - - DirectionalLightShadowFilter sf = new DirectionalLightShadowFilter(assetManager, 1024, 2); - sf.setLight(dl); - fpp.addFilter(sf); - fpp.addFilter(new SSAOFilter()); - viewPort.addProcessor(fpp); - - - } - - public void setupFloor() { - Quad q = new Quad(20, 20); - q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10)); - Geometry geom = new Geometry("floor", q); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.White); - geom.setMaterial(mat); - - geom.rotate(-FastMath.HALF_PI, 0, 0); - geom.center(); - geom.move(0, -0.3f, 0); - geom.setShadowMode(RenderQueue.ShadowMode.Receive); - rootNode.attachChild(geom); - } - - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if(isPressed && name.equals("toggleHWS")){ - hwSkinningEnable = !hwSkinningEnable; - for (SkinningControl sc : skinningControls) { - sc.setHardwareSkinningPreferred(hwSkinningEnable); - } - hwsText.setText("HWS : "+ hwSkinningEnable); - } - } - - private void makeHudText() { - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - hwsText = new BitmapText(guiFont); - hwsText.setSize(guiFont.getCharSet().getRenderedSize()); - hwsText.setText("HWS : "+ hwSkinningEnable); - hwsText.setLocalTranslation(0, cam.getHeight(), 0); - guiNode.attachChild(hwsText); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java deleted file mode 100644 index 6ca1611d19..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java +++ /dev/null @@ -1,85 +0,0 @@ -package jme3test.model.anim; - -import com.jme3.anim.AnimClip; -import com.jme3.anim.AnimComposer; -import com.jme3.anim.AnimTrack; -import com.jme3.anim.TransformTrack; -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; - -public class TestSpatialAnim extends SimpleApplication { - - public static void main(String[] args) { - TestSpatialAnim app = new TestSpatialAnim(); - app.start(); - } - - @Override - public void simpleInitApp() { - - AmbientLight al = new AmbientLight(); - rootNode.addLight(al); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(Vector3f.UNIT_XYZ.negate()); - rootNode.addLight(dl); - - // Create model - Box box = new Box(1, 1, 1); - Geometry geom = new Geometry("box", box); - geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); - Node model = new Node("model"); - model.attachChild(geom); - - Box child = new Box(0.5f, 0.5f, 0.5f); - Geometry childGeom = new Geometry("box", child); - childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); - Node childModel = new Node("childmodel"); - childModel.setLocalTranslation(2, 2, 2); - childModel.attachChild(childGeom); - model.attachChild(childModel); - - //animation parameters - float animTime = 5; - int fps = 25; - float totalXLength = 10; - - //calculating frames - int totalFrames = (int) (fps * animTime); - float dT = animTime / totalFrames, t = 0; - float dX = totalXLength / totalFrames, x = 0; - float[] times = new float[totalFrames]; - Vector3f[] translations = new Vector3f[totalFrames]; - Quaternion[] rotations = new Quaternion[totalFrames]; - Vector3f[] scales = new Vector3f[totalFrames]; - for (int i = 0; i < totalFrames; ++i) { - times[i] = t; - t += dT; - translations[i] = new Vector3f(x, 0, 0); - x += dX; - rotations[i] = Quaternion.IDENTITY; - scales[i] = Vector3f.UNIT_XYZ; - } - TransformTrack transformTrack = new TransformTrack(geom, times, translations, rotations, scales); - TransformTrack transformTrackChild = new TransformTrack(childGeom, times, translations, rotations, scales); - // creating the animation - AnimClip animClip = new AnimClip("anim"); - animClip.setTracks(new AnimTrack[] { transformTrack, transformTrackChild }); - - // create spatial animation control - AnimComposer animComposer = new AnimComposer(); - animComposer.addAnimClip(animClip); - - model.addControl(animComposer); - rootNode.attachChild(model); - - // run animation - model.getControl(AnimComposer.class).setCurrentAction("anim"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/package-info.java b/jme3-examples/src/main/java/jme3test/model/anim/package-info.java deleted file mode 100644 index dc7e590f17..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/anim/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for animated 3-D models - */ -package jme3test.model.anim; diff --git a/jme3-examples/src/main/java/jme3test/model/package-info.java b/jme3-examples/src/main/java/jme3test/model/package-info.java deleted file mode 100644 index 964c56fd87..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for 3-D models - */ -package jme3test.model; diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java b/jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java deleted file mode 100644 index 17c44a1430..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.model.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.BillboardControl; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Quad; - -/** - * - * @author Kirill Vainer - */ -public class TestBillboard extends SimpleApplication { - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10); - - Quad q = new Quad(2, 2); - Geometry g = new Geometry("Quad", q); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - g.setMaterial(mat); - - Quad q2 = new Quad(1, 1); - Geometry g3 = new Geometry("Quad2", q2); - Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat2.setColor("Color", ColorRGBA.Yellow); - g3.setMaterial(mat2); - g3.setLocalTranslation(.5f, .5f, .01f); - - Box b = new Box(.25f, .5f, .25f); - Geometry g2 = new Geometry("Box", b); - g2.setLocalTranslation(0, 0, 3); - g2.setMaterial(mat); - - Node bb = new Node("billboard"); - - BillboardControl control=new BillboardControl(); - - bb.addControl(control); - bb.attachChild(g); - bb.attachChild(g3); - - - n=new Node("parent"); - n.attachChild(g2); - n.attachChild(bb); - rootNode.attachChild(n); - - n2=new Node("parentParent"); - n2.setLocalTranslation(Vector3f.UNIT_X.mult(5)); - n2.attachChild(n); - - rootNode.attachChild(n2); - - -// rootNode.attachChild(bb); -// rootNode.attachChild(g2); - } - private Node n; - private Node n2; - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - n.rotate(0, tpf, 0); - n.move(0.1f*tpf, 0, 0); - n2.rotate(0, 0, -tpf); - } - - - - public static void main(String[] args) { - TestBillboard app = new TestBillboard(); - app.start(); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestBox.java b/jme3-examples/src/main/java/jme3test/model/shape/TestBox.java deleted file mode 100644 index 0e5e86aeff..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/TestBox.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.model.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -public class TestBox extends SimpleApplication { - - public static void main(String[] args){ - TestBox app = new TestBox(); - app.start(); - } - - @Override - public void simpleInitApp() { - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - geom.setMaterial(mat); - rootNode.attachChild(geom); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java b/jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java deleted file mode 100644 index 5f205def3b..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.model.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.util.BufferUtils; - -/** - * How to create custom meshes by specifying vertices - * We render the mesh in three different ways, once with a solid blue color, - * once with vertex colors, and once with a wireframe material. - * @author KayTrance - */ -public class TestCustomMesh extends SimpleApplication { - - public static void main(String[] args){ - TestCustomMesh app = new TestCustomMesh(); - app.start(); - } - - @Override - public void simpleInitApp() { - - Mesh m = new Mesh(); - - // Vertex positions in space - Vector3f [] vertices = new Vector3f[4]; - vertices[0] = new Vector3f(0,0,0); - vertices[1] = new Vector3f(3,0,0); - vertices[2] = new Vector3f(0,3,0); - vertices[3] = new Vector3f(3,3,0); - - // Texture coordinates - Vector2f [] texCoord = new Vector2f[4]; - texCoord[0] = new Vector2f(0,0); - texCoord[1] = new Vector2f(1,0); - texCoord[2] = new Vector2f(0,1); - texCoord[3] = new Vector2f(1,1); - - // Indexes. We define the order in which mesh should be constructed - short[] indexes = {2, 0, 1, 1, 3, 2}; - - // Setting buffers - m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices)); - m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord)); - m.setBuffer(Type.Index, 1, BufferUtils.createShortBuffer(indexes)); - m.updateBound(); - - // ************************************************************************* - // First mesh uses one solid color - // ************************************************************************* - - // Creating a geometry, and apply a single color material to it - Geometry geom = new Geometry("OurMesh", m); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - geom.setMaterial(mat); - - // Attaching our geometry to the root node. - rootNode.attachChild(geom); - - // ************************************************************************* - // Second mesh uses vertex colors to color each vertex - // ************************************************************************* - Mesh cMesh = m.clone(); - Geometry coloredMesh = new Geometry ("ColoredMesh", cMesh); - Material matVC = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - matVC.setBoolean("VertexColor", true); - - //We have 4 vertices and 4 color values for each of them. - //If you have more vertices, you need 'new float[yourVertexCount * 4]' here! - float[] colorArray = new float[4*4]; - int colorIndex = 0; - - //Set custom RGBA value for each Vertex. Values range from 0.0f to 1.0f - for(int i = 0; i < 4; i++){ - // Red value (is increased by .2 on each next vertex here) - colorArray[colorIndex++]= 0.1f+(.2f*i); - // Green value (is reduced by .2 on each next vertex) - colorArray[colorIndex++]= 0.9f-(0.2f*i); - // Blue value (remains the same in our case) - colorArray[colorIndex++]= 0.5f; - // Alpha value (no transparency set here) - colorArray[colorIndex++]= 1.0f; - } - // Set the color buffer - cMesh.setBuffer(Type.Color, 4, colorArray); - coloredMesh.setMaterial(matVC); - // move mesh a bit so that it doesn't intersect with the first one - coloredMesh.setLocalTranslation(4, 0, 0); - rootNode.attachChild(coloredMesh); - -// /** Alternatively, you can show the mesh vertices as points -// * instead of coloring the faces. */ -// cMesh.setMode(Mesh.Mode.Points); -// cMesh.setPointSize(10f); -// cMesh.updateBound(); -// cMesh.setStatic(); -// Geometry points = new Geometry("Points", m); -// points.setMaterial(mat); -// rootNode.attachChild(points); - - // ************************************************************************* - // Third mesh will use a wireframe shader to show wireframe - // ************************************************************************* - Mesh wfMesh = m.clone(); - Geometry wfGeom = new Geometry("wireframeGeometry", wfMesh); - Material matWireframe = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - matWireframe.setColor("Color", ColorRGBA.Green); - matWireframe.getAdditionalRenderState().setWireframe(true); - wfGeom.setMaterial(matWireframe); - wfGeom.setLocalTranslation(4, 4, 0); - rootNode.attachChild(wfGeom); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java b/jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java deleted file mode 100644 index bec3847faa..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.model.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Cylinder; -import com.jme3.texture.Texture; - -public class TestCylinder extends SimpleApplication { - - public static void main(String[] args){ - TestCylinder app = new TestCylinder(); - app.start(); - } - - @Override - public void simpleInitApp() { - Cylinder t = new Cylinder(20, 50, 1, 2, true); - Geometry geom = new Geometry("Cylinder", t); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - TextureKey key = new TextureKey("Interface/Logo/Monkey.jpg", true); - key.setGenerateMips(true); - Texture tex = assetManager.loadTexture(key); - tex.setMinFilter(Texture.MinFilter.Trilinear); - mat.setTexture("ColorMap", tex); - - geom.setMaterial(mat); - - rootNode.attachChild(geom); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java b/jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java deleted file mode 100644 index 25bde0a797..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.model.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.debug.Arrow; -import com.jme3.scene.debug.Grid; -import com.jme3.scene.debug.WireBox; -import com.jme3.scene.debug.WireSphere; - -public class TestDebugShapes extends SimpleApplication { - - public static void main(String[] args){ - TestDebugShapes app = new TestDebugShapes(); - app.start(); - } - - private Geometry putShape(Mesh shape, ColorRGBA color) { - Geometry g = new Geometry("shape", shape); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.getAdditionalRenderState().setWireframe(true); - mat.setColor("Color", color); - g.setMaterial(mat); - rootNode.attachChild(g); - return g; - } - - private void putArrow(Vector3f pos, Vector3f dir, ColorRGBA color){ - Arrow arrow = new Arrow(dir); - putShape(arrow, color).setLocalTranslation(pos); - } - - private void putBox(Vector3f pos, float size, ColorRGBA color) { - putShape(new WireBox(size, size, size), color).setLocalTranslation(pos); - } - - private void putGrid(Vector3f pos, ColorRGBA color) { - putShape(new Grid(6, 6, 0.2f), color).center().move(pos); - } - - private void putSphere(Vector3f pos, ColorRGBA color) { - putShape(new WireSphere(1), color).setLocalTranslation(pos); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(2,1.5f,2)); - cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - - putArrow(Vector3f.ZERO, Vector3f.UNIT_X, ColorRGBA.Red); - putArrow(Vector3f.ZERO, Vector3f.UNIT_Y, ColorRGBA.Green); - putArrow(Vector3f.ZERO, Vector3f.UNIT_Z, ColorRGBA.Blue); - - putBox(new Vector3f(2, 0, 0), 0.5f, ColorRGBA.Yellow); - putGrid(new Vector3f(3.5f, 0, 0), ColorRGBA.White); - putSphere(new Vector3f(4.5f, 0, 0), ColorRGBA.Magenta); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java b/jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java deleted file mode 100644 index 69f5b8f4f6..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.model.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Torus; - -public class TestExpandingTorus extends SimpleApplication { - - private float outerRadius = 1.5f; - private float rate = 1; - private Torus torus; - - public static void main(String[] args) { - TestExpandingTorus app = new TestExpandingTorus(); - app.start(); - } - - @Override - public void simpleInitApp() { - torus = new Torus(30, 10, .5f, 1f); - Geometry geom = new Geometry("Torus", torus); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - geom.setMaterial(mat); - rootNode.attachChild(geom); - } - - @Override - public void simpleUpdate(float tpf){ - if (outerRadius > 2.5f){ - outerRadius = 2.5f; - rate = -rate; - }else if (outerRadius < 1f){ - outerRadius = 1f; - rate = -rate; - } - outerRadius += rate * tpf; - torus.updateGeometry(30, 10, .5f, outerRadius); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java b/jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java deleted file mode 100644 index 0bdf0e7ac5..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.model.shape; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Sphere; - -public class TestSphere extends SimpleApplication { - - public static void main(String[] args){ - TestSphere app = new TestSphere(); - app.start(); - } - - @Override - public void simpleInitApp() { - Sphere sphMesh = new Sphere(14, 14, 1); - Material solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); - - for (int y = -5; y < 5; y++){ - for (int x = -5; x < 5; x++){ - Geometry sphere = new Geometry("sphere", sphMesh); - sphere.setMaterial(solidColor); - sphere.setLocalTranslation(x * 2, 0, y * 2); - rootNode.attachChild(sphere); - } - } - cam.setLocation(new Vector3f(0, 5, 0)); - cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/package-info.java b/jme3-examples/src/main/java/jme3test/model/shape/package-info.java deleted file mode 100644 index 60502bdb70..0000000000 --- a/jme3-examples/src/main/java/jme3test/model/shape/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for meshes - */ -package jme3test.model.shape; diff --git a/jme3-examples/src/main/java/jme3test/network/MovingAverage.java b/jme3-examples/src/main/java/jme3test/network/MovingAverage.java deleted file mode 100644 index 28addcb3d8..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/MovingAverage.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.network; - -class MovingAverage { - - final private long[] samples; - private long sum; - private int count, index; - - public MovingAverage(int numSamples){ - samples = new long[numSamples]; - } - - public void add(long sample){ - sum = sum - samples[index] + sample; - samples[index++] = sample; - if (index > count){ - count = index; - } - if (index >= samples.length){ - index = 0; - } - } - - public long getAverage(){ - if (count == 0) - return 0; - else - return (long) (sum / (float) count); - } - -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/network/TestChatClient.java b/jme3-examples/src/main/java/jme3test/network/TestChatClient.java deleted file mode 100644 index 7312122e67..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestChatClient.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2011-2021 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. - */ -package jme3test.network; - -import com.jme3.network.Client; -import com.jme3.network.ClientStateListener; -import com.jme3.network.ErrorListener; -import com.jme3.network.Message; -import com.jme3.network.MessageListener; -import com.jme3.network.Network; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.*; -import jme3test.network.TestChatServer.ChatMessage; - -/** - * A simple test chat server. When SM implements a set - * of standard chat classes this can become a lot simpler. - * - * @version $Revision$ - * @author Paul Speed - */ -public class TestChatClient extends JFrame { - - private final Client client; - private final JEditorPane chatLog; - private final StringBuilder chatMessages = new StringBuilder(); - private final JTextField nameField; - private final JTextField messageField; - - public TestChatClient(String host) throws IOException { - super("jME3 Test Chat Client - to:" + host); - - // Build out the UI - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - setSize(800, 600); - - chatLog = new JEditorPane(); - chatLog.setEditable(false); - chatLog.setContentType("text/html"); - chatLog.setText(""); - - getContentPane().add(new JScrollPane(chatLog), "Center"); - - // A crude form - JPanel p = new JPanel(); - p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); - p.add(new JLabel("Name:")); - nameField = new JTextField(System.getProperty("user.name", "yourname")); - Dimension d = nameField.getPreferredSize(); - nameField.setMaximumSize(new Dimension(120, d.height + 6)); - p.add(nameField); - p.add(new JLabel(" Message:")); - messageField = new JTextField(); - p.add(messageField); - p.add(new JButton(new SendAction(true))); - p.add(new JButton(new SendAction(false))); - - getContentPane().add(p, "South"); - - client = Network.connectToServer(TestChatServer.NAME, TestChatServer.VERSION, - host, TestChatServer.PORT, TestChatServer.UDP_PORT); - client.addMessageListener(new ChatHandler(), ChatMessage.class); - client.addClientStateListener(new ChatClientStateListener()); - client.addErrorListener(new ChatErrorListener()); - client.start(); - - System.out.println("Started client:" + client); - } - - @Override - public void dispose() { - System.out.println("Chat window closing."); - super.dispose(); - if( client.isConnected() ) { - client.close(); - } - } - - public static String getString(Component owner, String title, String message, String initialValue) { - return (String) JOptionPane.showInputDialog(owner, message, title, JOptionPane.PLAIN_MESSAGE, - null, null, initialValue); - } - - public static void main(String... args) throws Exception { - - // Increase the logging level for networking... - System.out.println("Setting logging to max"); - Logger networkLog = Logger.getLogger("com.jme3.network"); - networkLog.setLevel(Level.FINEST); - - // And we have to tell JUL's handler also - // turn up logging in a very convoluted way - Logger rootLog = Logger.getLogger(""); - if( rootLog.getHandlers().length > 0 ) { - rootLog.getHandlers()[0].setLevel(Level.FINEST); - } - - // Note: in JME 3.1 this is generally unnecessary as the server will - // send a message with all server-registered classes. - // TestChatServer.initializeClasses(); - // Leaving the call commented out to be illustrative regarding the - // common old pattern. - - // Grab a host string from the user - String s = getString(null, "Host Info", "Enter chat host:", "localhost"); - if (s == null) { - System.out.println("User cancelled."); - return; - } - - // Register a shutdown hook to get a message on the console when the - // app actually finishes - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - System.out.println("Chat client is terminating."); - } - }); - - - TestChatClient test = new TestChatClient(s); - test.setVisible(true); - } - - private class ChatHandler implements MessageListener { - - @Override - public void messageReceived(Client source, Message m) { - ChatMessage chat = (ChatMessage) m; - - System.out.println("Received:" + chat); - - // One of the least efficient ways to add text to a - // JEditorPane - chatMessages.append("" + (m.isReliable() ? "TCP" : "UDP") + ""); - chatMessages.append(" -- " + chat.getName() + " : "); - chatMessages.append(chat.getMessage()); - chatMessages.append("
"); - String s = "" + chatMessages + ""; - chatLog.setText(s); - - // Set selection to the end so that the scroll panel will scroll - // down. - chatLog.select(s.length(), s.length()); - } - } - - private class ChatClientStateListener implements ClientStateListener { - - @Override - public void clientConnected(Client c) { - System.out.println("clientConnected(" + c + ")"); - } - - @Override - public void clientDisconnected(Client c, DisconnectInfo info) { - System.out.println("clientDisconnected(" + c + "):" + info); - if( info != null ) { - // The connection was closed by the server - JOptionPane.showMessageDialog(rootPane, - info.reason, - "Connection Closed", - JOptionPane.INFORMATION_MESSAGE); - dispose(); - } - } - } - - private class ChatErrorListener implements ErrorListener { - - @Override - public void handleError( Client source, Throwable t ) { - System.out.println("handleError(" + source + ", " + t + ")"); - JOptionPane.showMessageDialog(rootPane, - String.valueOf(t), - "Connection Error", - JOptionPane.ERROR_MESSAGE); - } - - } - - private class SendAction extends AbstractAction { - - private final boolean reliable; - - public SendAction(boolean reliable) { - super(reliable ? "TCP" : "UDP"); - this.reliable = reliable; - } - - @Override - public void actionPerformed(ActionEvent evt) { - String name = nameField.getText(); - String message = messageField.getText(); - - ChatMessage chat = new ChatMessage(name, message); - chat.setReliable(reliable); - System.out.println("Sending:" + chat); - client.send(chat); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java b/jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java deleted file mode 100644 index ee08067ae0..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2015 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. - */ -package jme3test.network; - - -/** - * Combines the server instance and a client instance into the - * same JVM to show an example of, and to test, a pattern like - * self-hosted multiplayer games. - * - * @author Paul Speed - */ -public class TestChatClientAndServer { - - public static void main( String... args ) throws Exception { - - System.out.println("Starting chat server..."); - TestChatServer chatServer = new TestChatServer(); - chatServer.start(); - - System.out.println("Waiting for connections on port:" + TestChatServer.PORT); - - // Now launch a client - - TestChatClient test = new TestChatClient("localhost"); - test.setVisible(true); - - // Register a shutdown hook to get a message on the console when the - // app actually finishes - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - System.out.println("Client and server test is terminating."); - } - }); - - // Keep running basically forever or until the server - // shuts down - while( chatServer.isRunning() ) { - synchronized (chatServer) { - chatServer.wait(); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestChatServer.java b/jme3-examples/src/main/java/jme3test/network/TestChatServer.java deleted file mode 100644 index 31aca2ffe3..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestChatServer.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2011-2021 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. - */ -package jme3test.network; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.jme3.network.*; -import com.jme3.network.serializing.Serializable; -import com.jme3.network.serializing.Serializer; -import java.io.IOException; - -/** - * A simple test chat server. When SM implements a set - * of standard chat classes this can become a lot simpler. - * - * @version $Revision$ - * @author Paul Speed - */ -public class TestChatServer { - // Normally these and the initialized method would - // be in shared constants or something. - - public static final String NAME = "Test Chat Server"; - public static final int VERSION = 1; - public static final int PORT = 5110; - public static final int UDP_PORT = 5110; - - private Server server; - private boolean isRunning; - - public TestChatServer() throws IOException { - - // Use this to test the client/server name version check - this.server = Network.createServer(NAME, VERSION, PORT, UDP_PORT); - - // Initialize our own messages only after the server has been created. - // It registers some additional messages with the serializer by default - // that need to go before custom messages. - initializeClasses(); - - ChatHandler handler = new ChatHandler(); - server.addMessageListener(handler, ChatMessage.class); - - server.addConnectionListener(new ChatConnectionListener()); - } - - public boolean isRunning() { - return isRunning; - } - - public synchronized void start() { - if( isRunning ) { - return; - } - server.start(); - isRunning = true; - } - - public synchronized void close() { - if( !isRunning ) { - return; - } - - // Gracefully let any connections know that the server is - // going down. Without this, their connections will simply - // error out. - for( HostedConnection conn : server.getConnections() ) { - conn.close("Server is shutting down."); - } - try { - Thread.sleep(1000); // wait a couple beats to let the messages go out - } catch( InterruptedException e ) { - e.printStackTrace(); - } - - server.close(); - isRunning = false; - notifyAll(); - } - - protected void runCommand( HostedConnection conn, String user, String command ) { - if( "/shutdown".equals(command) ) { - server.broadcast(new ChatMessage("server", "Server is shutting down.")); - close(); - } else if( "/help".equals(command) ) { - StringBuilder sb = new StringBuilder(); - sb.append("Chat commands:\n"); - sb.append("/help - prints this message.\n"); - sb.append("/shutdown - shuts down the server."); - server.broadcast(new ChatMessage("server", sb.toString())); - } - } - - public static void initializeClasses() { - // Doing it here means that the client code only needs to - // call our initialize. - Serializer.registerClass(ChatMessage.class); - } - - public static void main(String... args) throws Exception { - - // Increase the logging level for networking... - System.out.println("Setting logging to max"); - Logger networkLog = Logger.getLogger("com.jme3.network"); - networkLog.setLevel(Level.FINEST); - - // And we have to tell JUL's handler also - // turn up logging in a very convoluted way - Logger rootLog = Logger.getLogger(""); - if( rootLog.getHandlers().length > 0 ) { - rootLog.getHandlers()[0].setLevel(Level.FINEST); - } - - TestChatServer chatServer = new TestChatServer(); - chatServer.start(); - - System.out.println("Waiting for connections on port:" + PORT); - - // Keep running basically forever - while( chatServer.isRunning ) { - synchronized (chatServer) { - chatServer.wait(); - } - } - } - - private class ChatHandler implements MessageListener { - - public ChatHandler() { - } - - @Override - public void messageReceived(HostedConnection source, Message m) { - if (m instanceof ChatMessage) { - // Keep track of the name just in case we - // want to know it for some other reason later, and it's - // a good example of session data. - ChatMessage cm = (ChatMessage)m; - source.setAttribute("name", cm.getName()); - - // Check for a / command - if( cm.message.startsWith("/") ) { - runCommand(source, cm.name, cm.message); - return; - } - - System.out.println("Broadcasting:" + m + " reliable:" + m.isReliable()); - - // Just rebroadcast... the reliable flag will stay the - // same so if it came in on UDP it will go out on that too - source.getServer().broadcast(cm); - } else { - System.err.println("Received odd message:" + m); - } - } - } - - private class ChatConnectionListener implements ConnectionListener { - - @Override - public void connectionAdded( Server server, HostedConnection conn ) { - System.out.println("connectionAdded(" + conn + ")"); - } - - @Override - public void connectionRemoved(Server server, HostedConnection conn) { - System.out.println("connectionRemoved(" + conn + ")"); - } - - } - - @Serializable - public static class ChatMessage extends AbstractMessage { - - private String name; - private String message; - - public ChatMessage() { - } - - public ChatMessage(String name, String message) { - setName(name); - setMessage(message); - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setMessage(String s) { - this.message = s; - } - - public String getMessage() { - return message; - } - - @Override - public String toString() { - return name + ":" + message; - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestLatency.java b/jme3-examples/src/main/java/jme3test/network/TestLatency.java deleted file mode 100644 index e449380ead..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestLatency.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.network; - -import com.jme3.network.*; -import com.jme3.network.serializing.Serializable; -import com.jme3.network.serializing.Serializer; -import java.io.IOException; - -public class TestLatency { - - private static long startTime; - private static Client client; - private static MovingAverage average = new MovingAverage(100); - - static { - startTime = System.currentTimeMillis(); - } - - private static long getTime(){ - return System.currentTimeMillis() - startTime; - } - - @Serializable - public static class TimestampMessage extends AbstractMessage { - - private long timeSent = 0; - private long timeReceived = 0; - - public TimestampMessage(){ - setReliable(false); - } - - public TimestampMessage(long timeSent, long timeReceived){ - setReliable(false); - this.timeSent = timeSent; - this.timeReceived = timeReceived; - } - - } - - public static void main(String[] args) throws IOException, InterruptedException{ - Serializer.registerClass(TimestampMessage.class); - - Server server = Network.createServer(5110); - server.start(); - - client = Network.connectToServer("localhost", 5110); - client.start(); - - client.addMessageListener(new MessageListener(){ - @Override - public void messageReceived(Client source, Message m) { - TimestampMessage timeMsg = (TimestampMessage) m; - - long curTime = getTime(); - //System.out.println("Time sent: " + timeMsg.timeSent); - //System.out.println("Time received by server: " + timeMsg.timeReceived); - //System.out.println("Time received by client: " + curTime); - - long latency = (curTime - timeMsg.timeSent); - System.out.println("Latency: " + (latency) + " ms"); - //long timeOffset = ((timeMsg.timeSent + curTime) / 2) - timeMsg.timeReceived; - //System.out.println("Approximate timeOffset: "+ (timeOffset) + " ms"); - - average.add(latency); - System.out.println("Average latency: " + average.getAverage()); - - long latencyOffset = latency - average.getAverage(); - System.out.println("Latency offset: " + latencyOffset); - - client.send(new TimestampMessage(getTime(), 0)); - } - }, TimestampMessage.class); - - server.addMessageListener(new MessageListener(){ - @Override - public void messageReceived(HostedConnection source, Message m) { - TimestampMessage timeMsg = (TimestampMessage) m; - TimestampMessage outMsg = new TimestampMessage(timeMsg.timeSent, getTime()); - source.send(outMsg); - } - }, TimestampMessage.class); - - Thread.sleep(1); - - client.send(new TimestampMessage(getTime(), 0)); - - Object obj = new Object(); - synchronized(obj){ - obj.wait(); - } - } - -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestMessages.java b/jme3-examples/src/main/java/jme3test/network/TestMessages.java deleted file mode 100644 index b67476ae1d..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestMessages.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.network; - -import com.jme3.network.*; -import com.jme3.network.serializing.Serializable; -import com.jme3.network.serializing.Serializer; -import java.io.IOException; - -public class TestMessages { - - @Serializable - public static class PingMessage extends AbstractMessage { - } - - @Serializable - public static class PongMessage extends AbstractMessage { - } - - private static class ServerPingResponder implements MessageListener { - @Override - public void messageReceived(HostedConnection source, com.jme3.network.Message message) { - if (message instanceof PingMessage){ - System.out.println("Server: Received ping message!"); - source.send(new PongMessage()); - } - } - } - - private static class ClientPingResponder implements MessageListener { - @Override - public void messageReceived(Client source, com.jme3.network.Message message) { - if (message instanceof PongMessage){ - System.out.println("Client: Received pong message!"); - } - } - } - - public static void main(String[] args) throws IOException, InterruptedException{ - Serializer.registerClass(PingMessage.class); - Serializer.registerClass(PongMessage.class); - - Server server = Network.createServer(5110); - server.start(); - - Client client = Network.connectToServer("localhost", 5110); - client.start(); - - server.addMessageListener(new ServerPingResponder(), PingMessage.class); - client.addMessageListener(new ClientPingResponder(), PongMessage.class); - - System.out.println("Client: Sending ping message.."); - client.send(new PingMessage()); - - Object obj = new Object(); - synchronized (obj){ - obj.wait(); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java b/jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java deleted file mode 100644 index 13bf63c8e2..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.network; - -import com.jme3.network.*; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class TestNetworkStress implements ConnectionListener { - - @Override - public void connectionAdded(Server server, HostedConnection conn) { - System.out.println("Client Connected: "+conn.getId()); - //conn.close("goodbye"); - } - - @Override - public void connectionRemoved(Server server, HostedConnection conn) { - } - - public static void main(String[] args) throws IOException, InterruptedException{ - Logger.getLogger("").getHandlers()[0].setLevel(Level.OFF); - - Server server = Network.createServer(5110); - server.start(); - server.addConnectionListener(new TestNetworkStress()); - - for (int i = 0; i < 1000; i++){ - Client client = Network.connectToServer("localhost", 5110); - client.start(); - - Thread.sleep(10); - - client.close(); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java b/jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java deleted file mode 100644 index 208af7b682..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.network; - -import com.jme3.app.SimpleApplication; -import com.jme3.export.Savable; -import com.jme3.network.Client; -import com.jme3.network.Network; -import com.jme3.network.Server; -import com.jme3.network.rmi.ObjectStore; -import com.jme3.network.serializing.Serializer; -import com.jme3.network.serializing.serializers.SavableSerializer; -import com.jme3.scene.Spatial; -import java.io.IOException; -import java.util.concurrent.Callable; - -public class TestRemoteCall { - - private static SimpleApplication serverApp; - - /** - * Interface implemented by the server, exposing - * RMI calls that clients can use. - */ - public static interface ServerAccess { - /** - * Attaches the model with the given name to the server's scene. - * - * @param model The model name - * - * @return True if the model was attached. - * - * @throws RuntimeException If some error occurs. - */ - public boolean attachChild(String model); - } - - public static class ServerAccessImpl implements ServerAccess { - @Override - public boolean attachChild(String model) { - if (model == null) - throw new RuntimeException("Cannot be null. .. etc"); - - final String finalModel = model; - serverApp.enqueue(new Callable() { - @Override - public Void call() throws Exception { - Spatial spatial = serverApp.getAssetManager().loadModel(finalModel); - serverApp.getRootNode().attachChild(spatial); - return null; - } - }); - return true; - } - } - - public static void createServer(){ - serverApp = new SimpleApplication() { - @Override - public void simpleInitApp() { - } - }; - serverApp.start(); - - try { - Server server = Network.createServer(5110); - server.start(); - - ObjectStore store = new ObjectStore(server); - store.exposeObject("access", new ServerAccessImpl()); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - - public static void main(String[] args) throws IOException, InterruptedException{ - Serializer.registerClass(Savable.class, new SavableSerializer()); - - createServer(); - - Client client = Network.connectToServer("localhost", 5110); - client.start(); - - ObjectStore store = new ObjectStore(client); - ServerAccess access = store.getExposedObject("access", ServerAccess.class, true); - boolean result = access.attachChild("Models/Oto/Oto.mesh.xml"); - System.out.println(result); - } -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestSerialization.java b/jme3-examples/src/main/java/jme3test/network/TestSerialization.java deleted file mode 100644 index 0d1ba0a585..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestSerialization.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.network; - -import com.jme3.network.*; -import com.jme3.network.serializing.Serializable; -import com.jme3.network.serializing.Serializer; -import java.io.IOException; -import java.util.*; - -public class TestSerialization implements MessageListener { - - @Serializable - public static class SomeObject { - - private int val; - - public SomeObject(){ - } - - public SomeObject(int val){ - this.val = val; - } - - public int getVal(){ - return val; - } - - @Override - public String toString(){ - return "SomeObject[val="+val+"]"; - } - } - - public enum Status { - High, - Middle, - Low; - } - - @Serializable - public static class TestSerializationMessage extends AbstractMessage { - - private boolean z; - private byte b; - private char c; - private short s; - private int i; - private float f; - private long l; - private double d; - - private int[] ia; - private List ls; - private Map mp; - - private Status status1; - private Status status2; - - private Date date; - - public TestSerializationMessage(){ - super(true); - } - - public TestSerializationMessage(boolean initIt){ - super(true); - if (initIt){ - z = true; - b = -88; - c = 'Y'; - s = 9999; - i = 123; - f = -75.4e8f; - l = 9438345072805034L; - d = -854834.914703e88; - ia = new int[]{ 456, 678, 999 }; - - ls = new ArrayList(); - ls.add("hello"); - ls.add(new SomeObject(-22)); - - mp = new HashMap(); - mp.put("abc", new SomeObject(555)); - - status1 = Status.High; - status2 = Status.Middle; - - date = new Date(System.currentTimeMillis()); - } - } - } - - @Override - public void messageReceived(HostedConnection source, Message m) { - TestSerializationMessage cm = (TestSerializationMessage) m; - System.out.println(cm.z); - System.out.println(cm.b); - System.out.println(cm.c); - System.out.println(cm.s); - System.out.println(cm.i); - System.out.println(cm.f); - System.out.println(cm.l); - System.out.println(cm.d); - System.out.println(Arrays.toString(cm.ia)); - System.out.println(cm.ls); - System.out.println(cm.mp); - System.out.println(cm.status1); - System.out.println(cm.status2); - System.out.println(cm.date); - } - - public static void main(String[] args) throws IOException, InterruptedException{ - Serializer.registerClass(SomeObject.class); - Serializer.registerClass(TestSerializationMessage.class); - - Server server = Network.createServer( 5110 ); - server.start(); - - Client client = Network.connectToServer( "localhost", 5110 ); - client.start(); - - server.addMessageListener(new TestSerialization(), TestSerializationMessage.class); - client.send(new TestSerializationMessage(true)); - - Thread.sleep(10000); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/network/TestThroughput.java b/jme3-examples/src/main/java/jme3test/network/TestThroughput.java deleted file mode 100644 index b27b17ef14..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/TestThroughput.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2011-2021 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. - */ -package jme3test.network; - -import com.jme3.network.*; -import com.jme3.network.serializing.Serializable; -import com.jme3.network.serializing.Serializer; -import java.io.IOException; - -public class TestThroughput implements MessageListener { //extends MessageAdapter { - - private static long lastTime = -1; - private static long counter = 0; - private static long total = 0; - // Change this flag to test UDP instead of TCP - final private static boolean testReliable = false; - final private boolean isOnServer; - - public TestThroughput(boolean isOnServer) { - this.isOnServer = isOnServer; - } - - @Serializable - public static class TestMessage extends AbstractMessage { - - public TestMessage() { - setReliable(testReliable); - } - } - - @Override - public void messageReceived(MessageConnection source, Message msg) { - - if (!isOnServer) { - // It's local to the client, so we got it back. - counter++; - total++; - long time = System.currentTimeMillis(); -//System.out.println( "total:" + total + " counter:" + counter + " lastTime:" + lastTime + " time:" + time ); - if (lastTime < 0) { - lastTime = time; - } else if (time - lastTime > 1000) { - long delta = time - lastTime; - double scale = delta / 1000.0; - double pps = counter / scale; - System.out.println("messages per second:" + pps + " total messages:" + total); - counter = 0; - lastTime = time; - } - } else { - if (source == null) { - System.out.println("Received a message from a not fully connected source, msg:" + msg); - } else { -//System.out.println( "sending:" + msg + " back to client:" + source ); - // The 'reliable' flag is transient and the server doesn't - // (yet) reset this value for us. - msg.setReliable(testReliable); - source.send(msg); - } - } - } - - public static void main(String[] args) throws IOException, InterruptedException { - - Serializer.registerClass(TestMessage.class); - - // Use this to test the client/server name version check - //Server server = Network.createServer( "bad name", 42, 5110, 5110 ); - Server server = Network.createServer(5110, 5110); - server.start(); - - Client client = Network.connectToServer("localhost", 5110); - client.start(); - - client.addMessageListener(new TestThroughput(false), TestMessage.class); - server.addMessageListener(new TestThroughput(true), TestMessage.class); - - Thread.sleep(1); - - TestMessage test = new TestMessage(); -// for( int i = 0; i < 10; i++ ) { - while (true) { -//System.out.println( "sending." ); - client.send(test); - } - - //Thread.sleep(5000); - } -} diff --git a/jme3-examples/src/main/java/jme3test/network/package-info.java b/jme3-examples/src/main/java/jme3test/network/package-info.java deleted file mode 100644 index 087eb1bb41..0000000000 --- a/jme3-examples/src/main/java/jme3test/network/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for network communication - */ -package jme3test.network; diff --git a/jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java b/jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java deleted file mode 100644 index 3fba0f46a0..0000000000 --- a/jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.niftygui; - -import com.jme3.app.Application; -import de.lessvoid.nifty.Nifty; -import de.lessvoid.nifty.screen.Screen; -import de.lessvoid.nifty.screen.ScreenController; - -/** - * A ScreenController for the "start" screen defined in - * "Interfaces/Nifty/HelloJme.xml", which is used in the TestAppStates and - * TestNiftyGui applications. - */ -public class StartScreenController implements ScreenController { - - final private Application application; - - /** - * Instantiate a ScreenController for the specified Application. - * - * @param app the Application - */ - public StartScreenController(Application app) { - this.application = app; - } - - /** - * Nifty invokes this method when the screen gets enabled for the first - * time. - * - * @param nifty (not null) - * @param screen (not null) - */ - @Override - public void bind(Nifty nifty, Screen screen) { - System.out.println("bind(" + screen.getScreenId() + ")"); - } - - /** - * Nifty invokes this method each time the screen starts up. - */ - @Override - public void onStartScreen() { - System.out.println("onStartScreen"); - } - - /** - * Nifty invokes this method each time the screen shuts down. - */ - @Override - public void onEndScreen() { - System.out.println("onEndScreen"); - } - - /** - * Stop the Application. Nifty invokes this method (via reflection) after - * the user clicks on the flashing orange panel. - */ - public void quit() { - application.stop(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java b/jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java deleted file mode 100644 index b40311f62c..0000000000 --- a/jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.niftygui; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.niftygui.NiftyJmeDisplay; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import de.lessvoid.nifty.Nifty; -import de.lessvoid.nifty.builder.LayerBuilder; -import de.lessvoid.nifty.builder.PanelBuilder; -import de.lessvoid.nifty.builder.ScreenBuilder; -import de.lessvoid.nifty.controls.button.builder.ButtonBuilder; -import de.lessvoid.nifty.screen.Screen; -import de.lessvoid.nifty.screen.ScreenController; - -public class TestIssue1013 extends SimpleApplication implements ScreenController { - - public static void main(String[] args) { - new TestIssue1013().start(); - } - - private NiftyJmeDisplay niftyDisplay; - - @Override - public void simpleInitApp() { - - // this box here always renders - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("/com/jme3/app/Monkey.png")); - geom.setMaterial(mat); - rootNode.attachChild(geom); - - niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort); - - Nifty nifty = niftyDisplay.getNifty(); - nifty.loadStyleFile("nifty-default-styles.xml"); - nifty.loadControlFile("nifty-default-controls.xml"); - - ScreenController ctrl = this; - - new ScreenBuilder("start") { - { - controller(ctrl); - layer(new LayerBuilder() { - { - childLayoutVertical(); - panel(new PanelBuilder() { - { - childLayoutCenter(); - width("100%"); - height("50%"); - backgroundColor("#ff0000"); - } - }); - control(new ButtonBuilder("RestartButton", "Restart Context") { - { - alignCenter(); - valignCenter(); - height("32px"); - width("480px"); - interactOnClick("restartContext()"); - } - }); - } - }); - } - }.build(nifty); - - guiViewPort.addProcessor(niftyDisplay); - nifty.gotoScreen("start"); - - flyCam.setDragToRotate(true); - } - - @Override - public void bind(Nifty nifty, Screen screen) { - } - - @Override - public void onStartScreen() { - } - - @Override - public void onEndScreen() { - } - - public void restartContext() { - // even without changing settings, stuff breaks! - restart(); - // ...and re-adding the processor doesn't help at all - guiViewPort.addProcessor(niftyDisplay); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java b/jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java deleted file mode 100644 index d63d988768..0000000000 --- a/jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2019-2022 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. - */ -package jme3test.niftygui; - -import com.jme3.app.SimpleApplication; -import com.jme3.niftygui.NiftyJmeDisplay; -import com.jme3.texture.image.ColorSpace; -import de.lessvoid.nifty.Nifty; -import de.lessvoid.nifty.screen.Screen; -import de.lessvoid.nifty.screen.ScreenController; - -/** - * Test case for JME issue #99: blendMode="multiply" in Nifty renders - * incorrectly. - *

- * If successful, two text labels will be legible. If unsuccessful, only the top - * one will be legible. - * - * @author Stephen Gold sgold@sonic.net - */ -public class TestIssue99 - extends SimpleApplication - implements ScreenController { - - public static void main(String[] args) { - TestIssue99 app = new TestIssue99(); - app.start(); - } - - @Override - public void simpleInitApp() { - /* - * GUI requires a cursor; prevent flyCam from hiding it. - */ - flyCam.setDragToRotate(true); - /* - * Start NiftyGUI without the batched renderer. - */ - ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() - ? ColorSpace.sRGB : ColorSpace.Linear; - NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay( - assetManager, inputManager, audioRenderer, guiViewPort, colorSpace); - guiViewPort.addProcessor(niftyDisplay); - /* - * Load GUI controls, styles, and layout from XML assets. - */ - Nifty nifty = niftyDisplay.getNifty(); - nifty.loadControlFile("nifty-default-controls.xml"); - nifty.loadStyleFile("nifty-default-styles.xml"); - nifty.fromXml("Interface/Nifty/test-issue-99.xml", - "test-issue-99", this); - } - - /** - * A callback from Nifty, invoked when the screen gets enabled for the first - * time. - * - * @param nifty (not null) - * @param screen (not null) - */ - @Override - public void bind(Nifty nifty, Screen screen) { - } - - /** - * A callback from Nifty, invoked each time the screen shuts down. - */ - @Override - public void onEndScreen() { - } - - /** - * A callback from Nifty, invoked each time the screen starts up. - */ - @Override - public void onStartScreen() { - } -} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java deleted file mode 100644 index f498c3b87d..0000000000 --- a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ - -package jme3test.niftygui; - -import com.jme3.app.SimpleApplication; -import com.jme3.niftygui.NiftyJmeDisplay; -import com.jme3.texture.image.ColorSpace; -import de.lessvoid.nifty.Nifty; - -public class TestNiftyExamples extends SimpleApplication { - - public static void main(String[] args){ - TestNiftyExamples app = new TestNiftyExamples(); - app.setPauseOnLostFocus(false); - app.start(); - } - - @Override - public void simpleInitApp() { - ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() - ? ColorSpace.sRGB : ColorSpace.Linear; - NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, - inputManager, - audioRenderer, - guiViewPort, - colorSpace); - Nifty nifty = niftyDisplay.getNifty(); - nifty.fromXml("all/intro.xml", "start"); - - // attach the nifty display to the gui view port as a processor - guiViewPort.addProcessor(niftyDisplay); - - // disable the fly cam - flyCam.setEnabled(false); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java deleted file mode 100644 index 873d90548a..0000000000 --- a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.niftygui; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.niftygui.NiftyJmeDisplay; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import de.lessvoid.nifty.Nifty; - -public class TestNiftyGui extends SimpleApplication { - - private Nifty nifty; - - public static void main(String[] args){ - TestNiftyGui app = new TestNiftyGui(); - app.setPauseOnLostFocus(false); - app.start(); - } - - @Override - public void simpleInitApp() { - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - geom.setMaterial(mat); - rootNode.attachChild(geom); - - NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay( - assetManager, - inputManager, - audioRenderer, - guiViewPort); - nifty = niftyDisplay.getNifty(); - StartScreenController startScreen = new StartScreenController(this); - nifty.fromXml("Interface/Nifty/HelloJme.xml", "start", startScreen); - - // attach the nifty display to the gui view port as a processor - guiViewPort.addProcessor(niftyDisplay); - - // disable the fly cam -// flyCam.setEnabled(false); -// flyCam.setDragToRotate(true); - inputManager.setCursorVisible(true); - } -} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java deleted file mode 100644 index da428f5d5e..0000000000 --- a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ - -package jme3test.niftygui; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.niftygui.NiftyJmeDisplay; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture.MagFilter; -import com.jme3.texture.Texture.MinFilter; -import com.jme3.texture.Texture2D; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; -import com.jme3.texture.image.ColorSpace; -import de.lessvoid.nifty.Nifty; - -public class TestNiftyToMesh extends SimpleApplication{ - - public static void main(String[] args){ - TestNiftyToMesh app = new TestNiftyToMesh(); - app.start(); - } - - @Override - public void simpleInitApp() { - ViewPort niftyView = renderManager.createPreView("NiftyView", new Camera(1024, 768)); - niftyView.setClearFlags(true, true, true); - - ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() - ? ColorSpace.sRGB : ColorSpace.Linear; - NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, - inputManager, - audioRenderer, - niftyView, - colorSpace); - Nifty nifty = niftyDisplay.getNifty(); - nifty.fromXml("all/intro.xml", "start"); - niftyView.addProcessor(niftyDisplay); - - Texture2D depthTex = new Texture2D(1024, 768, Format.Depth); - FrameBuffer fb = new FrameBuffer(1024, 768, 1); - fb.setDepthTarget(FrameBufferTarget.newTarget(depthTex)); - - Texture2D tex = new Texture2D(1024, 768, Format.RGBA8); - tex.setMinFilter(MinFilter.Trilinear); - tex.setMagFilter(MagFilter.Bilinear); - - fb.addColorTarget(FrameBufferTarget.newTarget(tex)); - niftyView.setClearFlags(true, true, true); - niftyView.setOutputFrameBuffer(fb); - - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", tex); - geom.setMaterial(mat); - rootNode.attachChild(geom); - } -} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/package-info.java b/jme3-examples/src/main/java/jme3test/niftygui/package-info.java deleted file mode 100644 index 485741acf3..0000000000 --- a/jme3-examples/src/main/java/jme3test/niftygui/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for Nifty GUI - */ -package jme3test.niftygui; diff --git a/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java b/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java deleted file mode 100644 index 737547fca9..0000000000 --- a/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.opencl; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.math.ColorRGBA; -import com.jme3.opencl.*; -import com.jme3.system.AppSettings; -import com.jme3.util.BufferUtils; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.util.Arrays; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Simple test checking if the basic functions of the OpenCL wrapper work - * @author shaman - */ -public class HelloOpenCL extends SimpleApplication { - private static final Logger LOG = Logger.getLogger(HelloOpenCL.class.getName()); - - public static void main(String[] args){ - HelloOpenCL app = new HelloOpenCL(); - AppSettings settings = new AppSettings(true); - settings.setOpenCLSupport(true); - settings.setVSync(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL2); - app.setSettings(settings); - app.start(); // start the game - } - - @Override - public void simpleInitApp() { - BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - Context clContext = context.getOpenCLContext(); - if (clContext == null) { - BitmapText txt = new BitmapText(fnt); - txt.setText("No OpenCL Context created!\nSee output log for details."); - txt.setLocalTranslation(5, settings.getHeight() - 5, 0); - guiNode.attachChild(txt); - return; - } - CommandQueue clQueue = clContext.createQueue(); - - StringBuilder str = new StringBuilder(); - str.append("OpenCL Context created:\n Platform: ") - .append(clContext.getDevices().get(0).getPlatform().getName()) - .append("\n Devices: ").append(clContext.getDevices()); - str.append("\nTests:"); - str.append("\n Buffers: ").append(testBuffer(clContext, clQueue)); - str.append("\n Kernel: ").append(testKernel(clContext, clQueue)); - str.append("\n Images: ").append(testImages(clContext, clQueue)); - - clQueue.release(); - - BitmapText txt1 = new BitmapText(fnt); - txt1.setText(str.toString()); - txt1.setLocalTranslation(5, settings.getHeight() - 5, 0); - guiNode.attachChild(txt1); - - flyCam.setEnabled(false); - inputManager.setCursorVisible(true); - } - - private static void assertEquals(byte expected, byte actual, String message) { - if (expected != actual) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - private static void assertEquals(long expected, long actual, String message) { - if (expected != actual) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - private static void assertEquals(double expected, double actual, String message) { - if (Math.abs(expected - actual) >= 0.00001) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - private static void assertEquals(Object expected, Object actual, String message) { - if (!Objects.equals(expected, actual)) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - - private boolean testBuffer(Context clContext, CommandQueue clQueue) { - try { - //create two buffers - ByteBuffer h1 = BufferUtils.createByteBuffer(256); - Buffer b1 = clContext.createBuffer(256); - ByteBuffer h2 = BufferUtils.createByteBuffer(256); - Buffer b2 = clContext.createBuffer(256); - - //fill buffer - h2.rewind(); - for (int i=0; i<256; ++i) { - h2.put((byte)i); - } - h2.rewind(); - b2.write(clQueue, h2); - - //copy b2 to b1 - b2.copyTo(clQueue, b1); - - //read buffer - h1.rewind(); - b1.read(clQueue, h1); - h1.rewind(); - for (int i=0; i<256; ++i) { - byte b = h1.get(); - assertEquals((byte) i, b, "Wrong byte read"); - } - - //read buffer with offset - int low = 26; - int high = 184; - h1.position(5); - Event event = b1.readAsync(clQueue, h1, high-low, low); - event.waitForFinished(); - h1.position(5); - for (int i=0; i deviceListBox; - - private static String selectedPlatform; - private static String selectedDevice; - private Context clContext; - private static List availablePlatforms; - private Buffer testBuffer; - private boolean bufferCreated; - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - new TestContextSwitching().start(); - } - - public TestContextSwitching() { - AppSettings settings = new AppSettings(true); - settings.setOpenCLSupport(true); - settings.setVSync(true); - settings.setWidth(800); - settings.setHeight(600); - settings.setOpenCLPlatformChooser(CustomPlatformChooser.class); - settings.setRenderer(AppSettings.LWJGL_OPENGL2); - - setSettings(settings); - setShowSettings(false); - } - - @Override - public void simpleInitApp() { - - clContext = null; - - NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay( - assetManager, - inputManager, - audioRenderer, - guiViewPort); - Nifty nifty = niftyDisplay.getNifty(); - nifty.fromXml("jme3test/opencl/ContextSwitchingScreen.xml", "Screen", this); - guiViewPort.addProcessor(niftyDisplay); - inputManager.setCursorVisible(true); - flyCam.setEnabled(false); - } - - @Override - public void simpleUpdate(float tpf) { - if (applyButton != null) { - updateInfos(); - } - } - - @Override - @SuppressWarnings("unchecked") - public void bind(Nifty nifty, Screen screen) { - applyButton = screen.findNiftyControl("ApplyButton", Button.class); - ListBox platformListBox - = screen.findNiftyControl("PlatformListBox", ListBox.class); - deviceListBox = screen.findNiftyControl("DeviceListBox", ListBox.class); - infoLabel = screen.findNiftyControl("InfoLabel", Label.class); - - updateInfos(); - - platformListBox.clear(); - for (Platform p : availablePlatforms) { - platformListBox.addItem(p.getName()); - } - platformListBox.selectItem(selectedPlatform); - changePlatform(selectedPlatform); - } - - private void updateInfos() { - - if (testBuffer == null && clContext != null && !bufferCreated) { - try { - testBuffer = clContext.createBuffer(1024).register(); - LOG.info("Test buffer created"); - } catch (OpenCLException ex) { - LOG.log(Level.SEVERE, "Unable to create buffer", ex); - } - bufferCreated = true; - } - - Context c = context.getOpenCLContext(); - if (c == clContext) { - return; - } - clContext = c; - LOG.info("context changed"); - testBuffer = null; - bufferCreated = false; - StringBuilder text = new StringBuilder(); - text.append("Current context:\n"); - text.append(" Platform: ").append(clContext.getDevices().get(0).getPlatform().getName()).append("\n"); - text.append(" Device: ").append(clContext.getDevices().get(0).getName()).append("\n"); - text.append(" Profile: ").append(clContext.getDevices().get(0).getProfile()).append("\n"); - text.append(" Memory: ").append(clContext.getDevices().get(0).getGlobalMemorySize()).append(" B\n"); - text.append(" Compute Units: ").append(clContext.getDevices().get(0).getComputeUnits()).append("\n"); - infoLabel.setText(text.toString()); - } - - @NiftyEventSubscriber(id="ApplyButton") - public void onButton(String id, ButtonClickedEvent event) { - LOG.log(Level.INFO, "Change context: platform={0}, device={1}", new Object[]{selectedPlatform, selectedDevice}); - restart(); - } - - private void changePlatform(String platform) { - selectedPlatform = platform; - Platform p = null; - for (Platform p2 : availablePlatforms) { - if (p2.getName().equals(selectedPlatform)) { - p = p2; - break; - } - } - deviceListBox.clear(); - if (p == null) { - return; - } - for (Device d : p.getDevices()) { - deviceListBox.addItem(d.getName()); - } - deviceListBox.selectItem(selectedDevice); - } - - @NiftyEventSubscriber(id="PlatformListBox") - public void onPlatformChanged(String id, ListBoxSelectionChangedEvent event) { - String p = event.getSelection().isEmpty() ? null : event.getSelection().get(0); - LOG.log(Level.INFO, "Selected platform changed to {0}", p); - selectedPlatform = p; - changePlatform(p); - } - - @NiftyEventSubscriber(id="DeviceListBox") - public void onDeviceChanged(String id, ListBoxSelectionChangedEvent event) { - String d = event.getSelection().isEmpty() ? null : event.getSelection().get(0); - LOG.log(Level.INFO, "Selected device changed to {0}", d); - selectedDevice = d; - } - - @Override - public void onStartScreen() { - - } - - @Override - public void onEndScreen() { - - } - - public static class CustomPlatformChooser implements PlatformChooser { - - public CustomPlatformChooser() {} - - @Override - public List chooseDevices(List platforms) { - availablePlatforms = platforms; - - Platform platform = null; - for (Platform p : platforms) { - if (p.getName().equals(selectedPlatform)) { - platform = p; - break; - } - } - if (platform == null) { - platform = platforms.get(0); - } - selectedPlatform = platform.getName(); - - Device device = null; - for (Device d : platform.getDevices()) { - if (d.getName().equals(selectedDevice)) { - device = d; - break; - } - } - if (device == null) { - for (Device d : platform.getDevices()) { - if (d.getDeviceType() == Device.DeviceType.GPU) { - device = d; - break; - } - } - } - if (device == null) { - device = platform.getDevices().get(0); - } - selectedDevice = device.getName(); - - return Collections.singletonList(device); - } - - } -} - diff --git a/jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java b/jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java deleted file mode 100644 index 3b3ec8fe7f..0000000000 --- a/jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.opencl; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.opencl.*; -import com.jme3.system.AppSettings; -import java.util.Collections; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class creates multiple instances of {@link TestVertexBufferSharing}. - * This is used to test if multiple opencl instances can run in parallel. - * @author Sebastian Weiss - */ -public class TestMultipleApplications extends SimpleApplication { - private static final Logger LOG = Logger.getLogger(TestMultipleApplications.class.getName()); - - private static final Object sync = new Object(); - private static List availableDevices; - private static int currentDeviceIndex; - - private CommandQueue clQueue; - private Kernel kernel; - private Buffer buffer; - private boolean failed; - private BitmapText statusText; - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - final AppSettings settings = new AppSettings(true); - settings.setOpenCLSupport(true); - settings.setVSync(true); - settings.setOpenCLPlatformChooser(CustomPlatformChooser.class); - settings.setRenderer(AppSettings.LWJGL_OPENGL2); - for (int i=0; i<2; ++i) { - new Thread() { - @Override - public void run() { - if (currentDeviceIndex == -1) { - return; - } - TestMultipleApplications app = new TestMultipleApplications(); - app.setSettings(settings); - app.setShowSettings(false); - app.start(); - } - }.start(); - } - } - - public static class CustomPlatformChooser implements PlatformChooser { - - public CustomPlatformChooser() {} - - @Override - public List chooseDevices(List platforms) { - synchronized(sync) { - if (currentDeviceIndex == -1) { - return Collections.emptyList(); - } - - Platform platform = platforms.get(0); - availableDevices = platform.getDevices(); - - Device device = platform.getDevices().get(currentDeviceIndex); - currentDeviceIndex ++; - if (currentDeviceIndex >= availableDevices.size()) { - currentDeviceIndex = -1; - } - - return Collections.singletonList(device); - } - } - - } - - @Override - public void simpleInitApp() { - Context clContext = context.getOpenCLContext(); - if (clContext == null) { - LOG.severe("No OpenCL context found"); - stop(); - return; - } - Device device = clContext.getDevices().get(0); - clQueue = clContext.createQueue(device); - clQueue.register(); - - String source = "" - + "__kernel void Fill(__global float* vb, float v)\n" - + "{\n" - + " int idx = get_global_id(0);\n" - + " vb[idx] = v;\n" - + "}\n"; - Program program = clContext.createProgramFromSourceCode(source); - program.build(); - program.register(); - kernel = program.createKernel("Fill"); - kernel.register(); - - buffer = clContext.createBuffer(4); - buffer.register(); - - flyCam.setEnabled(false); - inputManager.setCursorVisible(true); - - BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText infoText = new BitmapText(fnt); - //infoText.setBox(new Rectangle(0, 0, settings.getWidth(), settings.getHeight())); - infoText.setText("Device: "+clContext.getDevices()); - infoText.setLocalTranslation(0, settings.getHeight(), 0); - guiNode.attachChild(infoText); - statusText = new BitmapText(fnt); - //statusText.setBox(new Rectangle(0, 0, settings.getWidth(), settings.getHeight())); - statusText.setText("Running"); - statusText.setLocalTranslation(0, settings.getHeight() - infoText.getHeight() - 2, 0); - guiNode.attachChild(statusText); - } - - @Override - public void simpleUpdate(float tpf) { - //call kernel to test if it is still working - if (!failed) { - try { - kernel.Run1NoEvent(clQueue, new Kernel.WorkSize(1), buffer, 1.0f); - } catch (OpenCLException ex) { - LOG.log(Level.SEVERE, "Kernel call not working anymore", ex); - failed = true; - statusText.setText("Failed"); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java b/jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java deleted file mode 100644 index 2a712314cb..0000000000 --- a/jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.opencl; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.math.FastMath; -import com.jme3.math.Matrix3f; -import com.jme3.math.Matrix4f; -import com.jme3.opencl.*; -import com.jme3.system.AppSettings; -import com.jme3.util.BufferUtils; -import java.nio.*; -import java.util.Objects; -import java.util.Random; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Test class for the build in libraries - * @author shaman - */ -public class TestOpenCLLibraries extends SimpleApplication { - private static final Logger LOG = Logger.getLogger(TestOpenCLLibraries.class.getName()); - - public static void main(String[] args){ - TestOpenCLLibraries app = new TestOpenCLLibraries(); - AppSettings settings = new AppSettings(true); - settings.setOpenCLSupport(true); - settings.setVSync(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL2); - app.setSettings(settings); - app.start(); // start the game - } - - @Override - public void simpleInitApp() { - BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - Context clContext = context.getOpenCLContext(); - if (clContext == null) { - BitmapText txt = new BitmapText(fnt); - txt.setText("No OpenCL Context created!\nSee output log for details."); - txt.setLocalTranslation(5, settings.getHeight() - 5, 0); - guiNode.attachChild(txt); - return; - } - CommandQueue clQueue = clContext.createQueue(clContext.getDevices().get(0)); - - StringBuilder str = new StringBuilder(); - str.append("OpenCL Context created:\n Platform: ") - .append(clContext.getDevices().get(0).getPlatform().getName()) - .append("\n Devices: ").append(clContext.getDevices()); - str.append("\nTests:"); - str.append("\n Random numbers: ").append(testRandom(clContext, clQueue)); - str.append("\n Matrix3f: ").append(testMatrix3f(clContext, clQueue)); - str.append("\n Matrix4f: ").append(testMatrix4f(clContext, clQueue)); - - clQueue.release(); - - BitmapText txt1 = new BitmapText(fnt); - txt1.setText(str.toString()); - txt1.setLocalTranslation(5, settings.getHeight() - 5, 0); - guiNode.attachChild(txt1); - - flyCam.setEnabled(false); - inputManager.setCursorVisible(true); - } - - private static void assertEquals(byte expected, byte actual, String message) { - if (expected != actual) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - private static void assertEquals(long expected, long actual, String message) { - if (expected != actual) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - private static void assertEquals(double expected, double actual, String message) { - if (Math.abs(expected - actual) >= 0.00001) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - private static void assertEquals(Object expected, Object actual, String message) { - if (!Objects.equals(expected, actual)) { - System.err.println(message+": expected="+expected+", actual="+actual); - throw new AssertionError(); - } - } - - private boolean testRandom(Context clContext, CommandQueue clQueue) { - try { - //test for doubles - boolean supportsDoubles = clContext.getDevices().get(0).hasDouble(); - - //create code - String code = "" - + "#import \"Common/OpenCL/Random.clh\"\n" - + "__kernel void TestBool(__global ulong* seeds, __global uchar* results) {\n" - + " results[get_global_id(0)] = randBool(seeds + get_global_id(0)) ? 1 : 0;\n" - + "}\n" - + "__kernel void TestInt(__global ulong* seeds, __global int* results) {\n" - + " results[get_global_id(0)] = randInt(seeds + get_global_id(0));\n" - + "}\n" - + "__kernel void TestIntN(__global ulong* seeds, int n, __global int* results) {\n" - + " results[get_global_id(0)] = randIntN(n, seeds + get_global_id(0));\n" - + "}\n" - + "__kernel void TestLong(__global ulong* seeds, __global long* results) {\n" - + " results[get_global_id(0)] = randLong(seeds + get_global_id(0));\n" - + "}\n" - + "__kernel void TestFloat(__global ulong* seeds, __global float* results) {\n" - + " results[get_global_id(0)] = randFloat(seeds + get_global_id(0));\n" - + "}\n" - + "#ifdef RANDOM_DOUBLES\n" - + "__kernel void TestDouble(__global ulong* seeds, __global double* results) {\n" - + " results[get_global_id(0)] = randDouble(seeds + get_global_id(0));\n" - + "}\n" - + "#endif\n"; - if (supportsDoubles) { - code = "#define RANDOM_DOUBLES\n" + code; - } - Program program = clContext.createProgramFromSourceCodeWithDependencies(code, assetManager); - program.build(); - - int count = 256; - Kernel.WorkSize ws = new Kernel.WorkSize(count); - - //create seeds - Random initRandom = new Random(); - long[] seeds = new long[count]; - Random[] randoms = new Random[count]; - for (int i=0; i 0 ) { - fpp.setNumSamples(numSamples); - } - - BloomFilter bloom=new BloomFilter(); - bloom.setDownSamplingFactor(2); - bloom.setBlurScale(1.37f); - bloom.setExposurePower(3.30f); - bloom.setExposureCutOff(0.2f); - bloom.setBloomIntensity(2.45f); - BloomUI ui=new BloomUI(inputManager, bloom); - - - viewPort.addProcessor(fpp); - fpp.addFilter(bloom); - initInputs(); - - } - - private void initInputs() { - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - - ActionListener acl = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggle") && keyPressed) { - if(active){ - active=false; - viewPort.removeProcessor(fpp); - }else{ - active=true; - viewPort.addProcessor(fpp); - } - } - } - }; - - inputManager.addListener(acl, "toggle"); - - } - - - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java b/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java deleted file mode 100644 index 9e5a9aaed3..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.post.filters.BloomFilter.GlowMode; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; - -public class TestBloomAlphaThreshold extends SimpleApplication -{ - private boolean active = true; - private FilterPostProcessor fpp; - - public static void main(String[] args) - { - TestBloomAlphaThreshold app = new TestBloomAlphaThreshold(); - app.start(); - } - - @Override - public void simpleInitApp() - { - // put the camera in a bad position - cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -10)); - cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f)); - // cam.setFrustumFar(1000); - - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - - mat.setFloat("Shininess", 15f); - mat.setBoolean("UseMaterialColors", true); - mat.setColor("Ambient", ColorRGBA.Yellow.mult(0.2f)); - mat.setColor("Diffuse", ColorRGBA.Yellow.mult(0.2f)); - mat.setColor("Specular", ColorRGBA.Yellow.mult(0.8f)); - mat.setColor("GlowColor", ColorRGBA.Green); - - Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - matSoil.setFloat("Shininess", 15f); - matSoil.setBoolean("UseMaterialColors", true); - matSoil.setColor("Ambient", ColorRGBA.Gray); - matSoil.setColor("Diffuse", ColorRGBA.Black); - matSoil.setColor("Specular", ColorRGBA.Gray); - - Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); - teapot.setLocalTranslation(0, 0, 10); - - teapot.setMaterial(mat); - teapot.setShadowMode(ShadowMode.CastAndReceive); - teapot.setLocalScale(10.0f); - rootNode.attachChild(teapot); - - Vector3f boxMin1 = new Vector3f(-800f, -23f, -150f); - Vector3f boxMax1 = new Vector3f(800f, 3f, 1250f); - Box boxMesh1 = new Box(boxMin1, boxMax1); - Geometry soil = new Geometry("soil", boxMesh1); - soil.setMaterial(matSoil); - soil.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(soil); - - Material matBox = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - matBox.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png")); - matBox.setFloat("AlphaDiscardThreshold", 0.5f); - - Vector3f boxMin2 = new Vector3f(-5.5f, 8f, -4f); - Vector3f boxMax2 = new Vector3f(-1.5f, 12f, 0f); - Box boxMesh2 = new Box(boxMin2, boxMax2); - Geometry box = new Geometry("box", boxMesh2); - box.setMaterial(matBox); - box.setQueueBucket(RenderQueue.Bucket.Translucent); - // box.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(box); - - DirectionalLight light = new DirectionalLight(); - light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - light.setColor(ColorRGBA.White.mult(1.5f)); - rootNode.addLight(light); - - // load sky - Spatial sky = SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/FullskiesBlueClear03.dds", - EnvMapType.CubeMap); - sky.setCullHint(Spatial.CullHint.Never); - rootNode.attachChild(sky); - - fpp = new FilterPostProcessor(assetManager); - int numSamples = getContext().getSettings().getSamples(); - if (numSamples > 0) - { - fpp.setNumSamples(numSamples); - } - - BloomFilter bloom = new BloomFilter(GlowMode.Objects); - bloom.setDownSamplingFactor(2); - bloom.setBlurScale(1.37f); - bloom.setExposurePower(3.30f); - bloom.setExposureCutOff(0.2f); - bloom.setBloomIntensity(2.45f); - BloomUI ui = new BloomUI(inputManager, bloom); - - viewPort.addProcessor(fpp); - fpp.addFilter(bloom); - initInputs(); - - } - - private void initInputs() - { - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - - ActionListener acl = new ActionListener() - { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) - { - if (name.equals("toggle") && keyPressed) - { - if (active) - { - active = false; - viewPort.removeProcessor(fpp); - } - else - { - active = true; - viewPort.addProcessor(fpp); - } - } - } - }; - - inputManager.addListener(acl, "toggle"); - - } - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java b/jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java deleted file mode 100644 index ff6ab497f3..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.CartoonEdgeFilter; -import com.jme3.renderer.Caps; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.Spatial.CullHint; -import com.jme3.texture.Texture; - -public class TestCartoonEdge extends SimpleApplication { - - private FilterPostProcessor fpp; - - public static void main(String[] args){ - TestCartoonEdge app = new TestCartoonEdge(); - app.start(); - } - - public void setupFilters(){ - if (renderer.getCaps().contains(Caps.GLSL100)){ - fpp=new FilterPostProcessor(assetManager); - //fpp.setNumSamples(4); - int numSamples = getContext().getSettings().getSamples(); - if( numSamples > 0 ) { - fpp.setNumSamples(numSamples); - } - CartoonEdgeFilter toon=new CartoonEdgeFilter(); - toon.setEdgeColor(ColorRGBA.Yellow); - fpp.addFilter(toon); - viewPort.addProcessor(fpp); - } - } - - public void makeToonish(Spatial spatial){ - if (spatial instanceof Node){ - Node n = (Node) spatial; - for (Spatial child : n.getChildren()) - makeToonish(child); - }else if (spatial instanceof Geometry){ - Geometry g = (Geometry) spatial; - Material m = g.getMaterial(); - if (m.getMaterialDef().getMaterialParam("UseMaterialColors") != null) { - Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png"); -// t.setMinFilter(Texture.MinFilter.NearestNoMipMaps); -// t.setMagFilter(Texture.MagFilter.Nearest); - m.setTexture("ColorRamp", t); - m.setBoolean("UseMaterialColors", true); - m.setColor("Specular", ColorRGBA.Black); - m.setColor("Diffuse", ColorRGBA.White); - m.setBoolean("VertexLighting", true); - } - } - } - - public void setupLighting(){ - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, 1).normalizeLocal()); - dl.setColor(new ColorRGBA(2,2,2,1)); - - rootNode.addLight(dl); - } - - public void setupModel(){ - Spatial model = assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml"); - makeToonish(model); - model.rotate(0, FastMath.PI, 0); -// signpost.setLocalTranslation(12, 3.5f, 30); -// model.scale(0.10f); -// signpost.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(model); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.Gray); - - cam.setLocation(new Vector3f(-5.6310086f, 5.0892987f, -13.000479f)); - cam.setRotation(new Quaternion(0.1779095f, 0.20036356f, -0.03702727f, 0.96272093f)); - cam.update(); - - cam.setFrustumFar(300); - flyCam.setMoveSpeed(30); - - rootNode.setCullHint(CullHint.Never); - - setupLighting(); - setupModel(); - setupFilters(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java b/jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java deleted file mode 100644 index 52c125cb3e..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.ContrastAdjustmentFilter; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Sphere; -import com.jme3.texture.Texture; - -/** - * A {@link ContrastAdjustmentFilter} with user-controlled exponents, scales, and input range. - * - * @author pavl_g. - */ -public class TestContrastAdjustment extends SimpleApplication { - - /** - * Display filter status. - */ - private BitmapText statusText; - /** - * The filter being tested. - */ - private ContrastAdjustmentFilter contrastAdjustmentFilter; - - public static void main(String[] args) { - new TestContrastAdjustment().start(); - } - - @Override - public void simpleInitApp() { - /* - * Attach an unshaded globe to the scene. - */ - final Sphere globe = new Sphere(40, 40, 3.5f); - final Geometry earth = new Geometry("Earth", globe); - earth.rotate(-FastMath.HALF_PI, 0f, 0f); - final Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - final Texture texture = assetManager.loadTexture("Textures/Sky/Earth/Earth.jpg"); - material.setTexture("ColorMap", texture); - earth.setMaterial(material); - rootNode.attachChild(earth); - - final FilterPostProcessor postProcessor = new FilterPostProcessor(assetManager); - int numSamples = settings.getSamples(); - if (numSamples > 0) { - postProcessor.setNumSamples(numSamples); - } - viewPort.addProcessor(postProcessor); - /* - * Add the filter to be tested. - */ - contrastAdjustmentFilter = new ContrastAdjustmentFilter(); - //adjusting some parameters - contrastAdjustmentFilter.setExponents(1.8f, 1.8f, 2.1f) - .setInputRange(0, 0.367f) - .setScales(0.25f, 0.25f, 1f); - postProcessor.addFilter(contrastAdjustmentFilter); - - setUpUserInterface(); - } - - /** - * Update the status text. - * - * @param tpf unused - */ - @Override - public void simpleUpdate(float tpf) { - String status = contrastAdjustmentFilter.toString(); - statusText.setText(status); - } - - private void setUpUserInterface() { - /* - * Attach a BitmapText to display the status of the ContrastAdjustmentFilter. - */ - statusText = new BitmapText(guiFont); - guiNode.attachChild(statusText); - statusText.setLocalTranslation(0f, cam.getHeight(), 0f); - /* - * Create listeners for user keypresses. - */ - ActionListener action = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("reset") && keyPressed) { - contrastAdjustmentFilter.setExponents(1f, 1f, 1f) - .setInputRange(0f, 1f) - .setScales(1f, 1f, 1f); - } - } - }; - AnalogListener analog = new AnalogListener() { - @Override - public void onAnalog(String name, float value, float tpf) { - float increment = name.endsWith("+") ? 0.3f * tpf : -0.3f * tpf; - - if (name.startsWith("lower")) { - float newValue = contrastAdjustmentFilter.getLowerLimit() + increment; - contrastAdjustmentFilter.setLowerLimit(newValue); - - } else if (name.startsWith("upper")) { - float newValue = contrastAdjustmentFilter.getUpperLimit() + increment; - contrastAdjustmentFilter.setUpperLimit(newValue); - - } else if (name.startsWith("re")) { - float newValue = contrastAdjustmentFilter.getRedExponent() + increment; - contrastAdjustmentFilter.setRedExponent(newValue); - - } else if (name.startsWith("ge")) { - float newValue = contrastAdjustmentFilter.getGreenExponent() + increment; - contrastAdjustmentFilter.setGreenExponent(newValue); - - } else if (name.startsWith("be")) { - float newValue = contrastAdjustmentFilter.getBlueExponent() + increment; - contrastAdjustmentFilter.setBlueExponent(newValue); - - } else if (name.startsWith("rs")) { - float newValue = contrastAdjustmentFilter.getRedScale() + increment; - contrastAdjustmentFilter.setRedScale(newValue); - - } else if (name.startsWith("gs")) { - float newValue = contrastAdjustmentFilter.getGreenScale() + increment; - contrastAdjustmentFilter.setGreenScale(newValue); - - } else if (name.startsWith("bs")) { - float newValue = contrastAdjustmentFilter.getBlueScale() + increment; - contrastAdjustmentFilter.setBlueScale(newValue); - } - } - }; - /* - * Add mappings and listeners for user keypresses. - */ - System.out.println("Press Enter to reset the filter to defaults."); - inputManager.addMapping("reset", new KeyTrigger(KeyInput.KEY_RETURN)); - inputManager.addListener(action, "reset"); - - System.out.println("lower limit: press R to increase, F to decrease"); - inputManager.addMapping("lower+", new KeyTrigger(KeyInput.KEY_R)); - inputManager.addMapping("lower-", new KeyTrigger(KeyInput.KEY_F)); - inputManager.addListener(analog, "lower+", "lower-"); - - System.out.println("upper limit: press T to increase, G to decrease"); - inputManager.addMapping("upper+", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addMapping("upper-", new KeyTrigger(KeyInput.KEY_G)); - inputManager.addListener(analog, "upper+", "upper-"); - - System.out.println("red exponent: press Y to increase, H to decrease"); - inputManager.addMapping("re+", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("re-", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addListener(analog, "re+", "re-"); - - System.out.println("green exponent: press U to increase, J to decrease"); - inputManager.addMapping("ge+", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("ge-", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addListener(analog, "ge+", "ge-"); - - System.out.println("blue exponent: press I to increase, K to decrease"); - inputManager.addMapping("be+", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addMapping("be-", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addListener(analog, "be+", "be-"); - - System.out.println("red scale: press O to increase, L to decrease"); - inputManager.addMapping("rs+", new KeyTrigger(KeyInput.KEY_O)); - inputManager.addMapping("rs-", new KeyTrigger(KeyInput.KEY_L)); - inputManager.addListener(analog, "rs+", "rs-"); - - System.out.println("green scale: press P to increase, ; to decrease"); - inputManager.addMapping("gs+", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addMapping("gs-", new KeyTrigger(KeyInput.KEY_SEMICOLON)); - inputManager.addListener(analog, "gs+", "gs-"); - - System.out.println("blue scale: press [ to increase, ' to decrease"); - inputManager.addMapping("bs+", new KeyTrigger(KeyInput.KEY_LBRACKET)); - inputManager.addMapping("bs-", new KeyTrigger(KeyInput.KEY_APOSTROPHE)); - inputManager.addListener(analog, "bs+", "bs-"); - - System.out.println(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java b/jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java deleted file mode 100644 index 6883ddcabf..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.CrossHatchFilter; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; - -public class TestCrossHatch extends SimpleApplication { - - private boolean active=true; - private FilterPostProcessor fpp; - - public static void main(String[] args){ - TestCrossHatch app = new TestCrossHatch(); - app.start(); - } - - @Override - public void simpleInitApp() { - // put the camera in a bad position - cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f)); - cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f)); - //cam.setFrustumFar(1000); - - - Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); - mat.setFloat("Shininess", 15f); - mat.setBoolean("UseMaterialColors", true); - mat.setColor("Ambient", ColorRGBA.Yellow.mult(0.2f)); - mat.setColor("Diffuse", ColorRGBA.Yellow.mult(0.2f)); - mat.setColor("Specular", ColorRGBA.Yellow.mult(0.8f)); - - - - - Material matSoil = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); - matSoil.setFloat("Shininess", 15f); - matSoil.setBoolean("UseMaterialColors", true); - matSoil.setColor("Ambient", ColorRGBA.Gray); - matSoil.setColor("Diffuse", ColorRGBA.Black); - matSoil.setColor("Specular", ColorRGBA.Gray); - - - Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); - teapot.setLocalTranslation(0,0,10); - - teapot.setMaterial(mat); - teapot.setShadowMode(ShadowMode.CastAndReceive); - teapot.setLocalScale(10.0f); - rootNode.attachChild(teapot); - - - - Geometry soil = new Geometry("soil", new Box(800, 10, 700)); - soil.setLocalTranslation(0, -13, 550); - soil.setMaterial(matSoil); - soil.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(soil); - - DirectionalLight light=new DirectionalLight(); - light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - light.setColor(ColorRGBA.White.mult(1.5f)); - rootNode.addLight(light); - - // load sky - Spatial sky = SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/FullskiesBlueClear03.dds", - EnvMapType.CubeMap); - sky.setCullHint(Spatial.CullHint.Never); - rootNode.attachChild(sky); - - fpp=new FilterPostProcessor(assetManager); - - int numSamples = getContext().getSettings().getSamples(); - if( numSamples > 0 ) { - fpp.setNumSamples(numSamples); - } - - CrossHatchFilter chf=new CrossHatchFilter(); - - - - viewPort.addProcessor(fpp); - fpp.addFilter(chf); - initInputs(); - - } - - private void initInputs() { - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - - ActionListener acl = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggle") && keyPressed) { - if(active){ - active=false; - viewPort.removeProcessor(fpp); - }else{ - active=true; - viewPort.addProcessor(fpp); - } - } - } - }; - - inputManager.addListener(acl, "toggle"); - - } - - - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java b/jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java deleted file mode 100644 index 3690fe9aa7..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.DepthOfFieldFilter; -import com.jme3.renderer.Camera; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; -import java.util.ArrayList; -import java.util.List; - -/** - * test - * @author Nehon - */ -public class TestDepthOfField extends SimpleApplication { - - final private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f); - private TerrainQuad terrain; - private DepthOfFieldFilter dofFilter; - - public static void main(String[] args) { - TestDepthOfField app = new TestDepthOfField(); - app.start(); - } - - @Override - public void simpleInitApp() { - - - Node mainScene = new Node("Main Scene"); - rootNode.attachChild(mainScene); - - createTerrain(mainScene); - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(1.7f)); - mainScene.addLight(sun); - - DirectionalLight l = new DirectionalLight(); - l.setDirection(Vector3f.UNIT_Y.mult(-1)); - l.setColor(ColorRGBA.White.clone().multLocal(0.3f)); - mainScene.addLight(l); - - flyCam.setMoveSpeed(50); - cam.setFrustumFar(3000); - cam.setLocation(new Vector3f(-700, 100, 300)); - cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0})); - - - Spatial sky = SkyFactory.createSky(assetManager, - "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); - sky.setLocalScale(350); - mainScene.attachChild(sky); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - // fpp.setNumSamples(4); - int numSamples = getContext().getSettings().getSamples(); - if( numSamples > 0 ) { - fpp.setNumSamples(numSamples); - } - - dofFilter = new DepthOfFieldFilter(); - dofFilter.setFocusDistance(0); - dofFilter.setFocusRange(50); - dofFilter.setBlurScale(1.4f); - fpp.addFilter(dofFilter); - viewPort.addProcessor(fpp); - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - if (name.equals("toggle")) { - dofFilter.setEnabled(!dofFilter.isEnabled()); - } - - - } - } - }, "toggle"); - inputManager.addListener(new AnalogListener() { - - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("blurScaleUp")) { - dofFilter.setBlurScale(dofFilter.getBlurScale() + 0.01f); - System.out.println("blurScale : " + dofFilter.getBlurScale()); - } - if (name.equals("blurScaleDown")) { - dofFilter.setBlurScale(dofFilter.getBlurScale() - 0.01f); - System.out.println("blurScale : " + dofFilter.getBlurScale()); - } - if (name.equals("focusRangeUp")) { - dofFilter.setFocusRange(dofFilter.getFocusRange() + 1f); - System.out.println("focusRange : " + dofFilter.getFocusRange()); - } - if (name.equals("focusRangeDown")) { - dofFilter.setFocusRange(dofFilter.getFocusRange() - 1f); - System.out.println("focusRange : " + dofFilter.getFocusRange()); - } - if (name.equals("focusDistanceUp")) { - dofFilter.setFocusDistance(dofFilter.getFocusDistance() + 1f); - System.out.println("focusDistance : " + dofFilter.getFocusDistance()); - } - if (name.equals("focusDistanceDown")) { - dofFilter.setFocusDistance(dofFilter.getFocusDistance() - 1f); - System.out.println("focusDistance : " + dofFilter.getFocusDistance()); - } - - } - }, "blurScaleUp", "blurScaleDown", "focusRangeUp", "focusRangeDown", "focusDistanceUp", "focusDistanceDown"); - - - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("blurScaleUp", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("blurScaleDown", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("focusRangeUp", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addMapping("focusRangeDown", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("focusDistanceUp", new KeyTrigger(KeyInput.KEY_O)); - inputManager.addMapping("focusDistanceDown", new KeyTrigger(KeyInput.KEY_L)); - - } - - private void createTerrain(Node rootNode) { - Material matRock = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - } catch (Exception e) { - e.printStackTrace(); - } - terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - List cameras = new ArrayList<>(); - cameras.add(getCamera()); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(5, 5, 5)); - terrain.setLocalTranslation(new Vector3f(0, -30, 0)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(terrain); - - } - - @Override - public void simpleUpdate(float tpf) { - Vector3f origin = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); - Vector3f direction = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); - direction.subtractLocal(origin).normalizeLocal(); - Ray ray = new Ray(origin, direction); - CollisionResults results = new CollisionResults(); - int numCollisions = terrain.collideWith(ray, results); - if (numCollisions > 0) { - CollisionResult hit = results.getClosestCollision(); - fpsText.setText(""+hit.getDistance()); - dofFilter.setFocusDistance(hit.getDistance()/10.0f); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java b/jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java deleted file mode 100644 index 72a4c875f5..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.Renderer; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture2D; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; -import com.jme3.ui.Picture; - -/** - * Demonstrates FrameBuffer usage. - * The scene is first rendered to an FB with a texture attached, - * the texture is then rendered onto the screen in ortho mode. - * - * @author Kirill - */ -public class TestFBOPassthrough extends SimpleApplication { - - final private Node fbNode = new Node("Framebuffer Node"); - private FrameBuffer fb; - - public static void main(String[] args){ - TestFBOPassthrough app = new TestFBOPassthrough(); - app.start(); - } - - @Override - public void simpleInitApp() { - int w = settings.getWidth(); - int h = settings.getHeight(); - - //setup framebuffer - fb = new FrameBuffer(w, h, 1); - - Texture2D fbTex = new Texture2D(w, h, Format.RGBA8); - fb.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); - fb.addColorTarget(FrameBufferTarget.newTarget(fbTex)); - - // setup framebuffer's scene - Sphere sphMesh = new Sphere(20, 20, 1); - Material solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); - - Geometry sphere = new Geometry("sphere", sphMesh); - sphere.setMaterial(solidColor); - fbNode.attachChild(sphere); - - //setup main scene - Picture p = new Picture("Picture"); - p.setPosition(0, 0); - p.setWidth(w); - p.setHeight(h); - p.setTexture(assetManager, fbTex, false); - - rootNode.attachChild(p); - } - - @Override - public void simpleUpdate(float tpf){ - fbNode.updateLogicalState(tpf); - fbNode.updateGeometricState(); - } - - @Override - public void simpleRender(RenderManager rm){ - Renderer r = rm.getRenderer(); - - //do FBO rendering - r.setFrameBuffer(fb); - - rm.setCamera(cam, false); // FBO uses current camera - r.clearBuffers(true, true, true); - rm.renderScene(fbNode, viewPort); - rm.flushQueue(viewPort); - - //go back to default rendering and let - //SimpleApplication render the default scene - r.setFrameBuffer(null); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestFog.java b/jme3-examples/src/main/java/jme3test/post/TestFog.java deleted file mode 100644 index b7a913d79f..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestFog.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.FogFilter; -import com.jme3.renderer.Camera; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Node; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.util.SkyFactory; -import java.util.ArrayList; -import java.util.List; - -public class TestFog extends SimpleApplication { - - private FilterPostProcessor fpp; - private boolean enabled=true; - private FogFilter fog; - - public static void main(String[] args) { - TestFog app = new TestFog(); - app.start(); - } - - @Override - public void simpleInitApp() { - this.flyCam.setMoveSpeed(50); - Node mainScene=new Node(); - cam.setLocation(new Vector3f(-34.74095f, 95.21318f, -287.4945f)); - cam.setRotation(new Quaternion(0.023536969f, 0.9361278f, -0.016098259f, -0.35050195f)); - - // load sky - mainScene.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - createTerrain(mainScene); - - - - DirectionalLight sun = new DirectionalLight(); - Vector3f lightDir=new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - mainScene.addLight(sun); - - rootNode.attachChild(mainScene); - - fpp=new FilterPostProcessor(assetManager); - //fpp.setNumSamples(4); - int numSamples = getContext().getSettings().getSamples(); - if( numSamples > 0 ) { - fpp.setNumSamples(numSamples); - } - fog=new FogFilter(); - fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f)); - fog.setFogDistance(155); - fog.setFogDensity(1.0f); - fpp.addFilter(fog); - viewPort.addProcessor(fpp); - initInputs(); - } - - private void initInputs() { - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("DensityUp", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("DensityDown", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("DistanceUp", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("DistanceDown", new KeyTrigger(KeyInput.KEY_J)); - - - ActionListener acl = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggle") && keyPressed) { - if(enabled){ - enabled=false; - viewPort.removeProcessor(fpp); - }else{ - enabled=true; - viewPort.addProcessor(fpp); - } - } - - } - }; - - AnalogListener anl=new AnalogListener() { - - @Override - public void onAnalog(String name, float isPressed, float tpf) { - if(name.equals("DensityUp")){ - fog.setFogDensity(fog.getFogDensity()+0.001f); - System.out.println("Fog density : "+fog.getFogDensity()); - } - if(name.equals("DensityDown")){ - fog.setFogDensity(fog.getFogDensity()-0.010f); - System.out.println("Fog density : "+fog.getFogDensity()); - } - if(name.equals("DistanceUp")){ - fog.setFogDistance(fog.getFogDistance()+0.5f); - System.out.println("Fog Distance : "+fog.getFogDistance()); - } - if(name.equals("DistanceDown")){ - fog.setFogDistance(fog.getFogDistance()-0.5f); - System.out.println("Fog Distance : "+fog.getFogDistance()); - } - - } - }; - - inputManager.addListener(acl, "toggle"); - inputManager.addListener(anl, "DensityUp","DensityDown","DistanceUp","DistanceDown"); - - } - - private void createTerrain(Node rootNode) { - Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(Texture.WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(Texture.WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - } catch (Exception e) { - e.printStackTrace(); - } - TerrainQuad terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - List cameras = new ArrayList<>(); - cameras.add(getCamera()); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(5, 5, 5)); - terrain.setLocalTranslation(new Vector3f(0, -30, 0)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(RenderQueue.ShadowMode.Receive); - rootNode.attachChild(terrain); - - } -} - diff --git a/jme3-examples/src/main/java/jme3test/post/TestIssue1798.java b/jme3-examples/src/main/java/jme3test/post/TestIssue1798.java deleted file mode 100644 index 79605f29a8..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestIssue1798.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.CartoonEdgeFilter; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.system.AppSettings; -import com.jme3.texture.Texture; - -/** - * Test case for JME issue #1798: filtered scenes are squeezed by resizable - * windows. - *

- * If successful, a cartoon monkey head will be shown, and resizing the window - * (using the system's window manager) will not change its shape. - *

- * If unsuccessful, then making the window taller will make the head taller, and - * making the window wider will make the head wider. - *

- * Based on the TestCartoonEdge application. - */ -public class TestIssue1798 extends SimpleApplication { - // ************************************************************************* - // fields - - private FilterPostProcessor fpp; - // ************************************************************************* - // new methods exposed - - public static void main(String[] args) { - AppSettings s = new AppSettings(true); - s.setResizable(true); - TestIssue1798 app = new TestIssue1798(); - app.setSettings(s); - app.start(); - } - // ************************************************************************* - // SimpleApplication methods - - /** - * Initialize this application. - */ - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.Gray); - flyCam.setDragToRotate(true); - setupLighting(); - setupModel(); - setupFilters(); - } - // ************************************************************************* - // private methods - - private void makeToonish(Spatial spatial) { - if (spatial instanceof Node) { - Node n = (Node) spatial; - for (Spatial child : n.getChildren()) { - makeToonish(child); - } - } else if (spatial instanceof Geometry) { - Geometry g = (Geometry) spatial; - Material m = g.getMaterial(); - if (m.getMaterialDef().getMaterialParam("UseMaterialColors") != null) { - Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png"); - m.setTexture("ColorRamp", t); - m.setBoolean("UseMaterialColors", true); - m.setColor("Specular", ColorRGBA.Black); - m.setColor("Diffuse", ColorRGBA.White); - m.setBoolean("VertexLighting", true); - } - } - } - - private void setupFilters() { - fpp = new FilterPostProcessor(assetManager); - int numSamples = getContext().getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - CartoonEdgeFilter toon = new CartoonEdgeFilter(); - toon.setEdgeColor(ColorRGBA.Yellow); - fpp.addFilter(toon); - viewPort.addProcessor(fpp); - } - - private void setupLighting() { - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, 1).normalizeLocal()); - dl.setColor(new ColorRGBA(2, 2, 2, 1)); - rootNode.addLight(dl); - } - - private void setupModel() { - Spatial model = assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml"); - makeToonish(model); - rootNode.attachChild(model); - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestLightScattering.java b/jme3-examples/src/main/java/jme3test/post/TestLightScattering.java deleted file mode 100644 index c2940cab6b..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestLightScattering.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.LightScatteringFilter; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.util.SkyFactory; -import com.jme3.util.TangentBinormalGenerator; - -public class TestLightScattering extends SimpleApplication { - - public static void main(String[] args) { - TestLightScattering app = new TestLightScattering(); - - app.start(); - } - - @Override - public void simpleInitApp() { - // put the camera in a bad position - cam.setLocation(new Vector3f(55.35316f, -0.27061665f, 27.092093f)); - cam.setRotation(new Quaternion(0.010414706f, 0.9874893f, 0.13880467f, -0.07409228f)); -// cam.setDirection(new Vector3f(0,-0.5f,1.0f)); -// cam.setLocation(new Vector3f(0, 300, -500)); - //cam.setFrustumFar(1000); - flyCam.setMoveSpeed(10); - Material mat = assetManager.loadMaterial("Textures/Terrain/Rocky/Rocky.j3m"); - Spatial scene = assetManager.loadModel("Models/Terrain/Terrain.mesh.xml"); - TangentBinormalGenerator.generate(((Geometry)((Node)scene).getChild(0)).getMesh()); - scene.setMaterial(mat); - scene.setShadowMode(ShadowMode.CastAndReceive); - scene.setLocalScale(400); - scene.setLocalTranslation(0, -10, -120); - - rootNode.attachChild(scene); - - // load sky - rootNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/FullskiesBlueClear03.dds", - SkyFactory.EnvMapType.CubeMap)); - - DirectionalLight sun = new DirectionalLight(); - Vector3f lightDir = new Vector3f(-0.12f, -0.3729129f, 0.74847335f); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - scene.addLight(sun); - - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - int numSamples = getContext().getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - Vector3f lightPos = lightDir.multLocal(-3000); - LightScatteringFilter filter = new LightScatteringFilter(lightPos); - LightScatteringUI ui = new LightScatteringUI(inputManager, filter); - fpp.addFilter(filter); - viewPort.addProcessor(fpp); - } - - @Override - public void simpleUpdate(float tpf) { - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java b/jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java deleted file mode 100644 index a5422ac539..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.post.SceneProcessor; -import com.jme3.profile.AppProfiler; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture2D; -import com.jme3.ui.Picture; - -/** - * Demonstrates rendering to multiple texture targets of a single FrameBuffer. - * - *

The GUI viewport is tiled into 4 pictures, - * each displaying a different render of 5 colorful cubes in the main scene. - */ -public class TestMultiRenderTarget extends SimpleApplication implements SceneProcessor { - private FrameBuffer fb; - /** - * Displays the merged RGB (normal color) output

    - *
  • from "ExtractRGB.frag" location 3,
  • - *
  • in the lower-left quadrant of the window.
- */ - private Picture display1; - /** - * Displays the red-channel output in color
    - *
  • from "ExtractRGB.frag" location 0,
  • - *
  • in the upper-left quadrant of the window.
- */ - private Picture display2; - /** - * Displays the green-channel output in monochrome
    - *
  • from ExtractRGB.frag location 1,
  • - *
  • in the upper-right quadrant of the window.
- */ - private Picture display3; - /** - * Displays the blue-channel output in monochrome
    - *
  • from ExtractRGB.frag location 2,
  • - *
  • in the lower-right quadrant of the window.
- */ - private Picture display4; - - private boolean initialized = false; - - /** - * The main entry point for the TestMultiRenderTarget application. - * - * @param args unused - */ - public static void main(String[] args) { - TestMultiRenderTarget app = new TestMultiRenderTarget(); - app.start(); - } - - /** - * Add 5 colorful cubes to the main scene. - */ - protected void buildScene() { - Geometry cube1 = buildCube(ColorRGBA.Red); - cube1.setLocalTranslation(-1f, 0f, 0f); - Geometry cube2 = buildCube(ColorRGBA.Green); - cube2.setLocalTranslation(0f, 0f, 0f); - Geometry cube3 = buildCube(ColorRGBA.Blue); - cube3.setLocalTranslation(1f, 0f, 0f); - - Geometry cube4 = buildCube(ColorRGBA.randomColor()); - cube4.setLocalTranslation(-0.5f, 1f, 0f); - Geometry cube5 = buildCube(ColorRGBA.randomColor()); - cube5.setLocalTranslation(0.5f, 1f, 0f); - - rootNode.attachChild(cube1); - rootNode.attachChild(cube2); - rootNode.attachChild(cube3); - rootNode.attachChild(cube4); - rootNode.attachChild(cube5); - } - - /** - * Create a cube with the specified color, - * using a custom unshaded material that outputs 4 textures:
    - *
  • red channel only to location 0,
  • - *
  • green channel only to location 1,
  • - *
  • blue channel only to location 2,
  • - *
  • merged RGB to location 3.
- * - * @param color the desired albedo color (alias created) - * @return a new Geometry with no parent - */ - private Geometry buildCube(ColorRGBA color) { - Geometry cube = new Geometry("Box", new Box(0.5f, 0.5f, 0.5f)); - Material mat = new Material(assetManager, "TestMRT/MatDefs/ExtractRGB.j3md"); - mat.setColor("Albedo", color); - cube.setMaterial(mat); - return cube; - } - - @Override - public void simpleInitApp() { - viewPort.addProcessor(this); - buildScene(); - - display1 = new Picture("Picture"); - display1.move(0, 0, -1); // make it appear behind stats view - display2 = (Picture) display1.clone(); - display3 = (Picture) display1.clone(); - display4 = (Picture) display1.clone(); - } - - @Override - public void destroy() { - viewPort.removeProcessor(this); - super.destroy(); - } - - // Scene Processor from now on - @Override - public void initialize(RenderManager rm, ViewPort vp) { - reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight()); - viewPort.setOutputFrameBuffer(fb); - guiViewPort.setClearFlags(true, true, true); - - guiNode.attachChild(display1); - guiNode.attachChild(display2); - guiNode.attachChild(display3); - guiNode.attachChild(display4); - guiNode.updateGeometricState(); - } - - @Override - public void reshape(ViewPort vp, int w, int h) { - // You can use multiple channel formats as well. That's why red is using RGBA8 as an example. - Texture2D redTexture = new Texture2D(w, h, Format.RGBA8); // color texture - Texture2D greenTexture = new Texture2D(w, h, Format.Luminance8); // monochrome texture - Texture2D blueTexture = new Texture2D(w, h, Format.Luminance8); // monochrome texture - Texture2D rgbTexture = new Texture2D(w, h, Format.RGBA8); // color texture - - fb = new FrameBuffer(w, h, 1); - fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(redTexture)); // location 0 - fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(greenTexture)); // location 1 - fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(blueTexture)); // location 2 - fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(rgbTexture)); // location 3 - fb.setMultiTarget(true); - - display1.setTexture(assetManager, rgbTexture, false); - display2.setTexture(assetManager, redTexture, false); - display3.setTexture(assetManager, greenTexture, false); - display4.setTexture(assetManager, blueTexture, false); - - display1.setPosition(0, 0); // lower-left quadrant - display1.setWidth(w / 2f); - display1.setHeight(h / 2f); - - display2.setPosition(0, h / 2f); // upper-left quadrant - display2.setWidth(w / 2f); - display2.setHeight(h / 2f); - - display3.setPosition(w / 2f, h / 2f); // upper-right quadrant - display3.setWidth(w / 2f); - display3.setHeight(h / 2f); - - display4.setPosition(w / 2f, 0f); // lower-right quadrant - display4.setWidth(w / 2f); - display4.setHeight(h / 2f); - - guiNode.updateGeometricState(); - initialized = true; - } - - @Override - public boolean isInitialized() { - return initialized; - } - - @Override - public void preFrame(float tpf) { - } - - @Override - public void postQueue(RenderQueue rq) { - } - - @Override - public void postFrame(FrameBuffer out) { - } - - @Override - public void cleanup() { - initialized = false; - } - - @Override - public void setProfiler(AppProfiler profiler) { - // not implemented - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java b/jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java deleted file mode 100644 index fe0484ece5..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.*; -import com.jme3.post.ssao.SSAOFilter; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.util.SkyFactory; - -public class TestMultiViewsFilters extends SimpleApplication { - - public static void main(String[] args) { - TestMultiViewsFilters app = new TestMultiViewsFilters(); - app.start(); - } - private boolean filterEnabled = true; - - @Override - public void simpleInitApp() { - // create the geometry and attach it - Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - teaGeom.scale(3); - teaGeom.getMaterial().setColor("GlowColor", ColorRGBA.Green); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White); - dl.setDirection(Vector3f.UNIT_XYZ.negate()); - - rootNode.addLight(dl); - rootNode.attachChild(teaGeom); - - // Setup first view - cam.setViewPort(.5f, 1f, 0f, 0.5f); - cam.setLocation(new Vector3f(3.3212643f, 4.484704f, 4.2812433f)); - cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f)); - - // Setup second view - Camera cam2 = cam.clone(); - cam2.setViewPort(0f, 0.5f, 0f, 0.5f); - cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f)); - cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f)); - - final ViewPort view2 = renderManager.createMainView("Bottom Left", cam2); - view2.setClearFlags(true, true, true); - view2.attachScene(rootNode); - - // Setup third view - Camera cam3 = cam.clone(); - cam3.setName("cam3"); - cam3.setViewPort(0f, .5f, .5f, 1f); - cam3.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f)); - cam3.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f)); - - final ViewPort view3 = renderManager.createMainView("Top Left", cam3); - view3.setClearFlags(true, true, true); - view3.attachScene(rootNode); - - - // Setup fourth view - Camera cam4 = cam.clone(); - cam4.setName("cam4"); - cam4.setViewPort(.5f, 1f, .5f, 1f); - - cam4.setLocation(new Vector3f(4.775564f, 1.4548365f, 0.11491505f)); - cam4.setRotation(new Quaternion(0.02356979f, -0.74957186f, 0.026729556f, 0.66096294f)); - - final ViewPort view4 = renderManager.createMainView("Top Right", cam4); - view4.setClearFlags(true, true, true); - view4.attachScene(rootNode); - -// Camera cam5 = new Camera(200, 200); -// cam5.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f); -// cam5.setName("cam5"); -// cam5.setViewPort(5.23f, 6.33f, 0.56f, 1.66f); -// this.setViewPortAreas(5.23f, 6.33f, 0.56f, 1.66f); -// this.setViewPortCamSize(200, 200); -// 1046,1266,112,332 - Camera cam5 = cam.clone(); - cam5.setName("cam5"); - cam5.setViewPort(1046f/settings.getWidth(), 1266f/settings.getWidth(), 112f/settings.getHeight(), 332f/settings.getHeight()); - cam5.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f)); - cam5.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f)); - - final ViewPort view5 = renderManager.createMainView("center", cam5); - view5.setClearFlags(true, true, true); - view5.attachScene(rootNode); - - - - rootNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - - final FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - final FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager); - final FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager); - final FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager); - final FilterPostProcessor fpp5 = new FilterPostProcessor(assetManager); - - - // fpp.addFilter(new WaterFilter(rootNode, Vector3f.UNIT_Y.mult(-1))); - fpp3.addFilter(new CartoonEdgeFilter()); - - fpp2.addFilter(new CrossHatchFilter()); - final FogFilter ff = new FogFilter(ColorRGBA.Yellow, 0.7f, 2); - fpp.addFilter(ff); - - final RadialBlurFilter rbf = new RadialBlurFilter(1, 10); - // rbf.setEnabled(false); - fpp.addFilter(rbf); - - - SSAOFilter f = new SSAOFilter(1.8899765f, 20.490374f, 0.4699998f, 0.1f); - fpp4.addFilter(f); - SSAOUI ui = new SSAOUI(inputManager, f); - - fpp5.addFilter(new BloomFilter(BloomFilter.GlowMode.Objects)); - - viewPort.addProcessor(fpp); - view2.addProcessor(fpp2); - view3.addProcessor(fpp3); - view4.addProcessor(fpp4); - view5.addProcessor(fpp5); - - - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals("press") && isPressed) { - if (filterEnabled) { - viewPort.removeProcessor(fpp); - view2.removeProcessor(fpp2); - view3.removeProcessor(fpp3); - view4.removeProcessor(fpp4); - view5.removeProcessor(fpp5); - } else { - viewPort.addProcessor(fpp); - view2.addProcessor(fpp2); - view3.addProcessor(fpp3); - view4.addProcessor(fpp4); - view5.addProcessor(fpp5); - } - filterEnabled = !filterEnabled; - } - if (name.equals("filter") && isPressed) { - ff.setEnabled(!ff.isEnabled()); - rbf.setEnabled(!rbf.isEnabled()); - } - } - }, "press", "filter"); - - inputManager.addMapping("press", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("filter", new KeyTrigger(KeyInput.KEY_F)); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java b/jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java deleted file mode 100644 index 0d150bfe1a..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.asset.plugins.ZipLocator; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.post.filters.ColorOverlayFilter; -import com.jme3.post.ssao.SSAOFilter; -import com.jme3.scene.Spatial; -import com.jme3.util.SkyFactory; -import com.jme3.water.WaterFilter; -import java.io.File; - -public class TestMultiplesFilters extends SimpleApplication { - - private static boolean useHttp = false; - - public static void main(String[] args) { - TestMultiplesFilters app = new TestMultiplesFilters(); - app.start(); - } - private SSAOFilter ssaoFilter; - - @Override - public void simpleInitApp() { - File file = new File("wildhouse.zip"); - if (!file.exists()) { - useHttp = true; - } - - this.flyCam.setMoveSpeed(10); - cam.setLocation(new Vector3f(6.0344796f, 1.5054002f, 55.572033f)); - cam.setRotation(new Quaternion(0.0016069f, 0.9810479f, -0.008143323f, 0.19358753f)); - - // load sky - rootNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - - // create the geometry and attach it - // load the level from zip or http zip - if (useHttp) { - assetManager.registerLocator( - "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", - HttpZipLocator.class); - } else { - assetManager.registerLocator("wildhouse.zip", ZipLocator.class); - } - Spatial scene = assetManager.loadModel("main.scene"); - - - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f)); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - scene.addLight(sun); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - // fpp.setNumSamples(4); - ssaoFilter = new SSAOFilter(0.92f, 2.2f, 0.46f, 0.2f); - final WaterFilter water=new WaterFilter(rootNode,new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f)); - water.setWaterHeight(-20); - SSAOUI ui=new SSAOUI(inputManager,ssaoFilter); - final BloomFilter bloom = new BloomFilter(); - final ColorOverlayFilter overlay = new ColorOverlayFilter(ColorRGBA.LightGray); - - - fpp.addFilter(ssaoFilter); - - fpp.addFilter(water); - - fpp.addFilter(bloom); - - fpp.addFilter(overlay); - - viewPort.addProcessor(fpp); - - rootNode.attachChild(scene); - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if ("toggleSSAO".equals(name) && isPressed) { - if (ssaoFilter.isEnabled()) { - ssaoFilter.setEnabled(false); - } else { - ssaoFilter.setEnabled(true); - } - } - if ("toggleWater".equals(name) && isPressed) { - if (water.isEnabled()) { - water.setEnabled(false); - } else { - water.setEnabled(true); - } - } - if ("toggleBloom".equals(name) && isPressed) { - if (bloom.isEnabled()) { - bloom.setEnabled(false); - } else { - bloom.setEnabled(true); - } - } - if ("toggleOverlay".equals(name) && isPressed) { - if (overlay.isEnabled()) { - overlay.setEnabled(false); - } else { - overlay.setEnabled(true); - } - } - } - }, "toggleSSAO", "toggleBloom", "toggleWater","toggleOverlay"); - inputManager.addMapping("toggleSSAO", new KeyTrigger(KeyInput.KEY_1)); - inputManager.addMapping("toggleWater", new KeyTrigger(KeyInput.KEY_2)); - inputManager.addMapping("toggleBloom", new KeyTrigger(KeyInput.KEY_3)); - inputManager.addMapping("toggleOverlay", new KeyTrigger(KeyInput.KEY_4)); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestPostFilters.java b/jme3-examples/src/main/java/jme3test/post/TestPostFilters.java deleted file mode 100644 index b7f6658ce7..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestPostFilters.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.*; -import com.jme3.renderer.Caps; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.texture.Texture; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; -import com.jme3.util.TangentBinormalGenerator; - -public class TestPostFilters extends SimpleApplication implements ActionListener { - - private FilterPostProcessor fpp; - final private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); - private FadeFilter fade; - - public static void main(String[] args) { - TestPostFilters app = new TestPostFilters(); -// AppSettings settings = new AppSettings(true); -// settings.setRenderer(AppSettings.LWJGL_OPENGL2); -// app.setSettings(settings); - app.start(); - } - - public void setupFilters() { - if (renderer.getCaps().contains(Caps.GLSL100)) { - fpp = new FilterPostProcessor(assetManager); - // fpp.setNumSamples(4); - // fpp.setNumSamples(4); - //fpp.addFilter(new ColorOverlayFilter(ColorRGBA.LightGray)); - fpp.addFilter(new RadialBlurFilter()); - fade = new FadeFilter(1.0f); - fpp.addFilter(fade); - - - viewPort.addProcessor(fpp); - } - } - - public void setupSkyBox() { - Texture envMap; - if (renderer.getCaps().contains(Caps.FloatTexture)) { - envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.hdr"); - } else { - envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.jpg"); - } - Spatial sky = SkyFactory.createSky(assetManager, envMap, - new Vector3f(-1f, -1f, -1f), EnvMapType.SphereMap); - rootNode.attachChild(sky); - } - - public void setupLighting() { - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(lightDir); - - dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); - - rootNode.addLight(dl); - - dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1, 0, -1).normalizeLocal()); - - dl.setColor(new ColorRGBA(.4f, .4f, .4f, 1)); - - // rootNode.addLight(dl); - } - - public void setupFloor() { - Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); - Box floor = new Box(50, 1f, 50); - TangentBinormalGenerator.generate(floor); - floor.scaleTextureCoordinates(new Vector2f(5, 5)); - Geometry floorGeom = new Geometry("Floor", floor); - floorGeom.setMaterial(mat); - floorGeom.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(floorGeom); - } - - public void setupSignpost() { - Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); - Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); - signpost.setMaterial(mat); - signpost.rotate(0, FastMath.HALF_PI, 0); - signpost.setLocalTranslation(12, 3.5f, 30); - signpost.setLocalScale(4); - signpost.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(signpost); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(-32.295086f, 54.80136f, 79.59805f)); - cam.setRotation(new Quaternion(0.074364014f, 0.92519957f, -0.24794696f, 0.27748522f)); - - setupLighting(); - setupSkyBox(); - - - setupFloor(); - - setupSignpost(); - - setupFilters(); - - initInput(); - - } - - protected void initInput() { - flyCam.setMoveSpeed(50); - //init input - inputManager.addMapping("fadein", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addListener(this, "fadein"); - inputManager.addMapping("fadeout", new KeyTrigger(KeyInput.KEY_O)); - inputManager.addListener(this, "fadeout"); - - } - - @Override - public void onAction(String name, boolean value, float tpf) { - if (name.equals("fadein") && value) { - fade.fadeIn(); - System.out.println("fade in"); - - } - if (name.equals("fadeout") && value) { - fade.fadeOut(); - System.out.println("fade out"); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java b/jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java deleted file mode 100644 index 8661ee550e..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.ColorOverlayFilter; -import com.jme3.post.filters.ComposeFilter; -import com.jme3.scene.Spatial; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image; -import com.jme3.texture.Texture2D; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; -import com.jme3.texture.Image.Format; -import com.jme3.util.SkyFactory; - -/** - * This test showcases the possibility to compose the post filtered outputs of several viewports. - * The usual use case is when you want to apply some post process to the main viewport and then other post process to the gui viewport - * @author Nehon - */ -public class TestPostFiltersCompositing extends SimpleApplication { - - public static void main(String[] args) { - TestPostFiltersCompositing app = new TestPostFiltersCompositing(); -// AppSettings settings = new AppSettings(true); -// settings.putBoolean("GraphicsDebug", false); -// app.setSettings(settings); - app.start(); - - } - - @Override - public void simpleInitApp() { - this.flyCam.setMoveSpeed(10); - cam.setLocation(new Vector3f(0.028406568f, 2.015769f, 7.386517f)); - cam.setRotation(new Quaternion(-1.0729783E-5f, 0.9999721f, -0.0073241726f, -0.0014647911f)); - - - makeScene(); - - //Creating the main view port post processor - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(new ColorOverlayFilter(ColorRGBA.Blue)); - viewPort.addProcessor(fpp); - - //creating a frame buffer for the main viewport - FrameBuffer mainVPFrameBuffer = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); - Texture2D mainVPTexture = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); - mainVPFrameBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); - mainVPFrameBuffer.addColorTarget(FrameBufferTarget.newTarget(mainVPTexture)); - - viewPort.setOutputFrameBuffer(mainVPFrameBuffer); - - // Create the post processor for the GUI viewport. - final FilterPostProcessor guiFpp = new FilterPostProcessor(assetManager); - guiFpp.setFrameBufferFormat(Image.Format.RGBA8); - guiFpp.addFilter(new ColorOverlayFilter(ColorRGBA.Red)); - // This will compose the main viewport texture with the GUI-viewport back buffer. - // Note that you can switch the order of the filters so that GUI-viewport filters are applied or not to the main viewport texture - guiFpp.addFilter(new ComposeFilter(mainVPTexture)); - - guiViewPort.addProcessor(guiFpp); - - // Compositing is done by mixing texture depending on the alpha channel, so - // it's important that the GUI-viewport clear-color alpha value is set to 0. - guiViewPort.setBackgroundColor(ColorRGBA.BlackNoAlpha); - guiViewPort.setClearColor(true); - - - } - - private void makeScene() { - // load sky - rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap)); - //assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/wildhouse.zip", HttpZipLocator.class); - Spatial scene = assetManager.loadModel("Models/Test/CornellBox.j3o"); - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f)); - scene.addLight(sun); - rootNode.attachChild(scene); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestPosterization.java b/jme3-examples/src/main/java/jme3test/post/TestPosterization.java deleted file mode 100644 index aebb415a07..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestPosterization.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.PosterizationFilter; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.util.SkyFactory; - -public class TestPosterization extends SimpleApplication { - - private PosterizationFilter pf; - - public static void main(String[] args){ - TestPosterization app = new TestPosterization(); - app.start(); - } - - @Override - public void simpleInitApp() { - // put the camera in a bad position - cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f)); - cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f)); - - Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); - mat.setFloat("Shininess", 15f); - mat.setBoolean("UseMaterialColors", true); - mat.setColor("Ambient", ColorRGBA.Yellow.mult(0.2f)); - mat.setColor("Diffuse", ColorRGBA.Yellow.mult(0.2f)); - mat.setColor("Specular", ColorRGBA.Yellow.mult(0.8f)); - - Material matSoil = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); - matSoil.setFloat("Shininess", 15f); - matSoil.setBoolean("UseMaterialColors", true); - matSoil.setColor("Ambient", ColorRGBA.Gray); - matSoil.setColor("Diffuse", ColorRGBA.Black); - matSoil.setColor("Specular", ColorRGBA.Gray); - - Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); - teapot.setLocalTranslation(0,0,10); - - teapot.setMaterial(mat); - teapot.setShadowMode(ShadowMode.CastAndReceive); - teapot.setLocalScale(10.0f); - rootNode.attachChild(teapot); - - Geometry soil = new Geometry("soil", new Box(800, 10, 700)); - soil.setLocalTranslation(0, -13, 550); - soil.setMaterial(matSoil); - soil.setShadowMode(ShadowMode.CastAndReceive); - rootNode.attachChild(soil); - - DirectionalLight light=new DirectionalLight(); - light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - light.setColor(ColorRGBA.White.mult(1.5f)); - rootNode.addLight(light); - - // load sky - Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/FullskiesBlueClear03.dds", SkyFactory.EnvMapType.CubeMap); - sky.setCullHint(Spatial.CullHint.Never); - rootNode.attachChild(sky); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - int numSamples = getContext().getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - pf = new PosterizationFilter(); - fpp.addFilter(pf); - - viewPort.addProcessor(fpp); - initInputs(); - - } - - private void initInputs() { - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - - ActionListener acl = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggle") && keyPressed) { - pf.setEnabled(!pf.isEnabled()); - } - } - }; - - inputManager.addListener(acl, "toggle"); - - } - - - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java b/jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java deleted file mode 100644 index da00ccecd5..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture; -import com.jme3.texture.TextureCubeMap; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; - -/** - * Renders a rotating box to a cubemap texture, then applies the cubemap - * texture as a sky. - */ -public class TestRenderToCubemap extends SimpleApplication { - - private Geometry offBox; - private float angle = 0; - - public static void main(String[] args){ - TestRenderToCubemap app = new TestRenderToCubemap(); - app.start(); - } - - public Texture setupOffscreenView(){ - Camera offCamera = new Camera(512, 512); - - ViewPort offView - = renderManager.createPreView("Offscreen View", offCamera); - offView.setClearFlags(true, true, true); - offView.setBackgroundColor(ColorRGBA.DarkGray); - - // create offscreen framebuffer - FrameBuffer offBuffer = new FrameBuffer(512, 512, 1); - - //setup framebuffer's cam - offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f); - offCamera.setLocation(new Vector3f(0f, 0f, -5f)); - offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); - - //setup framebuffer's texture - TextureCubeMap offTex = new TextureCubeMap(512, 512, Format.RGBA8); - offTex.setMinFilter(Texture.MinFilter.Trilinear); - offTex.setMagFilter(Texture.MagFilter.Bilinear); - - //setup framebuffer to use texture - offBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); - offBuffer.setMultiTarget(true); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.NegativeX)); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.PositiveX)); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.NegativeY)); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.PositiveY)); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.NegativeZ)); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.PositiveZ)); - - //set viewport to render to offscreen framebuffer - offView.setOutputFrameBuffer(offBuffer); - - // setup framebuffer's scene - Box boxMesh = new Box( 1,1,1); - Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); - offBox = new Geometry("box", boxMesh); - offBox.setMaterial(material); - - // attach the scene to the viewport to be rendered - offView.attachScene(offBox); - - return offTex; - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(3, 3, 3)); - cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - - Texture offTex = setupOffscreenView(); - Spatial sky = SkyFactory.createSky(assetManager, offTex, - EnvMapType.CubeMap); - rootNode.attachChild(sky); - } - - @Override - public void simpleUpdate(float tpf){ - Quaternion q = new Quaternion(); - - angle += tpf; - angle %= FastMath.TWO_PI; - q.fromAngles(angle, 0, angle); - - offBox.setLocalRotation(q); - offBox.updateLogicalState(tpf); - offBox.updateGeometricState(); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java b/jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java deleted file mode 100644 index 1cfa50b9a2..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.SceneProcessor; -import com.jme3.profile.AppProfiler; -import com.jme3.renderer.Camera; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeContext.Type; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; -import com.jme3.texture.Image.Format; -import com.jme3.util.BufferUtils; -import com.jme3.util.Screenshots; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; -import java.nio.ByteBuffer; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; - -/** - * This test renders a scene to an offscreen framebuffer, then copies - * the contents to a Swing JFrame. Note that some parts are done inefficiently, - * this is done to make the code more readable. - */ -public class TestRenderToMemory extends SimpleApplication implements SceneProcessor { - - private Geometry offBox; - private float angle = 0; - - private FrameBuffer offBuffer; - private ImageDisplay display; - - private static final int width = 800, height = 600; - - private final ByteBuffer cpuBuf = BufferUtils.createByteBuffer(width * height * 4); - private final BufferedImage image = new BufferedImage(width, height, - BufferedImage.TYPE_INT_BGR); - - private class ImageDisplay extends JPanel { - - private long t; - private long total; - private int frames; - private int fps; - - @Override - public void paintComponent(Graphics gfx) { - super.paintComponent(gfx); - Graphics2D g2d = (Graphics2D) gfx; - - if (t == 0) - t = timer.getTime(); - -// g2d.setBackground(Color.BLACK); -// g2d.clearRect(0,0,width,height); - - synchronized (image){ - g2d.drawImage(image, null, 0, 0); - } - - long t2 = timer.getTime(); - long dt = t2 - t; - total += dt; - frames ++; - t = t2; - - if (total > timer.getResolution()) { - fps = frames; - total = 0; - frames = 0; - } - - g2d.setColor(Color.white); - g2d.drawString("FPS: "+fps, 0, getHeight() - 100); - } - } - - public static void main(String[] args){ - TestRenderToMemory app = new TestRenderToMemory(); - app.setPauseOnLostFocus(false); - AppSettings settings = new AppSettings(true); - settings.setResolution(1, 1); - app.setSettings(settings); - app.start(Type.OffscreenSurface); - } - - public void createDisplayFrame(){ - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - JFrame frame = new JFrame("Render Display"); - display = new ImageDisplay(); - display.setPreferredSize(new Dimension(width, height)); - frame.getContentPane().add(display); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.addWindowListener(new WindowAdapter(){ - @Override - public void windowClosed(WindowEvent e){ - stop(); - } - }); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setResizable(false); - frame.setVisible(true); - } - }); - } - - public void updateImageContents(){ - cpuBuf.clear(); - renderer.readFrameBuffer(offBuffer, cpuBuf); - - synchronized (image) { - Screenshots.convertScreenShot2(cpuBuf.asIntBuffer(), image); - } - - if (display != null) - display.repaint(); - } - - public void setupOffscreenView(){ - Camera offCamera = new Camera(width, height); - - // create a pre-view. a view that is rendered before the main view - ViewPort offView - = renderManager.createPreView("Offscreen View", offCamera); - offView.setBackgroundColor(ColorRGBA.DarkGray); - offView.setClearFlags(true, true, true); - - // this will let us know when the scene has been rendered to the - // frame buffer - offView.addProcessor(this); - - // create offscreen framebuffer - offBuffer = new FrameBuffer(width, height, 1); - - //setup framebuffer's cam - offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f); - offCamera.setLocation(new Vector3f(0f, 0f, -5f)); - offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); - - //setup framebuffer's texture -// offTex = new Texture2D(width, height, Format.RGBA8); - - //setup framebuffer to use renderbuffer - // this is faster for gpu -> cpu copies - offBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(Format.RGBA8)); - - //set viewport to render to offscreen framebuffer - offView.setOutputFrameBuffer(offBuffer); - - // setup framebuffer's scene - Box boxMesh = new Box(1, 1, 1); - Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); - offBox = new Geometry("box", boxMesh); - offBox.setMaterial(material); - - // attach the scene to the viewport to be rendered - offView.attachScene(offBox); - } - - @Override - public void simpleInitApp() { - setupOffscreenView(); - createDisplayFrame(); - } - - @Override - public void simpleUpdate(float tpf){ - Quaternion q = new Quaternion(); - angle += tpf; - angle %= FastMath.TWO_PI; - q.fromAngles(angle, 0, angle); - - offBox.setLocalRotation(q); - offBox.updateLogicalState(tpf); - offBox.updateGeometricState(); - } - - @Override - public void initialize(RenderManager rm, ViewPort vp) { - } - - @Override - public void reshape(ViewPort vp, int w, int h) { - } - - @Override - public boolean isInitialized() { - return true; - } - - @Override - public void preFrame(float tpf) { - } - - @Override - public void postQueue(RenderQueue rq) { - } - - /** - * Update the CPU image's contents after the scene has - * been rendered to the framebuffer. - */ - @Override - public void postFrame(FrameBuffer out) { - updateImageContents(); - } - - @Override - public void cleanup() { - } - - @Override - public void setProfiler(AppProfiler profiler) { - // not implemented - } - - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java b/jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java deleted file mode 100644 index 88de57274d..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; - -/** - * This test renders a scene to a texture, then displays the texture on a cube. - */ -public class TestRenderToTexture extends SimpleApplication implements ActionListener { - - private static final String TOGGLE_UPDATE = "Toggle Update"; - private Geometry offBox; - private float angle = 0; - private ViewPort offView; - - public static void main(String[] args){ - TestRenderToTexture app = new TestRenderToTexture(); - app.start(); - } - - public Texture setupOffscreenView(){ - Camera offCamera = new Camera(512, 512); - - offView = renderManager.createPreView("Offscreen View", offCamera); - offView.setClearFlags(true, true, true); - offView.setBackgroundColor(ColorRGBA.DarkGray); - - // create offscreen framebuffer - FrameBuffer offBuffer = new FrameBuffer(512, 512, 1); - - //setup framebuffer's cam - offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f); - offCamera.setLocation(new Vector3f(0f, 0f, -5f)); - offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); - - //setup framebuffer's texture - Texture2D offTex = new Texture2D(512, 512, Format.RGBA8); - offTex.setMinFilter(Texture.MinFilter.Trilinear); - offTex.setMagFilter(Texture.MagFilter.Bilinear); - - //setup framebuffer to use texture - offBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); - offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex)); - - //set viewport to render to offscreen framebuffer - offView.setOutputFrameBuffer(offBuffer); - - // setup framebuffer's scene - Box boxMesh = new Box(1, 1, 1); - Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); - offBox = new Geometry("box", boxMesh); - offBox.setMaterial(material); - - // attach the scene to the viewport to be rendered - offView.attachScene(offBox); - - return offTex; - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(3, 3, 3)); - cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - - //setup main scene - Geometry quad = new Geometry("box", new Box(1, 1, 1)); - - Texture offTex = setupOffscreenView(); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", offTex); - quad.setMaterial(mat); - rootNode.attachChild(quad); - inputManager.addMapping(TOGGLE_UPDATE, new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addListener(this, TOGGLE_UPDATE); - } - - @Override - public void simpleUpdate(float tpf){ - Quaternion q = new Quaternion(); - - if (offView.isEnabled()) { - angle += tpf; - angle %= FastMath.TWO_PI; - q.fromAngles(angle, 0, angle); - - offBox.setLocalRotation(q); - offBox.updateLogicalState(tpf); - offBox.updateGeometricState(); - } - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (name.equals(TOGGLE_UPDATE) && isPressed) { - offView.setEnabled(!offView.isEnabled()); - } - } - - -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestSSAO.java b/jme3-examples/src/main/java/jme3test/post/TestSSAO.java deleted file mode 100644 index 9275feb23d..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestSSAO.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.ssao.SSAOFilter; -import com.jme3.scene.Geometry; -import com.jme3.texture.Texture; - -public class TestSSAO extends SimpleApplication { - - public static void main(String[] args) { - TestSSAO app = new TestSSAO(); - app.start(); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(68.45442f, 8.235511f, 7.9676695f)); - cam.setRotation(new Quaternion(0.046916496f, -0.69500375f, 0.045538206f, 0.7160271f)); - - - flyCam.setMoveSpeed(50); - - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - Texture diff = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"); - diff.setWrap(Texture.WrapMode.Repeat); - Texture norm = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall_normal.jpg"); - norm.setWrap(Texture.WrapMode.Repeat); - mat.setTexture("DiffuseMap", diff); - mat.setTexture("NormalMap", norm); - mat.setFloat("Shininess", 2.0f); - - - AmbientLight al = new AmbientLight(); - al.setColor(new ColorRGBA(1.8f, 1.8f, 1.8f, 1.0f)); - - rootNode.addLight(al); - - Geometry model - = (Geometry) assetManager.loadModel("Models/Sponza/Sponza.j3o"); - model.getMesh().scaleTextureCoordinates(new Vector2f(2, 2)); - - model.setMaterial(mat); - - rootNode.attachChild(model); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - SSAOFilter ssaoFilter = new SSAOFilter(2.9299974f,32.920483f,5.8100376f,0.091000035f); - ssaoFilter.setApproximateNormals(true); - fpp.addFilter(ssaoFilter); - SSAOUI ui = new SSAOUI(inputManager, ssaoFilter); - - viewPort.addProcessor(fpp); - } - - @Override - public void simpleUpdate(float tpf) { - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestSSAO2.java b/jme3-examples/src/main/java/jme3test/post/TestSSAO2.java deleted file mode 100644 index 34fe62e27c..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestSSAO2.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.*; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.app.DetailedProfilerState; -import com.jme3.post.ssao.SSAOFilter; -import com.jme3.scene.*; -import com.jme3.scene.shape.Box; - -public class TestSSAO2 extends SimpleApplication { - - public static void main(String[] args) { - TestSSAO2 app = new TestSSAO2(); - app.start(); - } - - @Override - public void simpleInitApp() { - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1,-1,-1).normalizeLocal()); - rootNode.addLight(dl); - - flyCam.setDragToRotate(true); - setPauseOnLostFocus(false); - - getStateManager().attach(new DetailedProfilerState()); - - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - mat.setFloat("Shininess", 16f); - //mat.setBoolean("VertexLighting", true); - - - Geometry floor = new Geometry("floor", new Box(1000,0.1f,1000)); - floor.setMaterial(mat); - rootNode.attachChild(floor); - - Node teapotNode = (Node) assetManager.loadModel("Models/Teapot/Teapot.mesh.xml"); - Geometry teapot = (Geometry) teapotNode.getChild(0); - teapot.setMaterial(mat); -// Sphere sph = new Sphere(16, 16, 4); -// Geometry teapot = new Geometry("teapot", sph); - - - - // A special Material to visualize mesh normals: - //Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - for (int f = 10; f > 3; f--) { - for (int y = -f; y < f; y++) { - for (int x = -f; x < f; x++) { - Geometry clonePot = teapot.clone(); - - //clonePot.setMaterial(mat); - clonePot.setLocalTranslation(x * .5f, 10 - f, y * .5f); - clonePot.setLocalScale(.15f); - - rootNode.attachChild(clonePot); - } - } - } - - cam.setLocation(new Vector3f(10.247649f, 8.275992f, 10.405156f)); - cam.setRotation(new Quaternion(-0.083419204f, 0.90370524f, -0.20599906f, -0.36595422f)); - - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - SSAOFilter ssaoFilter = new SSAOFilter(2.9299974f,25f,5.8100376f,0.091000035f); - int numSamples = context.getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - - //ssaoFilter.setApproximateNormals(true); - fpp.addFilter(ssaoFilter); - SSAOUI ui = new SSAOUI(inputManager, ssaoFilter); - - viewPort.addProcessor(fpp); - } - - @Override - public void simpleUpdate(float tpf) { - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java b/jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java deleted file mode 100644 index b886829650..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.ToneMapFilter; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.system.AppSettings; - -public class TestToneMapFilter extends SimpleApplication { - - private boolean enabled = true; - private FilterPostProcessor fpp; - private ToneMapFilter toneMapFilter; - private float whitePointLog = 1f; - - public static void main(String[] args){ - TestToneMapFilter app = new TestToneMapFilter(); - AppSettings settings = new AppSettings(true); - - // Must turn on gamma correction, as otherwise it looks too dark. - settings.setGammaCorrection(true); - - app.setSettings(settings); - app.start(); - } - - public Geometry createHDRBox(){ - Box boxMesh = new Box(1, 1, 1); - Geometry box = new Geometry("Box", boxMesh); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Textures/HdrTest/Memorial.hdr")); - box.setMaterial(mat); - return box; - } - - @Override - public void simpleInitApp() { - System.out.println("== Tone Mapping Sample =="); - System.out.println(" SPACE:\tToggle tone-mapping OFF or ON"); - System.out.println(" Y:\tIncrease white-point"); - System.out.println(" H:\tDecrease white-point"); - - fpp = new FilterPostProcessor(assetManager); - toneMapFilter = new ToneMapFilter(); - fpp.addFilter(toneMapFilter); - viewPort.addProcessor(fpp); - - rootNode.attachChild(createHDRBox()); - - cam.setLocation(new Vector3f(0f,0f,3f)); - - initInputs(); - } - - private void initInputs() { - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - inputManager.addMapping("WhitePointUp", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("WhitePointDown", new KeyTrigger(KeyInput.KEY_H)); - - ActionListener acl = new ActionListener() { - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggle") && keyPressed) { - if (enabled) { - enabled = false; - viewPort.removeProcessor(fpp); - System.out.println("Tone Mapping OFF"); - } else { - enabled = true; - viewPort.addProcessor(fpp); - System.out.println("Tone Mapping ON"); - } - } - } - }; - - AnalogListener anl = new AnalogListener() { - - @Override - public void onAnalog(String name, float isPressed, float tpf) { - if (name.equals("WhitePointUp")) { - whitePointLog += tpf * 1.0; - if (whitePointLog > 4f) { - whitePointLog = 4f; - } - float wp = FastMath.exp(whitePointLog); - toneMapFilter.setWhitePoint(new Vector3f(wp, wp, wp)); - System.out.println("White point: " + wp); - } - - if (name.equals("WhitePointDown")) { - whitePointLog -= tpf * 1.0; - if (whitePointLog < -4f) { - whitePointLog = -4f; - } - float wp = FastMath.exp(whitePointLog); - toneMapFilter.setWhitePoint(new Vector3f(wp, wp, wp)); - System.out.println("White point: " + wp); - } - } - }; - - inputManager.addListener(acl, "toggle"); - inputManager.addListener(anl, "WhitePointUp", "WhitePointDown"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java b/jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java deleted file mode 100644 index 2e2c9874f7..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java +++ /dev/null @@ -1,98 +0,0 @@ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.CartoonEdgeFilter; -import com.jme3.renderer.queue.RenderQueue.Bucket; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.RectangleMesh; -import com.jme3.texture.Texture; - -public class TestTransparentCartoonEdge extends SimpleApplication { - - public static void main(String[] args){ - TestTransparentCartoonEdge app = new TestTransparentCartoonEdge(); - app.start(); - } - - @Override - public void simpleInitApp() { - renderManager.setAlphaToCoverage(true); - cam.setLocation(new Vector3f(0.14914267f, 0.58147097f, 4.7686534f)); - cam.setRotation(new Quaternion(-0.0044764364f, 0.9767943f, 0.21314798f, 0.020512417f)); - -// cam.setLocation(new Vector3f(2.0606942f, 3.20342f, 6.7860126f)); -// cam.setRotation(new Quaternion(-0.017481906f, 0.98241085f, -0.12393151f, -0.13857932f)); - - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - RectangleMesh rm = new RectangleMesh( - new Vector3f(-10, 0, 10), - new Vector3f(10, 0, 10), - new Vector3f(-10, 0, -10)); - rm.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(5)); - Geometry geom = new Geometry("floor", rm); - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - geom.setMaterial(mat); - geom.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(geom); - - // create the geometry and attach it - Spatial teaGeom = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); - teaGeom.setQueueBucket(Bucket.Transparent); - teaGeom.setShadowMode(ShadowMode.Cast); - makeToonish(teaGeom); - - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(2)); - rootNode.addLight(al); - - DirectionalLight dl1 = new DirectionalLight(); - dl1.setDirection(new Vector3f(1, -1, 1).normalizeLocal()); - dl1.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); - rootNode.addLight(dl1); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); - rootNode.addLight(dl); - - rootNode.attachChild(teaGeom); - - FilterPostProcessor fpp=new FilterPostProcessor(assetManager); - CartoonEdgeFilter toon=new CartoonEdgeFilter(); - toon.setEdgeWidth(0.5f); - toon.setEdgeIntensity(1.0f); - toon.setNormalThreshold(0.8f); - fpp.addFilter(toon); - viewPort.addProcessor(fpp); - } - - public void makeToonish(Spatial spatial){ - if (spatial instanceof Node){ - Node n = (Node) spatial; - for (Spatial child : n.getChildren()) - makeToonish(child); - }else if (spatial instanceof Geometry){ - Geometry g = (Geometry) spatial; - Material m = g.getMaterial(); - if (m.getMaterialDef().getName().equals("Phong Lighting")){ - Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png"); -// t.setMinFilter(Texture.MinFilter.NearestNoMipMaps); -// t.setMagFilter(Texture.MagFilter.Nearest); - m.setTexture("ColorRamp", t); - m.setBoolean("UseMaterialColors", true); - m.setColor("Specular", ColorRGBA.Black); - m.setColor("Diffuse", ColorRGBA.White); - m.setBoolean("VertexLighting", true); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java b/jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java deleted file mode 100644 index 6694454a9b..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java +++ /dev/null @@ -1,78 +0,0 @@ -package jme3test.post; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.ssao.SSAOFilter; -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.scene.shape.RectangleMesh; -import com.jme3.util.TangentBinormalGenerator; - -public class TestTransparentSSAO extends SimpleApplication { - - public static void main(String[] args) { - TestTransparentSSAO app = new TestTransparentSSAO(); - app.start(); - } - - @Override - public void simpleInitApp() { - renderManager.setAlphaToCoverage(true); - cam.setLocation(new Vector3f(0.14914267f, 0.58147097f, 4.7686534f)); - cam.setRotation(new Quaternion(-0.0044764364f, 0.9767943f, 0.21314798f, 0.020512417f)); - -// cam.setLocation(new Vector3f(2.0606942f, 3.20342f, 6.7860126f)); -// cam.setRotation(new Quaternion(-0.017481906f, 0.98241085f, -0.12393151f, -0.13857932f)); - - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - - RectangleMesh rm = new RectangleMesh( - new Vector3f(-10, 0, 10), - new Vector3f(10, 0, 10), - new Vector3f(-10, 0, -10)); - rm.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(5)); - Geometry geom = new Geometry("floor", rm); - Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); - geom.setMaterial(mat); - - geom.setShadowMode(ShadowMode.Receive); - TangentBinormalGenerator.generate(geom); - rootNode.attachChild(geom); - - // create the geometry and attach it - Spatial teaGeom = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); - teaGeom.setQueueBucket(Bucket.Transparent); - teaGeom.setShadowMode(ShadowMode.Cast); - - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(2)); - rootNode.addLight(al); - - DirectionalLight dl1 = new DirectionalLight(); - dl1.setDirection(new Vector3f(1, -1, 1).normalizeLocal()); - dl1.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); - rootNode.addLight(dl1); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - dl.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); - rootNode.addLight(dl); - - rootNode.attachChild(teaGeom); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - - SSAOFilter ssao = new SSAOFilter();//0.49997783f, 42.598858f, 35.999966f, 0.39299846f - fpp.addFilter(ssao); - - SSAOUI ui = new SSAOUI(inputManager, ssao); - - viewPort.addProcessor(fpp); - } -} diff --git a/jme3-examples/src/main/java/jme3test/post/package-info.java b/jme3-examples/src/main/java/jme3test/post/package-info.java deleted file mode 100644 index 8b0450420a..0000000000 --- a/jme3-examples/src/main/java/jme3test/post/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for post-processing, including filters - */ -package jme3test.post; diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java b/jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java deleted file mode 100644 index d5e02ae7a9..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java +++ /dev/null @@ -1,54 +0,0 @@ -package jme3test.renderer; -import com.jme3.app.SimpleApplication; - -import com.jme3.renderer.lwjgl.LwjglGL; -import com.jme3.renderer.opengl.GL; -import com.jme3.renderer.opengl.GLExt; -import com.jme3.renderer.opengl.GLFbo; -import com.jme3.renderer.opengl.GLRenderer; -import com.jme3.renderer.lwjgl.LwjglGLExt; -import com.jme3.renderer.lwjgl.LwjglGLFboEXT; -import com.jme3.renderer.Caps; - -import java.util.EnumSet; - -/** - * Simple application to test the getter and setters of AlphaToCoverage and - * DefaultAnisotropicFilter from the GLRenderer class. - * - * Since the app doesn't display anything relevant a stop() has been added - * This starts and closes the app on a successful run - */ -public class TestAlphaToCoverage extends SimpleApplication { - - public static void main(String[] args) { - new TestAlphaToCoverage().start(); - } - - final private GL gl = new LwjglGL(); - final private GLExt glext = new LwjglGLExt(); - final private GLFbo glfbo = new LwjglGLFboEXT(); - final private GLRenderer glRenderer= new GLRenderer(gl,glext,glfbo); - - final private EnumSet caps = glRenderer.getCaps(); - - - - @Override - public void simpleInitApp() { - glRenderer.setAlphaToCoverage(false); - assert !glRenderer.getAlphaToCoverage(); - - caps.add(Caps.Multisample); - glRenderer.setAlphaToCoverage(true); - assert glRenderer.getAlphaToCoverage(); - glRenderer.setAlphaToCoverage(false); - assert !glRenderer.getAlphaToCoverage(); - - glRenderer.setDefaultAnisotropicFilter(1); - assert glRenderer.getDefaultAnisotropicFilter() == 1; - - stop(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java b/jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java deleted file mode 100644 index 50a2377bef..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.util.TempVars; - -/** - * Tests the setting of the FOV and aspect ratios. - * - * @author Markil 3 - */ -public class TestAspectFov extends SimpleApplication implements AnalogListener { - private static final String FOV_IN = "fovIn"; - private static final String FOV_OUT = "fovOut"; - private BitmapText header, fov; - - public static void main(String[] args) { - new TestAspectFov().start(); - } - - @Override - public void simpleInitApp() { - header = new BitmapText(this.guiFont); - header.setText("Adjust FOV with R/F or with mouse scroll"); - guiNode.attachChild(header); - fov = new BitmapText(this.guiFont); - guiNode.attachChild(fov); - - viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); - flyCam.setMoveSpeed(100); - - // We add light so we see the scene - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(1.3f)); - rootNode.addLight(al); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White); - dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal()); - rootNode.addLight(dl); - - assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/town.zip", - HttpZipLocator.class); - Spatial sceneModel = assetManager.loadModel("main.scene"); - sceneModel.setLocalScale(2f); - - rootNode.attachChild(sceneModel); - - inputManager.addMapping(FOV_IN, new KeyTrigger(KeyInput.KEY_R)); - inputManager.addMapping(FOV_OUT, new KeyTrigger(KeyInput.KEY_F)); - inputManager.addListener(this, FOV_IN, FOV_OUT); - } - - @Override - public void update() { - /* - * Updates the labels - */ - TempVars vars = TempVars.get(); - super.update(); - header.setLocalTranslation(0, cam.getHeight(), 0); - vars.vect1.set(header.getLocalTranslation()); - vars.vect1.subtractLocal(0, header.getLineHeight(), 0); - fov.setLocalTranslation(vars.vect1); - fov.setText("FOV: " + cam.getFov()); - vars.vect1.subtractLocal(0, fov.getLineHeight(), 0); - vars.release(); - } - - @Override - public void onAnalog(String name, float value, float tpf) { - final float CHANGE_VALUE = tpf * 10; - float newFov = cam.getFov(); - switch (name) { - case FOV_IN: - newFov -= CHANGE_VALUE; - break; - case FOV_OUT: - newFov += CHANGE_VALUE; - break; - } - if (newFov > 0 && newFov != cam.getFov()) { - cam.setFov(newFov); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java b/jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java deleted file mode 100644 index bdb526710e..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2009-2018 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -/** - * Simple application to test a viewport/camera with a different aspect ratio - * than the display -- issue #357. The cube should render as a blue square, not - * a rectangle. - * - * Based closely on the test case submitted by slyh on September 28, 2015. - */ -public class TestAspectRatio extends SimpleApplication { - - public static void main(String[] args) { - new TestAspectRatio().start(); - } - - @Override - public void simpleInitApp() { - Geometry cube = new Geometry("blue cube", new Box(1, 1, 1)); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - cube.setMaterial(mat); - - rootNode.attachChild(cube); - - // Trying to update the viewport: - cam.setViewPortBottom(0.5f); - cam.resize(640, 480 / 2, false); - cam.setFrustumPerspective(40, 640f / (480 / 2), 0.05f, 500f); - cam.update(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java b/jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java deleted file mode 100644 index c8c004a9c3..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -package jme3test.renderer; - -import com.jme3.anim.util.AnimMigrationUtils; -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.material.Materials; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; -import com.jme3.texture.Texture; -import java.util.List; - -/** - * Demonstrates how to render a non-moving background image using a pre - * ViewPort. - * - * @author Stephen Gold sgold@sonic.net - */ -public class TestBackgroundImage extends SimpleApplication { - - private static ViewPort backgroundViewport; - - public static void main(String[] args) { - new TestBackgroundImage().start(); - } - - @Override - public void simpleInitApp() { - /* - * SimpleApplication creates 2 viewports: - * 1. the default viewport (rendered first, after clearing all buffers) - * 2. the GUI viewport (rendered last, without clearing any buffers) - * - * Create a 3rd ViewPort, named "background viewport", - * to be rendered BEFORE the default viewport. - */ - Camera backgroundCamera = guiViewPort.getCamera().clone(); - backgroundViewport = renderManager.createPreView( - "background viewport", backgroundCamera); - /* - * Don't clear the color buffer before drawing the main viewport. - * Clearing the color buffer would hide the background. - */ - boolean clearColorBuffer = false; - viewPort.setClearFlags(clearColorBuffer, true, true); - /* - * Create a quad to display the JMonkeyEngine logo, - * assign it to the Gui bucket, - * and attach it to the background viewport. - */ - Texture quadTexture - = assetManager.loadTexture("Interface/Logo/Monkey.png"); - Material quadMaterial = new Material(assetManager, Materials.UNSHADED); - quadMaterial.setTexture("ColorMap", quadTexture); - - float quadHeight = backgroundCamera.getHeight(); - float quadWidth = backgroundCamera.getWidth(); - Mesh quadMesh = new Quad(quadWidth, quadHeight); - - Spatial quadGeometry = new Geometry("quad geometry", quadMesh); - quadGeometry.setMaterial(quadMaterial); - quadGeometry.setQueueBucket(RenderQueue.Bucket.Gui); - backgroundViewport.attachScene(quadGeometry); - /* - * Add Jaime model and lighting to the default scene. - */ - loadModel(); - setupLights(); - /* - * Speed up camera motion for convenience. - */ - flyCam.setMoveSpeed(8f); - } - - @Override - public void simpleUpdate(float timePerFrame) { - /* - * Since SimpleApplication is unaware of the background viewport, - * the application must explicitly update its scenes. - */ - List scenes = backgroundViewport.getScenes(); - for (Spatial scene : scenes) { - scene.updateLogicalState(timePerFrame); - scene.updateGeometricState(); - } - } - - private void loadModel() { - Node jaime = (Node) assetManager.loadModel("Models/Jaime/Jaime.j3o"); - AnimMigrationUtils.migrate(jaime); - jaime.scale(3f); - rootNode.attachChild(jaime); - } - - private void setupLights() { - AmbientLight ambient = new AmbientLight(); - ambient.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); - rootNode.addLight(ambient); - - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(0f, -1f, -1f).normalizeLocal()); - sun.setColor(ColorRGBA.White.mult(1.5f)); - rootNode.addLight(sun); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java b/jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java deleted file mode 100644 index f979017b3c..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.material.RenderState; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; - -/** - * This test demonstrates the usage of customized blend equations and factors on a material.
- * Customized blend equations and factors always requires {@link com.jme3.material.RenderState.BlendMode#Custom}. - * - * @author the_Minka - */ -public class TestBlendEquations extends SimpleApplication { - - private Geometry leftQuad; - private Geometry rightQuad; - - private float timer; - - public static void main(String[] args) { - TestBlendEquations app = new TestBlendEquations(); - app.start(); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(0f, 0.5f, 3f)); - viewPort.setBackgroundColor(ColorRGBA.LightGray); - - // Add a light source to the scene. - DirectionalLight directionalLight = new DirectionalLight(); - directionalLight.setColor(ColorRGBA.Magenta); - directionalLight.setDirection(Vector3f.UNIT_XYZ.negate()); - rootNode.addLight(directionalLight); - - - // Create and add a teapot to the scene graph. - Spatial teapotModel = assetManager.loadModel("Models/Teapot/Teapot.obj"); - rootNode.attachChild(teapotModel); - - // Create the two moving quads with custom blend modes. - createLeftQuad(); - createRightQuad(); - } - - /** - * Adds a "transparent" quad to the scene, that shows an inverse blue value sight of the scene behind. - */ - private void createLeftQuad() { - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - - // This color creates a blue value image. The effect will have a strength of 80% (set by the alpha value). - material.setColor("Color", new ColorRGBA(0f, 0f, 1f, 0.8f)); - - // Result.RGB = Source.A * Source.RGB - Source.A * Destination.RGB - // Result.A = Destination.A - material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Custom); - material.getAdditionalRenderState().setBlendEquation(RenderState.BlendEquation.Subtract); - material.getAdditionalRenderState().setBlendEquationAlpha(RenderState.BlendEquationAlpha.Add); - material.getAdditionalRenderState().setCustomBlendFactors( - RenderState.BlendFunc.Src_Alpha, RenderState.BlendFunc.Src_Alpha, - RenderState.BlendFunc.Zero, RenderState.BlendFunc.One); - - leftQuad = new Geometry("LeftQuad", new Quad(1f, 1f)); - leftQuad.setMaterial(material); - leftQuad.setQueueBucket(RenderQueue.Bucket.Transparent); - rootNode.attachChild(leftQuad); - } - - /** - * Adds a "transparent" quad to the scene, that limits the color values of the scene behind the object.
- * This effect can be good seen on bright areas of the scene (e.g. areas with specular lighting effects). - */ - private void createRightQuad() { - Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - material.setColor("Color", new ColorRGBA(0.4f, 0.4f, 0.4f, 1f)); - - // Min( Source , Destination) - material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Custom); - material.getAdditionalRenderState().setBlendEquation(RenderState.BlendEquation.Min); - material.getAdditionalRenderState().setBlendEquationAlpha(RenderState.BlendEquationAlpha.Min); - - // In OpenGL no blend factors are used, when using the blend equations Min or Max! - //material.getAdditionalRenderState().setCustomBlendFactors( - // RenderState.BlendFunc.One, RenderState.BlendFunc.One, - // RenderState.BlendFunc.One, RenderState.BlendFunc.One); - - rightQuad = new Geometry("RightQuad", new Quad(1f, 1f)); - rightQuad.setMaterial(material); - rightQuad.setQueueBucket(RenderQueue.Bucket.Transparent); - rootNode.attachChild(rightQuad); - } - - @Override - public void simpleUpdate(float tpf) { - timer += tpf; - - float xOffset = FastMath.sin(timer * 0.5f) * 2f; - leftQuad.setLocalTranslation(xOffset - 2f, 0f, 0.5f); - rightQuad.setLocalTranslation(xOffset + 1f, 0f, 0.5f); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java b/jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java deleted file mode 100644 index 2244191459..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.control.AbstractControl; -import com.jme3.scene.shape.Box; -import com.jme3.system.AppSettings; - -/** - * Tests whether gamma correction works after a context restart. This test - * generates a series of boxes, each one with a slightly different shade from - * the other. If the boxes look the same before and after the restart, that - * means that gamma correction is working properly. - *

- * Note that for testing, it may be helpful to bypass the test chooser and run - * this class directly, since it can be easier to define your own settings - * beforehand. Of course, it should still work if all you need to test is the - * gamma correction, as long as you enable it in the settings dialog. - *

- * - * @author Markil 3 - */ -public class TestContextRestart extends SimpleApplication -{ - public static final String INPUT_RESTART_CONTEXT = "SIMPLEAPP_Restart"; - - public static void main(String[] args) - { - TestContextRestart app = new TestContextRestart(); - AppSettings settings = new AppSettings(true); - settings.setGammaCorrection(true); -// settings.setRenderer(AppSettings.LWJGL_OPENGL32); - app.setSettings(settings); - app.start(); - } - - @Override - public void simpleInitApp() - { - for (int i = 0, l = 256; i < l; i += 8) - { - Geometry box = new Geometry("Box" + i, new Box(10, 200, 10)); - Material mat = new Material(this.assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", new ColorRGBA((float) i / 255F, 0, 0, 1)); - box.setMaterial(mat); - box.setLocalTranslation(-2.5F * (l / 2 - i), 0, -700); - box.addControl(new AbstractControl() - { - @Override - protected void controlUpdate(float tpf) - { - float[] angles = this.getSpatial() - .getLocalRotation() - .toAngles(new float[3]); - angles[0] = angles[0] + (FastMath.PI / 500F); - this.getSpatial() - .setLocalRotation(new Quaternion().fromAngles(angles)); - } - - @Override - protected void controlRender(RenderManager rm, ViewPort vp) - { - - } - }); - this.rootNode.attachChild(box); - } - - this.viewPort.setBackgroundColor(ColorRGBA.Yellow); - - this.flyCam.setEnabled(false); - this.inputManager.setCursorVisible(true); - - inputManager.addMapping(INPUT_RESTART_CONTEXT, new KeyTrigger( - KeyInput.KEY_TAB)); - this.inputManager.addListener(new ActionListener() - { - @Override - public void onAction(String name, boolean isPressed, float tpf) - { - if (name.equals(INPUT_RESTART_CONTEXT)) - { - restart(); - } - } - }, INPUT_RESTART_CONTEXT); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java b/jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java deleted file mode 100644 index 20f0a55e89..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.material.RenderState; -import com.jme3.math.ColorRGBA; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -public class TestDepthFuncChange extends SimpleApplication { - - public static void main(String[] args) { - TestDepthFuncChange app = new TestDepthFuncChange(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - flyCam.setMoveSpeed(20); - - - //top of the screen - //default depth func (less or equal) rendering. - //2 cubes, a blue and a red. the red cube is offset by 0.2 WU to the right - //the red cube is put in the transparent bucket to be sure it's rendered after the blue one (but there is no transparency involved). - //You should see a small part of the blue cube on the left and the whole red cube - Box boxShape1 = new Box(1f, 1f, 1f); - Geometry cube1 = new Geometry("box", boxShape1); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - - cube1.setMaterial(mat); - rootNode.attachChild(cube1); - cube1.move(0, 1.5f, 0); - - Geometry cube2 = cube1.clone(true); - cube2.move(0.2f, 0 , 0); - cube2.setQueueBucket(RenderQueue.Bucket.Transparent); - cube2.getMaterial().setColor("Color", ColorRGBA.Red); - rootNode.attachChild(cube2); - - //Bottom of the screen - //here the 2 cubes are cloned and the depthFunc for the red cube's material is set to Less - //You should see the whole blue cube and a small part of the red cube on the right - Geometry cube3 = cube1.clone(); - Geometry cube4 = cube2.clone(true); - cube4.getMaterial().getAdditionalRenderState().setDepthFunc(RenderState.TestFunction.Less); - cube3.move(0,-3,0); - cube4.move(0,-3,0); - rootNode.attachChild(cube3); - rootNode.attachChild(cube4); - - //Note that if you move the camera z fighting will occur but that's expected. - - - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java b/jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java deleted file mode 100644 index 0f333ac661..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.material.RenderState; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.Renderer; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.AbstractControl; -import com.jme3.scene.shape.Sphere; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture2D; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; -import com.jme3.ui.Picture; - -public class TestDepthStencil extends SimpleApplication { - - private boolean enableStencil = false; - - final private Node fbNode = new Node("Framebuffer Node"); - private FrameBuffer fb; - - public static void main(String[] args){ - TestDepthStencil app = new TestDepthStencil(); - app.start(); - } - - @Override - public void simpleInitApp() { - int w = settings.getWidth(); - int h = settings.getHeight(); - - //setup framebuffer - fb = new FrameBuffer(w, h, 1); - - Texture2D fbTex = new Texture2D(w, h, Format.RGB8); - fb.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth24Stencil8)); - fb.addColorTarget(FrameBufferTarget.newTarget(fbTex)); - - // setup framebuffer's scene - Sphere sphMesh = new Sphere(20, 20, 1); - Material solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); - - final Geometry sphere = new Geometry("sphere", sphMesh); - sphere.setMaterial(solidColor); - fbNode.attachChild(sphere); - - sphere.addControl(new AbstractControl() { - @Override - protected void controlUpdate(float tpf) { - Material mat = sphere.getMaterial(); - mat.getAdditionalRenderState().setStencil(enableStencil, - RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, - RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, - RenderState.TestFunction.Never, RenderState.TestFunction.Never - //TestFunction.Always, TestFunction.Always - ); - } - - @Override - protected void controlRender(RenderManager rm, ViewPort vp) { - } - }); - - //setup main scene - Picture p = new Picture("Picture"); - p.setPosition(0, 0); - p.setWidth(w); - p.setHeight(h); - p.setTexture(assetManager, fbTex, false); - - rootNode.attachChild(p); - - inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); - ActionListener acl = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("toggle") && keyPressed) { - if (enableStencil) { - enableStencil = false; - System.out.println("Stencil Disabled (model should be visible)"); - } else { - enableStencil = true; - System.out.println("Stencil Enabled (model should be hidden)"); - } - } - } - }; - inputManager.addListener(acl, "toggle"); - - System.out.println("Press space to toggle stencil"); - } - - @Override - public void simpleUpdate(float tpf){ - fbNode.updateLogicalState(tpf); - fbNode.updateGeometricState(); - } - - @Override - public void simpleRender(RenderManager rm){ - Renderer r = rm.getRenderer(); - - //do FBO rendering - r.setFrameBuffer(fb); - - rm.setCamera(cam, false); // FBO uses current camera - r.clearBuffers(true, true, true); - rm.renderScene(fbNode, viewPort); - rm.flushQueue(viewPort); - - //go back to default rendering and let - //SimpleApplication render the default scene - r.setFrameBuffer(null); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java b/jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java deleted file mode 100644 index dbb2eaad8d..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.texture.Texture; - -/** - * Changes a material's texture from another thread while it is rendered. - * This should trigger the sorting function's inconsistent compare detection. - * - * @author Kirill Vainer - */ -public class TestInconsistentCompareDetection extends SimpleApplication { - - private static Texture t1, t2; - - public static void main(String[] args){ - TestInconsistentCompareDetection app = new TestInconsistentCompareDetection(); - app.start(); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(-11.674385f, 7.892636f, 33.133106f)); - cam.setRotation(new Quaternion(0.06426433f, 0.90940624f, -0.15329266f, 0.38125014f)); - - Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - m.setColor("Color", ColorRGBA.White); - - t1 = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"); - t2 = assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"); - - Box b = new Box(1, 1, 1); - - for (int x = 0; x < 12; x++) { - for (int y = 0; y < 12; y++) { - Geometry g = new Geometry("g_" + x + "_" + y, b); - Node monkey = new Node("n_" + x + "_" + y); - monkey.attachChild(g); - monkey.move(x * 2, 0, y * 2); - - Material newMat = m.clone(); - g.setMaterial(newMat); - - if (FastMath.rand.nextBoolean()) { - newMat.setTexture("ColorMap", t1); - } else { - newMat.setTexture("ColorMap", t2); - } - - rootNode.attachChild(monkey); - } - } - - Thread evilThread = new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - } - - // begin randomly changing textures after 1 sec. - while (true) { - for (Spatial child : rootNode.getChildren()) { - Geometry g = (Geometry) (((Node)child).getChild(0)); - Material m = g.getMaterial(); - Texture curTex = m.getTextureParam("ColorMap").getTextureValue(); - if (curTex == t1) { - m.setTexture("ColorMap", t2); - } else { - m.setTexture("ColorMap", t1); - } - } - } - } - }); - evilThread.setDaemon(true); - evilThread.start(); - } -} - diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java deleted file mode 100644 index 037dd980a6..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.system.AppSettings; - -/** - * Test for JMonkeyEngine issue #2011: context profiles are not defined for - * OpenGL v3.0/v3.1 - *

- * If the issue is resolved, then pressing the "0" or "1" key shouldn't crash - * the app; it should close the app display and create a new display, mostly - * black with statistics displayed in the lower left. - *

- * If the issue is not resolved, then pressing the "0" or "1" key should crash - * the app with multiple exceptions. - *

- * Since the issue was specific to LWJGL v3, this test should be built with the - * jme3-lwjgl3 library, not jme3-lwjgl. - * - * @author Stephen Gold - */ -public class TestIssue2011 extends SimpleApplication { - /** - * Main entry point for the TestIssue2011 application. - * - * @param args array of command-line arguments (not null) - */ - public static void main(String[] args) { - TestIssue2011 app = new TestIssue2011(); - app.start(); - } - - /** - * Initialize this application. - */ - @Override - public void simpleInitApp() { - inputManager.addMapping("3.0", new KeyTrigger(KeyInput.KEY_0), - new KeyTrigger(KeyInput.KEY_NUMPAD0)); - inputManager.addMapping("3.1", new KeyTrigger(KeyInput.KEY_1), - new KeyTrigger(KeyInput.KEY_NUMPAD1)); - inputManager.addMapping("3.2", new KeyTrigger(KeyInput.KEY_2), - new KeyTrigger(KeyInput.KEY_NUMPAD2)); - - ActionListener listener = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("3.0") && keyPressed) { - setApi(AppSettings.LWJGL_OPENGL30); - } else if (name.equals("3.1") && keyPressed) { - setApi(AppSettings.LWJGL_OPENGL31); - } else if (name.equals("3.2") && keyPressed) { - setApi(AppSettings.LWJGL_OPENGL32); - } - } - }; - - inputManager.addListener(listener, "3.0", "3.1", "3.2"); - } - - /** - * Restart the app, specifying which OpenGL version to use. - * - * @param desiredApi the string to be passed to setRenderer() - */ - private void setApi(String desiredApi) { - System.out.println("desiredApi = " + desiredApi); - settings.setRenderer(desiredApi); - setSettings(settings); - - restart(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java deleted file mode 100644 index ce276e81d9..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -package jme3test.renderer; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.material.MatParamOverride; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.shape.Box; -import com.jme3.shader.VarType; -import com.jme3.texture.Texture; - -/** - * Test a Material with increasing numbers of texture parameters, to see what - * happens when the renderer's dynamic limit is exceeded. - * - * If successful, this test throws an IllegalStateException with a helpful - * diagnostic message. - */ -public class TestIssue37 extends SimpleApplication { - - /** - * Edit this field to change how parameters are assigned (which determines - * where the exception is caught): true to use mat param overrides, false to - * use ordinary mat params. - */ - final private boolean useOverrides = true; - - private int numTextures; - private Material manyTexturesMaterial; - private Texture testTexture; - - public static void main(String[] args) { - Application application = new TestIssue37(); - application.start(); - } - - @Override - public void simpleInitApp() { - /* - * Attach a test geometry to the scene. - */ - Mesh cubeMesh = new Box(1f, 1f, 1f); - Geometry cubeGeometry = new Geometry("Box", cubeMesh); - rootNode.attachChild(cubeGeometry); - /* - * Apply a test material (with no textures assigned) to the geometry. - */ - manyTexturesMaterial = new Material(assetManager, - "jme3test/materials/TestIssue37.j3md"); - manyTexturesMaterial.setName("manyTexturesMaterial"); - cubeGeometry.setMaterial(manyTexturesMaterial); - numTextures = 0; - /* - * Load the test texture. - */ - String texturePath = "Interface/Logo/Monkey.jpg"; - testTexture = assetManager.loadTexture(texturePath); - } - - /** - * During each update, define another texture parameter until the dynamic - * limit is reached. - * - * @param tpf ignored - */ - @Override - public void simpleUpdate(float tpf) { - String parameterName = "ColorMap" + numTextures; - if (useOverrides) { - MatParamOverride override = new MatParamOverride(VarType.Texture2D, - parameterName, testTexture); - rootNode.addMatParamOverride(override); - } else { - manyTexturesMaterial.setTexture(parameterName, testTexture); - } - ++numTextures; - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java deleted file mode 100644 index d350566d03..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; - -/** - * Test for JMonkeyEngine issue #798: OpenGLException on restart with changed - * display settings. - *

- * If the issue is resolved, then pressing the "P", "T", or "Y" key shouldn't - * crash the app; it should close the app display and create a new display, - * mostly black with statistics displayed in the lower left. - *

- * If the issue is not resolved, the expected failure mode depends on whether - * assertions are enabled. If they're enabled, the app will crash with an - * OpenGLException. If assertions aren't enabled, the new window will be - * entirely black, with no statistics visible. - *

- * Since the issue was specific to LWJGL v2, this test should be built with the - * jme3-lwjgl library, not jme3-lwjgl3. - * - * @author Stephen Gold - */ -public class TestIssue798 extends SimpleApplication { - /** - * Main entry point for the TestIssue798 application. - * - * @param args array of command-line arguments (not null) - */ - public static void main(String[] args) { - TestIssue798 app = new TestIssue798(); - app.start(); - } - - /** - * Initialize this application. - */ - @Override - public void simpleInitApp() { - inputManager.addMapping("windowedMode", new KeyTrigger(KeyInput.KEY_F)); - inputManager.addMapping("moreSamples", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addMapping("toggleDepth", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addMapping("toggleBpp", new KeyTrigger(KeyInput.KEY_Y)); - - ActionListener listener = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("moreSamples") && keyPressed) { - moreSamples(); - } else if (name.equals("toggleBpp") && keyPressed) { - toggleBpp(); - } else if (name.equals("toggleDepth") && keyPressed) { - toggleDepth(); - } else if (name.equals("windowedMode") && keyPressed) { - windowedMode(); - } - } - }; - - inputManager.addListener(listener, - "moreSamples", "toggleBpp", "toggleDepth", "windowedMode"); - } - - /** - * Restart the app, requesting 2 more MSAA samples per pixel. - */ - private void moreSamples() { - int numSamples = settings.getSamples(); - numSamples += 2; - System.out.println("numSamples = " + numSamples); - settings.setSamples(numSamples); - setSettings(settings); - - restart(); - } - - /** - * Restart the app, requesting a different number of bits per pixel in the - * RGB buffer. - */ - private void toggleBpp() { - int bpp = settings.getBitsPerPixel(); - bpp = (bpp == 24) ? 16 : 24; - System.out.println("BPP = " + bpp); - settings.setBitsPerPixel(bpp); - setSettings(settings); - - restart(); - } - - /** - * Restart the app, requesting a different number of bits per pixel in the - * depth buffer. - */ - private void toggleDepth() { - int depthBits = settings.getDepthBits(); - depthBits = (depthBits == 24) ? 16 : 24; - System.out.println("depthBits = " + depthBits); - settings.setDepthBits(depthBits); - setSettings(settings); - - restart(); - } - - /** - * If the app is in fullscreen mode, restart it in 640x480 windowed mode. - */ - private void windowedMode() { - boolean isFullscreen = settings.isFullscreen(); - if (!isFullscreen) { - System.out.println("Request ignored: already in windowed mode!"); - return; - } - - System.out.println("fullscreen = " + false); - settings.setFullscreen(false); - settings.setWidth(640); - settings.setHeight(480); - setSettings(settings); - - restart(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java deleted file mode 100644 index 0f1893c43b..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; -import com.jme3.system.AppSettings; - -public class TestIssue801 extends SimpleApplication { - - public static void main(String[] args) { - AppSettings initialSettings = new AppSettings(true); - initialSettings.setBitsPerPixel(24); - - TestIssue801 app = new TestIssue801(); - app.setSettings(initialSettings); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(new ColorRGBA(0.3f, 0.3f, 0.3f, 1f)); - - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - geom.setMaterial(mat); - - rootNode.attachChild(geom); - inputManager.addMapping("changeBpp", new KeyTrigger(KeyInput.KEY_P)); - ActionListener listener = new ActionListener() { - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("changeBpp") && keyPressed) { - goWindowed(); - } - } - }; - inputManager.addListener(listener, "changeBpp"); - } - - void goWindowed() { - AppSettings newSettings = new AppSettings(false); - newSettings.copyFrom(settings); - newSettings.setBitsPerPixel(16); - - setSettings(newSettings); - restart(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java b/jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java deleted file mode 100644 index e73132d314..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.material.Material; -import com.jme3.material.Materials; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.shape.Line; -import com.jme3.system.AppSettings; - -/** - * Display the renderer's maximum line width. - * - * @author Stephen Gold sgold@sonic.net - */ -public class TestLineWidth extends SimpleApplication { - - public static void main(String... args) { - TestLineWidth app = new TestLineWidth(); - AppSettings set = new AppSettings(true); - set.setRenderer(AppSettings.LWJGL_OPENGL2); - app.setSettings(set); - app.start(); - } - - @Override - public void simpleInitApp() { - /* - * Generate a message to report (1) which renderer is selected - * and (2) the maximum line width. - */ - String rendererName = settings.getRenderer(); - float maxWidth = renderer.getMaxLineWidth(); - String message = String.format( - "using %s renderer%nmaximum line width = %.1f pixel%s", - rendererName, maxWidth, (maxWidth == 1f) ? "" : "s"); - /* - * Display the message, centered near the top of the display. - */ - BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText text = new BitmapText(font); - text.setSize(font.getCharSet().getRenderedSize()); - text.setText(message); - float leftX = (cam.getWidth() - text.getLineWidth()) / 2; - float topY = cam.getHeight(); - text.setLocalTranslation(leftX, topY, 0f); - guiNode.attachChild(text); - /* - * Display a vertical green line on the left side of the display. - */ - float lineWidth = Math.min(maxWidth, leftX); - drawVerticalLine(lineWidth, leftX / 2, ColorRGBA.Green); - } - - private void drawVerticalLine(float lineWidth, float x, ColorRGBA color) { - Material material = new Material(assetManager, Materials.UNSHADED); - material.setColor("Color", color.clone()); - material.getAdditionalRenderState().setLineWidth(lineWidth); - - float viewportHeight = cam.getHeight(); - Vector3f startLocation = new Vector3f(x, 0.1f * viewportHeight, 0f); - Vector3f endLocation = new Vector3f(x, 0.9f * viewportHeight, 0f); - Mesh wireMesh = new Line(startLocation, endLocation); - Geometry wire = new Geometry("wire", wireMesh); - wire.setMaterial(material); - guiNode.attachChild(wire); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java b/jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java deleted file mode 100644 index ae8e51dca5..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; - -public class TestMultiViews extends SimpleApplication { - - public static void main(String[] args) { - TestMultiViews app = new TestMultiViews(); - app.start(); - } - - @Override - public void simpleInitApp() { - // create the geometry and attach it - Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - teaGeom.scale(3); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White); - dl.setDirection(Vector3f.UNIT_XYZ.negate()); - - rootNode.addLight(dl); - rootNode.attachChild(teaGeom); - - // Setup first view - viewPort.setBackgroundColor(ColorRGBA.Blue); - cam.setViewPort(.5f, 1f, 0f, 0.5f); - cam.setLocation(new Vector3f(3.3212643f, 4.484704f, 4.2812433f)); - cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f)); - - // Setup second view - Camera cam2 = cam.clone(); - cam2.setViewPort(0f, 0.5f, 0f, 0.5f); - cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f)); - cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f)); - - ViewPort view2 = renderManager.createMainView("Bottom Left", cam2); - view2.setClearFlags(true, true, true); - view2.attachScene(rootNode); - - // Setup third view - Camera cam3 = cam.clone(); - cam3.setViewPort(0f, .5f, .5f, 1f); - cam3.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f)); - cam3.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f)); - - ViewPort view3 = renderManager.createMainView("Top Left", cam3); - view3.setClearFlags(true, true, true); - view3.attachScene(rootNode); - - // Setup fourth view - Camera cam4 = cam.clone(); - cam4.setViewPort(.5f, 1f, .5f, 1f); - cam4.setLocation(new Vector3f(4.775564f, 1.4548365f, 0.11491505f)); - cam4.setRotation(new Quaternion(0.02356979f, -0.74957186f, 0.026729556f, 0.66096294f)); - - ViewPort view4 = renderManager.createMainView("Top Right", cam4); - view4.setClearFlags(true, true, true); - view4.attachScene(rootNode); - - //test multiview for gui - guiViewPort.getCamera().setViewPort(.5f, 1f, .5f, 1f); - - // Setup second gui view - Camera guiCam2 = guiViewPort.getCamera().clone(); - guiCam2.setViewPort(0f, 0.5f, 0f, 0.5f); - ViewPort guiViewPort2 = renderManager.createPostView("Gui 2", guiCam2); - guiViewPort2.setClearFlags(false, false, false); - guiViewPort2.attachScene(guiViewPort.getScenes().get(0)); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java b/jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java deleted file mode 100644 index 990da80158..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; - -public class TestParallelProjection extends SimpleApplication implements AnalogListener { - - private float frustumSize = 1; - - public static void main(String[] args){ - TestParallelProjection app = new TestParallelProjection(); - app.start(); - } - - @Override - public void simpleInitApp() { - Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White); - dl.setDirection(Vector3f.UNIT_XYZ.negate()); - - rootNode.addLight(dl); - rootNode.attachChild(teaGeom); - - // Setup first view - cam.setParallelProjection(true); - float aspect = (float) cam.getWidth() / cam.getHeight(); - cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); - - inputManager.addListener(this, "Size+", "Size-"); - inputManager.addMapping("Size+", new KeyTrigger(KeyInput.KEY_W)); - inputManager.addMapping("Size-", new KeyTrigger(KeyInput.KEY_S)); - } - - @Override - public void onAnalog(String name, float value, float tpf) { - // Instead of moving closer/farther to object, we zoom in/out. - if (name.equals("Size-")) - frustumSize += 0.3f * tpf; - else - frustumSize -= 0.3f * tpf; - - float aspect = (float) cam.getWidth() / cam.getHeight(); - cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java b/jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java deleted file mode 100644 index 51f2f37071..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.renderer; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; - -/** - * Simple application to test split-screen rendering. Clicking with LMB toggles - * between a single camera/viewport (cam) and split screen (leftCam plus - * rightCam). See issue #357. - */ -public class TestSplitScreen extends SimpleApplication implements ActionListener { - - private boolean splitScreen = false; - final private Box mesh = new Box(1f, 1f, 1f); - final private Node leftScene = new Node("left scene"); - private ViewPort leftView, rightView; - - @Override - public void simpleInitApp() { - flyCam.setEnabled(false); - - Geometry blueBox = new Geometry("blue box", mesh); - Material blueMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - blueMat.setColor("Color", ColorRGBA.Blue); - blueBox.setMaterial(blueMat); - rootNode.attachChild(blueBox); - - Camera rightCam = cam.clone(); - rightCam.setViewPort(0.5f, 1f, 0f, 1f); - - rightView = renderManager.createMainView("right", rightCam); - rightView.setClearFlags(true, true, true); - rightView.setEnabled(false); - rightView.attachScene(rootNode); - - Geometry redBox = new Geometry("red box", mesh); - Material redMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - redMat.setColor("Color", ColorRGBA.Red); - redBox.setMaterial(redMat); - leftScene.attachChild(redBox); - - Camera leftCam = cam.clone(); - leftCam.setViewPort(0f, 0.5f, 0f, 1f); - - leftView = renderManager.createMainView("left", leftCam); - leftView.setClearFlags(true, true, true); - leftView.setEnabled(false); - leftView.attachScene(leftScene); - - inputManager.addMapping("lmb", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(this, "lmb"); - } - - @Override - public void onAction(String name, boolean keyPressed, float tpf) { - if (name.equals("lmb") && !keyPressed) { - splitScreen = !splitScreen; - viewPort.setEnabled(!splitScreen); - leftView.setEnabled(splitScreen); - rightView.setEnabled(splitScreen); - } - } - - @Override - public void simpleUpdate(float tpf) { - leftScene.updateLogicalState(tpf); - leftScene.updateGeometricState(); - } - - public static void main(String[] args) { - TestSplitScreen app = new TestSplitScreen(); - app.start(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/renderer/package-info.java b/jme3-examples/src/main/java/jme3test/renderer/package-info.java deleted file mode 100644 index aa907287a7..0000000000 --- a/jme3-examples/src/main/java/jme3test/renderer/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for rendering, including cameras - */ -package jme3test.renderer; diff --git a/jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java b/jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java deleted file mode 100644 index 6bd6298235..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ - -package jme3test.scene; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Box; - -public class TestLineWidthRenderState extends SimpleApplication { - - private Material mat; - - public static void main(String[] args){ - TestLineWidthRenderState app = new TestLineWidthRenderState(); - app.start(); - } - - - - @Override - public void simpleInitApp() { - setDisplayFps(false); - setDisplayStatView(false); - cam.setLocation(new Vector3f(5.5826545f, 3.6192513f, 8.016988f)); - cam.setRotation(new Quaternion(-0.04787097f, 0.9463123f, -0.16569641f, -0.27339742f)); - - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - mat.getAdditionalRenderState().setWireframe(true); - mat.getAdditionalRenderState().setLineWidth(2); - geom.setMaterial(mat); - rootNode.attachChild(geom); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if(name.equals("up") && isPressed){ - mat.getAdditionalRenderState().setLineWidth(mat.getAdditionalRenderState().getLineWidth() + 1); - } - if(name.equals("down") && isPressed){ - mat.getAdditionalRenderState().setLineWidth(Math.max(mat.getAdditionalRenderState().getLineWidth() - 1, 1)); - } - } - }, "up", "down"); - inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_J)); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java b/jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java deleted file mode 100644 index 6c8d4d87c1..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java +++ /dev/null @@ -1,45 +0,0 @@ -package jme3test.scene; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Box; - -public class TestRefreshFlagBug extends SimpleApplication { - - private float time = 0; - private boolean attached = false; - private Node inBetweenNode; - - public static void main(String[] args) { - TestRefreshFlagBug app = new TestRefreshFlagBug(); - app.start(); - } - - @Override - public void simpleUpdate(float tpf) { - time += tpf; - if (time > 5 && !attached) { - attached = true; - - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - geom.setMaterial(mat); - - inBetweenNode.attachChild(geom); - - // the refresh flags become corrupted here ... - inBetweenNode.getWorldBound(); - } - } - - @Override - public void simpleInitApp() { - inBetweenNode = new Node("In Between Node"); - rootNode.attachChild(inBetweenNode); - - flyCam.setDragToRotate(true); - } -} diff --git a/jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java b/jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java deleted file mode 100644 index 0e007de394..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.scene; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.asset.plugins.ZipLocator; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.SkyFactory; -import java.io.File; - -public class TestSceneLoading extends SimpleApplication { - - final private Sphere sphereMesh = new Sphere(32, 32, 10, false, true); - final private Geometry sphere = new Geometry("Sky", sphereMesh); - private static boolean useHttp = false; - - public static void main(String[] args) { - - TestSceneLoading app = new TestSceneLoading(); - app.start(); - } - - @Override - public void simpleUpdate(float tpf){ - sphere.setLocalTranslation(cam.getLocation()); - } - - @Override - public void simpleInitApp() { - File file = new File("wildhouse.zip"); - if (!file.exists()) { - useHttp = true; - } - - this.flyCam.setMoveSpeed(10); - - // load sky - rootNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - - // create the geometry and attach it - // load the level from zip or http zip - if (useHttp) { - assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", HttpZipLocator.class); - } else { - assetManager.registerLocator("wildhouse.zip", ZipLocator.class); - } - Spatial scene = assetManager.loadModel("main.scene"); - - AmbientLight al = new AmbientLight(); - scene.addLight(al); - - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(0.69077975f, -0.6277887f, -0.35875428f).normalizeLocal()); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - scene.addLight(sun); - - rootNode.attachChild(scene); - } -} diff --git a/jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java b/jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java deleted file mode 100644 index 81ff47e092..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.scene; - -import com.jme3.app.BasicProfilerState; -import com.jme3.app.DebugKeysAppState; -import com.jme3.app.FlyCamAppState; -import com.jme3.app.SimpleApplication; -import com.jme3.app.StatsAppState; -import com.jme3.app.state.ScreenshotAppState; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.control.AbstractControl; -import com.jme3.scene.shape.Box; -import java.util.Random; - - -/** - * Tests a deep scene with an unrecommended amount of objects. - * - * @author Paul Speed - */ -public class TestSceneStress extends SimpleApplication { - - final private static Box BOX = new Box(2f, 0.5f, 0.5f); - - private Material mat; - final private Random random = new Random(0); - - private int totalNodes = 0; - private int totalGeometry = 0; - private int totalControls = 0; - - public static void main( String... args ) { - - TestSceneStress test = new TestSceneStress(); - test.start(); - } - - public TestSceneStress() { - super(new StatsAppState(), new DebugKeysAppState(), new BasicProfilerState(false), - new FlyCamAppState(), - new ScreenshotAppState("", System.currentTimeMillis())); - } - - @Override - public void simpleInitApp() { - - stateManager.getState(FlyCamAppState.class).getCamera().setMoveSpeed(10); - - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - - // Create a deep, mostly static scene - Spatial oct = createOctSplit("root", 500, 5); - - rootNode.attachChild(oct); - - // Position to see most of it - cam.setLocation(new Vector3f(400.8009f, 370.16455f, -408.17984f)); - cam.setRotation(new Quaternion(0.24906662f, -0.3756747f, 0.105560325f, 0.88639235f)); - - System.out.println("Total nodes:" + totalNodes + " Total Geometry:" + totalGeometry + " Total controls:" + totalControls ); - } - - protected Spatial createOctSplit( String name, int size, int depth ) { - - if( depth == 0 ) { - // Done splitting - Geometry geom = new Geometry(name, BOX); - totalGeometry++; - geom.setMaterial(mat); - - if( random.nextFloat() < 0.01 ) { - RotatorControl control = new RotatorControl(random.nextFloat(), random.nextFloat(), random.nextFloat()); - geom.addControl(control); - totalControls++; - } - - return geom; - } - - Node root = new Node(name); - totalNodes++; - - int half = size / 2; - float quarter = half * 0.5f; - - for( int i = 0; i < 2; i++ ) { - float x = i * half - quarter; - for( int j = 0; j < 2; j++ ) { - float y = j * half - quarter; - for( int k = 0; k < 2; k++ ) { - float z = k * half - quarter; - - Spatial child = createOctSplit(name + "(" + i + ", " + j + ", " + k + ")", - half, depth - 1); - child.setLocalTranslation(x, y, z); - root.attachChild(child); - } - } - } - - return root; - } - - private class RotatorControl extends AbstractControl { - final private float[] rotate; - - public RotatorControl( float... rotate ) { - this.rotate = rotate; - } - - @Override - protected void controlUpdate( float tpf ) { - if( spatial != null ) { - spatial.rotate(rotate[0] * tpf, rotate[1] * tpf, rotate[2] * tpf); - } - } - - @Override - protected void controlRender( RenderManager rm, ViewPort vp ) { - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/scene/TestUserData.java b/jme3-examples/src/main/java/jme3test/scene/TestUserData.java deleted file mode 100644 index b482f1906e..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/TestUserData.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.scene; - -import com.jme3.app.SimpleApplication; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; - -public class TestUserData extends SimpleApplication { - - public static void main(String[] args) { - TestUserData app = new TestUserData(); - app.start(); - } - - @Override - public void simpleInitApp() { - Node scene = (Node) assetManager.loadModel("Scenes/DotScene/DotScene.scene"); - System.out.println("Scene: " + scene); - - Spatial testNode = scene.getChild("TestNode"); - System.out.println("TestNode: "+ testNode); - - for (String key : testNode.getUserDataKeys()){ - System.out.println("Property " + key + " = " + testNode.getUserData(key)); - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java deleted file mode 100644 index 8a3da3abdd..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.scene.instancing; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Spatial; -import com.jme3.scene.Node; -import com.jme3.scene.instancing.InstancedGeometry; -import com.jme3.scene.instancing.InstancedNode; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.system.AppSettings; - -public class TestInstanceNode extends SimpleApplication { - - private Mesh mesh1; - private Mesh mesh2; - private final Material[] materials = new Material[6]; - private Node instancedNode; - private float time = 0; - final private boolean INSTANCING = true; - - public static void main(String[] args){ - TestInstanceNode app = new TestInstanceNode(); - AppSettings settings = new AppSettings(true); - settings.setVSync(false); - app.setSettings(settings); - app.start(); - } - - private Geometry createInstance(float x, float z) { - Mesh mesh; - if (FastMath.nextRandomInt(0, 1) == 1) mesh = mesh2; - else mesh = mesh1; - Geometry geometry = new Geometry("randomGeom", mesh); - geometry.setMaterial(materials[FastMath.nextRandomInt(0, materials.length - 1)]); - geometry.setLocalTranslation(x, 0, z); - return geometry; - } - - @Override - public void simpleInitApp() { - mesh1 = new Sphere(13, 13, 0.4f, true, false); - mesh2 = new Box(0.4f, 0.4f, 0.4f); - - materials[0] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - materials[0].setBoolean("UseInstancing", INSTANCING); - materials[0].setColor("Color", ColorRGBA.Red); - - materials[1] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - materials[1].setBoolean("UseInstancing", INSTANCING); - materials[1].setColor("Color", ColorRGBA.Green); - - materials[2] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - materials[2].setBoolean("UseInstancing", INSTANCING); - materials[2].setColor("Color", ColorRGBA.Blue); - - materials[3] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - materials[3].setBoolean("UseInstancing", INSTANCING); - materials[3].setColor("Color", ColorRGBA.Cyan); - - materials[4] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - materials[4].setBoolean("UseInstancing", INSTANCING); - materials[4].setColor("Color", ColorRGBA.Magenta); - - materials[5] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - materials[5].setBoolean("UseInstancing", INSTANCING); - materials[5].setColor("Color", ColorRGBA.Yellow); - - instancedNode = new InstancedNode("instanced_node"); - - rootNode.attachChild(instancedNode); - - int extent = 30; - - for (int y = -extent; y < extent; y++) { - for (int x = -extent; x < extent; x++) { - Geometry instance = createInstance(x, y); - - float height = (smoothstep(0, 1, FastMath.nextRandomFloat()) * 2.5f) - 1.25f; - instance.setUserData("height", height); - instance.setUserData("dir", 1f); - - instancedNode.attachChild(instance); - } - } - - if (INSTANCING) { - ((InstancedNode)instancedNode).instance(); - } - - //instancedNode = (InstancedNode) instancedNode.clone(); - //instancedNode.move(0, 5, 0); - //rootNode.attachChild(instancedNode); - - cam.setLocation(new Vector3f(38.373516f, 6.689055f, 38.482082f)); - cam.setRotation(new Quaternion(-0.04004206f, 0.918326f, -0.096310444f, -0.38183528f)); - flyCam.setMoveSpeed(15); - flyCam.setEnabled(false); - } - - private float smoothstep(float edge0, float edge1, float x) { - // Scale, bias and saturate x to 0..1 range - x = FastMath.clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); - // Evaluate polynomial - return x * x * (3 - 2 * x); - } - - - @Override - public void simpleUpdate(float tpf) { - time += tpf; - - if (time > 1f) { - time = 0f; - - for (Spatial instance : instancedNode.getChildren()) { - if (!(instance instanceof InstancedGeometry)) { - Geometry geom = (Geometry) instance; - geom.setMaterial(materials[FastMath.nextRandomInt(0, materials.length - 1)]); - - Mesh mesh; - if (FastMath.nextRandomInt(0, 1) == 1) mesh = mesh2; - else mesh = mesh1; - geom.setMesh(mesh); - } - } - } - - for (Spatial child : instancedNode.getChildren()) { - if (!(child instanceof InstancedGeometry)) { - float val = ((Float)child.getUserData("height")).floatValue(); - float dir = ((Float)child.getUserData("dir")).floatValue(); - - val += (dir + ((FastMath.nextRandomFloat() * 0.5f) - 0.25f)) * tpf; - - if (val > 1f) { - val = 1f; - dir = -dir; - } else if (val < 0f) { - val = 0f; - dir = -dir; - } - - Vector3f translation = child.getLocalTranslation(); - translation.y = (smoothstep(0, 1, val) * 2.5f) - 1.25f; - - child.setUserData("height", val); - child.setUserData("dir", dir); - - child.setLocalTranslation(translation); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java deleted file mode 100644 index 087ce1b7c3..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java +++ /dev/null @@ -1,62 +0,0 @@ -package jme3test.scene.instancing; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.instancing.InstancedNode; -import com.jme3.scene.shape.Box; - -public class TestInstanceNodeWithLight extends SimpleApplication { - // Try to test with different offset - private static float offset = 12; - - public static void main(String[] args) { - TestInstanceNodeWithLight app = new TestInstanceNodeWithLight(); - app.start(); - } - - private Geometry box; - private PointLight pointLight; - - @Override - public void simpleInitApp() { - InstancedNode instancedNode = new InstancedNode("testInstancedNode"); - rootNode.attachChild(instancedNode); - - box = new Geometry("Box", new Box(0.5f, 0.5f, 0.5f)); - Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - material.setBoolean("UseInstancing", true); - material.setColor("Diffuse", ColorRGBA.Red); - material.setBoolean("UseMaterialColors", true); - box.setMaterial(material); - - instancedNode.attachChild(box); - instancedNode.instance(); - - pointLight = new PointLight(); - pointLight.setColor(ColorRGBA.White); - pointLight.setRadius(10f); - rootNode.addLight(pointLight); - - box.setLocalTranslation(new Vector3f(offset, 0, 0)); - pointLight.setPosition(new Vector3f(offset - 3f, 0, 0)); - - cam.setLocation(new Vector3f(offset - 5f, 0, 0)); - cam.lookAtDirection(Vector3f.UNIT_X, Vector3f.UNIT_Y); - } - - @Override - public void simpleUpdate(float tpf) { - offset += tpf; - - System.err.println(offset); - box.setLocalTranslation(new Vector3f(offset, 0, 0)); - pointLight.setPosition(new Vector3f(offset - 3f, 0, 0)); - - cam.setLocation(new Vector3f(offset - 5f, 0, 0)); - cam.lookAtDirection(Vector3f.UNIT_X, Vector3f.UNIT_Y); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java deleted file mode 100644 index 054f4e6efd..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.scene.instancing; - -import com.jme3.app.SimpleApplication; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.font.BitmapText; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Ray; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.instancing.InstancedNode; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.system.AppSettings; - - -/** - * A test case for using instancing with ray casting. - * - * Based on distance from camera, swap in/out more/less detailed geometry to/from an InstancedNode. - * - * @author duncanj - */ -public class TestInstancedNodeAttachDetachWithPicking extends SimpleApplication { - public static void main(String[] args) { - TestInstancedNodeAttachDetachWithPicking app = new TestInstancedNodeAttachDetachWithPicking(); - AppSettings settings = new AppSettings(true); - settings.setVSync(false); - app.setSettings(settings); - app.start(); - } - - private InstancedNode instancedNode; - - final private Vector3f[] locations = new Vector3f[10]; - final private Geometry[] spheres = new Geometry[10]; - final private Geometry[] boxes = new Geometry[10]; - - @Override - public void simpleInitApp() { - addPointLight(); - addAmbientLight(); - - Material material = createInstancedLightingMaterial(); - - instancedNode = new InstancedNode("theParentInstancedNode"); - rootNode.attachChild(instancedNode); - Sphere sphereMesh = new Sphere(16, 16, 1f); - Box boxMesh = new Box(0.7f, 0.7f, 0.7f); - // create 10 spheres & boxes, positioned along Z-axis successively further from the camera - for (int i = 0; i < 10; i++) { - Vector3f location = new Vector3f(0, -3, -(i*5)); - locations[i] = location; - - Geometry sphere = new Geometry("sphere", sphereMesh); - sphere.setMaterial(material); - sphere.setLocalTranslation(location); - instancedNode.attachChild(sphere); // initially just add the spheres to the InstancedNode - spheres[i] = sphere; - - Geometry box = new Geometry("box", boxMesh); - box.setMaterial(material); - box.setLocalTranslation(location); - boxes[i] = box; - } - instancedNode.instance(); - - flyCam.setMoveSpeed(30); - - - addCrossHairs(); - - // when you left-click, print the distance to the object to system.out - inputManager.addMapping("leftClick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if( isPressed ) { - CollisionResult result = pickFromCamera(); - if( result != null ) { - System.out.println("Picked = " + result.getGeometry() + ", Distance = "+result.getDistance()); - } - } - } - }, "leftClick"); - } - - @Override - public void simpleUpdate(float tpf) { - // Each frame, determine the distance to each sphere/box from the camera. - // If the object is > 25 units away, switch in the Box. If it's nearer, switch in the Sphere. - // Normally we wouldn't do this every frame, only when player has moved a sufficient distance, etc. - - - boolean modified = false; - for (int i = 0; i < 10; i++) { - Vector3f location = locations[i]; - float distance = location.distance(cam.getLocation()); - - if(distance > 25.0f && boxes[i].getParent() == null) { - modified = true; - instancedNode.attachChild(boxes[i]); - instancedNode.detachChild(spheres[i]); - } else if(distance <= 25.0f && spheres[i].getParent() == null) { - modified = true; - instancedNode.attachChild(spheres[i]); - instancedNode.detachChild(boxes[i]); - } - } - - if(modified) { - instancedNode.instance(); - } - } - - private Material createInstancedLightingMaterial() { - Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - material.setBoolean("UseMaterialColors", true); - material.setBoolean("UseInstancing", true); - material.setColor("Ambient", ColorRGBA.Red); - material.setColor("Diffuse", ColorRGBA.Red); - material.setColor("Specular", ColorRGBA.Red); - material.setFloat("Shininess", 1.0f); - return material; - } - - private void addAmbientLight() { - AmbientLight ambientLight = new AmbientLight(new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f)); - rootNode.addLight(ambientLight); - } - - private void addPointLight() { - PointLight pointLight = new PointLight(); - pointLight.setColor(ColorRGBA.White); - pointLight.setRadius(100f); - pointLight.setPosition(new Vector3f(10f, 10f, 0)); - rootNode.addLight(pointLight); - } - - private void addCrossHairs() { - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize()+4); - ch.setText("+"); // crosshairs - ch.setColor(ColorRGBA.White); - ch.setLocalTranslation( // center - settings.getWidth() / 2 - ch.getLineWidth() / 2, - settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); - guiNode.attachChild(ch); - } - - private CollisionResult pickFromCamera() { - CollisionResults results = new CollisionResults(); - Ray ray = new Ray(cam.getLocation(), cam.getDirection()); - instancedNode.collideWith(ray, results); - return results.getClosestCollision(); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java deleted file mode 100644 index 6d5b76da83..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.scene.instancing; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.instancing.InstancedNode; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.shadow.DirectionalLightShadowFilter; -import com.jme3.shadow.EdgeFilteringMode; -import com.jme3.system.AppSettings; - -/** - * A test case for using instancing with shadow filter. - * - * Based on distance from camera, swap in/out more/less detailed geometry to/from an InstancedNode. - * - * @author duncanj - */ -public class TestInstancedNodeAttachDetachWithShadowFilter extends SimpleApplication { - public static void main(String[] args) { - TestInstancedNodeAttachDetachWithShadowFilter app = new TestInstancedNodeAttachDetachWithShadowFilter(); - AppSettings settings = new AppSettings(true); - settings.setVSync(false); - app.setSettings(settings); - app.start(); - } - - private FilterPostProcessor filterPostProcessor; - private InstancedNode instancedNode; - - final private Vector3f[] locations = new Vector3f[10]; - final private Geometry[] spheres = new Geometry[10]; - final private Geometry[] boxes = new Geometry[10]; - - @Override - public void simpleInitApp() { - filterPostProcessor = new FilterPostProcessor(assetManager); - getViewPort().addProcessor(filterPostProcessor); - - addDirectionalLight(); - addAmbientLight(); - - Material instancingMaterial = createLightingMaterial(true, ColorRGBA.LightGray); - - instancedNode = new InstancedNode("theParentInstancedNode"); - instancedNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - rootNode.attachChild(instancedNode); - - // create 10 spheres & boxes, along the z-axis, successively further from the camera - Mesh sphereMesh = new Sphere(32, 32, 1f); - Mesh boxMesh = new Box(0.7f, 0.7f, 0.7f); - for (int z = 0; z < 10; z++) { - Vector3f location = new Vector3f(0, -3, -(z * 4)); - locations[z] = location; - - Geometry sphere = new Geometry("sphere", sphereMesh); - sphere.setMaterial(instancingMaterial); - sphere.setLocalTranslation(location); - instancedNode.attachChild(sphere); // initially just add the spheres to the InstancedNode - spheres[z] = sphere; - - Geometry box = new Geometry("box", boxMesh); - box.setMaterial(instancingMaterial); - box.setLocalTranslation(location); - boxes[z] = box; - } - - instancedNode.instance(); - - - Geometry floor = new Geometry("floor", new Box(20, 0.1f, 40)); - floor.setMaterial(createLightingMaterial(false, ColorRGBA.Yellow)); - floor.setLocalTranslation(5, -5, 0); - floor.setShadowMode(RenderQueue.ShadowMode.Receive); - rootNode.attachChild(floor); - - flyCam.setMoveSpeed(30); - } - - @Override - public void simpleUpdate(float tpf) { - // Each frame, determine the distance to each sphere/box from the camera. - // If the object is > 25 units away, switch in the Box. If it's nearer, switch in the Sphere. - // Normally we wouldn't do this every frame, only when player has moved a sufficient distance, etc. - - boolean modified = false; - for (int i = 0; i < 10; i++) { - Vector3f location = locations[i]; - float distance = location.distance(cam.getLocation()); - - if(distance > 25.0f && boxes[i].getParent() == null) { - modified = true; - instancedNode.attachChild(boxes[i]); - instancedNode.detachChild(spheres[i]); - } else if(distance <= 25.0f && spheres[i].getParent() == null) { - modified = true; - instancedNode.attachChild(spheres[i]); - instancedNode.detachChild(boxes[i]); - } - } - - if(modified) { - instancedNode.instance(); - } - } - - private Material createLightingMaterial(boolean useInstancing, ColorRGBA color) { - Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - material.setBoolean("UseMaterialColors", true); - material.setBoolean("UseInstancing", useInstancing); - material.setColor("Ambient", color); - material.setColor("Diffuse", color); - material.setColor("Specular", color); - material.setFloat("Shininess", 1.0f); - return material; - } - - private void addAmbientLight() { - AmbientLight ambientLight = new AmbientLight(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f)); - rootNode.addLight(ambientLight); - } - - private void addDirectionalLight() { - DirectionalLight light = new DirectionalLight(); - - light.setColor(ColorRGBA.White); - light.setDirection(new Vector3f(-1, -1, -1)); - - DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, 1024, 1); - dlsf.setLight(light); - dlsf.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON); - filterPostProcessor.addFilter(dlsf); - - rootNode.addLight(light); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java deleted file mode 100644 index f0fe8f6b7e..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ - -package jme3test.scene.instancing; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.scene.Geometry; -import com.jme3.scene.instancing.InstancedNode; -import com.jme3.scene.shape.Box; -import com.jme3.water.WaterFilter; - -/** - * A test case for using instancing with shadow filter. This is a test case - * for issue 2007 (Instanced objects are culled when using the WaterFilter). - * - * If test succeeds, all the boxes in the camera frustum will be rendered. If - * test fails, some of the boxes that are in the camera frustum will be culled. - * - * @author Ali-RS - */ -public class TestInstancingWithWaterFilter extends SimpleApplication { - public static void main(String[] args) { - TestInstancingWithWaterFilter test = new TestInstancingWithWaterFilter(); - test.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(10); - - DirectionalLight light = new DirectionalLight(); - light.setDirection(new Vector3f(-1, -1, -1)); - rootNode.addLight(light); - - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - mat.setBoolean("UseInstancing", true); - - Box mesh = new Box(0.5f, 0.5f, 0.5f); - - InstancedNode instanceNode = new InstancedNode("TestInstancedNode"); - //instanceNode.setCullHint(Spatial.CullHint.Never); - rootNode.attachChild(instanceNode); - - for (int i = 0; i < 200; i++) { - Geometry obj = new Geometry("TestBox" + i, mesh); - obj.setMaterial(mat); - obj.setLocalTranslation(i, i, 0); - instanceNode.attachChild(obj); - } - instanceNode.instance(); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - WaterFilter waterFilter = new WaterFilter(rootNode, light.getDirection()); - fpp.addFilter(waterFilter); - viewPort.addProcessor(fpp); - } -} diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java b/jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java deleted file mode 100644 index ddce65ca9a..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for instancing - */ -package jme3test.scene.instancing; diff --git a/jme3-examples/src/main/java/jme3test/scene/package-info.java b/jme3-examples/src/main/java/jme3test/scene/package-info.java deleted file mode 100644 index 9e19c9956a..0000000000 --- a/jme3-examples/src/main/java/jme3test/scene/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for various scene-graph features - */ -package jme3test.scene; diff --git a/jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java b/jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java deleted file mode 100644 index 717ed6d8f6..0000000000 --- a/jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.stress; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.LodControl; -import jme3tools.optimize.GeometryBatchFactory; - -public class TestBatchLod extends SimpleApplication { - - public static void main(String[] args) { - TestBatchLod app = new TestBatchLod(); - app.start(); - } - - @Override - 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); - - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - mat.setFloat("Shininess", 16f); - mat.setBoolean("VertexLighting", true); - teapot.setMaterial(mat); - - // A special Material to visualize mesh normals: - //Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - flyCam.setMoveSpeed(5); - for (int y = -5; y < 5; y++) { - for (int x = -5; x < 5; x++) { - Geometry clonePot = teapot.clone(); - - //clonePot.setMaterial(mat); - clonePot.setLocalTranslation(x * .5f, 0, y * .5f); - clonePot.setLocalScale(.15f); - clonePot.setMaterial(mat); - rootNode.attachChild(clonePot); - } - } - GeometryBatchFactory.optimize(rootNode, true); - LodControl control = new LodControl(); - rootNode.getChild(0).addControl(control); - cam.setLocation(new Vector3f(-1.0748308f, 1.35778f, -1.5380064f)); - cam.setRotation(new Quaternion(0.18343268f, 0.34531063f, -0.069015436f, 0.9177962f)); - - } -} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java b/jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java deleted file mode 100644 index 24861464ad..0000000000 --- a/jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.stress; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial.CullHint; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.NativeObjectManager; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Generates 400 new meshes every frame then leaks them. - * Notice how memory usage stays constant and OpenGL objects - * are properly destroyed. - */ -public class TestLeakingGL extends SimpleApplication { - - private Material solidColor; - private Sphere original; - - public static void main(String[] args){ - TestLeakingGL app = new TestLeakingGL(); - app.start(); - } - - @Override - public void simpleInitApp() { - original = new Sphere(4, 4, 1); - original.setStatic(); - //original.setInterleaved(); - - // this will make sure all spheres are rendered always - rootNode.setCullHint(CullHint.Never); - solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); - cam.setLocation(new Vector3f(0, 5, 0)); - cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - - Logger.getLogger(Node.class.getName()).setLevel(Level.WARNING); - Logger.getLogger(NativeObjectManager.class.getName()).setLevel(Level.WARNING); - } - - @Override - public void simpleUpdate(float tpf){ - rootNode.detachAllChildren(); - for (int y = -15; y < 15; y++){ - for (int x = -15; x < 15; x++){ - Mesh sphMesh = original.deepClone(); - Geometry sphere = new Geometry("sphere", sphMesh); - - sphere.setMaterial(solidColor); - sphere.setLocalTranslation(x * 1.5f, 0, y * 1.5f); - rootNode.attachChild(sphere); - } - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java b/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java deleted file mode 100644 index f182460251..0000000000 --- a/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.stress; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ScheduledThreadPoolExecutor; - -import com.jme3.anim.SkinningControl; -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.font.BitmapText; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.VertexBuffer; - -import jme3tools.optimize.LodGenerator; - -public class TestLodGeneration extends SimpleApplication { - - public static void main(String[] args) { - TestLodGeneration app = new TestLodGeneration(); - app.start(); - } - - private boolean wireFrame = false; - private float reductionValue = 0.0f; - private int lodLevel = 0; - private BitmapText hudText; - final private List listGeoms = new ArrayList<>(); - final private ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(5); - - @Override - public void simpleInitApp() { - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - rootNode.addLight(dl); - - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(0.6f)); - rootNode.addLight(al); - - // model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); - Node model = (Node) assetManager.loadModel("Models/Jaime/Jaime.j3o"); - BoundingBox b = ((BoundingBox) model.getWorldBound()); - model.setLocalScale(1.2f / (b.getYExtent() * 2)); - // model.setLocalTranslation(0,-(b.getCenter().y - b.getYExtent())* model.getLocalScale().y, 0); - for (Spatial spatial : model.getChildren()) { - if (spatial instanceof Geometry) { - listGeoms.add((Geometry) spatial); - } - } - - ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); - model.addControl(chaseCam); - chaseCam.setLookAtOffset(b.getCenter()); - chaseCam.setDefaultDistance(5); - chaseCam.setMinVerticalRotation(-FastMath.HALF_PI + 0.01f); - chaseCam.setZoomSensitivity(0.5f); - - SkinningControl skControl = model.getControl(SkinningControl.class); - if (skControl != null) { - skControl.setEnabled(false); - } - - reductionValue = 0.80f; - lodLevel = 1; - for (final Geometry geom : listGeoms) { - LodGenerator lodGenerator = new LodGenerator(geom); - lodGenerator.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL, reductionValue); - geom.setLodLevel(lodLevel); - } - - rootNode.attachChild(model); - flyCam.setEnabled(false); - - guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - hudText = new BitmapText(guiFont); - hudText.setSize(guiFont.getCharSet().getRenderedSize()); - hudText.setText(computeNbTri() + " tris"); - hudText.setLocalTranslation(cam.getWidth() / 2, hudText.getLineHeight(), 0); - guiNode.attachChild(hudText); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - if (name.equals("plus")) { - reductionValue += 0.05f; - updateLod(); - } - if (name.equals("minus")) { - reductionValue -= 0.05f; - updateLod(); - } - if (name.equals("wireFrame")) { - wireFrame = !wireFrame; - for (Geometry geom : listGeoms) { - Material mat = geom.getMaterial(); - mat.getAdditionalRenderState().setWireframe(wireFrame); - } - } - } - } - }, "plus", "minus", "wireFrame"); - - inputManager.addMapping("plus", new KeyTrigger(KeyInput.KEY_ADD)); - inputManager.addMapping("minus", new KeyTrigger(KeyInput.KEY_SUBTRACT)); - inputManager.addMapping("wireFrame", new KeyTrigger(KeyInput.KEY_SPACE)); - } - - @Override - public void simpleUpdate(float tpf) { - } - - @Override - public void destroy() { - super.destroy(); - exec.shutdown(); - } - - private void updateLod() { - reductionValue = FastMath.clamp(reductionValue, 0.0f, 1.0f); - makeLod(LodGenerator.TriangleReductionMethod.PROPORTIONAL, reductionValue, 1); - } - - private int computeNbTri() { - int nbTri = 0; - for (Geometry geom : listGeoms) { - Mesh mesh = geom.getMesh(); - if (mesh.getNumLodLevels() > 0) { - nbTri += mesh.getLodLevel(lodLevel).getNumElements(); - } else { - nbTri += mesh.getTriangleCount(); - } - } - return nbTri; - } - - private void makeLod(final LodGenerator.TriangleReductionMethod method, final float value, final int ll) { - exec.execute(new Runnable() { - @Override - public void run() { - for (final Geometry geom : listGeoms) { - LodGenerator lodGenerator = new LodGenerator(geom); - final VertexBuffer[] lods = lodGenerator.computeLods(method, value); - - enqueue(new Callable() { - @Override - public Void call() throws Exception { - geom.getMesh().setLodLevels(lods); - lodLevel = 0; - if (geom.getMesh().getNumLodLevels() > ll) { - lodLevel = ll; - } - geom.setLodLevel(lodLevel); - hudText.setText(computeNbTri() + " tris"); - return null; - } - }); - } - } - }); - } -} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestLodStress.java b/jme3-examples/src/main/java/jme3test/stress/TestLodStress.java deleted file mode 100644 index a02616680f..0000000000 --- a/jme3-examples/src/main/java/jme3test/stress/TestLodStress.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.stress; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.control.LodControl; - -public class TestLodStress extends SimpleApplication { - - public static void main(String[] args){ - TestLodStress app = new TestLodStress(); - app.setShowSettings(false); - app.setPauseOnLostFocus(false); - app.start(); - } - - @Override - public void simpleInitApp() { - 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); - -// 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); - teapot.setMaterial(mat); - - // A special Material to visualize mesh normals: - //Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); - - for (int y = -10; y < 10; y++){ - for (int x = -10; x < 10; x++){ - Geometry clonePot = teapot.clone(); - - //clonePot.setMaterial(mat); - clonePot.setLocalTranslation(x * .5f, 0, y * .5f); - clonePot.setLocalScale(.15f); - - LodControl control = new LodControl(); - clonePot.addControl(control); - rootNode.attachChild(clonePot); - } - } - - cam.setLocation(new Vector3f(8.378951f, 5.4324f, 8.795956f)); - cam.setRotation(new Quaternion(-0.083419204f, 0.90370524f, -0.20599906f, -0.36595422f)); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java b/jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java deleted file mode 100644 index a8c463b459..0000000000 --- a/jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.stress; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.TangentBinormalGenerator; - -public class TestParallelTangentGeneration { - - final private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - - public static void main(String[] args) { - - for (int i = 0; i < 10; i++) { - { - Node root = new Node("Root"); - for (int count = 0; count < 10; count++) { - for (int samples = 4; samples < 50; samples++) { - Geometry g = new Geometry(); - g.setMesh(new Sphere(samples, samples, 1.0f)); - root.attachChild(g); - } - } - - long start = System.currentTimeMillis(); - TangentBinormalGenerator.generate(root); - System.out.println("Serial " + (System.currentTimeMillis() - start)); - } - - { - Node root = new Node("Root"); - for (int count = 0; count < 10; count++) { - for (int samples = 4; samples < 50; samples++) { - Geometry g = new Geometry(); - g.setMesh(new Sphere(samples, samples, 1.0f)); - root.attachChild(g); - } - } - - long start = System.currentTimeMillis(); - TangentBinormalGenerator.generateParallel(root, executor); - System.out.println("Parallel " + (System.currentTimeMillis() - start)); - } - - } - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java b/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java deleted file mode 100644 index 34ab16f550..0000000000 --- a/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java +++ /dev/null @@ -1,109 +0,0 @@ -package jme3test.stress; - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.profile.*; -import com.jme3.renderer.ViewPort; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; -import com.jme3.texture.Texture; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class TestShaderNodesStress extends SimpleApplication { - - public static void main(String[] args) { - TestShaderNodesStress app = new TestShaderNodesStress(); - app.start(); - } - - @Override - public void simpleInitApp() { - - Quad q = new Quad(1, 1); - Geometry g = new Geometry("quad", q); - g.setLocalTranslation(-500, -500, 0); - g.setLocalScale(1000); - - rootNode.attachChild(g); - cam.setLocation(new Vector3f(0.0f, 0.0f, 0.40647888f)); - cam.setRotation(new Quaternion(0.0f, 1.0f, 0.0f, 0.0f)); - - Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md"); - //Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - - mat.setColor("Color", ColorRGBA.Yellow); - mat.setTexture("ColorMap", tex); - g.setMaterial(mat); - //place the geoms in the transparent bucket so that they are rendered back to front for maximum overdraw - g.setQueueBucket(RenderQueue.Bucket.Transparent); - - for (int i = 0; i < 1000; i++) { - Geometry cl = g.clone(false); - cl.move(0, 0, -(i + 1)); - rootNode.attachChild(cl); - } - - flyCam.setMoveSpeed(20); - Logger.getLogger("com.jme3").setLevel(Level.WARNING); - - this.setAppProfiler(new Profiler()); - - } - - private class Profiler implements AppProfiler { - - private long startTime; - private long updateTime; - private long renderTime; - private long sum; - private int nbFrames; - - @Override - public void appStep(AppStep step) { - - switch (step) { - case BeginFrame: - startTime = System.nanoTime(); - break; - case RenderFrame: - updateTime = System.nanoTime(); - // System.err.println("Update time : " + (updateTime - startTime)); - break; - case EndFrame: - nbFrames++; - if (nbFrames >= 150) { - renderTime = System.nanoTime(); - sum += renderTime - updateTime; - System.err.println("render time : " + (renderTime - updateTime)); - System.err.println("Average render time : " + (sum / (float)(nbFrames-150))); - } - break; - - } - - } - - @Override - public void appSubStep(String... additionalInfo) { - - } - - @Override - public void vpStep(VpStep step, ViewPort vp, RenderQueue.Bucket bucket) { - - } - - @Override - public void spStep(SpStep step, String... additionalInfo) { - - } - - } -} diff --git a/jme3-examples/src/main/java/jme3test/stress/package-info.java b/jme3-examples/src/main/java/jme3test/stress/package-info.java deleted file mode 100644 index ab72f67ad2..0000000000 --- a/jme3-examples/src/main/java/jme3test/stress/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * non-automated stress tests - */ -package jme3test.stress; diff --git a/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java b/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java deleted file mode 100644 index 8375db317a..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.terrain; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.light.LightProbe; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.shader.VarType; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.texture.TextureArray; -import java.util.ArrayList; -import java.util.List; - -/** - * This test uses 'AdvancedPBRTerrain.j3md' to create a terrain Material with - * more textures than 'PBRTerrain.j3md' can handle. - * - * Upon running the app, the user should see a mountainous, terrain-based - * landscape with some grassy areas, some snowy areas, and some tiled roads and - * gravel paths weaving between the valleys. Snow should be slightly - * shiny/reflective, and marble texture should be even shinier. If you would - * like to know what each texture is supposed to look like, you can find the - * textures used for this test case located in jme3-testdata. (Screenshots - * showing how this test-case should look will also be available soon so you can - * compare your results, and I will replace this comment with a link to their - * location as soon as they are posted.) - * - * Press 'p' to toggle tri-planar mode. Enabling tri-planar mode should prevent - * stretching of textures in steep areas of the terrain. - * - * Press 'n' to toggle between night and day. Pressing 'n' will cause the light - * to gradually fade darker/brighter until the min/max lighting levels are - * reached. At night the scene should be noticeably darker, and the marble and - * tiled-road texture should be noticeably glowing from the emissiveColors and - * the emissiveIntensity map that is packed into the alpha channel of the - * MetallicRoughness maps. - * - * The MetallicRoughness map stores: - *

    - *
  • AmbientOcclusion in the Red channel
  • - *
  • Roughness in the Green channel
  • - *
  • Metallic in the Blue channel
  • - *
  • EmissiveIntensity in the Alpha channel
  • - *
- * - * The shaders are still subject to the GLSL max limit of 16 textures, however - * each TextureArray counts as a single texture, and each TextureArray can store - * multiple images. For more information on texture arrays see: - * https://www.khronos.org/opengl/wiki/Array_Texture - * - * Uses assets from CC0Textures.com, licensed under CC0 1.0 Universal. For more - * information on the textures this test case uses, view the license.txt file - * located in the jme3-testdata directory where these textures are located: - * jme3-testdata/src/main/resources/Textures/Terrain/PBR - * - *

- * Notes: (as of 12 April 2021) - *

    - *
  1. - * The results look better with anti-aliasing, especially from a distance. This - * may be due to the way that the terrain is generated from a heightmap, as - * these same textures do not have this issue in my other project. - *
  2. - *
  3. - * The number of images per texture array may still be limited by - * GL_MAX_ARRAY_TEXTURE_LAYERS, however this value should be high enough that - * users will likely run into issues with extremely low FPS from too many - * texture-reads long before you surpass the limit of texture-layers per - * textureArray. If this ever becomes an issue, a secondary set of - * Albedo/Normal/MetallicRoughness texture arrays could be added to the shader - * to store any textures that surpass the limit of the primary textureArrays. - *
  4. - *
- * - * @author yaRnMcDonuts - */ -public class PBRTerrainAdvancedTest extends SimpleApplication { - - private TerrainQuad terrain; - private Material matTerrain; - private boolean triPlanar = false; - - private final int terrainSize = 512; - private final int patchSize = 256; - private final float dirtScale = 24; - private final float darkRockScale = 24; - private final float snowScale = 64; - private final float tileRoadScale = 64; - private final float grassScale = 24; - private final float marbleScale = 64; - private final float gravelScale = 64; - - private final ColorRGBA tilesEmissiveColor = new ColorRGBA(0.12f, 0.02f, 0.23f, 0.85f); //dim magenta emission - private final ColorRGBA marbleEmissiveColor = new ColorRGBA(0.0f, 0.0f, 1.0f, 1.0f); //fully saturated blue emission - - private AmbientLight ambientLight; - private DirectionalLight directionalLight; - private boolean isNight = false; - - private final float dayLightIntensity = 1.0f; - private final float nightLightIntensity = 0.03f; - - private BitmapText keybindingsText; - - private final float camMoveSpeed = 50f; - - public static void main(String[] args) { - PBRTerrainAdvancedTest app = new PBRTerrainAdvancedTest(); - app.start(); - } - - private final ActionListener actionListener = new ActionListener() { - @Override - public void onAction(String name, boolean pressed, float tpf) { - if (name.equals("triPlanar") && !pressed) { - triPlanar = !triPlanar; - if (triPlanar) { - matTerrain.setBoolean("useTriPlanarMapping", true); - // Tri-planar textures don't use the mesh's texture coordinates but real world coordinates, - // so we need to convert these texture coordinate scales into real world scales so it looks - // the same when we switch to/from tri-planar mode. - matTerrain.setFloat("AlbedoMap_0_scale", (dirtScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_1_scale", (darkRockScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_2_scale", (snowScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_3_scale", (tileRoadScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_4_scale", (grassScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_5_scale", (marbleScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_6_scale", (gravelScale / terrainSize)); - } else { - matTerrain.setBoolean("useTriPlanarMapping", false); - - matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); - matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); - matTerrain.setFloat("AlbedoMap_2_scale", snowScale); - matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); - matTerrain.setFloat("AlbedoMap_4_scale", grassScale); - matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); - matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); - } - } - if (name.equals("toggleNight") && !pressed) { - isNight = !isNight; - // Ambient and directional light are faded smoothly in update loop below. - } - } - }; - - @Override - public void simpleInitApp() { - setupKeys(); - setUpTerrain(); - setUpTerrainMaterial(); // <- This method contains the important info about using 'AdvancedPBRTerrain.j3md' - setUpLights(); - setUpCamera(); - } - - private void setUpTerrainMaterial() { - // advanced PBR terrain matdef - matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md"); - - matTerrain.setBoolean("useTriPlanarMapping", false); - - // ALPHA map (for splat textures) - matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); - matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); - // this material also supports 'AlphaMap_2', so you can get up to 12 texture slots - - // load textures for texture arrays - // These MUST all have the same dimensions and format in order to be put into a texture array. - //ALBEDO MAPS - Texture dirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - Texture darkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Color.png"); - Texture snow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Color.png"); - Texture tileRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Color.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - Texture marble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Color.png"); - Texture gravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Color.png"); - - // NORMAL MAPS - Texture normalMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_1K_Normal.png"); - Texture normalMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Normal.png"); - Texture normalMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Normal.png"); - Texture normalMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Normal.png"); - Texture normalMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Normal.png"); - Texture normalMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Normal.png"); - Texture normalMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Normal.png"); - - //PACKED METALLIC/ROUGHNESS / AMBIENT OCCLUSION / EMISSIVE INTENSITY MAPS - Texture metallicRoughnessAoEiMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel_015_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_PackedMetallicRoughnessMap.png"); - - // put all images into lists to create texture arrays. - // - // The index of each image in its list will be - // sent to the material to tell the shader to choose that texture from - // the textureArray when setting up a texture slot's mat params. - // - List albedoImages = new ArrayList<>(); - List normalMapImages = new ArrayList<>(); - List metallicRoughnessAoEiMapImages = new ArrayList<>(); - - albedoImages.add(dirt.getImage()); //0 - albedoImages.add(darkRock.getImage()); //1 - albedoImages.add(snow.getImage()); //2 - albedoImages.add(tileRoad.getImage()); //3 - albedoImages.add(grass.getImage()); //4 - albedoImages.add(marble.getImage()); //5 - albedoImages.add(gravel.getImage()); //6 - - normalMapImages.add(normalMapDirt.getImage()); //0 - normalMapImages.add(normalMapDarkRock.getImage()); //1 - normalMapImages.add(normalMapSnow.getImage()); //2 - normalMapImages.add(normalMapRoad.getImage()); //3 - normalMapImages.add(normalMapGrass.getImage()); //4 - normalMapImages.add(normalMapMarble.getImage()); //5 - normalMapImages.add(normalMapGravel.getImage()); //6 - - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDirt.getImage()); //0 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDarkRock.getImage()); //1 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapSnow.getImage()); //2 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapRoad.getImage()); //3 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGrass.getImage()); //4 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapMarble.getImage()); //5 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGravel.getImage()); //6 - - //initiate texture arrays - TextureArray albedoTextureArray = new TextureArray(albedoImages); - TextureArray normalParallaxTextureArray = new TextureArray(normalMapImages); // parallax is not used currently - TextureArray metallicRoughnessAoEiTextureArray = new TextureArray(metallicRoughnessAoEiMapImages); - - //apply wrapMode to the whole texture array, rather than each individual texture in the array - albedoTextureArray.setWrap(WrapMode.Repeat); - normalParallaxTextureArray.setWrap(WrapMode.Repeat); - metallicRoughnessAoEiTextureArray.setWrap(WrapMode.Repeat); - - //assign texture array to materials - matTerrain.setParam("AlbedoTextureArray", VarType.TextureArray, albedoTextureArray); - matTerrain.setParam("NormalParallaxTextureArray", VarType.TextureArray, normalParallaxTextureArray); - matTerrain.setParam("MetallicRoughnessAoEiTextureArray", VarType.TextureArray, metallicRoughnessAoEiTextureArray); - - //set up texture slots: - matTerrain.setInt("AlbedoMap_0", 0); // dirt is index 0 in the albedo image list - matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); - matTerrain.setFloat("Roughness_0", 1); - matTerrain.setFloat("Metallic_0", 0.02f); - - matTerrain.setInt("AlbedoMap_1", 1); // darkRock is index 1 in the albedo image list - matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); - matTerrain.setFloat("Roughness_1", 1); - matTerrain.setFloat("Metallic_1", 0.04f); - - matTerrain.setInt("AlbedoMap_2", 2); - matTerrain.setFloat("AlbedoMap_2_scale", snowScale); - matTerrain.setFloat("Roughness_2", 0.72f); - matTerrain.setFloat("Metallic_2", 0.12f); - - matTerrain.setInt("AlbedoMap_3", 3); - matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); - matTerrain.setFloat("Roughness_3", 1); - matTerrain.setFloat("Metallic_3", 0.04f); - - matTerrain.setInt("AlbedoMap_4", 4); - matTerrain.setFloat("AlbedoMap_4_scale", grassScale); - matTerrain.setFloat("Roughness_4", 1); - matTerrain.setFloat("Metallic_4", 0); - - matTerrain.setInt("AlbedoMap_5", 5); - matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); - matTerrain.setFloat("Roughness_5", 1); - matTerrain.setFloat("Metallic_5", 0.2f); - - matTerrain.setInt("AlbedoMap_6", 6); - matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); - matTerrain.setFloat("Roughness_6", 1); - matTerrain.setFloat("Metallic_6", 0.01f); - - // NORMAL MAPS - // int being passed to shader corresponds to the index of the texture's - // image in the List of images used to create its texture array - matTerrain.setInt("NormalMap_0", 0); - matTerrain.setInt("NormalMap_1", 1); - matTerrain.setInt("NormalMap_2", 2); - matTerrain.setInt("NormalMap_3", 3); - matTerrain.setInt("NormalMap_4", 4); - matTerrain.setInt("NormalMap_5", 5); - matTerrain.setInt("NormalMap_6", 6); - - //METALLIC/ROUGHNESS/AO/EI MAPS - matTerrain.setInt("MetallicRoughnessMap_0", 0); - matTerrain.setInt("MetallicRoughnessMap_1", 1); - matTerrain.setInt("MetallicRoughnessMap_2", 2); - matTerrain.setInt("MetallicRoughnessMap_3", 3); - matTerrain.setInt("MetallicRoughnessMap_4", 4); - matTerrain.setInt("MetallicRoughnessMap_5", 5); - matTerrain.setInt("MetallicRoughnessMap_6", 6); - - //EMISSIVE - matTerrain.setColor("EmissiveColor_5", marbleEmissiveColor); - matTerrain.setColor("EmissiveColor_3", tilesEmissiveColor); - //these two texture slots (marble & tiledRoad, indexed in each texture array at 5 and 3 respectively) both - // have packed MRAoEi maps with an emissiveTexture packed into the alpha channel - -// matTerrain.setColor("EmissiveColor_1", new ColorRGBA(0.08f, 0.01f, 0.1f, 0.4f)); -//this texture slot does not have a unique emissiveIntensityMap packed into its MRAoEi map, - // so setting an emissiveColor will apply equal intensity to every pixel - - terrain.setMaterial(matTerrain); - } - - private void setupKeys() { - flyCam.setMoveSpeed(50); - inputManager.addMapping("triPlanar", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addMapping("toggleNight", new KeyTrigger(KeyInput.KEY_N)); - - inputManager.addListener(actionListener, "triPlanar"); - inputManager.addListener(actionListener, "toggleNight"); - - keybindingsText = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt")); - keybindingsText.setText("Press 'N' to toggle day/night fade (takes a moment) \nPress 'P' to toggle tri-planar mode"); - - getGuiNode().attachChild(keybindingsText); - keybindingsText.move(new Vector3f(200, 120, 0)); - } - - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - - //smoothly transition from day to night - float currentLightIntensity = ambientLight.getColor().getRed(); - float incrementPerFrame = tpf * 0.3f; - - if (isNight) { - if (ambientLight.getColor().getRed() > nightLightIntensity) { - currentLightIntensity -= incrementPerFrame; - if (currentLightIntensity < nightLightIntensity) { - currentLightIntensity = nightLightIntensity; - } - - ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - } - } else { - if (ambientLight.getColor().getRed() < dayLightIntensity) { - currentLightIntensity += incrementPerFrame; - if (currentLightIntensity > dayLightIntensity) { - currentLightIntensity = dayLightIntensity; - } - - ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - } - } - } - - private void setUpTerrain() { - // HEIGHTMAP image (for the terrain heightmap) - TextureKey hmKey = new TextureKey("Textures/Terrain/splat/mountains512.png", false); - Texture heightMapImage = assetManager.loadTexture(hmKey); - - // CREATE HEIGHTMAP - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.3f); - heightmap.load(); - heightmap.smooth(0.9f, 1); - - } catch (Exception e) { - e.printStackTrace(); - } - - terrain = new TerrainQuad("terrain", patchSize + 1, terrainSize + 1, heightmap.getHeightMap()); -//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations - TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); - control.setLodCalculator(new DistanceLodCalculator(patchSize + 1, 2.7f)); // patch size, and a multiplier - terrain.addControl(control); - terrain.setMaterial(matTerrain); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(1f, 1f, 1f); - rootNode.attachChild(terrain); - } - - private void setUpLights() { - LightProbe probe = (LightProbe) assetManager.loadAsset("Scenes/LightProbes/quarry_Probe.j3o"); - - probe.setAreaType(LightProbe.AreaType.Spherical); - probe.getArea().setRadius(2000); - probe.getArea().setCenter(new Vector3f(0, 0, 0)); - rootNode.addLight(probe); - - directionalLight = new DirectionalLight(); - directionalLight.setDirection((new Vector3f(-0.3f, -0.5f, -0.3f)).normalize()); - directionalLight.setColor(ColorRGBA.White); - rootNode.addLight(directionalLight); - - ambientLight = new AmbientLight(); - directionalLight.setColor(ColorRGBA.White); - rootNode.addLight(ambientLight); - } - - private void setUpCamera() { - cam.setLocation(new Vector3f(0, 10, -10)); - cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y); - - getFlyByCamera().setMoveSpeed(camMoveSpeed); - } -} diff --git a/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java b/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java deleted file mode 100644 index db17e0da26..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java +++ /dev/null @@ -1,365 +0,0 @@ -package jme3test.terrain; - -/* - * Copyright (c) 2009-2021 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. - */ -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.light.LightProbe; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; - -/** - * This test uses 'PBRTerrain.j3md' to create a terrain Material for PBR. - * - * Upon running the app, the user should see a mountainous, terrain-based - * landscape with some grassy areas, some snowy areas, and some tiled roads and - * gravel paths weaving between the valleys. Snow should be slightly - * shiny/reflective, and marble texture should be even shinier. If you would - * like to know what each texture is supposed to look like, you can find the - * textures used for this test case located in jme3-testdata. (Screenshots - * showing how this test-case should look will also be available soon so you can - * compare your results, and I will replace this comment with a link to their - * location as soon as they are posted.) - * - * Press 'p' to toggle tri-planar mode. Enabling tri-planar mode should prevent - * stretching of textures in steep areas of the terrain. - * - * Press 'n' to toggle between night and day. Pressing 'n' will cause the light - * to gradually fade darker/brighter until the min/max lighting levels are - * reached. At night the scene should be noticeably darker. - * - * Uses assets from CC0Textures.com, licensed under CC0 1.0 Universal. For more - * information on the textures this test case uses, view the license.txt file - * located in the jme3-testdata directory where these textures are located: - * jme3-testdata/src/main/resources/Textures/Terrain/PBR - * - *

- * Notes: (as of 12 April 2021) - *

    - *
  1. - * This shader is subject to the GLSL max limit of 16 textures, and users should - * consider using "AdvancedPBRTerrain.j3md" instead if they need additional - * texture slots. - *
  2. - *
- * - * @author yaRnMcDonuts - */ -public class PBRTerrainTest extends SimpleApplication { - - private TerrainQuad terrain; - private Material matTerrain; - private boolean triPlanar = false; - - private final int terrainSize = 512; - private final int patchSize = 256; - private final float dirtScale = 24; - private final float darkRockScale = 24; - private final float snowScale = 64; - private final float tileRoadScale = 64; - private final float grassScale = 24; - private final float marbleScale = 64; - private final float gravelScale = 64; - - private AmbientLight ambientLight; - private DirectionalLight directionalLight; - private boolean isNight = false; - - private final float dayLightIntensity = 1.0f; - private final float nightLightIntensity = 0.03f; - - private BitmapText keybindingsText; - - private final float camMoveSpeed = 50f; - - public static void main(String[] args) { - PBRTerrainTest app = new PBRTerrainTest(); - app.start(); - } - - private final ActionListener actionListener = new ActionListener() { - @Override - public void onAction(String name, boolean pressed, float tpf) { - if (name.equals("triPlanar") && !pressed) { - triPlanar = !triPlanar; - if (triPlanar) { - matTerrain.setBoolean("useTriPlanarMapping", true); - // Tri-planar textures don't use the mesh's texture coordinates but real world coordinates, - // so we need to convert these texture coordinate scales into real world scales so it looks - // the same when we switch to/from tri-planar mode. - matTerrain.setFloat("AlbedoMap_0_scale", (dirtScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_1_scale", (darkRockScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_2_scale", (snowScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_3_scale", (tileRoadScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_4_scale", (grassScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_5_scale", (marbleScale / terrainSize)); - matTerrain.setFloat("AlbedoMap_6_scale", (gravelScale / terrainSize)); - } else { - matTerrain.setBoolean("useTriPlanarMapping", false); - - matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); - matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); - matTerrain.setFloat("AlbedoMap_2_scale", snowScale); - matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); - matTerrain.setFloat("AlbedoMap_4_scale", grassScale); - matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); - matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); - } - } - if (name.equals("toggleNight") && !pressed) { - isNight = !isNight; - // Ambient and directional light are faded smoothly in update loop below. - } - } - }; - - @Override - public void simpleInitApp() { - setupKeys(); - setUpTerrain(); - setUpTerrainMaterial(); - setUpLights(); - setUpCamera(); - } - - private void setUpTerrainMaterial() { - // PBR terrain matdef - matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/PBRTerrain.j3md"); - - matTerrain.setBoolean("useTriPlanarMapping", false); - - // ALPHA map (for splat textures) - matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); - matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); - // this material also supports 'AlphaMap_2', so you can get up to 12 diffuse textures - - // DIRT texture, Diffuse textures 0 to 3 use the first AlphaMap - Texture dirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - dirt.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_0", dirt); - matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); - matTerrain.setFloat("Roughness_0", 1); - matTerrain.setFloat("Metallic_0", 0); - //matTerrain.setInt("AfflictionMode_0", 0); - - // DARK ROCK texture - Texture darkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Color.png"); - darkRock.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_1", darkRock); - matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); - matTerrain.setFloat("Roughness_1", 0.92f); - matTerrain.setFloat("Metallic_1", 0.02f); - //matTerrain.setInt("AfflictionMode_1", 0); - - // SNOW texture - Texture snow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Color.png"); - snow.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_2", snow); - matTerrain.setFloat("AlbedoMap_2_scale", snowScale); - matTerrain.setFloat("Roughness_2", 0.55f); - matTerrain.setFloat("Metallic_2", 0.12f); - - Texture tiles = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Color.png"); - tiles.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_3", tiles); - matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); - matTerrain.setFloat("Roughness_3", 0.87f); - matTerrain.setFloat("Metallic_3", 0.08f); - - // GRASS texture - Texture grass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - grass.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_4", grass); - matTerrain.setFloat("AlbedoMap_4_scale", grassScale); - matTerrain.setFloat("Roughness_4", 1); - matTerrain.setFloat("Metallic_4", 0); - - // MARBLE texture - Texture marble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Color.png"); - marble.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_5", marble); - matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); - matTerrain.setFloat("Roughness_5", 0.06f); - matTerrain.setFloat("Metallic_5", 0.8f); - - // Gravel texture - Texture gravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Color.png"); - gravel.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_6", gravel); - matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); - matTerrain.setFloat("Roughness_6", 0.9f); - matTerrain.setFloat("Metallic_6", 0.07f); - // NORMAL MAPS - Texture normalMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_1K_Normal.png"); - normalMapDirt.setWrap(WrapMode.Repeat); - - Texture normalMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Normal.png"); - normalMapDarkRock.setWrap(WrapMode.Repeat); - - Texture normalMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Normal.png"); - normalMapSnow.setWrap(WrapMode.Repeat); - - Texture normalMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Normal.png"); - normalMapGravel.setWrap(WrapMode.Repeat); - - Texture normalMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Normal.png"); - normalMapGrass.setWrap(WrapMode.Repeat); - -// Texture normalMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Normal.png"); -// normalMapMarble.setWrap(WrapMode.Repeat); - - Texture normalMapTiles = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Normal.png"); - normalMapTiles.setWrap(WrapMode.Repeat); - - matTerrain.setTexture("NormalMap_0", normalMapDirt); - matTerrain.setTexture("NormalMap_1", normalMapDarkRock); - matTerrain.setTexture("NormalMap_2", normalMapSnow); - matTerrain.setTexture("NormalMap_3", normalMapTiles); - matTerrain.setTexture("NormalMap_4", normalMapGrass); -// matTerrain.setTexture("NormalMap_5", normalMapMarble); // Adding this texture would exceed the 16 texture limit. - matTerrain.setTexture("NormalMap_6", normalMapGravel); - - terrain.setMaterial(matTerrain); - } - - private void setupKeys() { - flyCam.setMoveSpeed(50); - inputManager.addMapping("triPlanar", new KeyTrigger(KeyInput.KEY_P)); - inputManager.addMapping("toggleNight", new KeyTrigger(KeyInput.KEY_N)); - - inputManager.addListener(actionListener, "triPlanar"); - inputManager.addListener(actionListener, "toggleNight"); - - keybindingsText = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt")); - keybindingsText.setText("Press 'N' to toggle day/night fade (takes a moment) \nPress 'P' to toggle tri-planar mode"); - - getGuiNode().attachChild(keybindingsText); - keybindingsText.move(new Vector3f(200, 120, 0)); - } - - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - - //smoothly transition from day to night - float currentLightIntensity = ambientLight.getColor().getRed(); - float incrementPerFrame = tpf * 0.3f; - - if (isNight) { - if (ambientLight.getColor().getRed() > nightLightIntensity) { - currentLightIntensity -= incrementPerFrame; - if (currentLightIntensity < nightLightIntensity) { - currentLightIntensity = nightLightIntensity; - } - - ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - } - } else { - if (ambientLight.getColor().getRed() < dayLightIntensity) { - currentLightIntensity += incrementPerFrame; - if (currentLightIntensity > dayLightIntensity) { - currentLightIntensity = dayLightIntensity; - } - - ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); - } - } - } - - private void setUpTerrain() { - // HEIGHTMAP image (for the terrain heightmap) - TextureKey hmKey = new TextureKey("Textures/Terrain/splat/mountains512.png", false); - Texture heightMapImage = assetManager.loadTexture(hmKey); - - // CREATE HEIGHTMAP - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.3f); - heightmap.load(); - heightmap.smooth(0.9f, 1); - - } catch (Exception e) { - e.printStackTrace(); - } - - terrain = new TerrainQuad("terrain", patchSize + 1, terrainSize + 1, heightmap.getHeightMap()); -//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations - TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); - control.setLodCalculator(new DistanceLodCalculator(patchSize + 1, 2.7f)); // patch size, and a multiplier - terrain.addControl(control); - terrain.setMaterial(matTerrain); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(1f, 1f, 1f); - rootNode.attachChild(terrain); - } - - private void setUpLights() { - LightProbe probe = (LightProbe) assetManager.loadAsset("Scenes/LightProbes/quarry_Probe.j3o"); - - probe.setAreaType(LightProbe.AreaType.Spherical); - probe.getArea().setRadius(2000); - probe.getArea().setCenter(new Vector3f(0, 0, 0)); - rootNode.addLight(probe); - - directionalLight = new DirectionalLight(); - directionalLight.setDirection((new Vector3f(-0.3f, -0.5f, -0.3f)).normalize()); - directionalLight.setColor(ColorRGBA.White); - rootNode.addLight(directionalLight); - - ambientLight = new AmbientLight(); - directionalLight.setColor(ColorRGBA.White); - rootNode.addLight(ambientLight); - } - - private void setUpCamera() { - cam.setLocation(new Vector3f(0, 10, -10)); - cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y); - - getFlyByCamera().setMoveSpeed(camMoveSpeed); - } -} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java deleted file mode 100644 index 76d10a8220..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java +++ /dev/null @@ -1,141 +0,0 @@ -package jme3test.terrain; - -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.ScreenshotAppState; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.terrain.geomipmap.TerrainGrid; -import com.jme3.terrain.geomipmap.TerrainGridLodControl; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.grid.FractalTileLoader; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.noise.ShaderUtils; -import com.jme3.terrain.noise.basis.FilteredBasis; -import com.jme3.terrain.noise.filter.IterativeFilter; -import com.jme3.terrain.noise.filter.OptimizedErode; -import com.jme3.terrain.noise.filter.PerturbFilter; -import com.jme3.terrain.noise.filter.SmoothFilter; -import com.jme3.terrain.noise.fractal.FractalSum; -import com.jme3.terrain.noise.modulator.NoiseModulator; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; - -public class TerrainFractalGridTest extends SimpleApplication { - - final private float grassScale = 64; - final private float dirtScale = 16; - final private float rockScale = 128; - - public static void main(final String[] args) { - TerrainFractalGridTest app = new TerrainFractalGridTest(); - app.start(); - } - - @Override - public void simpleInitApp() { - this.flyCam.setMoveSpeed(100f); - ScreenshotAppState state = new ScreenshotAppState(); - this.stateManager.attach(state); - - // TERRAIN TEXTURE material - Material mat_terrain = new Material(this.assetManager, - "Common/MatDefs/Terrain/HeightBasedTerrain.j3md"); - - // Parameters to material: - // regionXColorMap: X = 1..4 the texture that should be applied to state X - // regionX: a Vector3f containing the following information: - // regionX.x: the start height of the region - // regionX.y: the end height of the region - // regionX.z: the texture scale for the region - // it might not be the most elegant way for storing these 3 values, but it packs the data nicely :) - // slopeColorMap: the texture to be used for cliffs, and steep mountain sites - // slopeTileFactor: the texture scale for slopes - // terrainSize: the total size of the terrain (used for scaling the texture) - // GRASS texture - Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("region1ColorMap", grass); - mat_terrain.setVector3("region1", new Vector3f(15, 200, this.grassScale)); - - // DIRT texture - Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("region2ColorMap", dirt); - mat_terrain.setVector3("region2", new Vector3f(0, 20, this.dirtScale)); - - // ROCK texture - Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg"); - rock.setWrap(WrapMode.Repeat); - mat_terrain.setTexture("region3ColorMap", rock); - mat_terrain.setVector3("region3", new Vector3f(198, 260, this.rockScale)); - - mat_terrain.setTexture("region4ColorMap", rock); - mat_terrain.setVector3("region4", new Vector3f(198, 260, this.rockScale)); - - mat_terrain.setTexture("slopeColorMap", rock); - mat_terrain.setFloat("slopeTileFactor", 32); - - mat_terrain.setFloat("terrainSize", 513); - - FractalSum base = new FractalSum(); - base.setRoughness(0.7f); - base.setFrequency(1.0f); - base.setAmplitude(1.0f); - base.setLacunarity(2.12f); - base.setOctaves(8); - base.setScale(0.02125f); - base.addModulator(new NoiseModulator() { - - @Override - public float value(float... in) { - return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1); - } - }); - - FilteredBasis ground = new FilteredBasis(base); - - PerturbFilter perturb = new PerturbFilter(); - perturb.setMagnitude(0.119f); - - OptimizedErode therm = new OptimizedErode(); - therm.setRadius(5); - therm.setTalus(0.011f); - - SmoothFilter smooth = new SmoothFilter(); - smooth.setRadius(1); - smooth.setEffect(0.7f); - - IterativeFilter iterate = new IterativeFilter(); - iterate.addPreFilter(perturb); - iterate.addPostFilter(smooth); - iterate.setFilter(therm); - iterate.setIterations(1); - - ground.addPreFilter(iterate); - - TerrainGrid terrain - = new TerrainGrid("terrain", 33, 129, new FractalTileLoader(ground, 256f)); - terrain.setMaterial(mat_terrain); - terrain.setLocalTranslation(0, 0, 0); - terrain.setLocalScale(2f, 1f, 2f); - this.rootNode.attachChild(terrain); - - TerrainLodControl control - = new TerrainGridLodControl(terrain, this.getCamera()); - control.setLodCalculator(new DistanceLodCalculator(33, 2.7f)); // patch size, and a multiplier - terrain.addControl(control); - - this.getCamera().setLocation(new Vector3f(0, 300, 0)); - cam.setRotation(new Quaternion(0.51176f, -0.14f, 0.085f, 0.84336f)); - - this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); - - - } - - @Override - public void simpleUpdate(final float tpf) { - } -} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java deleted file mode 100644 index a5f01976bd..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java +++ /dev/null @@ -1,359 +0,0 @@ -package jme3test.terrain; - -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.ScreenshotAppState; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.asset.plugins.ZipLocator; -import com.jme3.bullet.BulletAppState; -import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; -import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; -import com.jme3.bullet.control.CharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.debug.Arrow; -import com.jme3.terrain.geomipmap.TerrainGrid; -import com.jme3.terrain.geomipmap.TerrainGridListener; -import com.jme3.terrain.geomipmap.TerrainGridLodControl; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.grid.FractalTileLoader; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.noise.ShaderUtils; -import com.jme3.terrain.noise.basis.FilteredBasis; -import com.jme3.terrain.noise.filter.IterativeFilter; -import com.jme3.terrain.noise.filter.OptimizedErode; -import com.jme3.terrain.noise.filter.PerturbFilter; -import com.jme3.terrain.noise.filter.SmoothFilter; -import com.jme3.terrain.noise.fractal.FractalSum; -import com.jme3.terrain.noise.modulator.NoiseModulator; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import java.io.File; - -public class TerrainGridAlphaMapTest extends SimpleApplication { - - private TerrainGrid terrain; - final private float grassScale = 64; - final private float dirtScale = 16; - final private float rockScale = 128; - private boolean usePhysics = false; - - public static void main(final String[] args) { - TerrainGridAlphaMapTest app = new TerrainGridAlphaMapTest(); - app.start(); - } - private CharacterControl player3; - - @Override - public void simpleInitApp() { - DirectionalLight sun = new DirectionalLight(); - sun.setColor(ColorRGBA.White); - sun.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - rootNode.addLight(sun); - - AmbientLight al = new AmbientLight(); - al.setColor(ColorRGBA.White.mult(1.3f)); - rootNode.addLight(al); - - File file = new File("TerrainGridTestData.zip"); - if (!file.exists()) { - assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/TerrainGridTestData.zip", HttpZipLocator.class); - } else { - assetManager.registerLocator("TerrainGridTestData.zip", ZipLocator.class); - } - - this.flyCam.setMoveSpeed(100f); - ScreenshotAppState state = new ScreenshotAppState(); - this.stateManager.attach(state); - - // TERRAIN TEXTURE material - Material material = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - material.setBoolean("useTriPlanarMapping", false); - //material.setBoolean("isTerrainGrid", true); - material.setFloat("Shininess", 0.0f); - - // GRASS texture - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - material.setTexture("DiffuseMap", grass); - material.setFloat("DiffuseMap_0_scale", grassScale); - - // DIRT texture - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - material.setTexture("DiffuseMap_1", dirt); - material.setFloat("DiffuseMap_1_scale", dirtScale); - - // ROCK texture - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - material.setTexture("DiffuseMap_2", rock); - material.setFloat("DiffuseMap_2_scale", rockScale); - - // WIREFRAME material - Material matWire = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - matWire.getAdditionalRenderState().setWireframe(true); - matWire.setColor("Color", ColorRGBA.Green); - - FractalSum base = new FractalSum(); - base.setRoughness(0.7f); - base.setFrequency(1.0f); - base.setAmplitude(1.0f); - base.setLacunarity(2.12f); - base.setOctaves(8); - base.setScale(0.02125f); - base.addModulator(new NoiseModulator() { - - @Override - public float value(float... in) { - return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1); - } - }); - - FilteredBasis ground = new FilteredBasis(base); - - PerturbFilter perturb = new PerturbFilter(); - perturb.setMagnitude(0.119f); - - OptimizedErode therm = new OptimizedErode(); - therm.setRadius(5); - therm.setTalus(0.011f); - - SmoothFilter smooth = new SmoothFilter(); - smooth.setRadius(1); - smooth.setEffect(0.7f); - - IterativeFilter iterate = new IterativeFilter(); - iterate.addPreFilter(perturb); - iterate.addPostFilter(smooth); - iterate.setFilter(therm); - iterate.setIterations(1); - - ground.addPreFilter(iterate); - - this.terrain = new TerrainGrid("terrain", 33, 257, new FractalTileLoader(ground, 256)); - this.terrain.setMaterial(material); - - this.terrain.setLocalTranslation(0, 0, 0); - this.terrain.setLocalScale(2f, 1f, 2f); - this.rootNode.attachChild(this.terrain); - - TerrainLodControl control = new TerrainGridLodControl(this.terrain, this.getCamera()); - control.setLodCalculator( new DistanceLodCalculator(33, 2.7f) ); // patch size, and a multiplier - this.terrain.addControl(control); - - final BulletAppState bulletAppState = new BulletAppState(); - stateManager.attach(bulletAppState); - - - this.getCamera().setLocation(new Vector3f(0, 256, 0)); - cam.setRotation(new Quaternion(-0.1f, 0.89826f, -0.2695f, -0.3325f)); - - this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); - - if (usePhysics) { - CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1); - player3 = new CharacterControl(capsuleShape, 0.5f); - player3.setJumpSpeed(20); - player3.setFallSpeed(10); - player3.setGravity(10); - - player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z)); - - bulletAppState.getPhysicsSpace().add(player3); - - } - terrain.addListener(new TerrainGridListener() { - - @Override - public void gridMoved(Vector3f newCenter) { - } - - @Override - public void tileAttached(Vector3f cell, TerrainQuad quad) { - Texture alpha = null; - try { - alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_" + (int)cell.x+ "_" + (int)cell.z + ".png"); - } catch (Exception e) { - alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_default.png"); - } - quad.getMaterial().setTexture("AlphaMap", alpha); - if (usePhysics) { - quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0)); - bulletAppState.getPhysicsSpace().add(quad); - } - updateMarkerElevations(); - } - - @Override - public void tileDetached(Vector3f cell, TerrainQuad quad) { - if (usePhysics) { - if (quad.getControl(RigidBodyControl.class) != null) { - bulletAppState.getPhysicsSpace().remove(quad); - quad.removeControl(RigidBodyControl.class); - } - } - updateMarkerElevations(); - } - }); - - this.initKeys(); - - markers = new Node(); - rootNode.attachChild(markers); - createMarkerPoints(1); - } - - private Node markers; - - - private void createMarkerPoints(float count) { - Node center = createAxisMarker(10); - markers.attachChild(center); - - float xS = (count-1)*terrain.getTerrainSize() - (terrain.getTerrainSize()/2); - float zS = (count-1)*terrain.getTerrainSize() - (terrain.getTerrainSize()/2); - float xSi = xS; - float zSi = zS; - for (int x=0; x collisionMarkers; - private Geometry selectedCollisionObject; - - public static void main(String[] args) { - TerrainTestCollision app = new TerrainTestCollision(); - app.start(); - } - - @Override - public void initialize() { - super.initialize(); - loadHintText(); - initCrossHairs(); - } - - @Override - public void simpleInitApp() { - collisionMarkers = new ArrayList<>(); - BulletAppState bulletAppState = new BulletAppState(); - bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); - stateManager.attach(bulletAppState); - setupKeys(); - matRock = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md"); - matRock.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matRock.setTexture("Tex1", grass); - matRock.setFloat("Tex1Scale", 64f); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matRock.setTexture("Tex2", dirt); - matRock.setFloat("Tex2Scale", 32f); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matRock.setTexture("Tex3", rock); - matRock.setFloat("Tex3Scale", 128f); - matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - matWire.getAdditionalRenderState().setWireframe(true); - matWire.setColor("Color", ColorRGBA.Green); - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - - } catch (Exception e) { - } - - terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); - control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier - terrain.addControl(control); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(2, 2, 2)); - terrain.setLocked(false); // unlock it so we can edit the height - rootNode.attachChild(terrain); - - // if set to false, only the first collision is returned and collision is slightly faster. - terrain.setSupportMultipleCollisions(true); - - /* - * Create PhysicsRigidBodyControl for collision - */ - terrain.addControl(new RigidBodyControl(0)); - bulletAppState.getPhysicsSpace().addAll(terrain); - - - // Add 5 physics spheres to the world, with random sizes and positions - // let them drop from the sky - for (int i = 0; i < 5; i++) { - float r = (float) (8 * Math.random()); - Geometry sphere = new Geometry("cannonball", new Sphere(10, 10, r)); - sphere.setMaterial(matWire); - float x = (float) (20 * Math.random()) - 40; // random position - float y = (float) (20 * Math.random()) - 40; // random position - float z = (float) (20 * Math.random()) - 40; // random position - sphere.setLocalTranslation(new Vector3f(x, 100 + y, z)); - sphere.addControl(new RigidBodyControl(new SphereCollisionShape(r), 2)); - rootNode.attachChild(sphere); - bulletAppState.getPhysicsSpace().add(sphere); - } - - Geometry collisionBox = new Geometry("collisionBox", new Box(2, 2, 2)); - collisionBox.setModelBound(new BoundingBox()); - collisionBox.setLocalTranslation(new Vector3f(20, 95, 30)); - collisionBox.setMaterial(matWire); - rootNode.attachChild(collisionBox); - selectedCollisionObject = collisionBox; - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(1, -0.5f, -0.1f).normalizeLocal()); - dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); - rootNode.addLight(dl); - - cam.setLocation(new Vector3f(43f, 121f, 10f)); - cam.setRotation(new Quaternion(0.15824f, -0.79309f, 0.23223f, 0.5404f)); - } - - public void loadHintText() { - BitmapText hintText = new BitmapText(guiFont); - hintText.setSize(guiFont.getCharSet().getRenderedSize()); - hintText.setLocalTranslation(0, getCamera().getHeight(), 0); - hintText.setText("Press T to toggle wireframe"); - guiNode.attachChild(hintText); - } - - protected void initCrossHairs() { - //guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, - settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); - guiNode.attachChild(ch); - } - - private void setupKeys() { - flyCam.setMoveSpeed(50); - inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addListener(actionListener, "wireframe"); - inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addMapping("Forwards", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("Backs", new KeyTrigger(KeyInput.KEY_I)); - inputManager.addListener(actionListener, "Lefts"); - inputManager.addListener(actionListener, "Rights"); - inputManager.addListener(actionListener, "Ups"); - inputManager.addListener(actionListener, "Downs"); - inputManager.addListener(actionListener, "Forwards"); - inputManager.addListener(actionListener, "Backs"); - inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "shoot"); - inputManager.addMapping("cameraDown", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); - inputManager.addListener(actionListener, "cameraDown"); - } - - @Override - public void update() { - super.update(); - } - - private void createCollisionMarkers(int num) { - for (int i = 0; i < num; i++) { - Sphere s = new Sphere(6, 6, 1); - Geometry collisionMarker = new Geometry("collisionMarker"); - collisionMarker.setMesh(s); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", i == 0 ? ColorRGBA.Orange : ColorRGBA.Blue); - collisionMarker.setMaterial(mat); - rootNode.attachChild(collisionMarker); - collisionMarkers.add(collisionMarker); - } - } - - final private ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String binding, boolean keyPressed, float tpf) { - if (binding.equals("wireframe") && !keyPressed) { - wireframe = !wireframe; - if (wireframe) { - terrain.setMaterial(matWire); - } else { - terrain.setMaterial(matRock); - } - } else if (binding.equals("shoot") && !keyPressed) { - Vector3f origin = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); - Vector3f direction = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); - direction.subtractLocal(origin).normalizeLocal(); - - Ray ray = new Ray(origin, direction); - CollisionResults results = new CollisionResults(); - - if (terrain.collideWith(ray, results) > 0) { - CollisionResult hit = results.getClosestCollision(); // sorts the collection before printing - printCollisions(results); - - // Remove old markers. - for (Geometry g: collisionMarkers) { - g.removeFromParent(); - } - collisionMarkers.clear(); - - createCollisionMarkers(results.size()); - - // Position Closest Collision - Vector2f loc = new Vector2f(hit.getContactPoint().x, hit.getContactPoint().z); - float height = terrain.getHeight(loc); - System.out.println("Closest Collision: " + hit.getContactPoint() + ", height: " + height + ", distance: " + hit.getDistance()); - collisionMarkers.get(0).setLocalTranslation(new Vector3f(hit.getContactPoint().x, height, hit.getContactPoint().z)); - - // Position Rest: When getClosestCollision has been called, the results are sorted, and thus 0 is closest. - for (int i = 1; i < results.size(); i++) { - collisionMarkers.get(i).setLocalTranslation(results.getCollision(i).getContactPoint()); - } - } - } else if (binding.equals("cameraDown") && !keyPressed) { - getCamera().lookAtDirection(new Vector3f(0, -1, 0), Vector3f.UNIT_Y); - } else if (binding.equals("Lefts") && !keyPressed) { - Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); - selectedCollisionObject.move(-0.5f, 0, 0); - testCollision(oldLoc); - } else if (binding.equals("Rights") && !keyPressed) { - Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); - selectedCollisionObject.move(0.5f, 0, 0); - testCollision(oldLoc); - } else if (binding.equals("Forwards") && !keyPressed) { - Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); - selectedCollisionObject.move(0, 0, 0.5f); - testCollision(oldLoc); - } else if (binding.equals("Backs") && !keyPressed) { - Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); - selectedCollisionObject.move(0, 0, -0.5f); - testCollision(oldLoc); - } else if (binding.equals("Ups") && !keyPressed) { - Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); - selectedCollisionObject.move(0, 0.5f, 0); - testCollision(oldLoc); - } else if (binding.equals("Downs") && !keyPressed) { - Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); - selectedCollisionObject.move(0, -0.5f, 0); - testCollision(oldLoc); - } - - } - }; - - private void testCollision(Vector3f oldLoc) { - if (terrain.collideWith(selectedCollisionObject.getWorldBound(), new CollisionResults()) > 0) { - selectedCollisionObject.setLocalTranslation(oldLoc); - } - } - - private void printCollisions(CollisionResults cr) { - System.out.println("================ Collision Results ================"); - for (int i = 0; i < cr.size(); i++) { - CollisionResult res = cr.getCollision(i); - System.out.println("Result " + i); - System.out.println("\t\t" + res.toString()); - } - System.out.println("================ END Collision Results ================"); - } -} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java deleted file mode 100644 index 4a34906fd0..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.terrain; - -import com.jme3.app.SimpleApplication; -import com.jme3.collision.CollisionResult; -import com.jme3.collision.CollisionResults; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.material.RenderState.BlendMode; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Ray; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.debug.Arrow; -import com.jme3.scene.shape.Sphere; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import java.util.ArrayList; -import java.util.List; - -/** - * - * @author Brent Owens - */ -public class TerrainTestModifyHeight extends SimpleApplication { - - private TerrainQuad terrain; - private Material matTerrain; - private Material matWire; - private boolean wireframe = false; - private BitmapText hintText; - final private float grassScale = 64; - final private float dirtScale = 16; - final private float rockScale = 128; - - private boolean raiseTerrain = false; - private boolean lowerTerrain = false; - - private Geometry marker; - private Geometry markerNormal; - - public static void main(String[] args) { - TerrainTestModifyHeight app = new TerrainTestModifyHeight(); - app.start(); - } - - @Override - public void simpleUpdate(float tpf){ - Vector3f intersection = getWorldIntersection(); - updateHintText(intersection); - - if (raiseTerrain){ - - if (intersection != null) { - adjustHeight(intersection, 64, tpf * 60); - } - }else if (lowerTerrain){ - if (intersection != null) { - adjustHeight(intersection, 64, -tpf * 60); - } - } - - if (terrain != null && intersection != null) { - float h = terrain.getHeight(new Vector2f(intersection.x, intersection.z)); - Vector3f tl = terrain.getWorldTranslation(); - marker.setLocalTranslation(tl.add(new Vector3f(intersection.x, h, intersection.z)) ); - markerNormal.setLocalTranslation(tl.add(new Vector3f(intersection.x, h, intersection.z)) ); - - Vector3f normal = terrain.getNormal(new Vector2f(intersection.x, intersection.z)); - ((Arrow)markerNormal.getMesh()).setArrowExtent(normal); - } - } - - @Override - public void simpleInitApp() { - loadHintText(); - initCrossHairs(); - setupKeys(); - - createMarker(); - - // WIREFRAME material - matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - matWire.getAdditionalRenderState().setWireframe(true); - matWire.setColor("Color", ColorRGBA.Green); - - createTerrain(); - //createTerrainGrid(); - - DirectionalLight light = new DirectionalLight(); - light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); - rootNode.addLight(light); - - AmbientLight ambLight = new AmbientLight(); - ambLight.setColor(new ColorRGBA(1f, 1f, 0.8f, 0.2f)); - rootNode.addLight(ambLight); - - cam.setLocation(new Vector3f(0, 256, 0)); - cam.setRotation(new Quaternion(0.25966f, 0.690398f, -0.2952f, 0.60727f)); - } - - public void loadHintText() { - hintText = new BitmapText(guiFont); - hintText.setLocalTranslation(0, getCamera().getHeight(), 0); - hintText.setText("Hit 1 to raise terrain, hit 2 to lower terrain"); - guiNode.attachChild(hintText); - } - - public void updateHintText(Vector3f target) { - int x = (int) getCamera().getLocation().x; - int y = (int) getCamera().getLocation().y; - int z = (int) getCamera().getLocation().z; - String targetText = ""; - if (target!= null) - targetText = " intersect: "+target.toString(); - hintText.setText("Press left mouse button to raise terrain, press right mouse button to lower terrain. " + x + "," + y + "," + z+targetText); - } - - protected void initCrossHairs() { - BitmapText ch = new BitmapText(guiFont); - ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); - ch.setText("+"); // crosshairs - ch.setLocalTranslation( // center - settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, - settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); - guiNode.attachChild(ch); - } - - private void setupKeys() { - flyCam.setMoveSpeed(100); - inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addListener(actionListener, "wireframe"); - inputManager.addMapping("Raise", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "Raise"); - inputManager.addMapping("Lower", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); - inputManager.addListener(actionListener, "Lower"); - } - final private ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean pressed, float tpf) { - if (name.equals("wireframe") && !pressed) { - wireframe = !wireframe; - if (wireframe) { - terrain.setMaterial(matWire); - } else { - terrain.setMaterial(matTerrain); - } - } else if (name.equals("Raise")) { - raiseTerrain = pressed; - } else if (name.equals("Lower")) { - lowerTerrain = pressed; - } - } - }; - - private void adjustHeight(Vector3f loc, float radius, float height) { - - // offset it by radius because in the loop we iterate through 2 radii - int radiusStepsX = (int) (radius / terrain.getLocalScale().x); - int radiusStepsZ = (int) (radius / terrain.getLocalScale().z); - - float xStepAmount = terrain.getLocalScale().x; - float zStepAmount = terrain.getLocalScale().z; - long start = System.currentTimeMillis(); - List locs = new ArrayList<>(); - List heights = new ArrayList<>(); - - for (int z = -radiusStepsZ; z < radiusStepsZ; z++) { - for (int x = -radiusStepsX; x < radiusStepsX; x++) { - - float locX = loc.x + (x * xStepAmount); - float locZ = loc.z + (z * zStepAmount); - - if (isInRadius(locX - loc.x, locZ - loc.z, radius)) { - // see if it is in the radius of the tool - float h = calculateHeight(radius, height, locX - loc.x, locZ - loc.z); - locs.add(new Vector2f(locX, locZ)); - heights.add(h); - } - } - } - - terrain.adjustHeight(locs, heights); - //System.out.println("Modified "+locs.size()+" points, took: " + (System.currentTimeMillis() - start)+" ms"); - terrain.updateModelBound(); - } - - private boolean isInRadius(float x, float y, float radius) { - Vector2f point = new Vector2f(x, y); - // return true if the distance is less than equal to the radius - return point.length() <= radius; - } - - private float calculateHeight(float radius, float heightFactor, float x, float z) { - // find percentage for each 'unit' in radius - Vector2f point = new Vector2f(x, z); - float val = point.length() / radius; - val = 1 - val; - if (val <= 0) { - val = 0; - } - return heightFactor * val; - } - - private Vector3f getWorldIntersection() { - Vector3f origin = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); - Vector3f direction = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); - direction.subtractLocal(origin).normalizeLocal(); - - Ray ray = new Ray(origin, direction); - CollisionResults results = new CollisionResults(); - int numCollisions = terrain.collideWith(ray, results); - if (numCollisions > 0) { - CollisionResult hit = results.getClosestCollision(); - return hit.getContactPoint(); - } - return null; - } - - private void createTerrain() { - // First, we load up our textures and the heightmap texture for the terrain - - // TERRAIN TEXTURE material - matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matTerrain.setBoolean("useTriPlanarMapping", false); - matTerrain.setBoolean("WardIso", true); - matTerrain.setFloat("Shininess", 0); - - // ALPHA map (for splat textures) - matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - - // GRASS texture - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap", grass); - matTerrain.setFloat("DiffuseMap_0_scale", grassScale); - - // DIRT texture - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_1", dirt); - matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); - - // ROCK texture - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_2", rock); - matTerrain.setFloat("DiffuseMap_2_scale", rockScale); - - // HEIGHTMAP image (for the terrain heightmap) - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.5f); - heightmap.load(); - heightmap.smooth(0.9f, 1); - - } catch (Exception e) { - e.printStackTrace(); - } - - // CREATE THE TERRAIN - terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); - control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier - terrain.addControl(control); - terrain.setMaterial(matTerrain); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(2.5f, 0.5f, 2.5f); - rootNode.attachChild(terrain); - } - - private void createMarker() { - // collision marker - Sphere sphere = new Sphere(8, 8, 0.5f); - marker = new Geometry("Marker"); - marker.setMesh(sphere); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", new ColorRGBA(251f/255f, 130f/255f, 0f, 0.6f)); - mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); - - marker.setMaterial(mat); - rootNode.attachChild(marker); - - - // surface normal marker - Arrow arrow = new Arrow(new Vector3f(0,1,0)); - markerNormal = new Geometry("MarkerNormal"); - markerNormal.setMesh(arrow); - markerNormal.setMaterial(mat); - rootNode.attachChild(markerNormal); - } -} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java deleted file mode 100644 index 06a4f95776..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.terrain; - -import com.jme3.app.SimpleApplication; -import com.jme3.export.Savable; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.export.binary.BinaryImporter; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Node; -import com.jme3.terrain.Terrain; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import java.io.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Saves and loads terrain. - * - * @author Brent Owens - */ -public class TerrainTestReadWrite extends SimpleApplication { - - private Terrain terrain; - final private float grassScale = 64; - final private float dirtScale = 16; - final private float rockScale = 128; - - public static void main(String[] args) { - TerrainTestReadWrite app = new TerrainTestReadWrite(); - app.start(); - //testHeightmapBuilding(); - } - - @Override - public void initialize() { - super.initialize(); - - loadHintText(); - } - - @Override - public void simpleInitApp() { - - - createControls(); - createMap(); - } - - private void createMap() { - Material matTerrain = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matTerrain.setBoolean("useTriPlanarMapping", false); - matTerrain.setBoolean("WardIso", true); - - // ALPHA map (for splat textures) - matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - - // HEIGHTMAP image (for the terrain heightmap) - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - - // GRASS texture - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap", grass); - matTerrain.setFloat("DiffuseMap_0_scale", grassScale); - - - // DIRT texture - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_1", dirt); - matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); - - // ROCK texture - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap_2", rock); - matTerrain.setFloat("DiffuseMap_2_scale", rockScale); - - - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matTerrain.setTexture("NormalMap", normalMap0); - matTerrain.setTexture("NormalMap_1", normalMap1); - matTerrain.setTexture("NormalMap_2", normalMap2); - - Material matWire = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - matWire.getAdditionalRenderState().setWireframe(true); - matWire.setColor("Color", ColorRGBA.Green); - - - // CREATE HEIGHTMAP - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f); - heightmap.load(); - - } catch (Exception e) { - e.printStackTrace(); - } - - if (new File("terrainsave.jme").exists()) { - loadTerrain(); - } else { - // create the terrain as normal, and give it a control for LOD management - TerrainQuad terrainQuad = new TerrainQuad("terrain", 65, 129, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations - TerrainLodControl control = new TerrainLodControl(terrainQuad, getCamera()); - control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier - terrainQuad.addControl(control); - terrainQuad.setMaterial(matTerrain); - terrainQuad.setLocalTranslation(0, -100, 0); - terrainQuad.setLocalScale(4f, 0.25f, 4f); - rootNode.attachChild(terrainQuad); - - this.terrain = terrainQuad; - } - - DirectionalLight light = new DirectionalLight(); - light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); - rootNode.addLight(light); - } - - /** - * Create the save and load actions and add them to the input listener - */ - private void createControls() { - flyCam.setMoveSpeed(50); - cam.setLocation(new Vector3f(0, 100, 0)); - cam.setRotation(new Quaternion(-0.1779f, 0.821934f, -0.39033f, -0.3747f)); - - inputManager.addMapping("save", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addListener(saveActionListener, "save"); - - inputManager.addMapping("load", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addListener(loadActionListener, "load"); - - inputManager.addMapping("clone", new KeyTrigger(KeyInput.KEY_C)); - inputManager.addListener(cloneActionListener, "clone"); - } - - public void loadHintText() { - BitmapText hintText = new BitmapText(guiFont); - hintText.setSize(guiFont.getCharSet().getRenderedSize()); - hintText.setLocalTranslation(0, getCamera().getHeight(), 0); - hintText.setText("Hit T to save, and Y to load"); - guiNode.attachChild(hintText); - } - final private ActionListener saveActionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean pressed, float tpf) { - if (name.equals("save") && !pressed) { - - FileOutputStream fos = null; - try { - long start = System.currentTimeMillis(); - fos = new FileOutputStream(new File("terrainsave.jme")); - - // we just use the exporter and pass in the terrain - BinaryExporter.getInstance().save((Savable)terrain, new BufferedOutputStream(fos)); - - fos.flush(); - float duration = (System.currentTimeMillis() - start) / 1000.0f; - System.out.println("Save took " + duration + " seconds"); - } catch (IOException ex) { - Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); - } finally { - try { - if (fos != null) { - fos.close(); - } - } catch (IOException e) { - Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, e); - } - } - } - } - }; - - private void loadTerrain() { - FileInputStream fis = null; - try { - long start = System.currentTimeMillis(); - // remove the existing terrain and detach it from the root node. - if (terrain != null) { - Node existingTerrain = (Node)terrain; - existingTerrain.removeFromParent(); - existingTerrain.removeControl(TerrainLodControl.class); - existingTerrain.detachAllChildren(); - terrain = null; - } - - // import the saved terrain, and attach it back to the root node - File f = new File("terrainsave.jme"); - fis = new FileInputStream(f); - BinaryImporter imp = BinaryImporter.getInstance(); - imp.setAssetManager(assetManager); - terrain = (TerrainQuad) imp.load(new BufferedInputStream(fis)); - rootNode.attachChild((Node)terrain); - - float duration = (System.currentTimeMillis() - start) / 1000.0f; - System.out.println("Load took " + duration + " seconds"); - - // now we have to add back the camera to the LOD control - TerrainLodControl lodControl = ((Node)terrain).getControl(TerrainLodControl.class); - if (lodControl != null) - lodControl.setCamera(getCamera()); - - } catch (IOException ex) { - Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); - } finally { - try { - if (fis != null) { - fis.close(); - } - } catch (IOException ex) { - Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - final private ActionListener loadActionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean pressed, float tpf) { - if (name.equals("load") && !pressed) { - loadTerrain(); - } - } - }; - final private ActionListener cloneActionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean pressed, float tpf) { - if (name.equals("clone") && !pressed) { - - Terrain clone = (Terrain) ((Node)terrain).clone(); - ((Node)terrain).removeFromParent(); - terrain = clone; - getRootNode().attachChild((Node)terrain); - } - } - }; -} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java deleted file mode 100644 index e4d60bd915..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.terrain; - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Sphere; -import com.jme3.terrain.ProgressMonitor; -import com.jme3.terrain.Terrain; -import com.jme3.terrain.geomipmap.MultiTerrainLodControl; -import com.jme3.terrain.geomipmap.NeighbourFinder; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import java.util.List; - -/** - * Demonstrates the NeighbourFinder interface for TerrainQuads, - * allowing you to tile terrains together without having to use - * TerrainGrid. It also introduces the MultiTerrainLodControl that - * will seam the edges of all the terrains supplied. - * - * @author sploreg - */ -public class TerrainTestTile extends SimpleApplication { - - private TiledTerrain terrain; - private Material matTerrain; - private Material matWire; - private boolean wireframe = false; - final private float grassScale = 256; - - - public static void main(String[] args) { - TerrainTestTile app = new TerrainTestTile(); - app.start(); - } - - - - @Override - public void simpleInitApp() { - loadHintText(); - setupKeys(); - - // WIREFRAME material - matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - matWire.getAdditionalRenderState().setWireframe(true); - matWire.setColor("Color", ColorRGBA.Green); - - terrain = new TiledTerrain(); - rootNode.attachChild(terrain); - - DirectionalLight light = new DirectionalLight(); - light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); - rootNode.addLight(light); - - AmbientLight ambLight = new AmbientLight(); - ambLight.setColor(new ColorRGBA(1f, 1f, 0.8f, 0.2f)); - rootNode.addLight(ambLight); - - cam.setLocation(new Vector3f(0, 256, 0)); - cam.lookAtDirection(new Vector3f(0, -1, -1).normalizeLocal(), Vector3f.UNIT_Y); - - - Sphere s = new Sphere(12, 12, 3); - Geometry g = new Geometry("marker"); - g.setMesh(s); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Red); - g.setMaterial(mat); - g.setLocalTranslation(0, -100, 0); - rootNode.attachChild(g); - - Geometry g2 = new Geometry("marker"); - g2.setMesh(s); - mat.setColor("Color", ColorRGBA.Red); - g2.setMaterial(mat); - g2.setLocalTranslation(10, -100, 0); - rootNode.attachChild(g2); - - Geometry g3 = new Geometry("marker"); - g3.setMesh(s); - mat.setColor("Color", ColorRGBA.Red); - g3.setMaterial(mat); - g3.setLocalTranslation(0, -100, 10); - rootNode.attachChild(g3); - } - - public void loadHintText() { - BitmapText hintText = new BitmapText(guiFont); - hintText.setLocalTranslation(0, getCamera().getHeight(), 0); - hintText.setText("Press T to toggle wireframe"); - guiNode.attachChild(hintText); - } - - - private void setupKeys() { - flyCam.setMoveSpeed(100); - inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addListener(actionListener, "wireframe"); - } - final private ActionListener actionListener = new ActionListener() { - - @Override - public void onAction(String name, boolean pressed, float tpf) { - if (name.equals("wireframe") && !pressed) { - wireframe = !wireframe; - if (wireframe) { - terrain.setMaterial(matWire); - } else { - terrain.setMaterial(matTerrain); - } - } - } - }; - - /** - * A sample class (node in this case) that demonstrates - * the use of NeighbourFinder. - * It just links up the left,right,top,bottom TerrainQuads - * so LOD can work. - * It does not implement many of the Terrain interface's methods, - * you will want to do that for your own implementations. - */ - private class TiledTerrain extends Node implements Terrain, NeighbourFinder { - - final private TerrainQuad terrain1; - final private TerrainQuad terrain2; - final private TerrainQuad terrain3; - final private TerrainQuad terrain4; - - TiledTerrain() { - // TERRAIN TEXTURE material - matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matTerrain.setBoolean("useTriPlanarMapping", false); - matTerrain.setBoolean("WardIso", true); - matTerrain.setFloat("Shininess", 0); - - // GRASS texture - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matTerrain.setTexture("DiffuseMap", grass); - matTerrain.setFloat("DiffuseMap_0_scale", grassScale); - - // CREATE THE TERRAIN - terrain1 = new TerrainQuad("terrain 1", 65, 513, null); - terrain1.setMaterial(matTerrain); - terrain1.setLocalTranslation(-256, -100, -256); - terrain1.setLocalScale(1f, 1f, 1f); - this.attachChild(terrain1); - - terrain2 = new TerrainQuad("terrain 2", 65, 513, null); - terrain2.setMaterial(matTerrain); - terrain2.setLocalTranslation(-256, -100, 256); - terrain2.setLocalScale(1f, 1f, 1f); - this.attachChild(terrain2); - - terrain3 = new TerrainQuad("terrain 3", 65, 513, null); - terrain3.setMaterial(matTerrain); - terrain3.setLocalTranslation(256, -100, -256); - terrain3.setLocalScale(1f, 1f, 1f); - this.attachChild(terrain3); - - terrain4 = new TerrainQuad("terrain 4", 65, 513, null); - terrain4.setMaterial(matTerrain); - terrain4.setLocalTranslation(256, -100, 256); - terrain4.setLocalScale(1f, 1f, 1f); - this.attachChild(terrain4); - - terrain1.setNeighbourFinder(this); - terrain2.setNeighbourFinder(this); - terrain3.setNeighbourFinder(this); - terrain4.setNeighbourFinder(this); - - MultiTerrainLodControl lodControl = new MultiTerrainLodControl(getCamera()); - lodControl.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier - lodControl.addTerrain(terrain1); - lodControl.addTerrain(terrain2); - lodControl.addTerrain(terrain3);// order of these seems to matter - lodControl.addTerrain(terrain4); - this.addControl(lodControl); - - } - - /** - * 1 3 - * 2 4 - */ - @Override - public TerrainQuad getRightQuad(TerrainQuad center) { - //System.out.println("lookup neighbour"); - if (center == terrain1) - return terrain3; - if (center == terrain2) - return terrain4; - - return null; - } - - /** - * 1 3 - * 2 4 - */ - @Override - public TerrainQuad getLeftQuad(TerrainQuad center) { - //System.out.println("lookup neighbour"); - if (center == terrain3) - return terrain1; - if (center == terrain4) - return terrain2; - - return null; - } - - /** - * 1 3 - * 2 4 - */ - @Override - public TerrainQuad getTopQuad(TerrainQuad center) { - //System.out.println("lookup neighbour"); - if (center == terrain2) - return terrain1; - if (center == terrain4) - return terrain3; - - return null; - } - - /** - * 1 3 - * 2 4 - */ - @Override - public TerrainQuad getDownQuad(TerrainQuad center) { - //System.out.println("lookup neighbour"); - if (center == terrain1) - return terrain2; - if (center == terrain3) - return terrain4; - - return null; - } - - @Override - public float getHeight(Vector2f xz) { - // you will have to offset the coordinate for each terrain, to center on it - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Vector3f getNormal(Vector2f xz) { - // you will have to offset the coordinate for each terrain, to center on it - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public float getHeightmapHeight(Vector2f xz) { - // you will have to offset the coordinate for each terrain, to center on it - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setHeight(Vector2f xzCoordinate, float height) { - // you will have to offset the coordinate for each terrain, to center on it - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setHeight(List xz, List height) { - // you will have to offset the coordinate for each terrain, to center on it - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void adjustHeight(Vector2f xzCoordinate, float delta) { - // you will have to offset the coordinate for each terrain, to center on it - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void adjustHeight(List xz, List height) { - // you will have to offset the coordinate for each terrain, to center on it - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public float[] getHeightMap() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getMaxLod() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setLocked(boolean locked) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void generateEntropy(ProgressMonitor monitor) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Material getMaterial() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Material getMaterial(Vector3f worldLocation) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getTerrainSize() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getNumMajorSubdivisions() { - throw new UnsupportedOperationException("Not supported yet."); - } - - - - } -} diff --git a/jme3-examples/src/main/java/jme3test/terrain/package-info.java b/jme3-examples/src/main/java/jme3test/terrain/package-info.java deleted file mode 100644 index 6cb10c70d3..0000000000 --- a/jme3-examples/src/main/java/jme3test/terrain/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for modeling terrain - */ -package jme3test.terrain; diff --git a/jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java b/jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java deleted file mode 100755 index 16ba966618..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java +++ /dev/null @@ -1,117 +0,0 @@ -package jme3test.texture; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.AssetManager; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Limits; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.RectangleMesh; -import com.jme3.texture.Image; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import com.jme3.texture.image.ColorSpace; -import com.jme3.texture.image.ImageRaster; -import com.jme3.util.BufferUtils; - -public class TestAnisotropicFilter extends SimpleApplication implements ActionListener { - - private int globalAniso = 1; - private int maxAniso = 1; - - @Override - public void simpleInitApp() { - maxAniso = renderer.getLimits().get(Limits.TextureAnisotropy); - - flyCam.setDragToRotate(true); - flyCam.setMoveSpeed(100); - cam.setLocation(new Vector3f(197.02617f, 4.6769195f, -194.89545f)); - cam.setRotation(new Quaternion(0.07921988f, 0.8992258f, -0.18292196f, 0.38943136f)); - - RectangleMesh rm = new RectangleMesh( - new Vector3f(-500, 0, 500), - new Vector3f(500, 0, 500), - new Vector3f(-500, 0, -500)); - rm.scaleTextureCoordinates(new Vector2f(1000, 1000)); - Geometry geom = new Geometry("rectangle", rm); - geom.setMaterial(createCheckerBoardMaterial(assetManager)); - rootNode.attachChild(geom); - - inputManager.addMapping("higher", new KeyTrigger(KeyInput.KEY_1)); - inputManager.addMapping("lower", new KeyTrigger(KeyInput.KEY_2)); - inputManager.addListener(this, "higher"); - inputManager.addListener(this, "lower"); - } - - private static Material createCheckerBoardMaterial(AssetManager assetManager) { - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - Texture tex = createCheckerBoardTexture(); // assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.dds"); - tex.setMagFilter(Texture.MagFilter.Bilinear); - tex.setMinFilter(Texture.MinFilter.Trilinear); - tex.setWrap(Texture.WrapMode.Repeat); - mat.setTexture("ColorMap", tex); - return mat; - } - - private static Texture2D createCheckerBoardTexture() { - Image image = new Image(Format.RGBA8, 1024, 1024, BufferUtils.createByteBuffer(1024 * 1024 * 4), ColorSpace.sRGB); - - ImageRaster raster = ImageRaster.create(image); - for (int y = 0; y < 1024; y++) { - for (int x = 0; x < 1024; x++) { - if (y < 512) { - if (x < 512) { - raster.setPixel(x, y, ColorRGBA.Black); - } else { - raster.setPixel(x, y, ColorRGBA.White); - } - } else { - if (x < 512) { - raster.setPixel(x, y, ColorRGBA.White); - } else { - raster.setPixel(x, y, ColorRGBA.Black); - } - } - } - } - - return new Texture2D(image); - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - return; - } - switch (name) { - case "higher": - globalAniso++; - if (globalAniso > 32) { - globalAniso = 32; - } - renderer.setDefaultAnisotropicFilter(globalAniso); - System.out.format("Global Aniso: %d / %d\r\n", globalAniso, maxAniso); - break; - case "lower": - globalAniso--; - if (globalAniso < 1) { - globalAniso = 1; - } - renderer.setDefaultAnisotropicFilter(globalAniso); - System.out.format("Global Aniso: %d / %d\r\n", globalAniso, maxAniso); - break; - } - } - - public static void main(String[] args) { - TestAnisotropicFilter app = new TestAnisotropicFilter(); - app.start(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java b/jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java deleted file mode 100644 index 5288d4ffe6..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java +++ /dev/null @@ -1,139 +0,0 @@ -package jme3test.texture; - - -import com.jme3.app.SimpleApplication; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.Rectangle; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; -import com.jme3.texture.Image; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.MagFilter; -import com.jme3.texture.Texture.MinFilter; -import com.jme3.texture.Texture2D; -import com.jme3.texture.image.ImageRaster; -import com.jme3.util.BufferUtils; -import java.nio.ByteBuffer; - -public class TestImageRaster extends SimpleApplication { - - private Image convertImage(Image image, Format newFormat) { - int width = image.getWidth(); - int height = image.getHeight(); - ByteBuffer data = BufferUtils.createByteBuffer( (int)Math.ceil(newFormat.getBitsPerPixel() / 8.0) * width * height); - Image convertedImage = new Image(newFormat, width, height, data,null, image.getColorSpace()); - - ImageRaster sourceReader = ImageRaster.create(image); - ImageRaster targetWriter = ImageRaster.create(convertedImage); - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - ColorRGBA color = sourceReader.getPixel(x, y); - targetWriter.setPixel(x, y, color); - } - } - - return convertedImage; - } - - private void convertAndPutImage(Image image, float posX, float posY) { - Texture tex = new Texture2D(image); - tex.setMagFilter(MagFilter.Nearest); - tex.setMinFilter(MinFilter.NearestNoMipMaps); - tex.setAnisotropicFilter(16); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", tex); - - Quad q = new Quad(5, 5); - Geometry g = new Geometry("quad", q); - g.setLocalTranslation(posX, posY - 5, -0.0001f); - g.setMaterial(mat); - rootNode.attachChild(g); - - BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText txt = new BitmapText(fnt); - txt.setBox(new Rectangle(0, 0, 5, 5)); - txt.setQueueBucket(RenderQueue.Bucket.Transparent); - txt.setSize(0.5f); - txt.setText(image.getFormat().name()); - txt.setLocalTranslation(posX, posY, 0); - rootNode.attachChild(txt); - } - - @Override - public void simpleInitApp() { - cam.setLocation(new Vector3f(16, 6, 36)); - flyCam.setMoveSpeed(10); - - Texture tex = assetManager.loadTexture("com/jme3/app/Monkey.png"); -// Texture tex = assetManager.loadTexture("Textures/HdrTest/Memorial.hdr"); - Image originalImage = tex.getImage(); - - Image image = convertImage(originalImage, Format.RGBA32F); - convertAndPutImage(image, 0, 0); - - image = convertImage(image, Format.RGB32F); - convertAndPutImage(image, 5, 0); - - image = convertImage(image, Format.RGBA16F); - convertAndPutImage(image, 10, 0); - - image = convertImage(image, Format.RGB16F); - convertAndPutImage(image, 15, 0); - - image = convertImage(image, Format.RGB16F_to_RGB9E5); - convertAndPutImage(image, 20, 0); - - image = convertImage(image, Format.RGB16F_to_RGB111110F); - convertAndPutImage(image, 25, 0); - - image = convertImage(image, Format.RGBA8); - convertAndPutImage(image, 10, 5); - - image = convertImage(image, Format.RGB8); - convertAndPutImage(image, 15, 5); - - image = convertImage(image, Format.ABGR8); - convertAndPutImage(image, 20, 5); - - image = convertImage(image, Format.BGR8); - convertAndPutImage(image, 25, 5); - - image = convertImage(image, Format.ARGB8); - convertAndPutImage(image, 30, 5); - - image = convertImage(image, Format.BGRA8); - convertAndPutImage(image, 35, 5); - - image = convertImage(image, Format.RGB5A1); - convertAndPutImage(image, 0, 10); - - image = convertImage(image, Format.RGB565); - convertAndPutImage(image, 5, 10); - - image = convertImage(image, Format.Luminance32F); - convertAndPutImage(image, 0, 15); - - image = convertImage(image, Format.Luminance16FAlpha16F); - convertAndPutImage(image, 5, 15); - - image = convertImage(image, Format.Luminance16F); - convertAndPutImage(image, 10, 15); - - image = convertImage(image, Format.Luminance8Alpha8); - convertAndPutImage(image, 15, 15); - - image = convertImage(image, Format.Luminance8); - convertAndPutImage(image, 20, 15); - } - - public static void main(String[] args) { - TestImageRaster app = new TestImageRaster(); - app.start(); - } -} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java b/jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java deleted file mode 100644 index 21c1b590b9..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.texture; - -import com.jme3.app.SimpleApplication; -import com.jme3.scene.Spatial; -import com.jme3.texture.Texture; -import com.jme3.util.SkyFactory; - -public class TestSkyLoading extends SimpleApplication { - - public static void main(String[] args){ - TestSkyLoading app = new TestSkyLoading(); - app.start(); - } - - @Override - public void simpleInitApp() { - Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg"); - Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg"); - Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg"); - Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg"); - Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg"); - Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg"); - - Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down); - rootNode.attachChild(sky); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java b/jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java deleted file mode 100644 index 89c0718733..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2017-2021 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. - */ -package jme3test.texture; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.util.SkyFactory; - -/** - * Simple application to test sky rotation with a cube-mapped sky. - * - * Press "T" to rotate the sky and floor to the camera's left. Press "Y" to - * rotate the sky and floor to the camera's right. Both should appear to move by - * the same amount in the same direction. - * - * See issue #651 for further information. - * - * @author Stephen Gold - */ -public class TestSkyRotation extends SimpleApplication implements ActionListener { - - /** - * objects visible in the scene - */ - private Spatial floor, sky; - /** - * Y-axis rotation angle in radians - */ - private float angle = 0f; - - public static void main(String[] arguments) { - TestSkyRotation application = new TestSkyRotation(); - application.start(); - } - - @Override - public void simpleInitApp() { - /* - * Configure the camera. - */ - flyCam.setEnabled(false); - Vector3f location = new Vector3f(-7f, 4f, 8f); - cam.setLocation(location); - Quaternion orientation; - orientation = new Quaternion(0.0037f, 0.944684f, -0.01067f, 0.327789f); - assert FastMath.approximateEquals(orientation.norm(), 1f); - cam.setRotation(orientation); - /* - * Attach a cube-mapped sky to the scene graph. - */ - sky = SkyFactory.createSky(assetManager, - "Scenes/Beach/FullskiesSunset0068.dds", - SkyFactory.EnvMapType.CubeMap); - rootNode.attachChild(sky); - /* - * Attach a "floor" geometry to the scene graph. - */ - Mesh floorMesh = new Box(10f, 0.1f, 10f); - floor = new Geometry("floor", floorMesh); - Material floorMaterial = new Material(assetManager, - "Common/MatDefs/Misc/Unshaded.j3md"); - floorMaterial.setTexture("ColorMap", - assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - floor.setMaterial(floorMaterial); - rootNode.attachChild(floor); - /* - * Configure mappings and listeners for keyboard input. - */ - inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addListener(this, "left"); - inputManager.addListener(this, "right"); - } - - /** - * Handle an input action from the user. - * - * @param name the name of the action - * @param ongoing true→depress key, false→release key - * @param ignored ignored - */ - @Override - public void onAction(String name, boolean ongoing, float ignored) { - if (!ongoing) { - return; - } - /* - * Update the Y-axis rotation angle based on which key was pressed. - */ - if (name.equals("left")) { - angle += 0.1f; // radians - System.out.print("rotate floor and sky leftward ..."); - } else if (name.equals("right")) { - angle -= 0.1f; // radians - System.out.printf("rotate floor and sky spatials rightward ..."); - } else { - return; - } - /* - * Update the local rotations of both objects based on the angle. - */ - System.out.printf(" to %.1f radians left of start%n", angle); - Quaternion rotation = new Quaternion(); - rotation.fromAngleNormalAxis(angle, Vector3f.UNIT_Y); - floor.setLocalRotation(rotation); - sky.setLocalRotation(rotation); - } -} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java b/jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java deleted file mode 100644 index e3f41b6fee..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.texture; - -import com.jme3.app.SimpleApplication; -import com.jme3.bounding.BoundingBox; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.scene.VertexBuffer.Usage; -import com.jme3.scene.shape.Sphere; -import com.jme3.texture.Image; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture3D; -import com.jme3.texture.image.ColorSpace; -import com.jme3.util.BufferUtils; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.util.ArrayList; - -public class TestTexture3D extends SimpleApplication { - - public static void main(String[] args) { - TestTexture3D app = new TestTexture3D(); - app.start(); - } - - @Override - public void simpleInitApp() { - //mouseInput.setCursorVisible(true); - flyCam.setMoveSpeed(10); - //creating a sphere - Sphere sphere = new Sphere(32, 32, 1); - // getting the bounding box - sphere.updateBound(); - BoundingBox bb = (BoundingBox) sphere.getBound(); - Vector3f min = bb.getMin(null); - float[] ext = new float[]{bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2}; - //we need to change the UV coordinates (the sphere is assumed to be inside the 3D image box) - sphere.clearBuffer(Type.TexCoord); - VertexBuffer vb = sphere.getBuffer(Type.Position); - FloatBuffer fb = (FloatBuffer) vb.getData(); - float[] uvCoordinates = BufferUtils.getFloatArray(fb); - //now transform the coordinates so that they are in the range of <0; 1> - for (int i = 0; i < uvCoordinates.length; i += 3) { - uvCoordinates[i] = (uvCoordinates[i] - min.x) / ext[0]; - uvCoordinates[i + 1] = (uvCoordinates[i + 1] - min.y) / ext[1]; - uvCoordinates[i + 2] = (uvCoordinates[i + 2] - min.z) / ext[2]; - } - //apply new texture coordinates - VertexBuffer uvCoordsBuffer = new VertexBuffer(Type.TexCoord); - uvCoordsBuffer.setupData(Usage.Static, 3, com.jme3.scene.VertexBuffer.Format.Float, - BufferUtils.createFloatBuffer(uvCoordinates)); - sphere.setBuffer(uvCoordsBuffer); - //create geometry, and apply material and our 3D texture - Geometry g = new Geometry("sphere", sphere); - Material material = new Material(assetManager, "jme3test/texture/tex3D.j3md"); - try { - Texture texture = this.getTexture(); - material.setTexture("Texture", texture); - } catch (IOException e) { - e.printStackTrace(); - } - g.setMaterial(material); - rootNode.attachChild(g); - //add some light so that it is visible - PointLight light = new PointLight(); - light.setColor(ColorRGBA.White); - light.setPosition(new Vector3f(5, 5, 5)); - light.setRadius(20); - rootNode.addLight(light); - light = new PointLight(); - light.setColor(ColorRGBA.White); - light.setPosition(new Vector3f(-5, -5, -5)); - light.setRadius(20); - rootNode.addLight(light); - } - - /** - * This method creates an RGB8 texture with the sizes of 10x10x10 pixels. - */ - private Texture getTexture() throws IOException { - ArrayList data = new ArrayList<>(1); - ByteBuffer bb = BufferUtils.createByteBuffer(10 * 10 * 10 * 3);//all data must be inside one buffer - for (int i = 0; i < 10; ++i) { - for (int j = 0; j < 10 * 10; ++j) { - bb.put((byte) (255f*i/10f)); - bb.put((byte) (255f*i/10f)); - bb.put((byte) (255f)); - } - } - bb.rewind(); - data.add(bb); - return new Texture3D(new Image(Format.RGB8, 10, 10, 10, data, null, ColorSpace.Linear)); - } -} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java b/jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java deleted file mode 100644 index ada3f1fffe..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.texture; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.shape.Quad; -import com.jme3.texture.Texture; - -public class TestTexture3DLoading extends SimpleApplication { - - public static void main(String[] args) { - TestTexture3DLoading app = new TestTexture3DLoading(); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - flyCam.setEnabled(false); - - - Quad q = new Quad(10, 10); - - Geometry geom = new Geometry("Quad", q); - Material material = new Material(assetManager, "jme3test/texture/tex3DThumb.j3md"); - TextureKey key = new TextureKey("Textures/3D/flame.dds"); - key.setGenerateMips(true); - key.setTextureTypeHint(Texture.Type.ThreeDimensional); - - Texture t = assetManager.loadTexture(key); - - int rows = 4;//4 * 4 - - q.scaleTextureCoordinates(new Vector2f(rows, rows)); - - // The image has only 8 pictures, and we have 16 thumbs, so the data will be interpolated by the GPU. - material.setFloat("InvDepth", 1f / 16f); - material.setInt("Rows", rows); - material.setTexture("Texture", t); - geom.setMaterial(material); - - rootNode.attachChild(geom); - - cam.setLocation(new Vector3f(4.7444625f, 5.160054f, 13.1939f)); - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java b/jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java deleted file mode 100644 index ba56b3ff2a..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java +++ /dev/null @@ -1,87 +0,0 @@ -package jme3test.texture; - - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Caps; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.TextureArray; -import com.jme3.util.BufferUtils; -import java.util.ArrayList; -import java.util.List; - -public class TestTextureArray extends SimpleApplication -{ - - @Override - public void simpleInitApp() - { - Material mat = new Material(assetManager, "jme3test/texture/UnshadedArray.j3md"); - - for (Caps caps : renderManager.getRenderer().getCaps()) { - System.out.println(caps.name()); - } - if(!renderManager.getRenderer().getCaps().contains(Caps.TextureArray)){ - throw new UnsupportedOperationException("Your hardware does not support TextureArray"); - } - - - Texture tex1 = assetManager.loadTexture( "Textures/Terrain/Pond/Pond.jpg"); - Texture tex2 = assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg"); - List images = new ArrayList<>(); - images.add(tex1.getImage()); - images.add(tex2.getImage()); - TextureArray tex3 = new TextureArray(images); - tex3.setMinFilter(Texture.MinFilter.Trilinear); - mat.setTexture("ColorMap", tex3); - - Mesh m = new Mesh(); - Vector3f[] vertices = new Vector3f[8]; - vertices[0] = new Vector3f(0, 0, 0); - vertices[1] = new Vector3f(3, 0, 0); - vertices[2] = new Vector3f(0, 3, 0); - vertices[3] = new Vector3f(3, 3, 0); - - vertices[4] = new Vector3f(3, 0, 0); - vertices[5] = new Vector3f(6, 0, 0); - vertices[6] = new Vector3f(3, 3, 0); - vertices[7] = new Vector3f(6, 3, 0); - - Vector3f[] texCoord = new Vector3f[8]; - texCoord[0] = new Vector3f(0, 0, 0); - texCoord[1] = new Vector3f(1, 0, 0); - texCoord[2] = new Vector3f(0, 1, 0); - texCoord[3] = new Vector3f(1, 1, 0); - - texCoord[4] = new Vector3f(0, 0, 1); - texCoord[5] = new Vector3f(1, 0, 1); - texCoord[6] = new Vector3f(0, 1, 1); - texCoord[7] = new Vector3f(1, 1, 1); - - int[] indexes = { 2, 0, 1, 1, 3, 2 , 6, 4, 5, 5, 7, 6}; - - m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices)); - m.setBuffer(Type.TexCoord, 3, BufferUtils.createFloatBuffer(texCoord)); - m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes)); - m.updateBound(); - - Geometry geom = new Geometry("Mesh", m); - geom.setMaterial(mat); - rootNode.attachChild(geom); - } - - /** - * @param args ignored - */ - public static void main(String[] args) - { - TestTextureArray app = new TestTextureArray(); - app.start(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java b/jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java deleted file mode 100644 index 0af064f557..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java +++ /dev/null @@ -1,87 +0,0 @@ -package jme3test.texture; - - -import com.jme3.app.SimpleApplication; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Caps; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.TextureArray; -import com.jme3.util.BufferUtils; -import java.util.ArrayList; -import java.util.List; - -public class TestTextureArrayCompressed extends SimpleApplication -{ - - @Override - public void simpleInitApp() - { - Material mat = new Material(assetManager, "jme3test/texture/UnshadedArray.j3md"); - - for (Caps caps : renderManager.getRenderer().getCaps()) { - System.out.println(caps.name()); - } - if(!renderManager.getRenderer().getCaps().contains(Caps.TextureArray)){ - throw new UnsupportedOperationException("Your hardware does not support TextureArray"); - } - - - Texture tex1 = assetManager.loadTexture( "Textures/Terrain/Pond/Pond_dxt5.dds"); - Texture tex2 = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall_dxt5.dds"); - List images = new ArrayList<>(); - images.add(tex1.getImage()); - images.add(tex2.getImage()); - TextureArray tex3 = new TextureArray(images); - tex3.setMinFilter(Texture.MinFilter.Trilinear); - mat.setTexture("ColorMap", tex3); - - Mesh m = new Mesh(); - Vector3f[] vertices = new Vector3f[8]; - vertices[0] = new Vector3f(0, 0, 0); - vertices[1] = new Vector3f(3, 0, 0); - vertices[2] = new Vector3f(0, 3, 0); - vertices[3] = new Vector3f(3, 3, 0); - - vertices[4] = new Vector3f(3, 0, 0); - vertices[5] = new Vector3f(6, 0, 0); - vertices[6] = new Vector3f(3, 3, 0); - vertices[7] = new Vector3f(6, 3, 0); - - Vector3f[] texCoord = new Vector3f[8]; - texCoord[0] = new Vector3f(0, 0, 0); - texCoord[1] = new Vector3f(1, 0, 0); - texCoord[2] = new Vector3f(0, 1, 0); - texCoord[3] = new Vector3f(1, 1, 0); - - texCoord[4] = new Vector3f(0, 0, 1); - texCoord[5] = new Vector3f(1, 0, 1); - texCoord[6] = new Vector3f(0, 1, 1); - texCoord[7] = new Vector3f(1, 1, 1); - - int[] indexes = { 2, 0, 1, 1, 3, 2 , 6, 4, 5, 5, 7, 6}; - - m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices)); - m.setBuffer(Type.TexCoord, 3, BufferUtils.createFloatBuffer(texCoord)); - m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes)); - m.updateBound(); - - Geometry geom = new Geometry("Mesh", m); - geom.setMaterial(mat); - rootNode.attachChild(geom); - } - - /** - * @param args ignored - */ - public static void main(String[] args) - { - TestTextureArrayCompressed app = new TestTextureArrayCompressed(); - app.start(); - } - -} diff --git a/jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java b/jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java deleted file mode 100644 index bcf4b4d8b1..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.texture.dds; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.TextureKey; -import com.jme3.math.ColorRGBA; -import com.jme3.renderer.RenderManager; -import com.jme3.texture.Texture2D; -import com.jme3.texture.plugins.DDSLoader; -import com.jme3.ui.Picture; - -/** - * Test various supported BC* textures in DDS file format - * - * @author Toni Helenius - */ -public class TestLoadDds extends SimpleApplication { - - public static void main(String[] args) { - TestLoadDds app = new TestLoadDds(); - //app.setShowSettings(false); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - assetManager.registerLoader(DDSLoader.class, "dds"); - - loadTexture(0, "Textures/dds/Monkey_PNG_BC7_1.DDS", "BC7"); - loadTexture(1, "Textures/dds/Monkey_PNG_BC6H_3.DDS", "BC6"); - loadTexture(2, "Textures/dds/Monkey_PNG_BC6H_SF_2.DDS", "BC6_SF"); - loadTexture(3, "Textures/dds/Monkey_PNG_BC5_S_6.DDS", "BC5_S"); - loadTexture(4, "Textures/dds/Monkey_PNG_BC5_7.DDS", "BC5"); - loadTexture(5, "Textures/dds/Monkey_PNG_BC4_S_8.DDS", "BC4_S"); - loadTexture(6, "Textures/dds/Monkey_PNG_BC4_9.DDS", "BC4"); - loadTexture(7, "Textures/dds/Monkey_PNG_BC3_10.DDS", "BC3"); - loadTexture(8, "Textures/dds/Monkey_PNG_BC2_11.DDS", "BC2"); - loadTexture(9, "Textures/dds/Monkey_PNG_BC1_12.DDS", "BC1"); - - flyCam.setDragToRotate(true); - - } - - private void loadTexture(int index, String texture, String description) { - Texture2D t = (Texture2D)assetManager.loadTexture(new TextureKey(texture, false)); - Picture p = new Picture(description, true); - p.setTexture(assetManager, t, false); - p.setLocalTranslation((index % 4) * 200, Math.floorDiv(index, 4) * 200, 0); - p.setWidth(200); - p.setHeight(200); - guiNode.attachChild(p); - } - - - @Override - public void simpleUpdate(float tpf) { - //TODO: add update code - } - - @Override - public void simpleRender(RenderManager rm) { - //TODO: add render code - } -} diff --git a/jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java b/jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java deleted file mode 100644 index 8c69c0a7ac..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2009-2015 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. - */ -package jme3test.texture.ktx; - -import com.jme3.app.SimpleApplication; -import com.jme3.math.ColorRGBA; -import com.jme3.renderer.RenderManager; -import com.jme3.texture.Texture2D; -import com.jme3.texture.plugins.ktx.KTXLoader; -import com.jme3.ui.Picture; - -/** - * test - * @author nehon - */ -public class TestLoadKtx extends SimpleApplication { - - public static void main(String[] args) { - TestLoadKtx app = new TestLoadKtx(); - //app.setShowSettings(false); - app.start(); - } - - @Override - public void simpleInitApp() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - assetManager.registerLoader(KTXLoader.class, "ktx"); - - - Texture2D t = (Texture2D)assetManager.loadTexture("Textures/ktx/down-reference.ktx"); - Picture p = new Picture("bla", false); - p.setTexture(assetManager, t, false); - p.setLocalTranslation(200, 200, 0); - p.setWidth(t.getImage().getWidth()); - p.setHeight(t.getImage().getHeight()); - guiNode.attachChild(p); - - - Texture2D t2 = (Texture2D)assetManager.loadTexture("Textures/ktx/up-reference.ktx"); - Picture p2 = new Picture("bla", false); - p2.setTexture(assetManager, t2, false); - p2.setLocalTranslation(400, 200, 0); - p2.setWidth(t2.getImage().getWidth()); - p2.setHeight(t2.getImage().getHeight()); - guiNode.attachChild(p2); - - Texture2D t3 = (Texture2D)assetManager.loadTexture("Textures/ktx/rgba-reference.ktx"); - Picture p3 = new Picture("bla", false); - p3.setTexture(assetManager, t3, false); - p3.setLocalTranslation(200, 400, 0); - p3.setWidth(t3.getImage().getWidth()); - p3.setHeight(t3.getImage().getHeight()); - guiNode.attachChild(p3); - - - Texture2D t4 = (Texture2D)assetManager.loadTexture("Textures/ktx/rgb-amg-reference.ktx"); - Picture p4 = new Picture("bla", false); - p4.setTexture(assetManager, t4, false); - p4.setLocalTranslation(400, 400, 0); - p4.setWidth(t4.getImage().getWidth()); - p4.setHeight(t4.getImage().getHeight()); - guiNode.attachChild(p4); - - - flyCam.setDragToRotate(true); - - } - - - @Override - public void simpleUpdate(float tpf) { - //TODO: add update code - } - - @Override - public void simpleRender(RenderManager rm) { - //TODO: add render code - } -} diff --git a/jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java b/jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java deleted file mode 100644 index 65f87771b4..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for textures in KTX (Khronos Texture) - * format - */ -package jme3test.texture.ktx; diff --git a/jme3-examples/src/main/java/jme3test/texture/package-info.java b/jme3-examples/src/main/java/jme3test/texture/package-info.java deleted file mode 100644 index 64d258c788..0000000000 --- a/jme3-examples/src/main/java/jme3test/texture/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for textures - */ -package jme3test.texture; diff --git a/jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java b/jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java deleted file mode 100644 index 2c54a5bdc9..0000000000 --- a/jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ -package jme3test.tools; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import jme3tools.savegame.SaveGame; - -public class TestSaveGame extends SimpleApplication { - - public static void main(String[] args) { - - TestSaveGame app = new TestSaveGame(); - app.start(); - } - - @Override - public void simpleUpdate(float tpf) { - } - - @Override - public void simpleInitApp() { - - // Create a Node to store player data. - Node myPlayer = new Node(); - myPlayer.setName("PlayerNode"); - myPlayer.setUserData("name", "Mario"); - myPlayer.setUserData("health", 100.0f); - myPlayer.setUserData("points", 0); - - // Attach the model to the Node. - Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - myPlayer.attachChild(model); - - // Before saving the game, detach the model since it doesn't need to be saved. - myPlayer.detachAllChildren(); - SaveGame.saveGame("mycompany/mygame", "savegame_001", myPlayer); - - // Later, the game is loaded again ... - Node player = (Node) SaveGame.loadGame("mycompany/mygame", "savegame_001"); - player.attachChild(model); - rootNode.attachChild(player); - - // and the player data are available. - System.out.println("Name: " + player.getUserData("name")); - System.out.println("Health: " + player.getUserData("health")); - System.out.println("Points: " + player.getUserData("points")); - - AmbientLight al = new AmbientLight(); - rootNode.addLight(al); - - // Note that your custom classes can also implement the Savable interface. - } -} diff --git a/jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java b/jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java deleted file mode 100644 index 5c3d6c98cb..0000000000 --- a/jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package jme3test.tools; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; -import jme3tools.optimize.TextureAtlas; - -public class TestTextureAtlas extends SimpleApplication { - - public static void main(String[] args) { - TestTextureAtlas app = new TestTextureAtlas(); - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setMoveSpeed(50); - Node scene = new Node("Scene"); - Spatial obj1 = assetManager.loadModel("Models/Ferrari/Car.scene"); - obj1.setLocalTranslation(-4, 0, 0); - Spatial obj2 = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - obj2.setLocalTranslation(-2, 0, 0); - Spatial obj3 = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml"); - obj3.setLocalTranslation(-0, 0, 0); - Spatial obj4 = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); - obj4.setLocalTranslation(2, 0, 0); - Spatial obj5 = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); - obj5.setLocalTranslation(4, 0, 0); - scene.attachChild(obj1); - scene.attachChild(obj2); - scene.attachChild(obj3); - scene.attachChild(obj4); - scene.attachChild(obj5); - - Geometry geom = TextureAtlas.makeAtlasBatch(scene, assetManager, 2048); - - AmbientLight al = new AmbientLight(); - rootNode.addLight(al); - - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(new Vector3f(0.69077975f, -0.6277887f, -0.35875428f).normalizeLocal()); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - rootNode.addLight(sun); - - rootNode.attachChild(geom); - - //quad to display material - Geometry box = new Geometry("displayquad", new Quad(4, 4)); - box.setMaterial(geom.getMaterial()); - box.setLocalTranslation(0, 1, 3); - rootNode.attachChild(box); - } -} diff --git a/jme3-examples/src/main/java/jme3test/tools/package-info.java b/jme3-examples/src/main/java/jme3test/tools/package-info.java deleted file mode 100644 index db76f10763..0000000000 --- a/jme3-examples/src/main/java/jme3test/tools/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for miscellaneous tools - */ -package jme3test.tools; diff --git a/jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java b/jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java deleted file mode 100644 index 2784d59fa1..0000000000 --- a/jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.water; - -import com.jme3.app.SimpleApplication; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.renderer.Camera; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.system.AppSettings; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.texture.Texture2D; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; -import com.jme3.water.WaterFilter; -import java.util.ArrayList; -import java.util.List; - -/** - * test - * - * @author normenhansen - */ -public class TestMultiPostWater extends SimpleApplication { - - final private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f); - final private static float WATER_HEIGHT = 90; - - public static void main(String[] args) { - TestMultiPostWater app = new TestMultiPostWater(); - AppSettings s = new AppSettings(true); - s.setRenderer(AppSettings.LWJGL_OPENGL2); - s.setAudioRenderer(AppSettings.LWJGL_OPENAL); - app.setSettings(s); - - app.start(); - } - - @Override - public void simpleInitApp() { - -// setDisplayFps(false); -// setDisplayStatView(false); - - Node mainScene = new Node("Main Scene"); - rootNode.attachChild(mainScene); - - createTerrain(mainScene); - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(1.7f)); - mainScene.addLight(sun); - - flyCam.setMoveSpeed(100); - - //cam.setLocation(new Vector3f(-700, 100, 300)); - //cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z)); - cam.setLocation(new Vector3f(-327.21957f, 251.6459f, 126.884346f)); - cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0})); - - - Spatial sky = SkyFactory.createSky(assetManager, - "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); - sky.setLocalScale(350); - - mainScene.attachChild(sky); - cam.setFrustumFar(4000); - - - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - - WaterFilter water = new WaterFilter(rootNode, lightDir); - water.setCenter(new Vector3f(9.628218f, -15.830074f, 199.23595f)); - water.setRadius(260); - water.setWaveScale(0.003f); - water.setMaxAmplitude(2f); - water.setFoamExistence(new Vector3f(1f, 4, 0.5f)); - water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); - water.setRefractionStrength(0.2f); - water.setWaterHeight(WATER_HEIGHT); - fpp.addFilter(water); - - WaterFilter water2 = new WaterFilter(rootNode, lightDir); - water2.setCenter(new Vector3f(-280.46027f, -24.971727f, -271.71976f)); - water2.setRadius(260); - water2.setWaterHeight(WATER_HEIGHT); - water2.setUseFoam(false); - water2.setUseRipples(false); - water2.setDeepWaterColor(ColorRGBA.Brown); - water2.setWaterColor(ColorRGBA.Brown.mult(2.0f)); - water2.setWaterTransparency(0.2f); - water2.setMaxAmplitude(0.3f); - water2.setWaveScale(0.008f); - water2.setSpeed(0.7f); - water2.setShoreHardness(1.0f); - water2.setRefractionConstant(0.2f); - water2.setShininess(0.3f); - water2.setSunScale(1.0f); - water2.setColorExtinction(new Vector3f(10.0f, 20.0f, 30.0f)); - fpp.addFilter(water2); - - - WaterFilter water3 = new WaterFilter(rootNode, lightDir); - water3.setCenter(new Vector3f(319.6663f, -18.367947f, -236.67674f)); - water3.setRadius(260); - water3.setWaterHeight(WATER_HEIGHT); - water3.setWaveScale(0.003f); - water3.setMaxAmplitude(2f); - water3.setFoamExistence(new Vector3f(1f, 4, 0.5f)); - water3.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); - water3.setRefractionStrength(0.2f); - water3.setDeepWaterColor(ColorRGBA.Red); - water3.setWaterColor(ColorRGBA.Red.mult(2.0f)); - water3.setLightColor(ColorRGBA.Red); - fpp.addFilter(water3); - - viewPort.addProcessor(fpp); - - //fpp.setNumSamples(4); - } - - private void createTerrain(Node rootNode) { - Material matRock = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/pools.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - } catch (Exception e) { - e.printStackTrace(); - } - TerrainQuad terrain - = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - List cameras = new ArrayList<>(); - cameras.add(getCamera()); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(5, 5, 5)); - terrain.setLocalTranslation(new Vector3f(0, -30, 0)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(terrain); - - } - - @Override - public void simpleUpdate(float tpf) { - } -} diff --git a/jme3-examples/src/main/java/jme3test/water/TestPostWater.java b/jme3-examples/src/main/java/jme3test/water/TestPostWater.java deleted file mode 100644 index 384d88f7f9..0000000000 --- a/jme3-examples/src/main/java/jme3test/water/TestPostWater.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2009-2022 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. - */ -package jme3test.water; - -import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioData.DataType; -import com.jme3.audio.AudioNode; -import com.jme3.audio.Filter; -import com.jme3.audio.LowPassFilter; -import com.jme3.font.BitmapText; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.post.filters.DepthOfFieldFilter; -import com.jme3.post.filters.FXAAFilter; -import com.jme3.post.filters.LightScatteringFilter; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.texture.Texture2D; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; -import com.jme3.water.WaterFilter; - -/** - * test - * - * @author normenhansen - */ -public class TestPostWater extends SimpleApplication { - - final private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f); - private WaterFilter water; - private AudioNode waves; - final private LowPassFilter aboveWaterAudioFilter = new LowPassFilter(1, 1); - final private Filter underWaterAudioFilter = new LowPassFilter(0.5f, 0.1f); - private boolean useDryFilter = true; - - public static void main(String[] args) { - TestPostWater app = new TestPostWater(); - app.start(); - } - - @Override - public void simpleInitApp() { - - setDisplayFps(false); - setDisplayStatView(false); - - Node mainScene = new Node("Main Scene"); - rootNode.attachChild(mainScene); - - createTerrain(mainScene); - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(1f)); - mainScene.addLight(sun); - - AmbientLight al = new AmbientLight(); - al.setColor(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f)); - mainScene.addLight(al); - - flyCam.setMoveSpeed(50); - - //cam.setLocation(new Vector3f(-700, 100, 300)); - //cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z)); -// cam.setLocation(new Vector3f(-327.21957f, 61.6459f, 126.884346f)); -// cam.setRotation(new Quaternion(0.052168474f, 0.9443102f, -0.18395276f, 0.2678024f)); - - - cam.setLocation(new Vector3f(-370.31592f, 182.04016f, 196.81192f)); - cam.setRotation(new Quaternion(0.015302252f, 0.9304095f, -0.039101653f, 0.3641086f)); - - - - - Spatial sky = SkyFactory.createSky(assetManager, - "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); - sky.setLocalScale(350); - - mainScene.attachChild(sky); - cam.setFrustumFar(4000); - - //Water Filter - water = new WaterFilter(rootNode, lightDir); - water.setWaterColor(new ColorRGBA().setAsSrgb(0.0078f, 0.3176f, 0.5f, 1.0f)); - water.setDeepWaterColor(new ColorRGBA().setAsSrgb(0.0039f, 0.00196f, 0.145f, 1.0f)); - water.setUnderWaterFogDistance(80); - water.setWaterTransparency(0.12f); - water.setFoamIntensity(0.4f); - water.setFoamHardness(0.3f); - water.setFoamExistence(new Vector3f(0.8f, 8f, 1f)); - water.setReflectionDisplace(50); - water.setRefractionConstant(0.25f); - water.setColorExtinction(new Vector3f(30, 50, 70)); - water.setCausticsIntensity(0.4f); - water.setWaveScale(0.003f); - water.setMaxAmplitude(2f); - water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); - water.setRefractionStrength(0.2f); - water.setWaterHeight(initialWaterHeight); - - //Bloom Filter - BloomFilter bloom = new BloomFilter(); - bloom.setExposurePower(55); - bloom.setBloomIntensity(1.0f); - - //Light Scattering Filter - LightScatteringFilter lsf = new LightScatteringFilter(lightDir.mult(-300)); - lsf.setLightDensity(0.5f); - - //Depth of field Filter - DepthOfFieldFilter dof = new DepthOfFieldFilter(); - dof.setFocusDistance(0); - dof.setFocusRange(100); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - - fpp.addFilter(water); - fpp.addFilter(bloom); - fpp.addFilter(dof); - fpp.addFilter(lsf); - fpp.addFilter(new FXAAFilter()); - -// fpp.addFilter(new TranslucentBucketFilter()); - int numSamples = getContext().getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - - - uw = cam.getLocation().y < waterHeight; - - waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", - DataType.Buffer); - waves.setLooping(true); - updateAudio(); - audioRenderer.playSource(waves); - // - viewPort.addProcessor(fpp); - - setText(0, 50, "1 - Set Foam Texture to Foam.jpg"); - setText(0, 80, "2 - Set Foam Texture to Foam2.jpg"); - setText(0, 110, "3 - Set Foam Texture to Foam3.jpg"); - setText(0, 140, "4 - Turn Dry Filter under water On/Off"); - setText(0, 240, "PgUp - Larger Reflection Map"); - setText(0, 270, "PgDn - Smaller Reflection Map"); - - inputManager.addListener(new ActionListener() { - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if (isPressed) { - if (name.equals("foam1")) { - water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg")); - } - if (name.equals("foam2")) { - water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); - } - if (name.equals("foam3")) { - water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg")); - } - - if (name.equals("upRM")) { - water.setReflectionMapSize(Math.min(water.getReflectionMapSize() * 2, 4096)); - System.out.println("Reflection map size : " + water.getReflectionMapSize()); - } - if (name.equals("downRM")) { - water.setReflectionMapSize(Math.max(water.getReflectionMapSize() / 2, 32)); - System.out.println("Reflection map size : " + water.getReflectionMapSize()); - } - if (name.equals("dryFilter")) { - useDryFilter = !useDryFilter; - } - } - } - }, "foam1", "foam2", "foam3", "upRM", "downRM", "dryFilter"); - inputManager.addMapping("foam1", new KeyTrigger(KeyInput.KEY_1)); - inputManager.addMapping("foam2", new KeyTrigger(KeyInput.KEY_2)); - inputManager.addMapping("foam3", new KeyTrigger(KeyInput.KEY_3)); - inputManager.addMapping("dryFilter", new KeyTrigger(KeyInput.KEY_4)); - inputManager.addMapping("upRM", new KeyTrigger(KeyInput.KEY_PGUP)); - inputManager.addMapping("downRM", new KeyTrigger(KeyInput.KEY_PGDN)); - } - - private void createTerrain(Node rootNode) { - Material matRock = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = null; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - } catch (Exception e) { - e.printStackTrace(); - } - TerrainQuad terrain - = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(5, 5, 5)); - terrain.setLocalTranslation(new Vector3f(0, -30, 0)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(terrain); - - } - //This part is to emulate tides, slightly varying the height of the water plane - private float time = 0.0f; - private float waterHeight = 0.0f; - final private float initialWaterHeight = 90f;//0.8f; - private boolean uw = false; - - @Override - public void simpleUpdate(float tpf) { - super.simpleUpdate(tpf); - // box.updateGeometricState(); - time += tpf; - waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f; - water.setWaterHeight(initialWaterHeight + waterHeight); - uw = water.isUnderWater(); - updateAudio(); - } - - protected void setText(int x, int y, String text) { - BitmapText txt2 = new BitmapText(guiFont); - txt2.setText(text); - txt2.setLocalTranslation(x, cam.getHeight() - y, 0); - txt2.setColor(ColorRGBA.Red); - guiNode.attachChild(txt2); - } - - /** - * Update the audio settings (dry filter and reverb) - * based on boolean fields ({@code uw} and {@code useDryFilter}). - */ - protected void updateAudio() { - Filter newDryFilter; - if (!useDryFilter) { - newDryFilter = null; - } else if (uw) { - newDryFilter = underWaterAudioFilter; - } else { - newDryFilter = aboveWaterAudioFilter; - } - Filter oldDryFilter = waves.getDryFilter(); - if (oldDryFilter != newDryFilter) { - System.out.println("dry filter : " + newDryFilter); - waves.setDryFilter(newDryFilter); - } - - boolean newReverbEnabled = !uw; - boolean oldReverbEnabled = waves.isReverbEnabled(); - if (oldReverbEnabled != newReverbEnabled) { - System.out.println("reverb enabled : " + newReverbEnabled); - waves.setReverbEnabled(newReverbEnabled); - } - } -} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java b/jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java deleted file mode 100644 index 3ac2c47ba0..0000000000 --- a/jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ -package jme3test.water; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.asset.plugins.ZipLocator; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.scene.Spatial; -import com.jme3.util.SkyFactory; -import com.jme3.water.WaterFilter; -import java.io.File; - -public class TestPostWaterLake extends SimpleApplication { - - private static boolean useHttp = false; - - public static void main(String[] args) { - TestPostWaterLake app = new TestPostWaterLake(); - app.start(); - } - - @Override - public void simpleInitApp() { - File file = new File("wildhouse.zip"); - if (!file.exists()) { - useHttp = true; - } - - this.flyCam.setMoveSpeed(10); - cam.setLocation(new Vector3f(-27.0f, 1.0f, 75.0f)); - // cam.setRotation(new Quaternion(0.03f, 0.9f, 0f, 0.4f)); - - // load sky - rootNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - - // create the geometry and attach it - // load the level from zip or http zip - if (useHttp) { - assetManager.registerLocator( - "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", - HttpZipLocator.class); - } else { - assetManager.registerLocator("wildhouse.zip", ZipLocator.class); - } - Spatial scene = assetManager.loadModel("main.scene"); - rootNode.attachChild(scene); - - DirectionalLight sun = new DirectionalLight(); - Vector3f lightDir = new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - scene.addLight(sun); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - final WaterFilter water = new WaterFilter(rootNode, lightDir); - water.setWaterHeight(-20); - water.setUseFoam(false); - water.setUseRipples(false); - water.setDeepWaterColor(ColorRGBA.Brown); - water.setWaterColor(ColorRGBA.Brown.mult(2.0f)); - water.setWaterTransparency(0.2f); - water.setMaxAmplitude(0.3f); - water.setWaveScale(0.008f); - water.setSpeed(0.7f); - water.setShoreHardness(1.0f); - water.setRefractionConstant(0.2f); - water.setShininess(0.3f); - water.setSunScale(1.0f); - water.setColorExtinction(new Vector3f(10.0f, 20.0f, 30.0f)); - fpp.addFilter(water); - viewPort.addProcessor(fpp); - - inputManager.addListener(new ActionListener() { - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - if(isPressed){ - if(water.isUseHQShoreline()){ - water.setUseHQShoreline(false); - }else{ - water.setUseHQShoreline(true); - } - } - } - }, "HQ"); - - inputManager.addMapping("HQ", new KeyTrigger(KeyInput.KEY_SPACE)); - } -} diff --git a/jme3-examples/src/main/java/jme3test/water/TestSceneWater.java b/jme3-examples/src/main/java/jme3test/water/TestSceneWater.java deleted file mode 100644 index c0f29cff8d..0000000000 --- a/jme3-examples/src/main/java/jme3test/water/TestSceneWater.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package jme3test.water; - -import com.jme3.app.SimpleApplication; -import com.jme3.asset.plugins.HttpZipLocator; -import com.jme3.asset.plugins.ZipLocator; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.*; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.RectangleMesh; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.SkyFactory; -import com.jme3.water.SimpleWaterProcessor; -import java.io.File; - -public class TestSceneWater extends SimpleApplication { - - // set default for applets - private static boolean useHttp = false; - - public static void main(String[] args) { - - TestSceneWater app = new TestSceneWater(); - app.start(); - } - - @Override - public void simpleInitApp() { - File file = new File("wildhouse.zip"); - if (!file.exists()) { - useHttp = true; - } - - this.flyCam.setMoveSpeed(10); - Node mainScene=new Node(); - cam.setLocation(new Vector3f(-27.0f, 1.0f, 75.0f)); - cam.setRotation(new Quaternion(0.03f, 0.9f, 0f, 0.4f)); - - // load sky - mainScene.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - - - // create the geometry and attach it - // load the level from zip or http zip - if (useHttp) { - assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", HttpZipLocator.class); - } else { - assetManager.registerLocator("wildhouse.zip", ZipLocator.class); - } - Spatial scene = assetManager.loadModel("main.scene"); - - DirectionalLight sun = new DirectionalLight(); - Vector3f lightDir=new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - scene.addLight(sun); - - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - //add lightPos Geometry - Sphere lite=new Sphere(8, 8, 3.0f); - Geometry lightSphere=new Geometry("lightsphere", lite); - lightSphere.setMaterial(mat); - Vector3f lightPos=lightDir.multLocal(-400); - lightSphere.setLocalTranslation(lightPos); - rootNode.attachChild(lightSphere); - - - SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager); - waterProcessor.setReflectionScene(mainScene); - waterProcessor.setDebug(false); - waterProcessor.setLightPosition(lightPos); - waterProcessor.setRefractionClippingOffset(1.0f); - - - //setting the water plane - Vector3f waterLocation=new Vector3f(0,-20,0); - waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y))); - WaterUI waterUi=new WaterUI(inputManager, waterProcessor); - waterProcessor.setWaterColor(ColorRGBA.Brown); - waterProcessor.setDebug(true); - //lower render size for higher performance -// waterProcessor.setRenderSize(128,128); - //raise depth to see through water -// waterProcessor.setWaterDepth(20); - //lower the distortion scale if the waves appear too strong -// waterProcessor.setDistortionScale(0.1f); - //lower the speed of the waves if they are too fast -// waterProcessor.setWaveSpeed(0.01f); - - RectangleMesh rect = new RectangleMesh( - new Vector3f(-200, -20, 250), - new Vector3f(200, -20, 250), - new Vector3f(-200, -20, -150)); - - //the texture coordinates define the general size of the waves - rect.scaleTextureCoordinates(new Vector2f(6f, 6f)); - - Geometry water = new Geometry("water", rect); - water.setShadowMode(ShadowMode.Receive); - water.setMaterial(waterProcessor.getMaterial()); - - rootNode.attachChild(water); - - viewPort.addProcessor(waterProcessor); - - mainScene.attachChild(scene); - rootNode.attachChild(mainScene); - } -} diff --git a/jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java b/jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java deleted file mode 100644 index 5bc6604a91..0000000000 --- a/jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.water; - -import com.jme3.app.SimpleApplication; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.SkyFactory; -import com.jme3.water.SimpleWaterProcessor; - -/** - * - * @author normenhansen - */ -public class TestSimpleWater extends SimpleApplication implements ActionListener { - - private Material mat; - private Spatial waterPlane; - private Geometry lightSphere; - private SimpleWaterProcessor waterProcessor; - private Node sceneNode; - private boolean useWater = true; - final private Vector3f lightPos = new Vector3f(33,12,-29); - - - public static void main(String[] args) { - TestSimpleWater app = new TestSimpleWater(); - app.start(); - } - - @Override - public void simpleInitApp() { - initInput(); - initScene(); - - //create processor - waterProcessor = new SimpleWaterProcessor(assetManager); - waterProcessor.setReflectionScene(sceneNode); - waterProcessor.setDebug(true); - viewPort.addProcessor(waterProcessor); - - waterProcessor.setLightPosition(lightPos); - - //create water quad - //waterPlane = waterProcessor.createWaterGeometry(100, 100); - waterPlane = assetManager.loadModel("Models/WaterTest/WaterTest.mesh.xml"); - waterPlane.setMaterial(waterProcessor.getMaterial()); - waterPlane.setLocalScale(40); - waterPlane.setLocalTranslation(-5, 0, 5); - - rootNode.attachChild(waterPlane); - } - - private void initScene() { - //init cam location - cam.setLocation(new Vector3f(0, 10, 10)); - cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - //init scene - sceneNode = new Node("Scene"); - mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); - Box b = new Box(1, 1, 1); - Geometry geom = new Geometry("Box", b); - geom.setMaterial(mat); - sceneNode.attachChild(geom); - - // load sky - sceneNode.attachChild(SkyFactory.createSky(assetManager, - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - rootNode.attachChild(sceneNode); - - //add lightPos Geometry - Sphere lite=new Sphere(8, 8, 3.0f); - lightSphere=new Geometry("lightsphere", lite); - lightSphere.setMaterial(mat); - lightSphere.setLocalTranslation(lightPos); - rootNode.attachChild(lightSphere); - } - - protected void initInput() { - flyCam.setMoveSpeed(3); - //init input - inputManager.addMapping("use_water", new KeyTrigger(KeyInput.KEY_O)); - inputManager.addListener(this, "use_water"); - inputManager.addMapping("lightup", new KeyTrigger(KeyInput.KEY_T)); - inputManager.addListener(this, "lightup"); - inputManager.addMapping("lightdown", new KeyTrigger(KeyInput.KEY_G)); - inputManager.addListener(this, "lightdown"); - inputManager.addMapping("lightleft", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addListener(this, "lightleft"); - inputManager.addMapping("lightright", new KeyTrigger(KeyInput.KEY_K)); - inputManager.addListener(this, "lightright"); - inputManager.addMapping("lightforward", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addListener(this, "lightforward"); - inputManager.addMapping("lightback", new KeyTrigger(KeyInput.KEY_J)); - inputManager.addListener(this, "lightback"); - } - - @Override - public void simpleUpdate(float tpf) { - fpsText.setText("Light Position: "+lightPos.toString()+" Change Light position with [U], [H], [J], [K] and [T], [G] Turn off water with [O]"); - lightSphere.setLocalTranslation(lightPos); - waterProcessor.setLightPosition(lightPos); - } - - @Override - public void onAction(String name, boolean value, float tpf) { - if (name.equals("use_water") && value) { - if (!useWater) { - useWater = true; - waterPlane.setMaterial(waterProcessor.getMaterial()); - } else { - useWater = false; - waterPlane.setMaterial(mat); - } - } else if (name.equals("lightup") && value) { - lightPos.y++; - } else if (name.equals("lightdown") && value) { - lightPos.y--; - } else if (name.equals("lightleft") && value) { - lightPos.x--; - } else if (name.equals("lightright") && value) { - lightPos.x++; - } else if (name.equals("lightforward") && value) { - lightPos.z--; - } else if (name.equals("lightback") && value) { - lightPos.z++; - } - } -} diff --git a/jme3-examples/src/main/java/jme3test/water/WaterUI.java b/jme3-examples/src/main/java/jme3test/water/WaterUI.java deleted file mode 100644 index f2713d885c..0000000000 --- a/jme3-examples/src/main/java/jme3test/water/WaterUI.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package jme3test.water; - -import com.jme3.input.InputManager; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.water.SimpleWaterProcessor; - -/** - * - * @author nehon - */ -public class WaterUI { - private SimpleWaterProcessor processor; - public WaterUI(InputManager inputManager, SimpleWaterProcessor proc) { - processor=proc; - - - System.out.println("----------------- Water UI Debugger --------------------"); - System.out.println("-- Water transparency : press Y to increase, H to decrease"); - System.out.println("-- Water depth : press U to increase, J to decrease"); -// System.out.println("-- AO scale : press I to increase, K to decrease"); -// System.out.println("-- AO bias : press O to increase, P to decrease"); -// System.out.println("-- Toggle AO on/off : press space bar"); -// System.out.println("-- Use only AO : press Num pad 0"); -// System.out.println("-- Output config declaration : press P"); - System.out.println("-------------------------------------------------------"); - - inputManager.addMapping("transparencyUp", new KeyTrigger(KeyInput.KEY_Y)); - inputManager.addMapping("transparencyDown", new KeyTrigger(KeyInput.KEY_H)); - inputManager.addMapping("depthUp", new KeyTrigger(KeyInput.KEY_U)); - inputManager.addMapping("depthDown", new KeyTrigger(KeyInput.KEY_J)); -// inputManager.addMapping("scaleUp", new KeyTrigger(KeyInput.KEY_I)); -// inputManager.addMapping("scaleDown", new KeyTrigger(KeyInput.KEY_K)); -// inputManager.addMapping("biasUp", new KeyTrigger(KeyInput.KEY_O)); -// inputManager.addMapping("biasDown", new KeyTrigger(KeyInput.KEY_L)); -// inputManager.addMapping("outputConfig", new KeyTrigger(KeyInput.KEY_P)); -// inputManager.addMapping("toggleUseAO", new KeyTrigger(KeyInput.KEY_SPACE)); -// inputManager.addMapping("toggleUseOnlyAo", new KeyTrigger(KeyInput.KEY_NUMPAD0)); - -// ActionListener acl = new ActionListener() { -// -// public void onAction(String name, boolean keyPressed, float tpf) { -// -// if (name.equals("toggleUseAO") && keyPressed) { -// ssaoConfig.setUseAo(!ssaoConfig.isUseAo()); -// System.out.println("use AO : "+ssaoConfig.isUseAo()); -// } -// if (name.equals("toggleUseOnlyAo") && keyPressed) { -// ssaoConfig.setUseOnlyAo(!ssaoConfig.isUseOnlyAo()); -// System.out.println("use Only AO : "+ssaoConfig.isUseOnlyAo()); -// -// } -// if (name.equals("outputConfig") && keyPressed) { -// System.out.println("new SSAOConfig("+ssaoConfig.getSampleRadius()+"f,"+ssaoConfig.getIntensity()+"f,"+ssaoConfig.getScale()+"f,"+ssaoConfig.getBias()+"f,"+ssaoConfig.isUseOnlyAo()+","+ssaoConfig.isUseAo()+");"); -// } -// -// } -// }; - - AnalogListener anl = new AnalogListener() { - - @Override - public void onAnalog(String name, float value, float tpf) { - if (name.equals("transparencyUp")) { - processor.setWaterTransparency(processor.getWaterTransparency()+0.001f); - System.out.println("Water transparency : "+processor.getWaterTransparency()); - } - if (name.equals("transparencyDown")) { - processor.setWaterTransparency(processor.getWaterTransparency()-0.001f); - System.out.println("Water transparency : "+processor.getWaterTransparency()); - } - if (name.equals("depthUp")) { - processor.setWaterDepth(processor.getWaterDepth()+0.001f); - System.out.println("Water depth : "+processor.getWaterDepth()); - } - if (name.equals("depthDown")) { - processor.setWaterDepth(processor.getWaterDepth()-0.001f); - System.out.println("Water depth : "+processor.getWaterDepth()); - } - - } - }; - // inputManager.addListener(acl,"toggleUseAO","toggleUseOnlyAo","outputConfig"); - inputManager.addListener(anl, "transparencyUp","transparencyDown","depthUp","depthDown"); - - } - - - -} diff --git a/jme3-examples/src/main/java/jme3test/water/package-info.java b/jme3-examples/src/main/java/jme3test/water/package-info.java deleted file mode 100644 index 8885d8452b..0000000000 --- a/jme3-examples/src/main/java/jme3test/water/package-info.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/** - * example apps and non-automated tests for water effects - */ -package jme3test.water; From d8d827b73d0d0d9afd06527edc854c96ddd11580 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Sat, 23 Sep 2023 10:31:37 -0500 Subject: [PATCH 14/18] Revert "merging new files." This reverts commit 1bda3f0cd20e6d052c9ee3d508e644221b53adc8. --- .../java/com/jme3/system/MonitorInfo.java | 66 +++ .../main/java/com/jme3/system/Monitors.java | 105 ++++ .../jme3test/app/state/RootNodeState.java | 54 ++ .../jme3test/app/state/TestAppStates.java | 107 ++++ .../java/jme3test/app/state/package-info.java | 35 ++ .../java/jme3test/asset/TestAssetCache.java | 230 ++++++++ .../java/jme3test/asset/TestOnlineJar.java | 82 +++ .../java/jme3test/asset/TestUrlLoading.java | 80 +++ .../java/jme3test/asset/package-info.java | 35 ++ .../main/java/jme3test/audio/TestAmbient.java | 88 +++ .../main/java/jme3test/audio/TestDoppler.java | 94 +++ .../java/jme3test/audio/TestIssue1761.java | 86 +++ .../java/jme3test/audio/TestMusicPlayer.form | 117 ++++ .../java/jme3test/audio/TestMusicPlayer.java | 311 ++++++++++ .../jme3test/audio/TestMusicStreaming.java | 60 ++ .../src/main/java/jme3test/audio/TestOgg.java | 70 +++ .../main/java/jme3test/audio/TestReverb.java | 84 +++ .../src/main/java/jme3test/audio/TestWav.java | 64 +++ .../java/jme3test/audio/package-info.java | 35 ++ .../main/java/jme3test/awt/AppHarness.java | 155 +++++ .../main/java/jme3test/awt/TestApplet.java | 151 +++++ .../main/java/jme3test/awt/TestAwtPanels.java | 152 +++++ .../main/java/jme3test/awt/TestCanvas.java | 283 +++++++++ .../java/jme3test/awt/TestSafeCanvas.java | 68 +++ .../main/java/jme3test/awt/package-info.java | 36 ++ .../java/jme3test/batching/TestBatchNode.java | 162 ++++++ .../batching/TestBatchNodeCluster.java | 362 ++++++++++++ .../jme3test/batching/TestBatchNodeTower.java | 250 ++++++++ .../java/jme3test/batching/package-info.java | 36 ++ .../jme3test/bounding/TestRayCollision.java | 65 +++ .../java/jme3test/bounding/package-info.java | 35 ++ .../java/jme3test/bullet/BombControl.java | 221 +++++++ .../jme3test/bullet/PhysicsHoverControl.java | 258 +++++++++ .../jme3test/bullet/PhysicsTestHelper.java | 371 ++++++++++++ .../jme3test/bullet/TestAttachDriver.java | 300 ++++++++++ .../bullet/TestAttachGhostObject.java | 129 +++++ .../jme3test/bullet/TestBetterCharacter.java | 297 ++++++++++ .../java/jme3test/bullet/TestBoneRagdoll.java | 244 ++++++++ .../java/jme3test/bullet/TestBrickTower.java | 251 ++++++++ .../java/jme3test/bullet/TestBrickWall.java | 204 +++++++ .../main/java/jme3test/bullet/TestCcd.java | 153 +++++ .../jme3test/bullet/TestCollisionGroups.java | 107 ++++ .../bullet/TestCollisionListener.java | 95 +++ .../bullet/TestCollisionShapeFactory.java | 137 +++++ .../java/jme3test/bullet/TestFancyCar.java | 226 ++++++++ .../java/jme3test/bullet/TestGhostObject.java | 117 ++++ .../jme3test/bullet/TestHoveringTank.java | 304 ++++++++++ .../java/jme3test/bullet/TestIssue1120.java | 214 +++++++ .../java/jme3test/bullet/TestIssue1125.java | 229 ++++++++ .../java/jme3test/bullet/TestIssue877.java | 148 +++++ .../java/jme3test/bullet/TestIssue883.java | 87 +++ .../TestKinematicAddToPhysicsSpaceIssue.java | 107 ++++ .../jme3test/bullet/TestLocalPhysics.java | 122 ++++ .../java/jme3test/bullet/TestPhysicsCar.java | 225 ++++++++ .../jme3test/bullet/TestPhysicsCharacter.java | 212 +++++++ .../bullet/TestPhysicsHingeJoint.java | 110 ++++ .../jme3test/bullet/TestPhysicsRayCast.java | 69 +++ .../jme3test/bullet/TestPhysicsReadWrite.java | 153 +++++ .../src/main/java/jme3test/bullet/TestQ3.java | 183 ++++++ .../java/jme3test/bullet/TestRagDoll.java | 152 +++++ .../jme3test/bullet/TestRagdollCharacter.java | 246 ++++++++ .../jme3test/bullet/TestSimplePhysics.java | 111 ++++ .../java/jme3test/bullet/TestSweepTest.java | 77 +++ .../java/jme3test/bullet/TestWalkingChar.java | 460 +++++++++++++++ .../java/jme3test/bullet/package-info.java | 35 ++ .../bullet/shape/TestGimpactShape.java | 342 +++++++++++ .../jme3test/bullet/shape/package-info.java | 36 ++ .../java/jme3test/collision/RayTrace.java | 101 ++++ .../jme3test/collision/TestMousePick.java | 153 +++++ .../jme3test/collision/TestRayCasting.java | 95 +++ .../collision/TestTriangleCollision.java | 127 ++++ .../java/jme3test/collision/package-info.java | 36 ++ .../jme3test/conversion/TestMipMapGen.java | 93 +++ .../jme3test/conversion/package-info.java | 35 ++ .../java/jme3test/effect/TestEverything.java | 201 +++++++ .../jme3test/effect/TestExplosionEffect.java | 282 +++++++++ .../java/jme3test/effect/TestIssue1773.java | 303 ++++++++++ .../jme3test/effect/TestMovingParticle.java | 96 ++++ .../effect/TestParticleExportingCloning.java | 74 +++ .../java/jme3test/effect/TestPointSprite.java | 91 +++ .../jme3test/effect/TestSoftParticles.java | 184 ++++++ .../java/jme3test/effect/package-info.java | 35 ++ .../jme3test/export/TestAssetLinkNode.java | 131 +++++ .../java/jme3test/export/TestIssue2068.java | 96 ++++ .../java/jme3test/export/TestOgreConvert.java | 81 +++ .../java/jme3test/export/package-info.java | 35 ++ .../main/java/jme3test/games/CubeField.java | 414 +++++++++++++ .../java/jme3test/games/RollingTheMonkey.java | 411 +++++++++++++ .../java/jme3test/games/WorldOfInception.java | 535 +++++++++++++++++ .../java/jme3test/games/package-info.java | 35 ++ .../java/jme3test/gui/TestBitmapFont.java | 134 +++++ .../jme3test/gui/TestBitmapFontAlignment.java | 144 +++++ .../jme3test/gui/TestBitmapFontLayout.java | 543 ++++++++++++++++++ .../java/jme3test/gui/TestBitmapText3D.java | 70 +++ .../main/java/jme3test/gui/TestCursor.java | 77 +++ .../src/main/java/jme3test/gui/TestOrtho.java | 58 ++ .../java/jme3test/gui/TestRtlBitmapText.java | 70 +++ .../java/jme3test/gui/TestSoftwareMouse.java | 136 +++++ .../main/java/jme3test/gui/TestZOrder.java | 64 +++ .../main/java/jme3test/gui/package-info.java | 36 ++ .../jme3test/helloworld/HelloAnimation.java | 123 ++++ .../java/jme3test/helloworld/HelloAssets.java | 91 +++ .../java/jme3test/helloworld/HelloAudio.java | 84 +++ .../jme3test/helloworld/HelloCollision.java | 190 ++++++ .../jme3test/helloworld/HelloEffects.java | 112 ++++ .../java/jme3test/helloworld/HelloInput.java | 112 ++++ .../java/jme3test/helloworld/HelloJME3.java | 61 ++ .../java/jme3test/helloworld/HelloLoop.java | 71 +++ .../jme3test/helloworld/HelloMaterial.java | 104 ++++ .../java/jme3test/helloworld/HelloNode.java | 85 +++ .../jme3test/helloworld/HelloPhysics.java | 225 ++++++++ .../jme3test/helloworld/HelloPicking.java | 182 ++++++ .../jme3test/helloworld/HelloTerrain.java | 125 ++++ .../helloworld/HelloTerrainCollision.java | 228 ++++++++ .../jme3test/helloworld/package-info.java | 35 ++ .../java/jme3test/input/TestCameraNode.java | 157 +++++ .../java/jme3test/input/TestChaseCamera.java | 162 ++++++ .../input/TestChaseCameraAppState.java | 156 +++++ .../java/jme3test/input/TestControls.java | 75 +++ .../java/jme3test/input/TestIssue1692.java | 134 +++++ .../java/jme3test/input/TestJoystick.java | 493 ++++++++++++++++ .../jme3test/input/combomoves/ComboMove.java | 143 +++++ .../input/combomoves/ComboMoveExecution.java | 126 ++++ .../input/combomoves/TestComboMoves.java | 217 +++++++ .../input/combomoves/package-info.java | 35 ++ .../java/jme3test/input/package-info.java | 35 ++ .../jme3test/light/ShadowTestUIManager.java | 181 ++++++ .../java/jme3test/light/TestColorApp.java | 88 +++ .../jme3test/light/TestConeVSFrustum.java | 263 +++++++++ .../light/TestDirectionalLightShadow.java | 377 ++++++++++++ .../light/TestEnvironmentMapping.java | 98 ++++ .../java/jme3test/light/TestGltfUnlit.java | 61 ++ .../light/TestLightControl2Directional.java | 169 ++++++ .../jme3test/light/TestLightControl2Spot.java | 178 ++++++ .../light/TestLightControlDirectional.java | 168 ++++++ .../jme3test/light/TestLightControlSpot.java | 177 ++++++ .../java/jme3test/light/TestLightRadius.java | 109 ++++ .../java/jme3test/light/TestLightingFog.java | 79 +++ .../java/jme3test/light/TestManyLights.java | 54 ++ .../jme3test/light/TestManyLightsSingle.java | 272 +++++++++ .../java/jme3test/light/TestObbVsBounds.java | 300 ++++++++++ ...stPointDirectionalAndSpotLightShadows.java | 175 ++++++ .../jme3test/light/TestPointLightShadows.java | 133 +++++ .../java/jme3test/light/TestShadowBug.java | 129 +++++ .../java/jme3test/light/TestShadowsPerf.java | 173 ++++++ .../jme3test/light/TestSimpleLighting.java | 124 ++++ .../java/jme3test/light/TestSpotLight.java | 155 +++++ .../jme3test/light/TestSpotLightShadows.java | 200 +++++++ .../jme3test/light/TestSpotLightTerrain.java | 206 +++++++ .../java/jme3test/light/TestTangentCube.java | 95 +++ .../java/jme3test/light/TestTangentGen.java | 134 +++++ .../jme3test/light/TestTangentGenBadUV.java | 109 ++++ .../java/jme3test/light/TestTangentSpace.java | 131 +++++ .../jme3test/light/TestTransparentShadow.java | 148 +++++ .../jme3test/light/TestTwoSideLighting.java | 122 ++++ .../java/jme3test/light/package-info.java | 35 ++ .../light/pbr/ConsoleProgressReporter.java | 75 +++ .../main/java/jme3test/light/pbr/RefEnv.java | 170 ++++++ .../jme3test/light/pbr/TestIssue1340.java | 92 +++ .../light/pbr/TestIssue1903Compat.java | 91 +++ .../jme3test/light/pbr/TestIssue1903Core.java | 71 +++ .../light/pbr/TestPBRDirectLighting.java | 122 ++++ .../jme3test/light/pbr/TestPBRLighting.java | 221 +++++++ .../java/jme3test/light/pbr/package-info.java | 35 ++ .../java/jme3test/material/TestBumpModel.java | 102 ++++ .../jme3test/material/TestColoredTexture.java | 83 +++ .../jme3test/material/TestGeometryShader.java | 46 ++ .../material/TestMatParamOverride.java | 113 ++++ .../material/TestMaterialCompare.java | 138 +++++ .../jme3test/material/TestNormalMapping.java | 93 +++ .../java/jme3test/material/TestParallax.java | 150 +++++ .../jme3test/material/TestParallaxPBR.java | 155 +++++ .../jme3test/material/TestShaderNodes.java | 43 ++ .../jme3test/material/TestSimpleBumps.java | 93 +++ .../material/TestTessellationShader.java | 73 +++ .../jme3test/material/TestUnshadedModel.java | 44 ++ .../java/jme3test/material/package-info.java | 35 ++ .../java/jme3test/math/TestHalfFloat.java | 55 ++ .../main/java/jme3test/math/package-info.java | 35 ++ .../java/jme3test/model/TestGltfLoading.java | 334 +++++++++++ .../java/jme3test/model/TestHoverTank.java | 96 ++++ .../java/jme3test/model/TestMonkeyHead.java | 100 ++++ .../jme3test/model/TestObjGroupsLoading.java | 119 ++++ .../java/jme3test/model/TestObjLoading.java | 60 ++ .../java/jme3test/model/TestOgreLoading.java | 112 ++++ .../java/jme3test/model/anim/EraseTimer.java | 109 ++++ .../model/anim/TestAnimMigration.java | 277 +++++++++ .../anim/TestAnimMorphSerialization.java | 198 +++++++ .../model/anim/TestAnimSerialization.java | 199 +++++++ .../model/anim/TestAnimationFactory.java | 90 +++ .../jme3test/model/anim/TestArmature.java | 218 +++++++ .../model/anim/TestAttachmentsNode.java | 129 +++++ .../model/anim/TestBaseAnimSerialization.java | 246 ++++++++ .../jme3test/model/anim/TestCustomAnim.java | 152 +++++ .../jme3test/model/anim/TestHWSkinning.java | 132 +++++ .../model/anim/TestHWSkinningOld.java | 112 ++++ .../jme3test/model/anim/TestIssue1395.java | 80 +++ .../model/anim/TestModelExportingCloning.java | 81 +++ .../java/jme3test/model/anim/TestMorph.java | 149 +++++ .../jme3test/model/anim/TestOgreAnim.java | 121 ++++ .../model/anim/TestOgreComplexAnim.java | 135 +++++ .../anim/TestSkeletonControlRefresh.java | 172 ++++++ .../jme3test/model/anim/TestSpatialAnim.java | 85 +++ .../jme3test/model/anim/package-info.java | 35 ++ .../java/jme3test/model/package-info.java | 35 ++ .../jme3test/model/shape/TestBillboard.java | 113 ++++ .../java/jme3test/model/shape/TestBox.java | 57 ++ .../jme3test/model/shape/TestCustomMesh.java | 153 +++++ .../jme3test/model/shape/TestCylinder.java | 66 +++ .../jme3test/model/shape/TestDebugShapes.java | 94 +++ .../model/shape/TestExpandingTorus.java | 71 +++ .../java/jme3test/model/shape/TestSphere.java | 65 +++ .../jme3test/model/shape/package-info.java | 35 ++ .../java/jme3test/network/MovingAverage.java | 63 ++ .../java/jme3test/network/TestChatClient.java | 236 ++++++++ .../network/TestChatClientAndServer.java | 74 +++ .../java/jme3test/network/TestChatServer.java | 237 ++++++++ .../java/jme3test/network/TestLatency.java | 125 ++++ .../java/jme3test/network/TestMessages.java | 90 +++ .../jme3test/network/TestNetworkStress.java | 68 +++ .../java/jme3test/network/TestRemoteCall.java | 119 ++++ .../jme3test/network/TestSerialization.java | 159 +++++ .../java/jme3test/network/TestThroughput.java | 118 ++++ .../java/jme3test/network/package-info.java | 35 ++ .../niftygui/StartScreenController.java | 92 +++ .../java/jme3test/niftygui/TestIssue1013.java | 127 ++++ .../java/jme3test/niftygui/TestIssue99.java | 107 ++++ .../jme3test/niftygui/TestNiftyExamples.java | 67 +++ .../java/jme3test/niftygui/TestNiftyGui.java | 78 +++ .../jme3test/niftygui/TestNiftyToMesh.java | 93 +++ .../java/jme3test/niftygui/package-info.java | 35 ++ .../java/jme3test/opencl/HelloOpenCL.java | 311 ++++++++++ .../jme3test/opencl/TestContextSwitching.java | 254 ++++++++ .../opencl/TestMultipleApplications.java | 169 ++++++ .../jme3test/opencl/TestOpenCLLibraries.java | 401 +++++++++++++ .../opencl/TestVertexBufferSharing.java | 183 ++++++ .../jme3test/opencl/TestWriteToTexture.java | 179 ++++++ .../java/jme3test/opencl/package-info.java | 35 ++ .../src/main/java/jme3test/post/BloomUI.java | 110 ++++ .../java/jme3test/post/LightScatteringUI.java | 140 +++++ .../src/main/java/jme3test/post/SSAOUI.java | 148 +++++ .../main/java/jme3test/post/TestBloom.java | 164 ++++++ .../post/TestBloomAlphaThreshold.java | 182 ++++++ .../java/jme3test/post/TestCartoonEdge.java | 133 +++++ .../jme3test/post/TestContrastAdjustment.java | 220 +++++++ .../java/jme3test/post/TestCrossHatch.java | 159 +++++ .../java/jme3test/post/TestDepthOfField.java | 237 ++++++++ .../jme3test/post/TestFBOPassthrough.java | 118 ++++ .../src/main/java/jme3test/post/TestFog.java | 209 +++++++ .../java/jme3test/post/TestIssue1798.java | 135 +++++ .../jme3test/post/TestLightScattering.java | 104 ++++ .../jme3test/post/TestMultiRenderTarget.java | 235 ++++++++ .../jme3test/post/TestMultiViewsFilters.java | 198 +++++++ .../jme3test/post/TestMultiplesFilters.java | 158 +++++ .../java/jme3test/post/TestPostFilters.java | 174 ++++++ .../post/TestPostFiltersCompositing.java | 117 ++++ .../java/jme3test/post/TestPosterization.java | 137 +++++ .../jme3test/post/TestRenderToCubemap.java | 137 +++++ .../jme3test/post/TestRenderToMemory.java | 270 +++++++++ .../jme3test/post/TestRenderToTexture.java | 149 +++++ .../src/main/java/jme3test/post/TestSSAO.java | 96 ++++ .../main/java/jme3test/post/TestSSAO2.java | 116 ++++ .../java/jme3test/post/TestToneMapFilter.java | 147 +++++ .../post/TestTransparentCartoonEdge.java | 98 ++++ .../jme3test/post/TestTransparentSSAO.java | 78 +++ .../main/java/jme3test/post/package-info.java | 35 ++ .../renderer/TestAlphaToCoverage.java | 54 ++ .../java/jme3test/renderer/TestAspectFov.java | 126 ++++ .../jme3test/renderer/TestAspectRatio.java | 68 +++ .../renderer/TestBackgroundImage.java | 145 +++++ .../jme3test/renderer/TestBlendEquations.java | 142 +++++ .../jme3test/renderer/TestContextRestart.java | 129 +++++ .../renderer/TestDepthFuncChange.java | 90 +++ .../jme3test/renderer/TestDepthStencil.java | 155 +++++ .../TestInconsistentCompareDetection.java | 121 ++++ .../java/jme3test/renderer/TestIssue2011.java | 107 ++++ .../java/jme3test/renderer/TestIssue37.java | 110 ++++ .../java/jme3test/renderer/TestIssue798.java | 156 +++++ .../java/jme3test/renderer/TestIssue801.java | 87 +++ .../java/jme3test/renderer/TestLineWidth.java | 103 ++++ .../jme3test/renderer/TestMultiViews.java | 110 ++++ .../renderer/TestParallelProjection.java | 85 +++ .../jme3test/renderer/TestSplitScreen.java | 114 ++++ .../java/jme3test/renderer/package-info.java | 35 ++ .../scene/TestLineWidthRenderState.java | 87 +++ .../jme3test/scene/TestRefreshFlagBug.java | 45 ++ .../java/jme3test/scene/TestSceneLoading.java | 98 ++++ .../java/jme3test/scene/TestSceneStress.java | 162 ++++++ .../java/jme3test/scene/TestUserData.java | 58 ++ .../scene/instancing/TestInstanceNode.java | 192 +++++++ .../instancing/TestInstanceNodeWithLight.java | 62 ++ ...tInstancedNodeAttachDetachWithPicking.java | 195 +++++++ ...ancedNodeAttachDetachWithShadowFilter.java | 176 ++++++ .../TestInstancingWithWaterFilter.java | 90 +++ .../scene/instancing/package-info.java | 35 ++ .../java/jme3test/scene/package-info.java | 35 ++ .../java/jme3test/stress/TestBatchLod.java | 88 +++ .../java/jme3test/stress/TestLeakingGL.java | 92 +++ .../jme3test/stress/TestLodGeneration.java | 208 +++++++ .../java/jme3test/stress/TestLodStress.java | 91 +++ .../stress/TestParallelTangentGeneration.java | 81 +++ .../stress/TestShaderNodesStress.java | 109 ++++ .../java/jme3test/stress/package-info.java | 35 ++ .../terrain/PBRTerrainAdvancedTest.java | 457 +++++++++++++++ .../java/jme3test/terrain/PBRTerrainTest.java | 365 ++++++++++++ .../terrain/TerrainFractalGridTest.java | 141 +++++ .../terrain/TerrainGridAlphaMapTest.java | 359 ++++++++++++ .../terrain/TerrainGridSerializationTest.java | 184 ++++++ .../jme3test/terrain/TerrainGridTest.java | 232 ++++++++ .../terrain/TerrainGridTileLoaderTest.java | 243 ++++++++ .../java/jme3test/terrain/TerrainTest.java | 216 +++++++ .../jme3test/terrain/TerrainTestAdvanced.java | 340 +++++++++++ .../jme3test/terrain/TerrainTestAndroid.java | 197 +++++++ .../terrain/TerrainTestCollision.java | 328 +++++++++++ .../terrain/TerrainTestModifyHeight.java | 339 +++++++++++ .../terrain/TerrainTestReadWrite.java | 292 ++++++++++ .../jme3test/terrain/TerrainTestTile.java | 372 ++++++++++++ .../java/jme3test/terrain/package-info.java | 35 ++ .../texture/TestAnisotropicFilter.java | 117 ++++ .../jme3test/texture/TestImageRaster.java | 139 +++++ .../java/jme3test/texture/TestSkyLoading.java | 60 ++ .../jme3test/texture/TestSkyRotation.java | 147 +++++ .../java/jme3test/texture/TestTexture3D.java | 131 +++++ .../texture/TestTexture3DLoading.java | 81 +++ .../jme3test/texture/TestTextureArray.java | 87 +++ .../texture/TestTextureArrayCompressed.java | 87 +++ .../jme3test/texture/dds/TestLoadDds.java | 95 +++ .../jme3test/texture/ktx/TestLoadKtx.java | 108 ++++ .../jme3test/texture/ktx/package-info.java | 36 ++ .../java/jme3test/texture/package-info.java | 35 ++ .../java/jme3test/tools/TestSaveGame.java | 85 +++ .../java/jme3test/tools/TestTextureAtlas.java | 90 +++ .../java/jme3test/tools/package-info.java | 35 ++ .../jme3test/water/TestMultiPostWater.java | 216 +++++++ .../java/jme3test/water/TestPostWater.java | 326 +++++++++++ .../jme3test/water/TestPostWaterLake.java | 127 ++++ .../java/jme3test/water/TestSceneWater.java | 147 +++++ .../java/jme3test/water/TestSimpleWater.java | 169 ++++++ .../src/main/java/jme3test/water/WaterUI.java | 123 ++++ .../java/jme3test/water/package-info.java | 35 ++ 340 files changed, 47946 insertions(+) create mode 100644 jme3-core/src/main/java/com/jme3/system/MonitorInfo.java create mode 100644 jme3-core/src/main/java/com/jme3/system/Monitors.java create mode 100644 jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java create mode 100644 jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java create mode 100644 jme3-examples/src/main/java/jme3test/app/state/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java create mode 100644 jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java create mode 100644 jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/asset/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestAmbient.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestDoppler.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestOgg.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestReverb.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/TestWav.java create mode 100644 jme3-examples/src/main/java/jme3test/audio/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/awt/AppHarness.java create mode 100644 jme3-examples/src/main/java/jme3test/awt/TestApplet.java create mode 100644 jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java create mode 100644 jme3-examples/src/main/java/jme3test/awt/TestCanvas.java create mode 100644 jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java create mode 100644 jme3-examples/src/main/java/jme3test/awt/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java create mode 100644 jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java create mode 100644 jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java create mode 100644 jme3-examples/src/main/java/jme3test/batching/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java create mode 100644 jme3-examples/src/main/java/jme3test/bounding/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/BombControl.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCcd.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestQ3.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java create mode 100644 jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/collision/RayTrace.java create mode 100644 jme3-examples/src/main/java/jme3test/collision/TestMousePick.java create mode 100644 jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java create mode 100644 jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java create mode 100644 jme3-examples/src/main/java/jme3test/collision/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java create mode 100644 jme3-examples/src/main/java/jme3test/conversion/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/TestEverything.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java create mode 100644 jme3-examples/src/main/java/jme3test/effect/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java create mode 100644 jme3-examples/src/main/java/jme3test/export/TestIssue2068.java create mode 100644 jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java create mode 100644 jme3-examples/src/main/java/jme3test/export/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/games/CubeField.java create mode 100644 jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java create mode 100644 jme3-examples/src/main/java/jme3test/games/WorldOfInception.java create mode 100644 jme3-examples/src/main/java/jme3test/games/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestCursor.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestOrtho.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/TestZOrder.java create mode 100644 jme3-examples/src/main/java/jme3test/gui/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java create mode 100644 jme3-examples/src/main/java/jme3test/helloworld/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/input/TestCameraNode.java create mode 100644 jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java create mode 100644 jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java create mode 100644 jme3-examples/src/main/java/jme3test/input/TestControls.java create mode 100644 jme3-examples/src/main/java/jme3test/input/TestIssue1692.java create mode 100644 jme3-examples/src/main/java/jme3test/input/TestJoystick.java create mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java create mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java create mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java create mode 100644 jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/input/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestColorApp.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightRadius.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestLightingFog.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestManyLights.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestShadowBug.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestSpotLight.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentCube.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentGen.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java create mode 100644 jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java create mode 100644 jme3-examples/src/main/java/jme3test/light/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java create mode 100644 jme3-examples/src/main/java/jme3test/light/pbr/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestBumpModel.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestParallax.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java create mode 100644 jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java create mode 100644 jme3-examples/src/main/java/jme3test/material/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java create mode 100644 jme3-examples/src/main/java/jme3test/math/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/model/TestHoverTank.java create mode 100644 jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java create mode 100644 jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/model/TestObjLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java create mode 100644 jme3-examples/src/main/java/jme3test/model/anim/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/model/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestBox.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java create mode 100644 jme3-examples/src/main/java/jme3test/model/shape/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/network/MovingAverage.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestChatClient.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestChatServer.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestLatency.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestMessages.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestSerialization.java create mode 100644 jme3-examples/src/main/java/jme3test/network/TestThroughput.java create mode 100644 jme3-examples/src/main/java/jme3test/network/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java create mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java create mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java create mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java create mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java create mode 100644 jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java create mode 100644 jme3-examples/src/main/java/jme3test/niftygui/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java create mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestContextSwitching.java create mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java create mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java create mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java create mode 100644 jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java create mode 100644 jme3-examples/src/main/java/jme3test/opencl/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/post/BloomUI.java create mode 100644 jme3-examples/src/main/java/jme3test/post/LightScatteringUI.java create mode 100644 jme3-examples/src/main/java/jme3test/post/SSAOUI.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestBloom.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestFog.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestIssue1798.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestLightScattering.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestPostFilters.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestPosterization.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestSSAO.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestSSAO2.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java create mode 100644 jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java create mode 100644 jme3-examples/src/main/java/jme3test/post/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java create mode 100644 jme3-examples/src/main/java/jme3test/renderer/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/TestUserData.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/scene/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java create mode 100644 jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java create mode 100644 jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java create mode 100644 jme3-examples/src/main/java/jme3test/stress/TestLodStress.java create mode 100644 jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java create mode 100644 jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java create mode 100644 jme3-examples/src/main/java/jme3test/stress/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridSerializationTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainGridTileLoaderTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTest.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestAdvanced.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestAndroid.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestCollision.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java create mode 100644 jme3-examples/src/main/java/jme3test/terrain/package-info.java create mode 100755 jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/texture/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java create mode 100644 jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java create mode 100644 jme3-examples/src/main/java/jme3test/tools/package-info.java create mode 100644 jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java create mode 100644 jme3-examples/src/main/java/jme3test/water/TestPostWater.java create mode 100644 jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java create mode 100644 jme3-examples/src/main/java/jme3test/water/TestSceneWater.java create mode 100644 jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java create mode 100644 jme3-examples/src/main/java/jme3test/water/WaterUI.java create mode 100644 jme3-examples/src/main/java/jme3test/water/package-info.java diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java new file mode 100644 index 0000000000..a7791d37b2 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.system; + +/** + * This class holds information about the monitor that was returned by glfwGetMonitors() calls in + * the context class + * + * @author Kevin Bales + */ +public class MonitorInfo { + + /** + * monitorID - monitor id that was return from Lwjgl3. + */ + public long monitorID = 0; + + /** + * width - width that was return from Lwjgl3. + */ + public int width = 1080; + + /** + * height - height that was return from Lwjgl3. + */ + public int height = 1920; + + /** + * rate - refresh rate that was return from Lwjgl3. + */ + public int rate = 60; + + /** + * primary - indicates if the monitor is the primary monitor. + */ + public boolean primary = false; + + /** + * name - monitor name that was return from Lwjgl3. + */ + public String name = "Generic Monitor"; + +} diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java new file mode 100644 index 0000000000..b834e518f8 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/system/Monitors.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.system; + +import java.util.ArrayList; + +/** + * This class holds all information about all monitors that where return from the glfwGetMonitors() + * call. It stores them into an + * + * @author Kevin Bales + */ +public class Monitors { + + private ArrayList monitors = new ArrayList(); + + public int addNewMonitor(long monitorID) { + MonitorInfo info = new MonitorInfo(); + info.monitorID = monitorID; + monitors.add(info); + return monitors.size() - 1; + } + + /** + * This function returns the size of the monitor ArrayList + * + * @return the + */ + public int size() { + return monitors.size(); + } + + /** + * Call to get monitor information on a certain monitor. + * + * @param pos the position in the arraylist of the monitor information that you want to get. + * @return returns the MonitorInfo data for the monitor called for. + */ + public MonitorInfo get(int pos) { + if (pos < monitors.size()) + return monitors.get(pos); + + return null; + } + + /** + * Set information about this monitor stored in monPos position in the array list. + * + * @param monPos arraylist position of monitor to update + * @param width the current width the monitor is displaying + * @param height the current height the monitor is displaying + * @param rate the current refresh rate the monitor is set to + */ + public void setInfo(int monPos, String name, int width, int height, int rate) { + if (monPos < monitors.size()) { + MonitorInfo info = monitors.get(monPos); + if (info != null) { + info.width = width; + info.height = height; + info.rate = rate; + info.name = name; + } + } + } + + /** + * This function will mark a certain monitor as the primary monitor. + * + * @param monPos the position in the arraylist of which monitor is the primary monitor + */ + public void setPrimaryMonitor(int monPos) { + if (monPos < monitors.size()) { + MonitorInfo info = monitors.get(monPos); + if (info != null) + info.primary = true; + } + + } + + + +} diff --git a/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java b/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java new file mode 100644 index 0000000000..463ada9307 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.app.state; + +import com.jme3.app.state.AbstractAppState; +import com.jme3.scene.Node; + +public class RootNodeState extends AbstractAppState { + + final private Node rootNode = new Node("Root Node"); + + public Node getRootNode(){ + return rootNode; + } + + @Override + public void update(float tpf) { + super.update(tpf); + + rootNode.updateLogicalState(tpf); + rootNode.updateGeometricState(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java b/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java new file mode 100644 index 0000000000..dbc90d1200 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2022 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. + */ + +package jme3test.app.state; + +import com.jme3.app.LegacyApplication; +import com.jme3.niftygui.NiftyJmeDisplay; +import com.jme3.scene.Spatial; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeContext; +import com.jme3.texture.image.ColorSpace; +import jme3test.niftygui.StartScreenController; + +public class TestAppStates extends LegacyApplication { + + public static void main(String[] args){ + TestAppStates app = new TestAppStates(); + app.start(); + } + + @Override + public void start(JmeContext.Type contextType){ + AppSettings settings = new AppSettings(true); + settings.setResolution(1024, 768); + setSettings(settings); + + super.start(contextType); + } + + @Override + public void initialize(){ + super.initialize(); + + System.out.println("Initialize"); + + RootNodeState state = new RootNodeState(); + viewPort.attachScene(state.getRootNode()); + stateManager.attach(state); + + Spatial model = assetManager.loadModel("Models/Teapot/Teapot.obj"); + model.scale(3); + model.setMaterial(assetManager.loadMaterial("Interface/Logo/Logo.j3m")); + state.getRootNode().attachChild(model); + + ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() + ? ColorSpace.sRGB : ColorSpace.Linear; + NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, + inputManager, + audioRenderer, + guiViewPort, + colorSpace); + StartScreenController startScreen = new StartScreenController(this); + niftyDisplay.getNifty().fromXml("Interface/Nifty/HelloJme.xml", "start", + startScreen); + guiViewPort.addProcessor(niftyDisplay); + } + + @Override + public void update(){ + super.update(); + + // do some animation + float tpf = timer.getTimePerFrame(); + + stateManager.update(tpf); + stateManager.render(renderManager); + + // render the viewports + renderManager.render(tpf, context.isRenderable()); + } + + @Override + public void destroy(){ + super.destroy(); + + System.out.println("Destroy"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/app/state/package-info.java b/jme3-examples/src/main/java/jme3test/app/state/package-info.java new file mode 100644 index 0000000000..e16b33942e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/app/state/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for appstates + */ +package jme3test.app.state; diff --git a/jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java b/jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java new file mode 100644 index 0000000000..d7cef54c90 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/asset/TestAssetCache.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.asset; + +import com.jme3.asset.AssetKey; +import com.jme3.asset.AssetProcessor; +import com.jme3.asset.CloneableAssetProcessor; +import com.jme3.asset.CloneableSmartAsset; +import com.jme3.asset.cache.AssetCache; +import com.jme3.asset.cache.SimpleAssetCache; +import com.jme3.asset.cache.WeakRefAssetCache; +import com.jme3.asset.cache.WeakRefCloneAssetCache; +import java.util.ArrayList; +import java.util.List; + +public class TestAssetCache { + + /** + * Counter for asset keys + */ + private static int counter = 0; + + /** + * Dummy data is an asset having 10 KB to put a dent in the garbage collector + */ + private static class DummyData implements CloneableSmartAsset { + + private AssetKey key; + private byte[] data = new byte[10 * 1024]; + + @Override + public DummyData clone(){ + try { + DummyData clone = (DummyData) super.clone(); + clone.data = data.clone(); + return clone; + } catch (CloneNotSupportedException ex) { + throw new AssertionError(); + } + } + + public byte[] getData(){ + return data; + } + + @Override + public AssetKey getKey() { + return key; + } + + @Override + public void setKey(AssetKey key) { + this.key = key; + } + } + + /** + * Dummy key is indexed by a generated ID + */ + private static class DummyKey extends AssetKey implements Cloneable { + + private int id = 0; + + public DummyKey(){ + super("."); + id = counter++; + } + + public DummyKey(int id){ + super("."); + this.id = id; + } + + @Override + public int hashCode(){ + return id; + } + + @Override + public boolean equals(Object other){ + return ((DummyKey)other).id == id; + } + + @Override + public DummyKey clone(){ + return new DummyKey(id); + } + + @Override + public String toString() { + return "ID=" + id; + } + } + + private static void runTest(boolean cloneAssets, boolean smartCache, boolean keepRefs, int limit) { + counter = 0; + List refs = new ArrayList<>(limit); + + AssetCache cache; + AssetProcessor proc = null; + + if (cloneAssets) { + proc = new CloneableAssetProcessor(); + } + + if (smartCache) { + if (cloneAssets) { + cache = new WeakRefCloneAssetCache(); + } else { + cache = new WeakRefAssetCache(); + } + } else { + cache = new SimpleAssetCache(); + } + + System.gc(); + System.gc(); + System.gc(); + System.gc(); + + long memory = Runtime.getRuntime().freeMemory(); + + while (counter < limit){ + // Create a key + DummyKey key = new DummyKey(); + + // Create some data + DummyData data = new DummyData(); + + // Postprocess the data before placing it in the cache. + if (proc != null){ + data = (DummyData) proc.postProcess(key, data); + } + + if (data.key != null){ + // Keeping a hard reference to the key in the cache + // means the asset will never be collected => bug + throw new AssertionError(); + } + + cache.addToCache(key, data); + + // Get the asset from the cache + AssetKey keyToGet = key.clone(); + + // NOTE: Commented out because getFromCache leaks the original key +// DummyData someLoaded = (DummyData) cache.getFromCache(keyToGet); +// if (someLoaded != data){ +// // Failed to get the same asset from the cache => bug +// // Since a hard reference to the key is kept, +// // it cannot be collected at this point. +// throw new AssertionError(); +// } + + // Clone the asset + if (proc != null){ + // Data is now the clone! + data = (DummyData) proc.createClone(data); + if (smartCache) { + // Registering a clone is only needed + // if smart cache is used. + cache.registerAssetClone(keyToGet, data); + // The clone of the asset must have the same key as the original + // otherwise => bug + if (data.key != key){ + throw new AssertionError(); + } + } + } + + // Keep references to the asset => *should* prevent + // collections of the asset in the cache thus causing + // an out of memory error. + if (keepRefs){ + // Prevent the saved references from taking too much memory. + if (cloneAssets) { + data.data = null; + } + refs.add(data); + } + + if ((counter % 1000) == 0){ + long newMem = Runtime.getRuntime().freeMemory(); + System.out.println("Allocated objects: " + counter); + System.out.println("Allocated memory: " + ((memory - newMem)/(1024*1024)) + " MB" ); + memory = newMem; + } + } + } + + public static void main(String[] args){ + // Test cloneable smart asset + System.out.println("====== Running Cloneable Smart Asset Test ======"); + runTest(true, true, false, 100000); + + // Test non-cloneable smart asset + System.out.println("====== Running Non-cloneable Smart Asset Test ======"); + runTest(false, true, false, 100000); + } +} diff --git a/jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java b/jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java new file mode 100644 index 0000000000..0a864a0cda --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/asset/TestOnlineJar.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.asset; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.ui.Picture; + +/** + * This tests loading a file from a jar stored online. + * @author Kirill Vainer + */ +public class TestOnlineJar extends SimpleApplication { + + public static void main(String[] args){ + TestOnlineJar app = new TestOnlineJar(); + app.start(); + } + + @Override + public void simpleInitApp() { + // create a simple plane/quad + Quad quadMesh = new Quad(1, 1); + quadMesh.updateGeometry(1, 1, true); + + Geometry quad = new Geometry("Textured Quad", quadMesh); + + assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/town.zip", + HttpZipLocator.class); + assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", + HttpZipLocator.class); + + Picture pic1 = new Picture("Picture1"); + pic1.move(0, 0, -1); + pic1.setPosition(0, 0); + pic1.setWidth(128); + pic1.setHeight(128); + pic1.setImage(assetManager, "grass.jpg", false); + guiNode.attachChild(pic1); + + Picture pic2 = new Picture("Picture1"); + pic2.move(0, 0, -1); + pic2.setPosition(128, 0); + pic2.setWidth(128); + pic2.setHeight(128); + pic2.setImage(assetManager, "glasstile2.png", false); + guiNode.attachChild(pic2); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java b/jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java new file mode 100644 index 0000000000..563eb4c7c7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/asset/TestUrlLoading.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.asset; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.asset.plugins.UrlLocator; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Texture; + +/** + * Load an image and display it from the internet using the UrlLocator. + * @author Kirill Vainer + */ +public class TestUrlLoading extends SimpleApplication { + + public static void main(String[] args){ + TestUrlLoading app = new TestUrlLoading(); + app.start(); + } + + @Override + public void simpleInitApp() { + // create a simple plane/quad + Quad quadMesh = new Quad(1, 1); + quadMesh.updateGeometry(1, 1, true); + + Geometry quad = new Geometry("Textured Quad", quadMesh); + + assetManager.registerLocator("https://raw.githubusercontent.com/jMonkeyEngine/BookSamples/master/assets/Textures/", + UrlLocator.class); + TextureKey key = new TextureKey("mucha-window.png", false); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", tex); + quad.setMaterial(mat); + + float aspect = tex.getImage().getWidth() / (float) tex.getImage().getHeight(); + quad.setLocalScale(new Vector3f(aspect * 1.5f, 1.5f, 1)); + quad.center(); + + rootNode.attachChild(quad); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/asset/package-info.java b/jme3-examples/src/main/java/jme3test/asset/package-info.java new file mode 100644 index 0000000000..a79bade643 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/asset/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for asset loading + */ +package jme3test.asset; diff --git a/jme3-examples/src/main/java/jme3test/audio/TestAmbient.java b/jme3-examples/src/main/java/jme3test/audio/TestAmbient.java new file mode 100644 index 0000000000..708fe1c77a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestAmbient.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.audio; + +import com.jme3.app.SimpleApplication; +import com.jme3.audio.AudioData.DataType; +import com.jme3.audio.AudioNode; +import com.jme3.audio.Environment; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +public class TestAmbient extends SimpleApplication { + + public static void main(String[] args) { + TestAmbient test = new TestAmbient(); + test.start(); + } + + @Override + public void simpleInitApp() { + float[] eax = new float[]{15, 38.0f, 0.300f, -1000, -3300, 0, + 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f, 0.00f, + 0.00f, -229, 0.088f, 0.00f, 0.00f, 0.00f, 0.125f, 1.000f, + 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f}; + Environment env = new Environment(eax); + audioRenderer.setEnvironment(env); + + AudioNode waves = new AudioNode(assetManager, + "Sound/Environment/Ocean Waves.ogg", DataType.Buffer); + waves.setPositional(true); + waves.setLocalTranslation(new Vector3f(0, 0,0)); + waves.setMaxDistance(100); + waves.setRefDistance(5); + + AudioNode nature = new AudioNode(assetManager, + "Sound/Environment/Nature.ogg", DataType.Stream); + nature.setPositional(false); + nature.setVolume(3); + + waves.playInstance(); + nature.play(); + + // just a blue box to mark the spot + Box box1 = new Box(.5f, .5f, .5f); + Geometry player = new Geometry("Player", box1); + Material mat1 = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.Blue); + player.setMaterial(mat1); + rootNode.attachChild(player); + } + + @Override + public void simpleUpdate(float tpf) { + } +} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestDoppler.java b/jme3-examples/src/main/java/jme3test/audio/TestDoppler.java new file mode 100644 index 0000000000..1065e1cee9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestDoppler.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.audio; + +import com.jme3.app.SimpleApplication; +import com.jme3.audio.AudioData; +import com.jme3.audio.AudioNode; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Torus; + +/** + * Test Doppler Effect + */ +public class TestDoppler extends SimpleApplication { + + private float pos = -5; + private float vel = 5; + private AudioNode ufoNode; + + public static void main(String[] args){ + TestDoppler test = new TestDoppler(); + test.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10); + + Torus torus = new Torus(10, 6, 1, 3); + Geometry g = new Geometry("Torus Geom", torus); + g.rotate(-FastMath.HALF_PI, 0, 0); + g.center(); + + g.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); +// rootNode.attachChild(g); + + ufoNode = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", AudioData.DataType.Buffer); + ufoNode.setLooping(true); + ufoNode.setPitch(0.5f); + ufoNode.setRefDistance(1); + ufoNode.setMaxDistance(100000000); + ufoNode.setVelocityFromTranslation(true); + ufoNode.play(); + + Geometry ball = new Geometry("Beeper", new Sphere(10, 10, 0.1f)); + ball.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + ufoNode.attachChild(ball); + + rootNode.attachChild(ufoNode); + } + + + @Override + public void simpleUpdate(float tpf) { + pos += tpf * vel; + if (pos < -10 || pos > 10) { + vel *= -1; + } + ufoNode.setLocalTranslation(new Vector3f(pos, 0, 0)); + } +} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java b/jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java new file mode 100644 index 0000000000..134cb18ee9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestIssue1761.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2009-2022 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. + */ +package jme3test.audio; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.UrlLocator; +import com.jme3.audio.AudioData; +import com.jme3.audio.AudioNode; +import java.util.Random; + +/** + * Stress test to reproduce JME issue #1761 (AssertionError in ALAudioRenderer). + * + *

After some network delay, a song will play, + * albeit slowly and in a broken fashion. + * If the issue is solved, the song will play all the way through. + * If the issue is present, an AssertionError will be thrown, usually within a + * second of the song starting. + */ +public class TestIssue1761 extends SimpleApplication { + + private AudioNode audioNode; + final private Random random = new Random(); + + /** + * Main entry point for the TestIssue1761 application. + * + * @param unused array of command-line arguments + */ + public static void main(String[] unused) { + TestIssue1761 test = new TestIssue1761(); + test.start(); + } + + @Override + public void simpleInitApp() { + assetManager.registerLocator( + "https://web.archive.org/web/20170625151521if_/http://www.vorbis.com/music/", + UrlLocator.class); + audioNode = new AudioNode(assetManager, "Lumme-Badloop.ogg", + AudioData.DataType.Stream); + audioNode.setPositional(false); + audioNode.play(); + } + + @Override + public void simpleUpdate(float tpf) { + /* + * Randomly pause and restart the audio. + */ + if (random.nextInt(2) == 0) { + audioNode.pause(); + } else { + audioNode.play(); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form b/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form new file mode 100644 index 0000000000..2834858a01 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.form @@ -0,0 +1,117 @@ + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java b/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java new file mode 100644 index 0000000000..da6b4e9a2f --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestMusicPlayer.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2009-2023 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. + */ + +package jme3test.audio; + +import com.jme3.asset.AssetInfo; +import com.jme3.asset.AssetLoader; +import com.jme3.audio.*; +import com.jme3.audio.AudioSource.Status; +import com.jme3.audio.plugins.OGGLoader; +import com.jme3.audio.plugins.WAVLoader; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeSystem; +import com.jme3.system.NativeLibraries; +import com.jme3.system.NativeLibraryLoader; + +import java.io.*; +import javax.swing.JFileChooser; + +public class TestMusicPlayer extends javax.swing.JFrame { + + private AudioRenderer ar; + private AudioData musicData; + private AudioNode musicSource; + private float musicLength = 0; + private float curTime = 0; + final private Listener listener = new Listener(); + + static { + // Load lwjgl and openal natives if lwjgl version 2 is in classpath. + // + // In case of lwjgl 2, natives are loaded when LwjglContext is + // started, but in this test we do not create a LwjglContext, + // so we should handle loading natives ourselves if running + // with lwjgl 2. + NativeLibraryLoader.loadNativeLibrary(NativeLibraries.Lwjgl.getName(), false); + NativeLibraryLoader.loadNativeLibrary(NativeLibraries.OpenAL.getName(), false); + } + + public TestMusicPlayer() { + initComponents(); + setLocationRelativeTo(null); + initAudioPlayer(); + } + + private void initAudioPlayer(){ + AppSettings settings = new AppSettings(true); + settings.setRenderer(null); // disable rendering + settings.setAudioRenderer("LWJGL"); + ar = JmeSystem.newAudioRenderer(settings); + ar.initialize(); + ar.setListener(listener); + AudioContext.setAudioRenderer(ar); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + pnlButtons = new javax.swing.JPanel(); + sldVolume = new javax.swing.JSlider(); + btnRewind = new javax.swing.JButton(); + btnStop = new javax.swing.JButton(); + btnPlay = new javax.swing.JButton(); + btnFF = new javax.swing.JButton(); + btnOpen = new javax.swing.JButton(); + pnlBar = new javax.swing.JPanel(); + lblTime = new javax.swing.JLabel(); + sldBar = new javax.swing.JSlider(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + + pnlButtons.setLayout(new javax.swing.BoxLayout(pnlButtons, javax.swing.BoxLayout.LINE_AXIS)); + + sldVolume.setMajorTickSpacing(20); + sldVolume.setOrientation(javax.swing.JSlider.VERTICAL); + sldVolume.setPaintTicks(true); + sldVolume.setValue(100); + sldVolume.addChangeListener(new javax.swing.event.ChangeListener() { + @Override + public void stateChanged(javax.swing.event.ChangeEvent evt) { + sldVolumeStateChanged(evt); + } + }); + pnlButtons.add(sldVolume); + + btnRewind.setText("<<"); + pnlButtons.add(btnRewind); + + btnStop.setText("[ ]"); + btnStop.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnStopActionPerformed(evt); + } + }); + pnlButtons.add(btnStop); + + btnPlay.setText("II / >"); + btnPlay.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnPlayActionPerformed(evt); + } + }); + pnlButtons.add(btnPlay); + + btnFF.setText(">>"); + btnFF.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnFFActionPerformed(evt); + } + }); + pnlButtons.add(btnFF); + + btnOpen.setText("Open ..."); + btnOpen.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnOpenActionPerformed(evt); + } + }); + pnlButtons.add(btnOpen); + + getContentPane().add(pnlButtons, java.awt.BorderLayout.CENTER); + + pnlBar.setLayout(new javax.swing.BoxLayout(pnlBar, javax.swing.BoxLayout.LINE_AXIS)); + + lblTime.setText("0:00-0:00"); + lblTime.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 3, 3)); + pnlBar.add(lblTime); + + sldBar.setValue(0); + sldBar.addChangeListener(new javax.swing.event.ChangeListener() { + @Override + public void stateChanged(javax.swing.event.ChangeEvent evt) { + sldBarStateChanged(evt); + } + }); + pnlBar.add(sldBar); + + getContentPane().add(pnlBar, java.awt.BorderLayout.PAGE_START); + + pack(); + }// //GEN-END:initComponents + + private void btnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOpenActionPerformed + JFileChooser chooser = new JFileChooser(); + chooser.setAcceptAllFileFilterUsed(true); + chooser.setDialogTitle("Select OGG file"); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + chooser.setMultiSelectionEnabled(false); + if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION){ + btnStopActionPerformed(null); + + final File selected = chooser.getSelectedFile(); + AssetLoader loader = null; + if(selected.getName().endsWith(".wav")){ + loader = new WAVLoader(); + }else{ + loader = new OGGLoader(); + } + + AudioKey key = new AudioKey(selected.getName(), true, true); + try{ + musicData = (AudioData) loader.load(new AssetInfo(null, key) { + @Override + public InputStream openStream() { + try{ + return new FileInputStream(selected); + }catch (FileNotFoundException ex){ + ex.printStackTrace(); + } + return null; + } + }); + }catch (IOException ex){ + ex.printStackTrace(); + } + + musicSource = new AudioNode(musicData, key); + // A positional AudioNode would prohibit stereo sound! + musicSource.setPositional(false); + musicLength = musicData.getDuration(); + updateTime(); + } + }//GEN-LAST:event_btnOpenActionPerformed + + private void updateTime(){ + int max = (int) (musicLength * 100); + int pos = (int) (curTime * 100); + sldBar.setMaximum(max); + sldBar.setValue(pos); + + int minutesTotal = (int) (musicLength / 60); + int secondsTotal = (int) (musicLength % 60); + int minutesNow = (int) (curTime / 60); + int secondsNow = (int) (curTime % 60); + String txt = String.format("%01d:%02d-%01d:%02d", minutesNow, secondsNow, + minutesTotal, secondsTotal); + lblTime.setText(txt); + } + + private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayActionPerformed + if (musicSource == null){ + btnOpenActionPerformed(evt); + return; + } + + if (musicSource.getStatus() == Status.Playing){ + musicSource.setPitch(1); + ar.pauseSource(musicSource); + }else{ + musicSource.setPitch(1); + musicSource.play(); + } + }//GEN-LAST:event_btnPlayActionPerformed + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + ar.cleanup(); + }//GEN-LAST:event_formWindowClosing + + private void sldVolumeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldVolumeStateChanged + listener.setVolume(sldVolume.getValue() / 100f); + ar.setListener(listener); + }//GEN-LAST:event_sldVolumeStateChanged + + private void btnStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStopActionPerformed + if (musicSource != null){ + musicSource.setPitch(1); + ar.stopSource(musicSource); + } + }//GEN-LAST:event_btnStopActionPerformed + + private void btnFFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFFActionPerformed + if (musicSource != null && musicSource.getStatus() == Status.Playing) { + musicSource.setPitch(2); + } + }//GEN-LAST:event_btnFFActionPerformed + + private void sldBarStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldBarStateChanged + // do nothing: OGG/Vorbis supports seeking, but only for time = 0! + }//GEN-LAST:event_sldBarStateChanged + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + new TestMusicPlayer().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnFF; + private javax.swing.JButton btnOpen; + private javax.swing.JButton btnPlay; + private javax.swing.JButton btnRewind; + private javax.swing.JButton btnStop; + private javax.swing.JLabel lblTime; + private javax.swing.JPanel pnlBar; + private javax.swing.JPanel pnlButtons; + private javax.swing.JSlider sldBar; + private javax.swing.JSlider sldVolume; + // End of variables declaration//GEN-END:variables + +} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java b/jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java new file mode 100644 index 0000000000..677d6d2483 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestMusicStreaming.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.audio; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.UrlLocator; +import com.jme3.audio.AudioData; +import com.jme3.audio.AudioNode; + +public class TestMusicStreaming extends SimpleApplication { + + public static void main(String[] args){ + TestMusicStreaming test = new TestMusicStreaming(); + test.start(); + } + + @Override + public void simpleInitApp(){ + assetManager.registerLocator("https://web.archive.org/web/20170625151521if_/http://www.vorbis.com/music/", UrlLocator.class); + AudioNode audioSource = new AudioNode(assetManager, "Lumme-Badloop.ogg", + AudioData.DataType.Stream); + audioSource.setPositional(false); + audioSource.setReverbEnabled(false); + audioSource.play(); + } + + @Override + public void simpleUpdate(float tpf){} + +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/audio/TestOgg.java b/jme3-examples/src/main/java/jme3test/audio/TestOgg.java new file mode 100644 index 0000000000..3e4099c660 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestOgg.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.audio; + +import com.jme3.app.SimpleApplication; +import com.jme3.audio.AudioData.DataType; +import com.jme3.audio.AudioNode; +import com.jme3.audio.AudioSource; +import com.jme3.audio.LowPassFilter; + +public class TestOgg extends SimpleApplication { + + private AudioNode audioSource; + + public static void main(String[] args){ + TestOgg test = new TestOgg(); + test.start(); + } + + @Override + public void simpleInitApp(){ + System.out.println("Playing without filter"); + audioSource = new AudioNode(assetManager, "Sound/Effects/Foot steps.ogg", DataType.Buffer); + audioSource.play(); + } + + @Override + public void simpleUpdate(float tpf){ + if (audioSource.getStatus() != AudioSource.Status.Playing){ + audioRenderer.deleteAudioData(audioSource.getAudioData()); + + System.out.println("Playing with low pass filter"); + audioSource = new AudioNode(assetManager, "Sound/Effects/Foot steps.ogg", DataType.Buffer); + audioSource.setDryFilter(new LowPassFilter(1f, .1f)); + audioSource.setVolume(3); + audioSource.play(); + } + } + +} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestReverb.java b/jme3-examples/src/main/java/jme3test/audio/TestReverb.java new file mode 100644 index 0000000000..aff0a2d464 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestReverb.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.audio; + +import com.jme3.app.SimpleApplication; +import com.jme3.audio.AudioData; +import com.jme3.audio.AudioNode; +import com.jme3.audio.Environment; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; + +public class TestReverb extends SimpleApplication { + + private AudioNode audioSource; + private float time = 0; + private float nextTime = 1; + + public static void main(String[] args) { + TestReverb test = new TestReverb(); + test.start(); + } + + @Override + public void simpleInitApp() { + audioSource = new AudioNode(assetManager, "Sound/Effects/Bang.wav", + AudioData.DataType.Buffer); + + float[] eax = new float[]{15, 38.0f, 0.300f, -1000, -3300, 0, + 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f, 0.00f, 0.00f, + -229, 0.088f, 0.00f, 0.00f, 0.00f, 0.125f, 1.000f, 0.250f, + 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f}; + audioRenderer.setEnvironment(new Environment(eax)); + Environment env = Environment.Cavern; + audioRenderer.setEnvironment(env); + } + + @Override + public void simpleUpdate(float tpf) { + time += tpf; + + if (time > nextTime) { + Vector3f v = new Vector3f(); + v.setX(FastMath.nextRandomFloat()); + v.setY(FastMath.nextRandomFloat()); + v.setZ(FastMath.nextRandomFloat()); + v.multLocal(40, 2, 40); + v.subtractLocal(20, 1, 20); + + audioSource.setLocalTranslation(v); + audioSource.playInstance(); + time = 0; + nextTime = FastMath.nextRandomFloat() * 2 + 0.5f; + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/audio/TestWav.java b/jme3-examples/src/main/java/jme3test/audio/TestWav.java new file mode 100644 index 0000000000..70ec211f23 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/TestWav.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.audio; + +import com.jme3.app.SimpleApplication; +import com.jme3.audio.AudioData; +import com.jme3.audio.AudioNode; + +public class TestWav extends SimpleApplication { + + private float time = 0; + private AudioNode audioSource; + + public static void main(String[] args) { + TestWav test = new TestWav(); + test.start(); + } + + @Override + public void simpleUpdate(float tpf) { + time += tpf; + if (time > 1f) { + audioSource.playInstance(); + time = 0; + } + + } + + @Override + public void simpleInitApp() { + audioSource = new AudioNode(assetManager, "Sound/Effects/Gun.wav", + AudioData.DataType.Buffer); + audioSource.setLooping(false); + } +} diff --git a/jme3-examples/src/main/java/jme3test/audio/package-info.java b/jme3-examples/src/main/java/jme3test/audio/package-info.java new file mode 100644 index 0000000000..d6c39d933d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/audio/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for sound effects and music + */ +package jme3test.audio; diff --git a/jme3-examples/src/main/java/jme3test/awt/AppHarness.java b/jme3-examples/src/main/java/jme3test/awt/AppHarness.java new file mode 100644 index 0000000000..0faa1a6507 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/awt/AppHarness.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.awt; + +import com.jme3.app.LegacyApplication; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeCanvasContext; +import com.jme3.system.JmeSystem; +import java.applet.Applet; +import java.awt.Canvas; +import java.awt.Graphics; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import javax.swing.SwingUtilities; + +/** + * + * @author Kirill + */ +public class AppHarness extends Applet { + + private JmeCanvasContext context; + private Canvas canvas; + private LegacyApplication app; + + private String appClass; + private URL appCfg = null; + + @SuppressWarnings("unchecked") + private void createCanvas(){ + AppSettings settings = new AppSettings(true); + + // load app cfg + if (appCfg != null){ + try { + InputStream in = appCfg.openStream(); + settings.load(in); + in.close(); + } catch (IOException ex){ + ex.printStackTrace(); + } + } + + settings.setWidth(getWidth()); + settings.setHeight(getHeight()); + settings.setAudioRenderer(null); + + JmeSystem.setLowPermissions(true); + + try{ + Class clazz = Class.forName(appClass); + app = (LegacyApplication) clazz.getDeclaredConstructor().newInstance(); + }catch (ClassNotFoundException + | InstantiationException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException ex) { + ex.printStackTrace(); + } + + app.setSettings(settings); + app.createCanvas(); + + context = (JmeCanvasContext) app.getContext(); + canvas = context.getCanvas(); + canvas.setSize(getWidth(), getHeight()); + + add(canvas); + app.startCanvas(); + } + + @Override + public final void update(Graphics g) { + canvas.setSize(getWidth(), getHeight()); + } + + @Override + public void init(){ + appClass = getParameter("AppClass"); + if (appClass == null) + throw new RuntimeException("The required parameter AppClass isn't specified!"); + + try { + appCfg = new URL(getParameter("AppSettingsURL")); + } catch (MalformedURLException ex) { + ex.printStackTrace(); + appCfg = null; + } + + createCanvas(); + System.out.println("applet:init"); + } + + @Override + public void start(){ + context.setAutoFlushFrames(true); + System.out.println("applet:start"); + } + + @Override + public void stop(){ + context.setAutoFlushFrames(false); + System.out.println("applet:stop"); + } + + @Override + public void destroy(){ + System.out.println("applet:destroyStart"); + SwingUtilities.invokeLater(new Runnable(){ + @Override + public void run(){ + removeAll(); + System.out.println("applet:destroyRemoved"); + } + }); + app.stop(true); + System.out.println("applet:destroyDone"); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/awt/TestApplet.java b/jme3-examples/src/main/java/jme3test/awt/TestApplet.java new file mode 100644 index 0000000000..e9e473b852 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/awt/TestApplet.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.awt; + +import com.jme3.app.LegacyApplication; +import com.jme3.app.SimpleApplication; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeCanvasContext; +import com.jme3.system.JmeSystem; +import java.applet.Applet; +import java.awt.Canvas; +import java.awt.Graphics; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.Callable; +import javax.swing.SwingUtilities; + +public class TestApplet extends Applet { + + private static JmeCanvasContext context; + private static LegacyApplication app; + private static Canvas canvas; + private static TestApplet applet; + + public TestApplet(){ + } + + @SuppressWarnings("unchecked") + public static void createCanvas(String appClass){ + AppSettings settings = new AppSettings(true); + settings.setWidth(640); + settings.setHeight(480); + settings.setRenderer(AppSettings.LWJGL_OPENGL2); + + JmeSystem.setLowPermissions(true); + + try{ + Class clazz = Class.forName(appClass); + app = (LegacyApplication) clazz.getDeclaredConstructor().newInstance(); + } catch (ClassNotFoundException + | InstantiationException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException ex) { + ex.printStackTrace(); + } + + app.setSettings(settings); + app.createCanvas(); + + context = (JmeCanvasContext) app.getContext(); + canvas = context.getCanvas(); + canvas.setSize(settings.getWidth(), settings.getHeight()); + } + + public static void startApp(){ + applet.add(canvas); + app.startCanvas(); + + app.enqueue(new Callable(){ + @Override + public Void call(){ + if (app instanceof SimpleApplication){ + SimpleApplication simpleApp = (SimpleApplication) app; + simpleApp.getFlyByCamera().setDragToRotate(true); + simpleApp.getInputManager().setCursorVisible(true); + } + return null; + } + }); + } + + public void freezeApp(){ + remove(canvas); + } + + public void unfreezeApp(){ + add(canvas); + } + + @Override + public final void update(Graphics g) { +// canvas.setSize(getWidth(), getHeight()); + } + + @Override + public void init(){ + applet = this; + createCanvas("jme3test.model.shape.TestBox"); + startApp(); + app.setPauseOnLostFocus(false); + System.out.println("applet:init"); + } + + @Override + public void start(){ +// context.setAutoFlushFrames(true); + System.out.println("applet:start"); + } + + @Override + public void stop(){ +// context.setAutoFlushFrames(false); + System.out.println("applet:stop"); + } + + @Override + public void destroy(){ + SwingUtilities.invokeLater(new Runnable(){ + @Override + public void run(){ + removeAll(); + System.out.println("applet:destroyStart"); + } + }); + app.stop(true); + System.out.println("applet:destroyEnd"); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java b/jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java new file mode 100644 index 0000000000..9dab109021 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/awt/TestAwtPanels.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package jme3test.awt; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; +import com.jme3.system.awt.AwtPanel; +import com.jme3.system.awt.AwtPanelsContext; +import com.jme3.system.awt.PaintMode; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.concurrent.CountDownLatch; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class TestAwtPanels extends SimpleApplication { + + private static final Logger logger = Logger.getLogger(TestAwtPanels.class.getName()); + + final private static CountDownLatch panelsAreReady = new CountDownLatch(1); + private static TestAwtPanels app; + private static AwtPanel panel, panel2; + private static int panelsClosed = 0; + + private static void createWindowForPanel(AwtPanel panel, int location){ + JFrame frame = new JFrame("Render Display " + location); + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add(panel, BorderLayout.CENTER); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosed(WindowEvent e) { + if (++panelsClosed == 2){ + app.stop(); + } + } + }); + frame.pack(); + frame.setLocation(location, Toolkit.getDefaultToolkit().getScreenSize().height - 400); + frame.setVisible(true); + } + + public static void main(String[] args){ + Logger.getLogger("com.jme3").setLevel(Level.WARNING); + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + logger.warning("Could not set native look and feel."); + } + + app = new TestAwtPanels(); + app.setShowSettings(false); + AppSettings settings = new AppSettings(true); + settings.setCustomRenderer(AwtPanelsContext.class); + settings.setFrameRate(60); + app.setSettings(settings); + app.start(); + + SwingUtilities.invokeLater(new Runnable(){ + @Override + public void run(){ + /* + * Sleep 2 seconds to ensure there's no race condition. + * The sleep is not required for correctness. + */ + try { + Thread.sleep(2000); + } catch (InterruptedException exception) { + return; + } + + final AwtPanelsContext ctx = (AwtPanelsContext) app.getContext(); + panel = ctx.createPanel(PaintMode.Accelerated); + panel.setPreferredSize(new Dimension(400, 300)); + ctx.setInputSource(panel); + + panel2 = ctx.createPanel(PaintMode.Accelerated); + panel2.setPreferredSize(new Dimension(400, 300)); + + createWindowForPanel(panel, 300); + createWindowForPanel(panel2, 700); + /* + * Both panels are ready. + */ + panelsAreReady.countDown(); + } + }); + } + + @Override + public void simpleInitApp() { + flyCam.setDragToRotate(true); + + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + geom.setMaterial(mat); + rootNode.attachChild(geom); + /* + * Wait until both AWT panels are ready. + */ + try { + panelsAreReady.await(); + } catch (InterruptedException exception) { + throw new RuntimeException("Interrupted while waiting for panels", exception); + } + + panel.attachTo(true, viewPort); + guiViewPort.setClearFlags(true, true, true); + panel2.attachTo(false, guiViewPort); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java new file mode 100644 index 0000000000..bb4b39ac95 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.awt; + +import com.jme3.app.LegacyApplication; +import com.jme3.app.SimpleApplication; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeCanvasContext; +import com.jme3.util.JmeFormatter; +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.Callable; +import java.util.logging.ConsoleHandler; +import java.util.logging.Handler; +import java.util.logging.Logger; +import javax.swing.*; + +public class TestCanvas { + + private static JmeCanvasContext context; + private static Canvas canvas; + private static LegacyApplication app; + private static JFrame frame; + private static Container canvasPanel1, canvasPanel2; + private static Container currentPanel; + private static JTabbedPane tabbedPane; + private static final String appClass = "jme3test.post.TestRenderToTexture"; + + private static void createTabs(){ + tabbedPane = new JTabbedPane(); + + canvasPanel1 = new JPanel(); + canvasPanel1.setLayout(new BorderLayout()); + tabbedPane.addTab("jME3 Canvas 1", canvasPanel1); + + canvasPanel2 = new JPanel(); + canvasPanel2.setLayout(new BorderLayout()); + tabbedPane.addTab("jME3 Canvas 2", canvasPanel2); + + frame.getContentPane().add(tabbedPane); + + currentPanel = canvasPanel1; + } + + private static void createMenu(){ + JMenuBar menuBar = new JMenuBar(); + frame.setJMenuBar(menuBar); + + JMenu menuTortureMethods = new JMenu("Canvas Torture Methods"); + menuBar.add(menuTortureMethods); + + final JMenuItem itemRemoveCanvas = new JMenuItem("Remove Canvas"); + menuTortureMethods.add(itemRemoveCanvas); + itemRemoveCanvas.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (itemRemoveCanvas.getText().equals("Remove Canvas")){ + currentPanel.remove(canvas); + + itemRemoveCanvas.setText("Add Canvas"); + }else if (itemRemoveCanvas.getText().equals("Add Canvas")){ + currentPanel.add(canvas, BorderLayout.CENTER); + + itemRemoveCanvas.setText("Remove Canvas"); + } + } + }); + + final JMenuItem itemHideCanvas = new JMenuItem("Hide Canvas"); + menuTortureMethods.add(itemHideCanvas); + itemHideCanvas.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (itemHideCanvas.getText().equals("Hide Canvas")){ + canvas.setVisible(false); + itemHideCanvas.setText("Show Canvas"); + }else if (itemHideCanvas.getText().equals("Show Canvas")){ + canvas.setVisible(true); + itemHideCanvas.setText("Hide Canvas"); + } + } + }); + + final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2"); + menuTortureMethods.add(itemSwitchTab); + itemSwitchTab.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e){ + if (itemSwitchTab.getText().equals("Switch to tab #2")){ + canvasPanel1.remove(canvas); + canvasPanel2.add(canvas, BorderLayout.CENTER); + currentPanel = canvasPanel2; + itemSwitchTab.setText("Switch to tab #1"); + }else if (itemSwitchTab.getText().equals("Switch to tab #1")){ + canvasPanel2.remove(canvas); + canvasPanel1.add(canvas, BorderLayout.CENTER); + currentPanel = canvasPanel1; + itemSwitchTab.setText("Switch to tab #2"); + } + } + }); + + JMenuItem itemSwitchLaf = new JMenuItem("Switch Look and Feel"); + menuTortureMethods.add(itemSwitchLaf); + itemSwitchLaf.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e){ + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Throwable t){ + t.printStackTrace(); + } + SwingUtilities.updateComponentTreeUI(frame); + frame.pack(); + } + }); + + JMenuItem itemSmallSize = new JMenuItem("Set size to (0, 0)"); + menuTortureMethods.add(itemSmallSize); + itemSmallSize.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e){ + Dimension preferred = frame.getPreferredSize(); + frame.setPreferredSize(new Dimension(0, 0)); + frame.pack(); + frame.setPreferredSize(preferred); + } + }); + + JMenuItem itemKillCanvas = new JMenuItem("Stop/Start Canvas"); + menuTortureMethods.add(itemKillCanvas); + itemKillCanvas.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + currentPanel.remove(canvas); + app.stop(true); + + createCanvas(appClass); + currentPanel.add(canvas, BorderLayout.CENTER); + frame.pack(); + startApp(); + } + }); + + JMenuItem itemExit = new JMenuItem("Exit"); + menuTortureMethods.add(itemExit); + itemExit.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + frame.dispose(); + app.stop(); + } + }); + } + + private static void createFrame(){ + frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.addWindowListener(new WindowAdapter(){ + @Override + public void windowClosed(WindowEvent e) { + app.stop(); + } + }); + + createTabs(); + createMenu(); + } + + @SuppressWarnings("unchecked") + public static void createCanvas(String appClass){ + AppSettings settings = new AppSettings(true); + settings.setWidth(640); + settings.setHeight(480); + + try{ + Class clazz = Class.forName(appClass); + app = (LegacyApplication) clazz.getDeclaredConstructor().newInstance(); + }catch (ClassNotFoundException + | InstantiationException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException ex) { + ex.printStackTrace(); + } + + app.setPauseOnLostFocus(false); + app.setSettings(settings); + app.createCanvas(); + app.startCanvas(); + + context = (JmeCanvasContext) app.getContext(); + canvas = context.getCanvas(); + canvas.setSize(settings.getWidth(), settings.getHeight()); + } + + public static void startApp(){ + app.startCanvas(); + app.enqueue(new Callable(){ + @Override + public Void call(){ + if (app instanceof SimpleApplication){ + SimpleApplication simpleApp = (SimpleApplication) app; + simpleApp.getFlyByCamera().setDragToRotate(true); + } + return null; + } + }); + + } + + public static void main(String[] args){ + JmeFormatter formatter = new JmeFormatter(); + + Handler consoleHandler = new ConsoleHandler(); + consoleHandler.setFormatter(formatter); + + Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]); + Logger.getLogger("").addHandler(consoleHandler); + + createCanvas(appClass); + + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + } + + SwingUtilities.invokeLater(new Runnable(){ + @Override + public void run(){ + JPopupMenu.setDefaultLightWeightPopupEnabled(false); + + createFrame(); + + currentPanel.add(canvas, BorderLayout.CENTER); + frame.pack(); + startApp(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + }); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java new file mode 100644 index 0000000000..5c6940df31 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/awt/TestSafeCanvas.java @@ -0,0 +1,68 @@ +package jme3test.awt; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeCanvasContext; +import java.awt.Canvas; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JFrame; + +public class TestSafeCanvas extends SimpleApplication { + + public static void main(String[] args) throws InterruptedException{ + AppSettings settings = new AppSettings(true); + settings.setWidth(640); + settings.setHeight(480); + + final TestSafeCanvas app = new TestSafeCanvas(); + app.setPauseOnLostFocus(false); + app.setSettings(settings); + app.createCanvas(); + app.startCanvas(true); + + JmeCanvasContext context = (JmeCanvasContext) app.getContext(); + Canvas canvas = context.getCanvas(); + canvas.setSize(settings.getWidth(), settings.getHeight()); + + + + Thread.sleep(3000); + + JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + app.stop(); + } + }); + frame.getContentPane().add(canvas); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + Thread.sleep(3000); + + frame.getContentPane().remove(canvas); + + Thread.sleep(3000); + + frame.getContentPane().add(canvas); + } + + @Override + public void simpleInitApp() { + flyCam.setDragToRotate(true); + + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + geom.setMaterial(mat); + rootNode.attachChild(geom); + } +} diff --git a/jme3-examples/src/main/java/jme3test/awt/package-info.java b/jme3-examples/src/main/java/jme3test/awt/package-info.java new file mode 100644 index 0000000000..36025141ca --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/awt/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for interfacing to the Abstract Window + * Toolkit (AWT) + */ +package jme3test.awt; diff --git a/jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java b/jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java new file mode 100644 index 0000000000..c04069ef88 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.batching; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.BatchNode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.debug.WireFrustum; +import com.jme3.scene.shape.Box; +import com.jme3.system.NanoTimer; +import com.jme3.util.TangentBinormalGenerator; + +/** + * A test to demonstrate the usage and functionality of the {@link BatchNode} + * @author Nehon + */ +public class TestBatchNode extends SimpleApplication { + private BatchNode batch; + private WireFrustum frustum; + private final Vector3f[] points; + private Geometry cube2; + private float time = 0; + private DirectionalLight dl; + private boolean done = false; + + public static void main(String[] args) { + TestBatchNode app = new TestBatchNode(); + app.start(); + } + + public TestBatchNode() { + points = new Vector3f[8]; + for (int i = 0; i < points.length; i++) { + points[i] = new Vector3f(); + } + } + + @Override + public void simpleInitApp() { + timer = new NanoTimer(); + batch = new BatchNode("theBatchNode"); + + /* + * A cube with a color "bleeding" through transparent texture. Uses + * Texture from jme3-testdata library! + */ + Box boxShape4 = new Box(1f, 1f, 1f); + Geometry cube = new Geometry("cube1", boxShape4); + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + cube.setMaterial(mat); + //Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + //mat.setColor("Diffuse", ColorRGBA.Blue); + //mat.setBoolean("UseMaterialColors", true); + /* + * A cube with a color "bleeding" through transparent texture. Uses + * Texture from jme3-testdata library! + */ + Box box = new Box(1f, 1f, 1f); + cube2 = new Geometry("cube2", box); + cube2.setMaterial(mat); + + TangentBinormalGenerator.generate(cube); + TangentBinormalGenerator.generate(cube2); + + batch.attachChild(cube); + // batch.attachChild(cube2); + // batch.setMaterial(mat); + batch.batch(); + rootNode.attachChild(batch); + cube.setLocalTranslation(3, 0, 0); + cube2.setLocalTranslation(0, 20, 0); + + updateBoundingPoints(points); + frustum = new WireFrustum(points); + Geometry frustumMdl = new Geometry("f", frustum); + frustumMdl.setCullHint(Spatial.CullHint.Never); + frustumMdl.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + frustumMdl.getMaterial().getAdditionalRenderState().setWireframe(true); + frustumMdl.getMaterial().setColor("Color", ColorRGBA.Red); + rootNode.attachChild(frustumMdl); + dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White.mult(2)); + dl.setDirection(new Vector3f(1, -1, -1)); + rootNode.addLight(dl); + flyCam.setMoveSpeed(10); + } + + @Override + public void simpleUpdate(float tpf) { + if (!done) { + done = true; + batch.attachChild(cube2); + batch.batch(); + } + updateBoundingPoints(points); + frustum.update(points); + time += tpf; + dl.setDirection(cam.getDirection()); + cube2.setLocalTranslation(FastMath.sin(-time) * 3, FastMath.cos(time) * 3, 0); + cube2.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Z)); + cube2.setLocalScale(Math.max(FastMath.sin(time), 0.5f)); + + // batch.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Z)); + } + + public void updateBoundingPoints(Vector3f[] points) { + BoundingBox bb = (BoundingBox) batch.getWorldBound(); + float xe = bb.getXExtent(); + float ye = bb.getYExtent(); + float ze = bb.getZExtent(); + float x = bb.getCenter().x; + float y = bb.getCenter().y; + float z = bb.getCenter().z; + + points[0].set(new Vector3f(x - xe, y - ye, z - ze)); + points[1].set(new Vector3f(x - xe, y + ye, z - ze)); + points[2].set(new Vector3f(x + xe, y + ye, z - ze)); + points[3].set(new Vector3f(x + xe, y - ye, z - ze)); + + points[4].set(new Vector3f(x + xe, y - ye, z + ze)); + points[5].set(new Vector3f(x - xe, y - ye, z + ze)); + points[6].set(new Vector3f(x - xe, y + ye, z + ze)); + points[7].set(new Vector3f(x + xe, y + ye, z + ze)); + } +} diff --git a/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java b/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java new file mode 100644 index 0000000000..52a87492c4 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeCluster.java @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.batching; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.scene.*; +import com.jme3.scene.debug.Arrow; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; +import com.jme3.system.NanoTimer; +import java.util.ArrayList; +import java.util.Random; + +public class TestBatchNodeCluster extends SimpleApplication { + + public static void main(String[] args) { + TestBatchNodeCluster app = new TestBatchNodeCluster(); + settingst = new AppSettings(true); + //settingst.setFrameRate(75); + settingst.setResolution(640, 480); + settingst.setVSync(false); + settingst.setFullscreen(false); + app.setSettings(settingst); + app.setShowSettings(false); + app.start(); + } + final private ActionListener al = new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("Start Game")) { +// randomGenerator(); + } + } + }; + final private Random rand = new Random(); + final private int maxCubes = 2000; + final private int startAt = 0; + final private ArrayList xPosition = new ArrayList<>(); + final private ArrayList yPosition = new ArrayList<>(); + final private ArrayList zPosition = new ArrayList<>(); + final private int yLimitf = 60, yLimits = -20; + private static AppSettings settingst; + final private int lineLength = 50; + private BatchNode batchNode; + private Material mat1; + private Material mat2; + private Material mat3; + private Material mat4; + private Node terrain; +// protected Geometry player; + + @Override + public void simpleInitApp() { + timer = new NanoTimer(); + + batchNode = new SimpleBatchNode("BatchNode"); + + + xPosition.add(0); + yPosition.add(0); + zPosition.add(0); + + mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.White); + mat1.setColor("GlowColor", ColorRGBA.Blue.mult(10)); + + mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.setColor("Color", ColorRGBA.White); + mat2.setColor("GlowColor", ColorRGBA.Red.mult(10)); + + mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat3.setColor("Color", ColorRGBA.White); + mat3.setColor("GlowColor", ColorRGBA.Yellow.mult(10)); + + mat4 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat4.setColor("Color", ColorRGBA.White); + mat4.setColor("GlowColor", ColorRGBA.Orange.mult(10)); + + randomGenerator(); + + //rootNode.attachChild(SkyFactory.createSky( + // assetManager, "Textures/SKY02.zip", false)); + inputManager.addMapping("Start Game", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addListener(al, new String[]{"Start Game"}); + + + cam.setLocation(new Vector3f(-34.403286f, 126.65158f, 434.791f)); + cam.setRotation(new Quaternion(0.022630932f, 0.9749435f, -0.18736298f, 0.11776358f)); + + + batchNode.batch(); + + + terrain = new Node("terrain"); + terrain.setLocalTranslation(50, 0, 50); + terrain.attachChild(batchNode); + + flyCam.setMoveSpeed(100); + rootNode.attachChild(terrain); + Vector3f pos = new Vector3f(-40, 0, -40); + batchNode.setLocalTranslation(pos); + + + Arrow a = new Arrow(new Vector3f(0, 50, 0)); + Geometry g = new Geometry("a", a); + g.setLocalTranslation(terrain.getLocalTranslation()); + Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + m.setColor("Color", ColorRGBA.Blue); + g.setMaterial(m); + + + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(new BloomFilter(BloomFilter.GlowMode.Objects)); +// SSAOFilter ssao = new SSAOFilter(8.630104f,22.970434f,2.9299977f,0.2999997f); +// fpp.addFilter(ssao); + viewPort.addProcessor(fpp); + // viewPort.setBackgroundColor(ColorRGBA.DarkGray); + } + + public void randomGenerator() { + for (int i = startAt; i < maxCubes - 1; i++) { + randomize(); + Geometry box = new Geometry("Box" + i, new Box(1, 1, 1)); + box.setLocalTranslation(new Vector3f(xPosition.get(xPosition.size() - 1), + yPosition.get(yPosition.size() - 1), + zPosition.get(zPosition.size() - 1))); + batchNode.attachChild(box); + if (i < 500) { + box.setMaterial(mat1); + } else if (i < 1000) { + + box.setMaterial(mat2); + } else if (i < 1500) { + + box.setMaterial(mat3); + } else { + + box.setMaterial(mat4); + } + + } + } + +// public BatchNode randomBatch() { +// +// int randomn = rand.nextInt(4); +// if (randomn == 0) { +// return blue; +// } else if (randomn == 1) { +// return brown; +// } else if (randomn == 2) { +// return pink; +// } else if (randomn == 3) { +// return orange; +// } +// return null; +// } + public ColorRGBA randomColor() { + ColorRGBA color = ColorRGBA.Black; + int randomn = rand.nextInt(4); + if (randomn == 0) { + color = ColorRGBA.Orange; + } else if (randomn == 1) { + color = ColorRGBA.Blue; + } else if (randomn == 2) { + color = ColorRGBA.Brown; + } else if (randomn == 3) { + color = ColorRGBA.Magenta; + } + return color; + } + + public void randomize() { + int xpos = xPosition.get(xPosition.size() - 1); + int ypos = yPosition.get(yPosition.size() - 1); + int zpos = zPosition.get(zPosition.size() - 1); + int x = 0; + int y = 0; + int z = 0; + boolean unTrue = true; + while (unTrue) { + unTrue = false; + boolean xChanged = false; + x = 0; + y = 0; + z = 0; + if (xpos >= lineLength * 2) { + x = 2; + xChanged = true; + } else { + x = xPosition.get(xPosition.size() - 1) + 2; + } + if (xChanged) { + //y = yPosition.get(yPosition.size() - lineLength) + 2; + } else { + y = rand.nextInt(3); + if (yPosition.size() > lineLength) { + if (yPosition.size() > 51) { + if (y == 0 && ypos < yLimitf && getym(lineLength) > ypos - 2) { + y = ypos + 2; + } else if (y == 1 && ypos > yLimits && getym(lineLength) < ypos + 2) { + y = ypos - 2; + } else if (y == 2 && getym(lineLength) > ypos - 2 && getym(lineLength) < ypos + 2) { + y = ypos; + } else { + if (ypos >= yLimitf) { + y = ypos - 2; + } else if (ypos <= yLimits) { + y = ypos + 2; + } else if (y == 0 && getym(lineLength) >= ypos - 4) { + y = ypos - 2; + } else if (y == 0 && getym(lineLength) >= ypos - 2) { + y = ypos; + } else if (y == 1 && getym(lineLength) >= ypos + 4) { + y = ypos + 2; + } else if (y == 1 && getym(lineLength) >= ypos + 2) { + y = ypos; + } else if (y == 2 && getym(lineLength) <= ypos - 2) { + y = ypos - 2; + } else if (y == 2 && getym(lineLength) >= ypos + 2) { + y = ypos + 2; + } else { + System.out.println("wtf"); + } + } + } else if (yPosition.size() == lineLength) { + if (y == 0 && ypos < yLimitf) { + y = getym(lineLength) + 2; + } else if (y == 1 && ypos > yLimits) { + y = getym(lineLength) - 2; + } + } + } else { + if (y == 0 && ypos < yLimitf) { + y = ypos + 2; + } else if (y == 1 && ypos > yLimits) { + y = ypos - 2; + } else if (y == 2) { + y = ypos; + } else if (y == 0 && ypos >= yLimitf) { + y = ypos - 2; + } else if (y == 1 && ypos <= yLimits) { + y = ypos + 2; + } + } + } + if (xChanged) { + z = zpos + 2; + } else { + z = zpos; + } +// for (int i = 0; i < xPosition.size(); i++) +// { +// if (x - xPosition.get(i) <= 1 && x - xPosition.get(i) >= -1 && +// y - yPosition.get(i) <= 1 && y - yPosition.get(i) >= -1 +// &&z - zPosition.get(i) <= 1 && z - zPosition.get(i) >= +// -1) +// { +// unTrue = true; +// } +// } + } + xPosition.add(x); + yPosition.add(y); + zPosition.add(z); + } + + public int getxm(int i) { + return xPosition.get(xPosition.size() - i); + } + + public int getym(int i) { + return yPosition.get(yPosition.size() - i); + } + + public int getzm(int i) { + return zPosition.get(zPosition.size() - i); + } + + public int getx(int i) { + return xPosition.get(i); + } + + public int gety(int i) { + return yPosition.get(i); + } + + public int getz(int i) { + return zPosition.get(i); + } + private float time = 0; + + @Override + public void simpleUpdate(float tpf) { + time += tpf; + int random = rand.nextInt(2000); + float mult1 = 1.0f; + float mult2 = 1.0f; + if (random < 500) { + mult1 = 1.0f; + mult2 = 1.0f; + } else if (random < 1000) { + mult1 = -1.0f; + mult2 = 1.0f; + } else if (random < 1500) { + mult1 = 1.0f; + mult2 = -1.0f; + } else if (random <= 2000) { + mult1 = -1.0f; + mult2 = -1.0f; + } + Spatial box = batchNode.getChild("Box" + random); + if (box != null) { + Vector3f v = box.getLocalTranslation(); + box.setLocalTranslation(v.x + FastMath.sin(time * mult1) * 20, v.y + (FastMath.sin(time * mult1) * FastMath.cos(time * mult1) * 20), v.z + FastMath.cos(time * mult2) * 20); + } + terrain.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Y)); + + + } +} diff --git a/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java b/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java new file mode 100644 index 0000000000..5f0e603fb5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/batching/TestBatchNodeTower.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.batching; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.font.BitmapText; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.BatchNode; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; +import com.jme3.shadow.CompareMode; +import com.jme3.shadow.DirectionalLightShadowFilter; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.system.AppSettings; +import com.jme3.system.NanoTimer; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import jme3test.bullet.BombControl; + +/** + * + * @author double1984 (tower mod by atom) + */ +public class TestBatchNodeTower extends SimpleApplication { + + final private int bricksPerLayer = 8; + final private int brickLayers = 30; + + final private static float brickWidth = .75f, brickHeight = .25f, brickDepth = .25f; + final private float radius = 3f; + private float angle = 0; + + + private Material mat; + private Material mat2; + private Material mat3; + private Sphere bullet; + private Box brick; + private SphereCollisionShape bulletCollisionShape; + + private BulletAppState bulletAppState; + final private BatchNode batchNode = new BatchNode("batch Node"); + + public static void main(String args[]) { + TestBatchNodeTower f = new TestBatchNodeTower(); + AppSettings s = new AppSettings(true); + f.setSettings(s); + f.start(); + } + + @Override + public void simpleInitApp() { + timer = new NanoTimer(); + bulletAppState = new BulletAppState(); + bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); + // bulletAppState.setEnabled(false); + stateManager.attach(bulletAppState); + bullet = new Sphere(32, 32, 0.4f, true, false); + bullet.setTextureMode(TextureMode.Projected); + bulletCollisionShape = new SphereCollisionShape(0.4f); + + brick = new Box(brickWidth, brickHeight, brickDepth); + brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); + initMaterial(); + initTower(); + initFloor(); + initCrossHairs(); + this.cam.setLocation(new Vector3f(0, 25f, 8f)); + cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0)); + cam.setFrustumFar(80); + inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(actionListener, "shoot"); + rootNode.setShadowMode(ShadowMode.Off); + + batchNode.batch(); + batchNode.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(batchNode); + + DirectionalLightShadowFilter shadowRenderer + = new DirectionalLightShadowFilter(assetManager, 1024, 2); + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + shadowRenderer.setLight(dl); + shadowRenderer.setLambda(0.55f); + shadowRenderer.setShadowIntensity(0.6f); + shadowRenderer.setShadowCompareMode(CompareMode.Hardware); + shadowRenderer.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(shadowRenderer); + viewPort.addProcessor(fpp); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + final private ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("shoot") && !keyPressed) { + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(mat2); + bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); + bulletGeometry.setLocalTranslation(cam.getLocation()); + RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); +// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); + bulletNode.setLinearVelocity(cam.getDirection().mult(25)); + bulletGeometry.addControl(bulletNode); + rootNode.attachChild(bulletGeometry); + getPhysicsSpace().add(bulletNode); + } + } + }; + + public void initTower() { + double tempX = 0; + double tempY = 0; + double tempZ = 0; + angle = 0f; + for (int i = 0; i < brickLayers; i++){ + // Increment rows + if (i != 0) { + tempY += brickHeight * 2; + } else { + tempY = brickHeight; + } + // Alternate brick seams + angle = 360.0f / bricksPerLayer * i/2f; + for (int j = 0; j < bricksPerLayer; j++){ + tempZ = Math.cos(Math.toRadians(angle))*radius; + tempX = Math.sin(Math.toRadians(angle))*radius; + System.out.println("x="+((float)(tempX))+" y="+((float)(tempY))+" z="+(float)(tempZ)); + Vector3f vt = new Vector3f((float)(tempX), (float)(tempY), (float)(tempZ)); + // Add crenelation + if (i==brickLayers-1){ + if (j%2 == 0){ + addBrick(vt); + } + } + // Create main tower + else { + addBrick(vt); + } + angle += 360.0/bricksPerLayer; + } + } + + } + + public void initFloor() { + Box floorBox = new Box(10f, 0.1f, 5f); + floorBox.scaleTextureCoordinates(new Vector2f(3, 6)); + + Geometry floor = new Geometry("floor", floorBox); + floor.setMaterial(mat3); + floor.setShadowMode(ShadowMode.Receive); + floor.setLocalTranslation(0, 0, 0); + floor.addControl(new RigidBodyControl(0)); + this.rootNode.attachChild(floor); + this.getPhysicsSpace().add(floor); + } + + public void initMaterial() { + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + mat.setTexture("ColorMap", tex); + + mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); + key2.setGenerateMips(true); + Texture tex2 = assetManager.loadTexture(key2); + mat2.setTexture("ColorMap", tex2); + + mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); + key3.setGenerateMips(true); + Texture tex3 = assetManager.loadTexture(key3); + tex3.setWrap(WrapMode.Repeat); + mat3.setTexture("ColorMap", tex3); + } + + public void addBrick(Vector3f ori) { + Geometry reBoxg = new Geometry("brick", brick); + reBoxg.setMaterial(mat); + reBoxg.setLocalTranslation(ori); + reBoxg.rotate(0f, (float)Math.toRadians(angle) , 0f ); + reBoxg.addControl(new RigidBodyControl(1.5f)); + reBoxg.setShadowMode(ShadowMode.CastAndReceive); + reBoxg.getControl(RigidBodyControl.class).setFriction(1.6f); + this.batchNode.attachChild(reBoxg); + this.getPhysicsSpace().add(reBoxg); + } + + protected void initCrossHairs() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, + settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); + guiNode.attachChild(ch); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/batching/package-info.java b/jme3-examples/src/main/java/jme3test/batching/package-info.java new file mode 100644 index 0000000000..714fe0ab6e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/batching/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for batching multiple geometries into a + * single Mesh + */ +package jme3test.batching; diff --git a/jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java b/jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java new file mode 100644 index 0000000000..839628407d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bounding/TestRayCollision.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.bounding; + +import com.jme3.bounding.BoundingBox; +import com.jme3.collision.CollisionResults; +import com.jme3.math.Ray; +import com.jme3.math.Vector3f; + +/** + * Tests picking/collision between bounds and shapes. + */ +public class TestRayCollision { + + public static void main(String[] args){ + Ray r = new Ray(Vector3f.ZERO, Vector3f.UNIT_X); + BoundingBox bbox = new BoundingBox(new Vector3f(5, 0, 0), 1, 1, 1); + + CollisionResults res = new CollisionResults(); + bbox.collideWith(r, res); + + System.out.println("Bounding:" +bbox); + System.out.println("Ray: "+r); + + System.out.println("Num collisions: "+res.size()); + for (int i = 0; i < res.size(); i++){ + System.out.println("--- Collision #"+i+" ---"); + float dist = res.getCollision(i).getDistance(); + Vector3f pt = res.getCollision(i).getContactPoint(); + System.out.println("distance: "+dist); + System.out.println("point: "+pt); + } + } + +} diff --git a/jme3-examples/src/main/java/jme3test/bounding/package-info.java b/jme3-examples/src/main/java/jme3test/bounding/package-info.java new file mode 100644 index 0000000000..6e7428f082 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bounding/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for bounding volumes + */ +package jme3test.bounding; diff --git a/jme3-examples/src/main/java/jme3test/bullet/BombControl.java b/jme3-examples/src/main/java/jme3test/bullet/BombControl.java new file mode 100644 index 0000000000..49f9a43982 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/BombControl.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.asset.AssetManager; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.PhysicsTickListener; +import com.jme3.bullet.collision.PhysicsCollisionEvent; +import com.jme3.bullet.collision.PhysicsCollisionListener; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.objects.PhysicsGhostObject; +import com.jme3.bullet.objects.PhysicsRigidBody; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.effect.shapes.EmitterSphereShape; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import java.io.IOException; +import java.util.Iterator; + +/** + * + * @author normenhansen + */ +public class BombControl extends RigidBodyControl implements PhysicsCollisionListener, PhysicsTickListener { + + private float explosionRadius = 10; + private PhysicsGhostObject ghostObject; + final private Vector3f vector = new Vector3f(); + final private Vector3f vector2 = new Vector3f(); + private float forceFactor = 1; + private ParticleEmitter effect; + final private float fxTime = 0.5f; + final private float maxTime = 4f; + private float curTime = -1.0f; + private float timer; + + public BombControl(CollisionShape shape, float mass) { + super(shape, mass); + createGhostObject(); + } + + public BombControl(AssetManager manager, CollisionShape shape, float mass) { + super(shape, mass); + createGhostObject(); + prepareEffect(manager); + } + + @Override + public void setPhysicsSpace(PhysicsSpace space) { + super.setPhysicsSpace(space); + if (space != null) { + space.addCollisionListener(this); + } + } + + private void prepareEffect(AssetManager assetManager) { + int COUNT_FACTOR = 1; + float COUNT_FACTOR_F = 1f; + effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR); + effect.setSelectRandomImage(true); + effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (1f / COUNT_FACTOR_F))); + effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); + effect.setStartSize(1.3f); + effect.setEndSize(2f); + effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); + effect.setParticlesPerSec(0); + effect.setGravity(0, -5f, 0); + effect.setLowLife(.4f); + effect.setHighLife(.5f); + effect.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, 7, 0)); + effect.getParticleInfluencer().setVelocityVariation(1f); + effect.setImagesX(2); + effect.setImagesY(2); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); + effect.setMaterial(mat); + } + + protected void createGhostObject() { + ghostObject = new PhysicsGhostObject(new SphereCollisionShape(explosionRadius)); + } + + @Override + public void collision(PhysicsCollisionEvent event) { + if (space == null) { + return; + } + if (event.getObjectA() == this || event.getObjectB() == this) { + space.add(ghostObject); + ghostObject.setPhysicsLocation(getPhysicsLocation(vector)); + space.addTickListener(this); + if (effect != null && spatial.getParent() != null) { + curTime = 0; + effect.setLocalTranslation(spatial.getLocalTranslation()); + spatial.getParent().attachChild(effect); + effect.emitAllParticles(); + } + space.remove(this); + spatial.removeFromParent(); + } + } + + @Override + public void prePhysicsTick(PhysicsSpace space, float f) { + space.removeCollisionListener(this); + } + + @Override + public void physicsTick(PhysicsSpace space, float f) { + //get all overlapping objects and apply impulse to them + for (Iterator it = ghostObject.getOverlappingObjects().iterator(); it.hasNext();) { + PhysicsCollisionObject physicsCollisionObject = it.next(); + if (physicsCollisionObject instanceof PhysicsRigidBody) { + PhysicsRigidBody rBody = (PhysicsRigidBody) physicsCollisionObject; + rBody.getPhysicsLocation(vector2); + vector2.subtractLocal(vector); + float force = explosionRadius - vector2.length(); + force *= forceFactor; + force = force > 0 ? force : 0; + vector2.normalizeLocal(); + vector2.multLocal(force); + ((PhysicsRigidBody) physicsCollisionObject).applyImpulse(vector2, Vector3f.ZERO); + } + } + space.removeTickListener(this); + space.remove(ghostObject); + } + + @Override + public void update(float tpf) { + super.update(tpf); + if(enabled){ + timer+=tpf; + if(timer>maxTime){ + if(spatial.getParent()!=null){ + space.removeCollisionListener(this); + space.remove(this); + spatial.removeFromParent(); + } + } + } + if (enabled && curTime >= 0) { + curTime += tpf; + if (curTime > fxTime) { + curTime = -1; + effect.removeFromParent(); + } + } + } + + /** + * @return the explosionRadius + */ + public float getExplosionRadius() { + return explosionRadius; + } + + /** + * @param explosionRadius the explosionRadius to set + */ + public void setExplosionRadius(float explosionRadius) { + this.explosionRadius = explosionRadius; + createGhostObject(); + } + + public float getForceFactor() { + return forceFactor; + } + + public void setForceFactor(float forceFactor) { + this.forceFactor = forceFactor; + } + + + @Override + public void read(JmeImporter im) throws IOException { + throw new UnsupportedOperationException("Reading not supported."); + } + + @Override + public void write(JmeExporter ex) throws IOException { + throw new UnsupportedOperationException("Saving not supported."); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java b/jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java new file mode 100644 index 0000000000..8f38323d26 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.PhysicsTickListener; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.PhysicsControl; +import com.jme3.bullet.objects.PhysicsVehicle; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Spatial; +import com.jme3.scene.control.Control; +import com.jme3.util.clone.Cloner; +import com.jme3.util.clone.JmeCloneable; +import java.io.IOException; + +/** + * PhysicsHoverControl uses a RayCast Vehicle with "slippery wheels" to simulate a hovering tank + * @author normenhansen + */ +public class PhysicsHoverControl extends PhysicsVehicle implements PhysicsControl, PhysicsTickListener, JmeCloneable { + + protected Spatial spatial; + protected boolean enabled = true; + protected PhysicsSpace space = null; + protected float steeringValue = 0; + protected float accelerationValue = 0; + protected int xw = 3; + protected int zw = 5; + protected int yw = 2; + protected Vector3f HOVER_HEIGHT_LF_START = new Vector3f(xw, 1, zw); + protected Vector3f HOVER_HEIGHT_RF_START = new Vector3f(-xw, 1, zw); + protected Vector3f HOVER_HEIGHT_LR_START = new Vector3f(xw, 1, -zw); + protected Vector3f HOVER_HEIGHT_RR_START = new Vector3f(-xw, 1, -zw); + protected Vector3f HOVER_HEIGHT_LF = new Vector3f(xw, -yw, zw); + protected Vector3f HOVER_HEIGHT_RF = new Vector3f(-xw, -yw, zw); + protected Vector3f HOVER_HEIGHT_LR = new Vector3f(xw, -yw, -zw); + protected Vector3f HOVER_HEIGHT_RR = new Vector3f(-xw, -yw, -zw); + protected Vector3f tempVect1 = new Vector3f(0, 0, 0); + protected Vector3f tempVect2 = new Vector3f(0, 0, 0); + protected Vector3f tempVect3 = new Vector3f(0, 0, 0); +// protected float rotationCounterForce = 10000f; +// protected float speedCounterMult = 2000f; +// protected float multiplier = 1000f; + + public PhysicsHoverControl() { + } + + /** + * Creates a new PhysicsNode with the supplied collision shape + * @param shape the desired collision shape + */ + public PhysicsHoverControl(CollisionShape shape) { + super(shape); + createWheels(); + } + + public PhysicsHoverControl(CollisionShape shape, float mass) { + super(shape, mass); + createWheels(); + } + + @Deprecated + @Override + public Control cloneForSpatial(Spatial spatial) { + throw new UnsupportedOperationException(); + } + + @Override + public Object jmeClone() { + throw new UnsupportedOperationException("Not yet implemented."); + } + + @Override + public void cloneFields( Cloner cloner, Object original ) { + throw new UnsupportedOperationException("Not yet implemented."); + } + + @Override + public void setSpatial(Spatial spatial) { + this.spatial = spatial; + setUserObject(spatial); + if (spatial == null) { + return; + } + setPhysicsLocation(spatial.getWorldTranslation()); + setPhysicsRotation(spatial.getWorldRotation().toRotationMatrix()); + } + + @Override + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Override + public boolean isEnabled() { + return enabled; + } + + private void createWheels() { + addWheel(HOVER_HEIGHT_LF_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); + addWheel(HOVER_HEIGHT_RF_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); + addWheel(HOVER_HEIGHT_LR_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); + addWheel(HOVER_HEIGHT_RR_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false); + for (int i = 0; i < 4; i++) { + getWheel(i).setFrictionSlip(0.001f); + } + } + + @Override + public void prePhysicsTick(PhysicsSpace space, float f) { + Vector3f angVel = getAngularVelocity(); + float rotationVelocity = angVel.getY(); + Vector3f dir = getForwardVector(tempVect2).multLocal(1, 0, 1).normalizeLocal(); + getLinearVelocity(tempVect3); + Vector3f linearVelocity = tempVect3.multLocal(1, 0, 1); + float groundSpeed = linearVelocity.length(); + + if (steeringValue != 0) { + if (rotationVelocity < 1 && rotationVelocity > -1) { + applyTorque(tempVect1.set(0, steeringValue, 0)); + } + } else { + // counter the steering value! + if (rotationVelocity > 0.2f) { + applyTorque(tempVect1.set(0, -mass * 20, 0)); + } else if (rotationVelocity < -0.2f) { + applyTorque(tempVect1.set(0, mass * 20, 0)); + } + } + if (accelerationValue > 0) { + // counter force that will adjust velocity + // if we are not going where we want to go. + // this will prevent "drifting" and thus improve control + // of the vehicle + if (groundSpeed > FastMath.ZERO_TOLERANCE) { + float d = dir.dot(linearVelocity.normalize()); + Vector3f counter = dir.project(linearVelocity).normalizeLocal().negateLocal().multLocal(1 - d); + applyForce(counter.multLocal(mass * 10), Vector3f.ZERO); + } + + if (linearVelocity.length() < 30) { + applyForce(dir.multLocal(accelerationValue), Vector3f.ZERO); + } + } else { + // counter the acceleration value + if (groundSpeed > FastMath.ZERO_TOLERANCE) { + linearVelocity.normalizeLocal().negateLocal(); + applyForce(linearVelocity.mult(mass * 10), Vector3f.ZERO); + } + } + } + + @Override + public void physicsTick(PhysicsSpace space, float f) { + } + + @Override + public void update(float tpf) { + if (enabled && spatial != null) { + getMotionState().applyTransform(spatial); + } + } + + @Override + public void render(RenderManager rm, ViewPort vp) { + } + + @Override + public void setPhysicsSpace(PhysicsSpace space) { + createVehicle(space); + if (space == null) { + if (this.space != null) { + this.space.removeCollisionObject(this); + this.space.removeTickListener(this); + } + this.space = space; + } else { + space.addCollisionObject(this); + space.addTickListener(this); + } + this.space = space; + } + + @Override + public PhysicsSpace getPhysicsSpace() { + return space; + } + + @Override + public void write(JmeExporter ex) throws IOException { + super.write(ex); + OutputCapsule oc = ex.getCapsule(this); + oc.write(enabled, "enabled", true); + oc.write(spatial, "spatial", null); + } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); + InputCapsule ic = im.getCapsule(this); + enabled = ic.readBoolean("enabled", true); + spatial = (Spatial) ic.readSavable("spatial", null); + } + + /** + * @param steeringValue the steeringValue to set + */ + @Override + public void steer(float steeringValue) { + this.steeringValue = steeringValue * getMass(); + } + + /** + * @param accelerationValue the accelerationValue to set + */ + @Override + public void accelerate(float accelerationValue) { + this.accelerationValue = accelerationValue * getMass(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java b/jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java new file mode 100644 index 0000000000..59d02d64c8 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/PhysicsTestHelper.java @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.Application; +import com.jme3.asset.AssetManager; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.collision.shapes.GImpactCollisionShape; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; +import com.jme3.texture.Texture; +import com.jme3.util.BufferUtils; + +/** + * + * @author normenhansen + */ +public class PhysicsTestHelper { + /** + * A private constructor to inhibit instantiation of this class. + */ + private PhysicsTestHelper() { + } + + /** + * creates a simple physics test world with a floor, an obstacle and some test boxes + * + * @param rootNode where lights and geometries should be added + * @param assetManager for loading assets + * @param space where collision objects should be added + */ + public static void createPhysicsTestWorld(Node rootNode, AssetManager assetManager, PhysicsSpace space) { + AmbientLight light = new AmbientLight(); + light.setColor(ColorRGBA.LightGray); + rootNode.addLight(light); + + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + + Box floorBox = new Box(140, 0.25f, 140); + Geometry floorGeometry = new Geometry("Floor", floorBox); + floorGeometry.setMaterial(material); + floorGeometry.setLocalTranslation(0, -5, 0); +// Plane plane = new Plane(); +// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y); +// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0)); + floorGeometry.addControl(new RigidBodyControl(0)); + rootNode.attachChild(floorGeometry); + space.add(floorGeometry); + + //movable boxes + for (int i = 0; i < 12; i++) { + Box box = new Box(0.25f, 0.25f, 0.25f); + Geometry boxGeometry = new Geometry("Box", box); + boxGeometry.setMaterial(material); + boxGeometry.setLocalTranslation(i, 5, -3); + //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh + boxGeometry.addControl(new RigidBodyControl(2)); + rootNode.attachChild(boxGeometry); + space.add(boxGeometry); + } + + //immovable sphere with mesh collision shape + Sphere sphere = new Sphere(8, 8, 1); + Geometry sphereGeometry = new Geometry("Sphere", sphere); + sphereGeometry.setMaterial(material); + sphereGeometry.setLocalTranslation(4, -4, 2); + sphereGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0)); + rootNode.attachChild(sphereGeometry); + space.add(sphereGeometry); + + } + + public static void createPhysicsTestWorldSoccer(Node rootNode, AssetManager assetManager, PhysicsSpace space) { + AmbientLight light = new AmbientLight(); + light.setColor(ColorRGBA.LightGray); + rootNode.addLight(light); + + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + + Box floorBox = new Box(20, 0.25f, 20); + Geometry floorGeometry = new Geometry("Floor", floorBox); + floorGeometry.setMaterial(material); + floorGeometry.setLocalTranslation(0, -0.25f, 0); +// Plane plane = new Plane(); +// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y); +// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0)); + floorGeometry.addControl(new RigidBodyControl(0)); + rootNode.attachChild(floorGeometry); + space.add(floorGeometry); + + //movable spheres + for (int i = 0; i < 5; i++) { + Sphere sphere = new Sphere(16, 16, .5f); + Geometry ballGeometry = new Geometry("Soccer ball", sphere); + ballGeometry.setMaterial(material); + ballGeometry.setLocalTranslation(i, 2, -3); + //RigidBodyControl automatically uses Sphere collision shapes when attached to single geometry with sphere mesh + ballGeometry.addControl(new RigidBodyControl(.001f)); + ballGeometry.getControl(RigidBodyControl.class).setRestitution(1); + rootNode.attachChild(ballGeometry); + space.add(ballGeometry); + } + { + //immovable Box with mesh collision shape + Box box = new Box(1, 1, 1); + Geometry boxGeometry = new Geometry("Box", box); + boxGeometry.setMaterial(material); + boxGeometry.setLocalTranslation(4, 1, 2); + boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0)); + rootNode.attachChild(boxGeometry); + space.add(boxGeometry); + } + { + //immovable Box with mesh collision shape + Box box = new Box(1, 1, 1); + Geometry boxGeometry = new Geometry("Box", box); + boxGeometry.setMaterial(material); + boxGeometry.setLocalTranslation(4, 3, 4); + boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0)); + rootNode.attachChild(boxGeometry); + space.add(boxGeometry); + } + } + + /** + * creates a box geometry with a RigidBodyControl + * + * @param assetManager for loading assets + * @return a new Geometry + */ + public static Geometry createPhysicsTestBox(AssetManager assetManager) { + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Box box = new Box(0.25f, 0.25f, 0.25f); + Geometry boxGeometry = new Geometry("Box", box); + boxGeometry.setMaterial(material); + //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh + boxGeometry.addControl(new RigidBodyControl(2)); + return boxGeometry; + } + + /** + * creates a sphere geometry with a RigidBodyControl + * + * @param assetManager for loading assets + * @return a new Geometry + */ + public static Geometry createPhysicsTestSphere(AssetManager assetManager) { + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Sphere sphere = new Sphere(8, 8, 0.25f); + Geometry boxGeometry = new Geometry("Sphere", sphere); + boxGeometry.setMaterial(material); + //RigidBodyControl automatically uses sphere collision shapes when attached to single geometry with sphere mesh + boxGeometry.addControl(new RigidBodyControl(2)); + return boxGeometry; + } + + /** + * creates an empty node with a RigidBodyControl + * + * @param manager for loading assets + * @param shape a shape for the collision object + * @param mass a mass for rigid body + * @return a new Node + */ + public static Node createPhysicsTestNode(AssetManager manager, CollisionShape shape, float mass) { + Node node = new Node("PhysicsNode"); + RigidBodyControl control = new RigidBodyControl(shape, mass); + node.addControl(control); + return node; + } + + /** + * creates the necessary input listener and action to shoot balls from the camera + * + * @param app the application that's running + * @param rootNode where ball geometries should be added + * @param space where collision objects should be added + */ + public static void createBallShooter(final Application app, final Node rootNode, final PhysicsSpace space) { + ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + Sphere bullet = new Sphere(32, 32, 0.4f, true, false); + bullet.setTextureMode(TextureMode.Projected); + Material mat2 = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); + key2.setGenerateMips(true); + Texture tex2 = app.getAssetManager().loadTexture(key2); + mat2.setTexture("ColorMap", tex2); + if (name.equals("shoot") && !keyPressed) { + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(mat2); + bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); + bulletGeometry.setLocalTranslation(app.getCamera().getLocation()); + RigidBodyControl bulletControl = new RigidBodyControl(10); + bulletGeometry.addControl(bulletControl); + bulletControl.setLinearVelocity(app.getCamera().getDirection().mult(25)); + bulletGeometry.addControl(bulletControl); + rootNode.attachChild(bulletGeometry); + space.add(bulletControl); + } + } + }; + app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + app.getInputManager().addListener(actionListener, "shoot"); + } + + /** + * Creates a curved "floor" with a GImpactCollisionShape provided as the RigidBodyControl's collision + * shape. Surface has four slightly concave corners to allow for multiple tests and minimize falling off + * the edge of the floor. + * + * @param assetManager for loading assets + * @param floorDimensions width/depth of the "floor" (X/Z) + * @param position sets the floor's local translation + * @return a new Geometry + */ + public static Geometry createGImpactTestFloor(AssetManager assetManager, float floorDimensions, Vector3f position) { + Geometry floor = createTestFloor(assetManager, floorDimensions, position, ColorRGBA.Red); + RigidBodyControl floorControl = new RigidBodyControl(new GImpactCollisionShape(floor.getMesh()), 0); + floor.addControl(floorControl); + return floor; + } + + /** + * Creates a curved "floor" with a MeshCollisionShape provided as the RigidBodyControl's collision shape. + * Surface has four slightly concave corners to allow for multiple tests and minimize falling off the edge + * of the floor. + * + * @param assetManager for loading assets + * @param floorDimensions width/depth of the "floor" (X/Z) + * @param position sets the floor's local translation + * @return a new Geometry + */ + public static Geometry createMeshTestFloor(AssetManager assetManager, float floorDimensions, Vector3f position) { + Geometry floor = createTestFloor(assetManager, floorDimensions, position, new ColorRGBA(0.5f, 0.5f, 0.9f, 1)); + RigidBodyControl floorControl = new RigidBodyControl(new MeshCollisionShape(floor.getMesh()), 0); + floor.addControl(floorControl); + return floor; + } + + private static Geometry createTestFloor(AssetManager assetManager, float floorDimensions, Vector3f position, ColorRGBA color) { + Geometry floor = new Geometry("floor", createFloorMesh(20, floorDimensions)); + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.getAdditionalRenderState().setWireframe(true); + material.setColor("Color", color); + floor.setMaterial(material); + floor.setLocalTranslation(position); + return floor; + } + + private static Mesh createFloorMesh(int meshDetail, float floorDimensions) { + if (meshDetail < 10) { + meshDetail = 10; + } + int numVertices = meshDetail * meshDetail * 2 * 3;//width * depth * two tris * 3 verts per tri + + int[] indexBuf = new int[numVertices]; + int i = 0; + for (int x = 0; x < meshDetail; x++) { + for (int z = 0; z < meshDetail; z++) { + indexBuf[i] = i++; + indexBuf[i] = i++; + indexBuf[i] = i++; + indexBuf[i] = i++; + indexBuf[i] = i++; + indexBuf[i] = i++; + } + } + + float[] vertBuf = new float[numVertices * 3]; + float xIncrement = floorDimensions / meshDetail; + float zIncrement = floorDimensions / meshDetail; + int j = 0; + for (int x = 0; x < meshDetail; x++) { + float xPos = x * xIncrement; + for (int z = 0; z < meshDetail; z++) { + float zPos = z * zIncrement; + //First tri + vertBuf[j++] = xPos; + vertBuf[j++] = getY(xPos, zPos, floorDimensions); + vertBuf[j++] = zPos; + vertBuf[j++] = xPos; + vertBuf[j++] = getY(xPos, zPos + zIncrement, floorDimensions); + vertBuf[j++] = zPos + zIncrement; + vertBuf[j++] = xPos + xIncrement; + vertBuf[j++] = getY(xPos + xIncrement, zPos, floorDimensions); + vertBuf[j++] = zPos; + //Second tri + vertBuf[j++] = xPos; + vertBuf[j++] = getY(xPos, zPos + zIncrement, floorDimensions); + vertBuf[j++] = zPos + zIncrement; + vertBuf[j++] = xPos + xIncrement; + vertBuf[j++] = getY(xPos + xIncrement, zPos + zIncrement, floorDimensions); + vertBuf[j++] = zPos + zIncrement; + vertBuf[j++] = xPos + xIncrement; + vertBuf[j++] = getY(xPos + xIncrement, zPos, floorDimensions); + vertBuf[j++] = zPos; + } + } + + Mesh m = new Mesh(); + m.setBuffer(VertexBuffer.Type.Index, 1, BufferUtils.createIntBuffer(indexBuf)); + m.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertBuf)); + m.updateBound(); + return m; + } + + private static float getY(float x, float z, float max) { + float yMaxHeight = 8; + float xv = FastMath.unInterpolateLinear(FastMath.abs(x - (max / 2)), 0, max) * FastMath.TWO_PI; + float zv = FastMath.unInterpolateLinear(FastMath.abs(z - (max / 2)), 0, max) * FastMath.TWO_PI; + + float xComp = (FastMath.sin(xv) + 1) * 0.5f; + float zComp = (FastMath.sin(zv) + 1) * 0.5f; + + return -yMaxHeight * xComp * zComp; + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java b/jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java new file mode 100644 index 0000000000..8c1c712603 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestAttachDriver.java @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2009-2023 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. + */ + +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.CompoundCollisionShape; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.control.VehicleControl; +import com.jme3.bullet.joints.SliderJoint; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Cylinder; +import com.jme3.texture.Texture; + +/** + * Tests attaching/detaching nodes via joints + * @author normenhansen + */ +public class TestAttachDriver extends SimpleApplication implements ActionListener { + + private VehicleControl vehicle; + private RigidBodyControl bridge; + private SliderJoint slider; + private final float accelerationForce = 1000.0f; + private final float brakeForce = 100.0f; + private float steeringValue = 0; + private float accelerationValue = 0; + final private Vector3f jumpForce = new Vector3f(0, 3000, 0); + private BulletAppState bulletAppState; + + public static void main(String[] args) { + TestAttachDriver app = new TestAttachDriver(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + setupKeys(); + setupFloor(); + buildPlayer(); + } + + private PhysicsSpace getPhysicsSpace(){ + return bulletAppState.getPhysicsSpace(); + } + + private void setupKeys() { + inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addListener(this, "Lefts"); + inputManager.addListener(this, "Rights"); + inputManager.addListener(this, "Ups"); + inputManager.addListener(this, "Downs"); + inputManager.addListener(this, "Space"); + inputManager.addListener(this, "Reset"); + } + + public void setupFloor() { + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key = new TextureKey("Interface/Logo/Monkey.jpg", true); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + tex.setMinFilter(Texture.MinFilter.Trilinear); + mat.setTexture("ColorMap", tex); + + Box floor = new Box(100, 1f, 100); + Geometry floorGeom = new Geometry("Floor", floor); + floorGeom.setMaterial(mat); + floorGeom.setLocalTranslation(new Vector3f(0f, -3, 0f)); + + floorGeom.addControl(new RigidBodyControl(new MeshCollisionShape(floorGeom.getMesh()), 0)); + rootNode.attachChild(floorGeom); + getPhysicsSpace().add(floorGeom); + } + + private void buildPlayer() { + Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + mat.getAdditionalRenderState().setWireframe(true); + mat.setColor("Color", ColorRGBA.Red); + + //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0 + //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0 + CompoundCollisionShape compoundShape = new CompoundCollisionShape(); + BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f)); + compoundShape.addChildShape(box, new Vector3f(0, 1, 0)); + + //create vehicle node + Node vehicleNode=new Node("vehicleNode"); + vehicle = new VehicleControl(compoundShape, 800); + vehicleNode.addControl(vehicle); + + //setting suspension values for wheels, this can be a bit tricky + //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en + float stiffness = 60.0f;//200=f1 car + float compValue = .3f; //(should be lower than damp) + float dampValue = .4f; + vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); + vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); + vehicle.setSuspensionStiffness(stiffness); + vehicle.setMaxSuspensionForce(10000.0f); + + //Create four wheels and add them at their locations + Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0 + Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0 + float radius = 0.5f; + float restLength = 0.3f; + float yOff = 0.5f; + float xOff = 1f; + float zOff = 2f; + + Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true); + + Node node1 = new Node("wheel 1 node"); + Geometry wheels1 = new Geometry("wheel 1", wheelMesh); + node1.attachChild(wheels1); + wheels1.rotate(0, FastMath.HALF_PI, 0); + wheels1.setMaterial(mat); + vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff), + wheelDirection, wheelAxle, restLength, radius, true); + + Node node2 = new Node("wheel 2 node"); + Geometry wheels2 = new Geometry("wheel 2", wheelMesh); + node2.attachChild(wheels2); + wheels2.rotate(0, FastMath.HALF_PI, 0); + wheels2.setMaterial(mat); + vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff), + wheelDirection, wheelAxle, restLength, radius, true); + + Node node3 = new Node("wheel 3 node"); + Geometry wheels3 = new Geometry("wheel 3", wheelMesh); + node3.attachChild(wheels3); + wheels3.rotate(0, FastMath.HALF_PI, 0); + wheels3.setMaterial(mat); + vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff), + wheelDirection, wheelAxle, restLength, radius, false); + + Node node4 = new Node("wheel 4 node"); + Geometry wheels4 = new Geometry("wheel 4", wheelMesh); + node4.attachChild(wheels4); + wheels4.rotate(0, FastMath.HALF_PI, 0); + wheels4.setMaterial(mat); + vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff), + wheelDirection, wheelAxle, restLength, radius, false); + + vehicleNode.attachChild(node1); + vehicleNode.attachChild(node2); + vehicleNode.attachChild(node3); + vehicleNode.attachChild(node4); + + rootNode.attachChild(vehicleNode); + getPhysicsSpace().add(vehicle); + + //driver + Node driverNode=new Node("driverNode"); + driverNode.setLocalTranslation(0,2,0); + RigidBodyControl driver + = new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,.5f,0.2f))); + driverNode.addControl(driver); + + rootNode.attachChild(driverNode); + getPhysicsSpace().add(driver); + + //joint + slider=new SliderJoint(driver, vehicle, Vector3f.UNIT_Y.negate(), Vector3f.UNIT_Y, true); + slider.setUpperLinLimit(.1f); + slider.setLowerLinLimit(-.1f); + + getPhysicsSpace().add(slider); + + Node pole1Node=new Node("pole1Node"); + Node pole2Node=new Node("pole1Node"); + Node bridgeNode=new Node("pole1Node"); + pole1Node.setLocalTranslation(new Vector3f(-2,-1,4)); + pole2Node.setLocalTranslation(new Vector3f(2,-1,4)); + bridgeNode.setLocalTranslation(new Vector3f(0,1.4f,4)); + + RigidBodyControl pole1=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0); + pole1Node.addControl(pole1); + RigidBodyControl pole2=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0); + pole2Node.addControl(pole2); + bridge=new RigidBodyControl(new BoxCollisionShape(new Vector3f(2.5f,0.2f,0.2f))); + bridgeNode.addControl(bridge); + + rootNode.attachChild(pole1Node); + rootNode.attachChild(pole2Node); + rootNode.attachChild(bridgeNode); + getPhysicsSpace().add(pole1); + getPhysicsSpace().add(pole2); + getPhysicsSpace().add(bridge); + + } + + @Override + public void simpleUpdate(float tpf) { + Quaternion quat=new Quaternion(); + cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Lefts")) { + if (value) { + steeringValue += .5f; + } else { + steeringValue -= .5f; + } + vehicle.steer(steeringValue); + } else if (binding.equals("Rights")) { + if (value) { + steeringValue -= .5f; + } else { + steeringValue += .5f; + } + vehicle.steer(steeringValue); + } else if (binding.equals("Ups")) { + if (value) { + accelerationValue += accelerationForce; + } else { + accelerationValue -= accelerationForce; + } + vehicle.accelerate(accelerationValue); + } else if (binding.equals("Downs")) { + if (value) { + vehicle.brake(brakeForce); + } else { + vehicle.brake(0f); + } + } else if (binding.equals("Space")) { + if (value) { + if (slider != null) { + getPhysicsSpace().remove(slider); + slider.destroy(); + slider = null; + } + vehicle.applyImpulse(jumpForce, Vector3f.ZERO); + } + } else if (binding.equals("Reset")) { + if (value) { + System.out.println("Reset"); + vehicle.setPhysicsLocation(new Vector3f(0, 0, 0)); + vehicle.setPhysicsRotation(new Matrix3f()); + vehicle.setLinearVelocity(Vector3f.ZERO); + vehicle.setAngularVelocity(Vector3f.ZERO); + vehicle.resetSuspension(); + bridge.setPhysicsLocation(new Vector3f(0,1.4f,4)); + bridge.setPhysicsRotation(Matrix3f.IDENTITY); + bridge.setLinearVelocity(Vector3f.ZERO); + bridge.setAngularVelocity(Vector3f.ZERO); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java b/jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java new file mode 100644 index 0000000000..f722899363 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.GhostControl; +import com.jme3.bullet.control.PhysicsControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.joints.HingeJoint; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; + +/** + * Tests attaching ghost nodes to physics nodes via the scene graph + * @author normenhansen + */ +public class TestAttachGhostObject extends SimpleApplication implements AnalogListener { + + private HingeJoint joint; + private GhostControl ghostControl; + private Node collisionNode; + private BulletAppState bulletAppState; + + public static void main(String[] args) { + TestAttachGhostObject app = new TestAttachGhostObject(); + app.start(); + } + + private void setupKeys() { + inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this, "Lefts", "Rights", "Space"); + } + + @Override + public void onAnalog(String binding, float value, float tpf) { + if (binding.equals("Lefts")) { + joint.enableMotor(true, 1, .1f); + } else if (binding.equals("Rights")) { + joint.enableMotor(true, -1, .1f); + } else if (binding.equals("Space")) { + joint.enableMotor(false, 0, 0); + } + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + setupKeys(); + setupJoint(); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + public void setupJoint() { + Node holderNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.1f, .1f, .1f)), 0); + holderNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, 0, 0f)); + rootNode.attachChild(holderNode); + getPhysicsSpace().add(holderNode); + + Node hammerNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.3f, .3f, .3f)), 1); + hammerNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -1, 0f)); + rootNode.attachChild(hammerNode); + getPhysicsSpace().add(hammerNode); + + //immovable + collisionNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.3f, .3f, .3f)), 0); + collisionNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(1.8f, 0, 0f)); + rootNode.attachChild(collisionNode); + getPhysicsSpace().add(collisionNode); + + //ghost node + ghostControl = new GhostControl(new SphereCollisionShape(0.7f)); + + hammerNode.addControl(ghostControl); + getPhysicsSpace().add(ghostControl); + + joint = new HingeJoint(holderNode.getControl(RigidBodyControl.class), hammerNode.getControl(RigidBodyControl.class), Vector3f.ZERO, new Vector3f(0f, -1, 0f), Vector3f.UNIT_Z, Vector3f.UNIT_Z); + getPhysicsSpace().add(joint); + } + + @Override + public void simpleUpdate(float tpf) { + if (ghostControl.getOverlappingObjects().contains(collisionNode.getControl(PhysicsControl.class))) { + fpsText.setText("collide"); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java b/jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java new file mode 100644 index 0000000000..25065c484b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestBetterCharacter.java @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.control.BetterCharacterControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.scene.CameraNode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.CameraControl.ControlDirection; +import com.jme3.scene.shape.Sphere; +import com.jme3.system.AppSettings; + +/** + * A walking physical character followed by a 3rd person camera. (No animation.) + * + * @author normenhansen, zathras + */ +public class TestBetterCharacter extends SimpleApplication implements ActionListener { + + private BulletAppState bulletAppState; + private BetterCharacterControl physicsCharacter; + private Node characterNode; + private CameraNode camNode; + final private Vector3f walkDirection = new Vector3f(0, 0, 0); + final private Vector3f viewDirection = new Vector3f(0, 0, 1); + private boolean leftStrafe = false, rightStrafe = false, forward = false, backward = false, + leftRotate = false, rightRotate = false; + final private Vector3f normalGravity = new Vector3f(0, -9.81f, 0); + private Geometry planet; + + public static void main(String[] args) { + TestBetterCharacter app = new TestBetterCharacter(); + AppSettings settings = new AppSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL2); + settings.setAudioRenderer(AppSettings.LWJGL_OPENAL); + app.setSettings(settings); + app.start(); + } + + @Override + public void simpleInitApp() { + //setup keyboard mapping + setupKeys(); + + // activate physics + bulletAppState = new BulletAppState() { + @Override + public void prePhysicsTick(PhysicsSpace space, float tpf) { + // Apply radial gravity near the planet, downward gravity elsewhere. + checkPlanetGravity(); + } + }; + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + + // init a physics test scene + PhysicsTestHelper.createPhysicsTestWorldSoccer(rootNode, assetManager, bulletAppState.getPhysicsSpace()); + PhysicsTestHelper.createBallShooter(this, rootNode, bulletAppState.getPhysicsSpace()); + setupPlanet(); + + // Create a node for the character model + characterNode = new Node("character node"); + characterNode.setLocalTranslation(new Vector3f(4, 5, 2)); + + // Add a character control to the node, so we can add other things and + // control the model rotation. + physicsCharacter = new BetterCharacterControl(0.3f, 2.5f, 8f); + characterNode.addControl(physicsCharacter); + getPhysicsSpace().add(physicsCharacter); + + // Load model, attach to character node + Node model = (Node) assetManager.loadModel("Models/Jaime/Jaime.j3o"); + model.setLocalScale(1.50f); + characterNode.attachChild(model); + + // Add character node to the rootNode + rootNode.attachChild(characterNode); + + cam.setLocation(new Vector3f(10f, 6f, -5f)); + + // Set forward camera node that follows the character, only used when + // view is "locked" + camNode = new CameraNode("CamNode", cam); + camNode.setControlDir(ControlDirection.SpatialToCamera); + camNode.setLocalTranslation(new Vector3f(0, 2, -6)); + Quaternion quat = new Quaternion(); + // These coordinates are local, the camNode is attached to the character node! + quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y); + camNode.setLocalRotation(quat); + characterNode.attachChild(camNode); + // Disable by default, can be enabled via keyboard shortcut + camNode.setEnabled(false); + } + + @Override + public void simpleUpdate(float tpf) { + // Get current forward and left vectors of model by using its rotation + // to rotate the unit vectors + Vector3f modelForwardDir = characterNode.getWorldRotation().mult(Vector3f.UNIT_Z); + Vector3f modelLeftDir = characterNode.getWorldRotation().mult(Vector3f.UNIT_X); + + // WalkDirection is global! + // You *can* make your character fly with this. + walkDirection.set(0, 0, 0); + if (leftStrafe) { + walkDirection.addLocal(modelLeftDir.mult(3)); + } else if (rightStrafe) { + walkDirection.addLocal(modelLeftDir.negate().multLocal(3)); + } + if (forward) { + walkDirection.addLocal(modelForwardDir.mult(3)); + } else if (backward) { + walkDirection.addLocal(modelForwardDir.negate().multLocal(3)); + } + physicsCharacter.setWalkDirection(walkDirection); + + // ViewDirection is local to characters physics system! + // The final world rotation depends on the gravity and on the state of + // setApplyPhysicsLocal() + if (leftRotate) { + Quaternion rotateL = new Quaternion().fromAngleAxis(FastMath.PI * tpf, Vector3f.UNIT_Y); + rotateL.multLocal(viewDirection); + } else if (rightRotate) { + Quaternion rotateR = new Quaternion().fromAngleAxis(-FastMath.PI * tpf, Vector3f.UNIT_Y); + rotateR.multLocal(viewDirection); + } + physicsCharacter.setViewDirection(viewDirection); + fpsText.setText("Touch da ground = " + physicsCharacter.isOnGround()); + if (!lockView) { + cam.lookAt(characterNode.getWorldTranslation().add(new Vector3f(0, 2, 0)), Vector3f.UNIT_Y); + } + } + + private void setupPlanet() { + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + //immovable sphere with mesh collision shape + Sphere sphere = new Sphere(64, 64, 20); + planet = new Geometry("Sphere", sphere); + planet.setMaterial(material); + planet.setLocalTranslation(30, -15, 30); + planet.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0)); + rootNode.attachChild(planet); + getPhysicsSpace().add(planet); + } + + private void checkPlanetGravity() { + Vector3f planetDist = planet.getWorldTranslation().subtract(characterNode.getWorldTranslation()); + if (planetDist.length() < 24) { + physicsCharacter.setGravity(planetDist.normalizeLocal().multLocal(9.81f)); + } else { + physicsCharacter.setGravity(normalGravity); + } + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Strafe Left")) { + if (value) { + leftStrafe = true; + } else { + leftStrafe = false; + } + } else if (binding.equals("Strafe Right")) { + if (value) { + rightStrafe = true; + } else { + rightStrafe = false; + } + } else if (binding.equals("Rotate Left")) { + if (value) { + leftRotate = true; + } else { + leftRotate = false; + } + } else if (binding.equals("Rotate Right")) { + if (value) { + rightRotate = true; + } else { + rightRotate = false; + } + } else if (binding.equals("Walk Forward")) { + if (value) { + forward = true; + } else { + forward = false; + } + } else if (binding.equals("Walk Backward")) { + if (value) { + backward = true; + } else { + backward = false; + } + } else if (binding.equals("Jump")) { + physicsCharacter.jump(); + } else if (binding.equals("Duck")) { + if (value) { + physicsCharacter.setDucked(true); + } else { + physicsCharacter.setDucked(false); + } + } else if (binding.equals("Lock View")) { + if (value && lockView) { + lockView = false; + } else if (value && !lockView) { + lockView = true; + } + flyCam.setEnabled(!lockView); + camNode.setEnabled(lockView); + } + } + private boolean lockView = false; + + private void setupKeys() { + inputManager.addMapping("Strafe Left", + new KeyTrigger(KeyInput.KEY_U), + new KeyTrigger(KeyInput.KEY_Z)); + inputManager.addMapping("Strafe Right", + new KeyTrigger(KeyInput.KEY_O), + new KeyTrigger(KeyInput.KEY_X)); + inputManager.addMapping("Rotate Left", + new KeyTrigger(KeyInput.KEY_J), + new KeyTrigger(KeyInput.KEY_LEFT)); + inputManager.addMapping("Rotate Right", + new KeyTrigger(KeyInput.KEY_L), + new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addMapping("Walk Forward", + new KeyTrigger(KeyInput.KEY_I), + new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("Walk Backward", + new KeyTrigger(KeyInput.KEY_K), + new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("Jump", + new KeyTrigger(KeyInput.KEY_F), + new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("Duck", + new KeyTrigger(KeyInput.KEY_G), + new KeyTrigger(KeyInput.KEY_LSHIFT), + new KeyTrigger(KeyInput.KEY_RSHIFT)); + inputManager.addMapping("Lock View", + new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addListener(this, "Strafe Left", "Strafe Right"); + inputManager.addListener(this, "Rotate Left", "Rotate Right"); + inputManager.addListener(this, "Walk Forward", "Walk Backward"); + inputManager.addListener(this, "Jump", "Duck", "Lock View"); + } + + @Override + public void simpleRender(RenderManager rm) { + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java b/jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java new file mode 100644 index 0000000000..538ec8b31c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.animation.DynamicAnimControl; +import com.jme3.bullet.animation.PhysicsLink; +import com.jme3.bullet.animation.RagdollCollisionListener; +import com.jme3.bullet.collision.PhysicsCollisionEvent; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; +import com.jme3.texture.Texture; + +/** + * @author normenhansen + */ +public class TestBoneRagdoll + extends SimpleApplication + implements ActionListener, RagdollCollisionListener { + + private AnimComposer composer; + private DynamicAnimControl ragdoll; + private float bulletSize = 1f; + private Material matBullet; + private Node model; + private PhysicsSpace physicsSpace; + private Sphere bullet; + private SphereCollisionShape bulletCollisionShape; + + public static void main(String[] args) { + TestBoneRagdoll app = new TestBoneRagdoll(); + app.start(); + } + + public void onStandDone() { + composer.setCurrentAction("IdleTop"); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("boom") && !isPressed) { + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(matBullet); + bulletGeometry.setLocalTranslation(cam.getLocation()); + bulletGeometry.setLocalScale(bulletSize); + bulletCollisionShape = new SphereCollisionShape(bulletSize); + BombControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1f); + bulletNode.setForceFactor(8f); + bulletNode.setExplosionRadius(20f); + bulletNode.setCcdMotionThreshold(0.001f); + bulletNode.setLinearVelocity(cam.getDirection().mult(180f)); + bulletGeometry.addControl(bulletNode); + rootNode.attachChild(bulletGeometry); + physicsSpace.add(bulletNode); + } + if (name.equals("bullet+") && isPressed) { + bulletSize += 0.1f; + } + if (name.equals("bullet-") && isPressed) { + bulletSize -= 0.1f; + } + if (name.equals("shoot") && !isPressed) { + Geometry bulletg = new Geometry("bullet", bullet); + bulletg.setMaterial(matBullet); + bulletg.setLocalTranslation(cam.getLocation()); + bulletg.setLocalScale(bulletSize); + bulletCollisionShape = new SphereCollisionShape(bulletSize); + RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, bulletSize * 10f); + bulletNode.setCcdMotionThreshold(0.001f); + bulletNode.setLinearVelocity(cam.getDirection().mult(80f)); + bulletg.addControl(bulletNode); + rootNode.attachChild(bulletg); + physicsSpace.add(bulletNode); + } + if (name.equals("stop") && isPressed) { + ragdoll.setEnabled(!ragdoll.isEnabled()); + ragdoll.setRagdollMode(); + } + if (name.equals("toggle") && isPressed) { + Vector3f v = new Vector3f(model.getLocalTranslation()); + v.y = 0f; + Quaternion q = new Quaternion(); + float[] angles = new float[3]; + model.getLocalRotation().toAngles(angles); + q.fromAngleAxis(angles[1], Vector3f.UNIT_Y); + Transform endModelTransform + = new Transform(v, q, new Vector3f(1f, 1f, 1f)); + if (angles[0] < 0f) { + composer.setCurrentAction("BackOnce"); + ragdoll.blendToKinematicMode(0.5f, endModelTransform); + } else { + composer.setCurrentAction("FrontOnce"); + ragdoll.blendToKinematicMode(0.5f, endModelTransform); + } + } + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(50f); + cam.setLocation(new Vector3f(0.3f, 6.7f, 22.3f)); + cam.setRotation(new Quaternion(-2E-4f, 0.993025f, -0.1179f, -0.0019f)); + + initCrossHairs(); + initMaterial(); + setupKeys(); + setupLight(); + + BulletAppState bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + //bulletAppState.setDebugEnabled(true); + physicsSpace = bulletAppState.getPhysicsSpace(); + + bullet = new Sphere(32, 32, 1f, true, false); + bullet.setTextureMode(TextureMode.Projected); + bulletCollisionShape = new SphereCollisionShape(1f); + + PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, + physicsSpace); + + model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); + rootNode.attachChild(model); + + composer = model.getControl(AnimComposer.class); + composer.setCurrentAction("Dance"); + + Action standUpFront = composer.action("StandUpFront"); + composer.actionSequence("FrontOnce", + standUpFront, Tweens.callMethod(this, "onStandDone")); + Action standUpBack = composer.action("StandUpBack"); + composer.actionSequence("BackOnce", + standUpBack, Tweens.callMethod(this, "onStandDone")); + + ragdoll = new DynamicAnimControl(); + TestRagdollCharacter.setupSinbad(ragdoll); + model.addControl(ragdoll); + physicsSpace.add(ragdoll); + ragdoll.addCollisionListener(this); + } + + @Override + public void collide(PhysicsLink bone, PhysicsCollisionObject object, + PhysicsCollisionEvent event) { + if (object.getUserObject() != null + && object.getUserObject() instanceof Geometry) { + Geometry geom = (Geometry) object.getUserObject(); + if ("bullet".equals(geom.getName())) { + ragdoll.setRagdollMode(); + } + } + } + + private void initCrossHairs() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2f); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2f - guiFont.getCharSet().getRenderedSize() / 3f * 2f, + settings.getHeight() / 2f + ch.getLineHeight() / 2f, 0f); + guiNode.attachChild(ch); + } + + private void initMaterial() { + matBullet = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); + key2.setGenerateMips(true); + Texture tex2 = assetManager.loadTexture(key2); + matBullet.setTexture("ColorMap", tex2); + } + + private void setupKeys() { + inputManager.addMapping("boom", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + inputManager.addMapping("bullet+", new KeyTrigger(KeyInput.KEY_PERIOD)); + inputManager.addMapping("bullet-", new KeyTrigger(KeyInput.KEY_COMMA)); + inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + + inputManager.addListener(this, + "boom", "bullet-", "bullet+", "shoot", "stop", "toggle"); + + } + + private void setupLight() { + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1f).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1f)); + rootNode.addLight(dl); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java b/jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java new file mode 100644 index 0000000000..a265bdba96 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestBrickTower.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +/* + * Copyright (c) 2009-2012 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. + */ + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.font.BitmapText; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; + +/** + * + * @author double1984 (tower mod by atom) + */ +public class TestBrickTower extends SimpleApplication { + + final private int bricksPerLayer = 8; + final private int brickLayers = 30; + + final private static float brickWidth = .75f, brickHeight = .25f, brickDepth = .25f; + final private float radius = 3f; + private float angle = 0; + + + private Material mat; + private Material mat2; + private Material mat3; + private Sphere bullet; + private Box brick; + private SphereCollisionShape bulletCollisionShape; + + private BulletAppState bulletAppState; + + public static void main(String args[]) { + TestBrickTower f = new TestBrickTower(); + f.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); + // bulletAppState.setEnabled(false); + stateManager.attach(bulletAppState); + bullet = new Sphere(32, 32, 0.4f, true, false); + bullet.setTextureMode(TextureMode.Projected); + bulletCollisionShape = new SphereCollisionShape(0.4f); + + brick = new Box(brickWidth, brickHeight, brickDepth); + brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); + initMaterial(); + initTower(); + initFloor(); + initCrossHairs(); + this.cam.setLocation(new Vector3f(0, 25f, 8f)); + cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0)); + cam.setFrustumFar(80); + inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(actionListener, "shoot"); + rootNode.setShadowMode(ShadowMode.Off); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + final private ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("shoot") && !keyPressed) { + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(mat2); + bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); + bulletGeometry.setLocalTranslation(cam.getLocation()); + RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); +// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); + bulletNode.setLinearVelocity(cam.getDirection().mult(25)); + bulletGeometry.addControl(bulletNode); + rootNode.attachChild(bulletGeometry); + getPhysicsSpace().add(bulletNode); + } + } + }; + + public void initTower() { + double tempX = 0; + double tempY = 0; + double tempZ = 0; + angle = 0f; + for (int i = 0; i < brickLayers; i++){ + // Increment rows + if(i!=0) + tempY+=brickHeight*2; + else + tempY=brickHeight; + // Alternate brick seams + angle = 360.0f / bricksPerLayer * i/2f; + for (int j = 0; j < bricksPerLayer; j++){ + tempZ = Math.cos(Math.toRadians(angle))*radius; + tempX = Math.sin(Math.toRadians(angle))*radius; + System.out.println("x="+((float)(tempX))+" y="+((float)(tempY))+" z="+(float)(tempZ)); + Vector3f vt = new Vector3f((float)(tempX), (float)(tempY), (float)(tempZ)); + // Add crenelation + if (i==brickLayers-1){ + if (j%2 == 0){ + addBrick(vt); + } + } + // Create main tower + else { + addBrick(vt); + } + angle += 360.0/bricksPerLayer; + } + } + + } + + public void initFloor() { + Box floorBox = new Box(10f, 0.1f, 5f); + floorBox.scaleTextureCoordinates(new Vector2f(3, 6)); + + Geometry floor = new Geometry("floor", floorBox); + floor.setMaterial(mat3); + floor.setShadowMode(ShadowMode.Receive); + floor.setLocalTranslation(0, 0, 0); + floor.addControl(new RigidBodyControl(0)); + this.rootNode.attachChild(floor); + this.getPhysicsSpace().add(floor); + } + + public void initMaterial() { + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + mat.setTexture("ColorMap", tex); + + mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); + key2.setGenerateMips(true); + Texture tex2 = assetManager.loadTexture(key2); + mat2.setTexture("ColorMap", tex2); + + mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); + key3.setGenerateMips(true); + Texture tex3 = assetManager.loadTexture(key3); + tex3.setWrap(WrapMode.Repeat); + mat3.setTexture("ColorMap", tex3); + } + + public void addBrick(Vector3f ori) { + Geometry brickGeometry = new Geometry("brick", brick); + brickGeometry.setMaterial(mat); + brickGeometry.setLocalTranslation(ori); + brickGeometry.rotate(0f, (float)Math.toRadians(angle) , 0f ); + brickGeometry.addControl(new RigidBodyControl(1.5f)); + brickGeometry.setShadowMode(ShadowMode.CastAndReceive); + brickGeometry.getControl(RigidBodyControl.class).setFriction(1.6f); + this.rootNode.attachChild(brickGeometry); + this.getPhysicsSpace().add(brickGeometry); + } + + protected void initCrossHairs() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, + settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); + guiNode.attachChild(ch); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java b/jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java new file mode 100644 index 0000000000..d0cbdb2bba --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestBrickWall.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; + +/** + * + * @author double1984 + */ +public class TestBrickWall extends SimpleApplication { + + final private static float bLength = 0.48f; + final private static float bWidth = 0.24f; + final private static float bHeight = 0.12f; + private Material mat; + private Material mat2; + private Material mat3; + private static Sphere bullet; + private static Box brick; + + private BulletAppState bulletAppState; + + public static void main(String args[]) { + TestBrickWall f = new TestBrickWall(); + f.start(); + } + + @Override + public void simpleInitApp() { + + bulletAppState = new BulletAppState(); + bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); + stateManager.attach(bulletAppState); + + bullet = new Sphere(32, 32, 0.4f, true, false); + bullet.setTextureMode(TextureMode.Projected); + brick = new Box(bLength, bHeight, bWidth); + brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); + + initMaterial(); + initWall(); + initFloor(); + initCrossHairs(); + this.cam.setLocation(new Vector3f(0, 6f, 6f)); + cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0)); + cam.setFrustumFar(15); + inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(actionListener, "shoot"); + inputManager.addMapping("gc", new KeyTrigger(KeyInput.KEY_X)); + inputManager.addListener(actionListener, "gc"); + + rootNode.setShadowMode(ShadowMode.Off); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + final private ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("shoot") && !keyPressed) { + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(mat2); + bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); + bulletGeometry.setLocalTranslation(cam.getLocation()); + + SphereCollisionShape bulletCollisionShape = new SphereCollisionShape(0.4f); + RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); +// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); + bulletNode.setLinearVelocity(cam.getDirection().mult(25)); + bulletGeometry.addControl(bulletNode); + rootNode.attachChild(bulletGeometry); + getPhysicsSpace().add(bulletNode); + } + if (name.equals("gc") && !keyPressed) { + System.gc(); + } + } + }; + + public void initWall() { + float startX = bLength / 4; + float height = 0; + for (int j = 0; j < 15; j++) { + for (int i = 0; i < 4; i++) { + Vector3f vt = new Vector3f(i * bLength * 2 + startX, bHeight + height, 0); + addBrick(vt); + } + startX = -startX; + height += 2 * bHeight; + } + } + + public void initFloor() { + Box floorBox = new Box(10f, 0.1f, 5f); + floorBox.scaleTextureCoordinates(new Vector2f(3, 6)); + + Geometry floor = new Geometry("floor", floorBox); + floor.setMaterial(mat3); + floor.setShadowMode(ShadowMode.Receive); + floor.setLocalTranslation(0, -0.1f, 0); + floor.addControl(new RigidBodyControl(new BoxCollisionShape(new Vector3f(10f, 0.1f, 5f)), 0)); + this.rootNode.attachChild(floor); + this.getPhysicsSpace().add(floor); + } + + public void initMaterial() { + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + mat.setTexture("ColorMap", tex); + + mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); + key2.setGenerateMips(true); + Texture tex2 = assetManager.loadTexture(key2); + mat2.setTexture("ColorMap", tex2); + + mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); + key3.setGenerateMips(true); + Texture tex3 = assetManager.loadTexture(key3); + tex3.setWrap(WrapMode.Repeat); + mat3.setTexture("ColorMap", tex3); + } + + public void addBrick(Vector3f ori) { + + Geometry brickGeometry = new Geometry("brick", brick); + brickGeometry.setMaterial(mat); + brickGeometry.setLocalTranslation(ori); + //for geometry with sphere mesh the physics system automatically uses a sphere collision shape + brickGeometry.addControl(new RigidBodyControl(1.5f)); + brickGeometry.setShadowMode(ShadowMode.CastAndReceive); + brickGeometry.getControl(RigidBodyControl.class).setFriction(0.6f); + this.rootNode.attachChild(brickGeometry); + this.getPhysicsSpace().add(brickGeometry); + } + + protected void initCrossHairs() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, + settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); + guiNode.attachChild(ch); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCcd.java b/jme3-examples/src/main/java/jme3test/bullet/TestCcd.java new file mode 100644 index 0000000000..3c5ff09282 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestCcd.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; + +/** + * + * @author normenhansen + */ +public class TestCcd extends SimpleApplication implements ActionListener { + + private Material mat; + private Material mat2; + private Sphere bullet; + private SphereCollisionShape bulletCollisionShape; + private BulletAppState bulletAppState; + + public static void main(String[] args) { + TestCcd app = new TestCcd(); + app.start(); + } + + private void setupKeys() { + inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addMapping("shoot2", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + inputManager.addListener(this, "shoot"); + inputManager.addListener(this, "shoot2"); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + bullet = new Sphere(32, 32, 0.4f, true, false); + bullet.setTextureMode(TextureMode.Projected); + bulletCollisionShape = new SphereCollisionShape(0.1f); + setupKeys(); + + mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + mat.getAdditionalRenderState().setWireframe(true); + mat.setColor("Color", ColorRGBA.Green); + + mat2 = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.getAdditionalRenderState().setWireframe(true); + mat2.setColor("Color", ColorRGBA.Red); + + // An obstacle mesh, does not move (mass=0) + Node node2 = new Node(); + node2.setName("mesh"); + node2.setLocalTranslation(new Vector3f(2.5f, 0, 0f)); + node2.addControl(new RigidBodyControl(new MeshCollisionShape(new Box(4, 4, 0.1f)), 0)); + rootNode.attachChild(node2); + getPhysicsSpace().add(node2); + + // The floor, does not move (mass=0) + Node node3 = new Node(); + node3.setLocalTranslation(new Vector3f(0f, -6, 0f)); + node3.addControl(new RigidBodyControl(new BoxCollisionShape(new Vector3f(100, 1, 100)), 0)); + rootNode.attachChild(node3); + getPhysicsSpace().add(node3); + + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleUpdate(float tpf) { + //TODO: add update code + } + + @Override + public void simpleRender(RenderManager rm) { + //TODO: add render code + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("shoot") && !value) { + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(mat); + bulletGeometry.setName("bullet"); + bulletGeometry.setLocalTranslation(cam.getLocation()); + bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); + bulletGeometry.addControl(new RigidBodyControl(bulletCollisionShape, 1)); + bulletGeometry.getControl(RigidBodyControl.class).setCcdMotionThreshold(0.1f); + bulletGeometry.getControl(RigidBodyControl.class).setLinearVelocity(cam.getDirection().mult(40)); + rootNode.attachChild(bulletGeometry); + getPhysicsSpace().add(bulletGeometry); + } else if (binding.equals("shoot2") && !value) { + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(mat2); + bulletGeometry.setName("bullet"); + bulletGeometry.setLocalTranslation(cam.getLocation()); + bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); + bulletGeometry.addControl(new RigidBodyControl(bulletCollisionShape, 1)); + bulletGeometry.getControl(RigidBodyControl.class).setLinearVelocity(cam.getDirection().mult(40)); + rootNode.attachChild(bulletGeometry); + getPhysicsSpace().add(bulletGeometry); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java new file mode 100644 index 0000000000..516345d47d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionGroups.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; + +/** + * + * @author normenhansen + */ +public class TestCollisionGroups extends SimpleApplication { + + private BulletAppState bulletAppState; + + public static void main(String[] args) { + TestCollisionGroups app = new TestCollisionGroups(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + + // Add a physics sphere to the world + Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); + physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); + rootNode.attachChild(physicsSphere); + getPhysicsSpace().add(physicsSphere); + + // Add a physics sphere to the world + Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); + physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); + physicsSphere2.getControl(RigidBodyControl.class).addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_02); + rootNode.attachChild(physicsSphere2); + getPhysicsSpace().add(physicsSphere2); + + // an obstacle mesh, does not move (mass=0) + Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); + node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); + node2.getControl(RigidBodyControl.class).setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02); + node2.getControl(RigidBodyControl.class).setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_02); + rootNode.attachChild(node2); + getPhysicsSpace().add(node2); + + // the floor, does not move (mass=0) + Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Box(100f, 0.2f, 100f)), 0); + node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); + rootNode.attachChild(node3); + getPhysicsSpace().add(node3); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleUpdate(float tpf) { + //TODO: add update code + } + + @Override + public void simpleRender(RenderManager rm) { + //TODO: add render code + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java new file mode 100644 index 0000000000..01714f5b3b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.PhysicsCollisionEvent; +import com.jme3.bullet.collision.PhysicsCollisionListener; +import com.jme3.renderer.RenderManager; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; + +/** + * + * @author normenhansen + */ +public class TestCollisionListener extends SimpleApplication implements PhysicsCollisionListener { + + private BulletAppState bulletAppState; + + public static void main(String[] args) { + TestCollisionListener app = new TestCollisionListener(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + Sphere bullet = new Sphere(32, 32, 0.4f, true, false); + bullet.setTextureMode(TextureMode.Projected); + + PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); + PhysicsTestHelper.createBallShooter(this, rootNode, bulletAppState.getPhysicsSpace()); + + // add ourselves as collision listener + getPhysicsSpace().addCollisionListener(this); + } + + private PhysicsSpace getPhysicsSpace(){ + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleUpdate(float tpf) { + //TODO: add update code + } + + @Override + public void simpleRender(RenderManager rm) { + //TODO: add render code + } + + @Override + public void collision(PhysicsCollisionEvent event) { + if ("Box".equals(event.getNodeA().getName()) || "Box".equals(event.getNodeB().getName())) { + if ("bullet".equals(event.getNodeA().getName()) || "bullet".equals(event.getNodeB().getName())) { + fpsText.setText("You hit the box!"); + } + } + } + +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java new file mode 100644 index 0000000000..2128149d25 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestCollisionShapeFactory.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Cylinder; +import com.jme3.scene.shape.Torus; + +/** + * This is a basic Test of jbullet-jme functions + * + * @author normenhansen + */ +public class TestCollisionShapeFactory extends SimpleApplication { + + private BulletAppState bulletAppState; + private Material mat1; + private Material mat2; + private Material mat3; + + public static void main(String[] args) { + TestCollisionShapeFactory app = new TestCollisionShapeFactory(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + createMaterial(); + + Node node = new Node("node1"); + attachRandomGeometry(node, mat1); + randomizeTransform(node); + + Node node2 = new Node("node2"); + attachRandomGeometry(node2, mat2); + randomizeTransform(node2); + + node.attachChild(node2); + rootNode.attachChild(node); + + RigidBodyControl control = new RigidBodyControl(0); + node.addControl(control); + getPhysicsSpace().add(control); + + //test single geometry too + Geometry myGeom = new Geometry("cylinder", new Cylinder(16, 16, 0.5f, 1)); + myGeom.setMaterial(mat3); + randomizeTransform(myGeom); + rootNode.attachChild(myGeom); + RigidBodyControl control3 = new RigidBodyControl(0); + myGeom.addControl(control3); + getPhysicsSpace().add(control3); + } + + private void attachRandomGeometry(Node node, Material mat) { + Box box = new Box(0.25f, 0.25f, 0.25f); + Torus torus = new Torus(16, 16, 0.2f, 0.8f); + Geometry[] boxes = new Geometry[]{ + new Geometry("box1", box), + new Geometry("box2", box), + new Geometry("box3", box), + new Geometry("torus1", torus), + new Geometry("torus2", torus), + new Geometry("torus3", torus) + }; + for (int i = 0; i < boxes.length; i++) { + Geometry geometry = boxes[i]; + geometry.setLocalTranslation((float) Math.random() * 10 -10, (float) Math.random() * 10 -10, (float) Math.random() * 10 -10); + geometry.setLocalRotation(new Quaternion().fromAngles((float) Math.random() * FastMath.PI, (float) Math.random() * FastMath.PI, (float) Math.random() * FastMath.PI)); + geometry.setLocalScale((float) Math.random() * 10 -10, (float) Math.random() * 10 -10, (float) Math.random() * 10 -10); + geometry.setMaterial(mat); + node.attachChild(geometry); + } + } + + private void randomizeTransform(Spatial spat){ + spat.setLocalTranslation((float) Math.random() * 10, (float) Math.random() * 10, (float) Math.random() * 10); + spat.setLocalTranslation((float) Math.random() * 10, (float) Math.random() * 10, (float) Math.random() * 10); + spat.setLocalScale((float) Math.random() * 2, (float) Math.random() * 2, (float) Math.random() * 2); + } + + private void createMaterial() { + mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.Green); + mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.setColor("Color", ColorRGBA.Red); + mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat3.setColor("Color", ColorRGBA.Yellow); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java b/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java new file mode 100644 index 0000000000..ce21b1f15b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.VehicleControl; +import com.jme3.bullet.util.CollisionShapeFactory; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.FastMath; +import com.jme3.math.Matrix3f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; + +public class TestFancyCar extends SimpleApplication implements ActionListener { + + private BulletAppState bulletAppState; + private VehicleControl player; + private float steeringValue = 0; + private float accelerationValue = 0; + private Node carNode; + + public static void main(String[] args) { + TestFancyCar app = new TestFancyCar(); + app.start(); + } + + private void setupKeys() { + inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addListener(this, "Lefts"); + inputManager.addListener(this, "Rights"); + inputManager.addListener(this, "Ups"); + inputManager.addListener(this, "Downs"); + inputManager.addListener(this, "Reset"); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + cam.setFrustumFar(150f); + flyCam.setMoveSpeed(10); + + setupKeys(); + PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, getPhysicsSpace()); + buildPlayer(); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.5f, -1f, -0.3f).normalizeLocal()); + rootNode.addLight(dl); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + private Geometry findGeom(Spatial spatial, String name) { + if (spatial instanceof Node) { + Node node = (Node) spatial; + for (int i = 0; i < node.getQuantity(); i++) { + Spatial child = node.getChild(i); + Geometry result = findGeom(child, name); + if (result != null) { + return result; + } + } + } else if (spatial instanceof Geometry) { + if (spatial.getName().startsWith(name)) { + return (Geometry) spatial; + } + } + return null; + } + + private void buildPlayer() { + float stiffness = 120.0f;//200=f1 car + float compValue = 0.2f; //(lower than damp!) + float dampValue = 0.3f; + final float mass = 400; + + // Load model and get chassis Geometry + carNode = (Node) assetManager.loadModel("Models/Ferrari/Car.scene"); + carNode.setShadowMode(ShadowMode.Cast); + Geometry chassis = findGeom(carNode, "Car"); + + // Create a hull collision shape for the chassis + CollisionShape carHull = CollisionShapeFactory.createDynamicMeshShape(chassis); + + // Create a vehicle control + player = new VehicleControl(carHull, mass); + carNode.addControl(player); + + // Setting default values for wheels + player.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); + player.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); + player.setSuspensionStiffness(stiffness); + player.setMaxSuspensionForce(10000); + + // Create four wheels and add them at their locations. + // Note that our fancy car actually goes backward. + Vector3f wheelDirection = new Vector3f(0, -1, 0); + Vector3f wheelAxle = new Vector3f(-1, 0, 0); + + Geometry wheel_fr = findGeom(carNode, "WheelFrontRight"); + wheel_fr.center(); + BoundingBox box = (BoundingBox) wheel_fr.getModelBound(); + float wheelRadius = box.getYExtent(); + float back_wheel_h = (wheelRadius * 1.7f) - 1f; + float front_wheel_h = (wheelRadius * 1.9f) - 1f; + player.addWheel(wheel_fr.getParent(), box.getCenter().add(0, -front_wheel_h, 0), + wheelDirection, wheelAxle, 0.2f, wheelRadius, true); + + Geometry wheel_fl = findGeom(carNode, "WheelFrontLeft"); + wheel_fl.center(); + box = (BoundingBox) wheel_fl.getModelBound(); + player.addWheel(wheel_fl.getParent(), box.getCenter().add(0, -front_wheel_h, 0), + wheelDirection, wheelAxle, 0.2f, wheelRadius, true); + + Geometry wheel_br = findGeom(carNode, "WheelBackRight"); + wheel_br.center(); + box = (BoundingBox) wheel_br.getModelBound(); + player.addWheel(wheel_br.getParent(), box.getCenter().add(0, -back_wheel_h, 0), + wheelDirection, wheelAxle, 0.2f, wheelRadius, false); + + Geometry wheel_bl = findGeom(carNode, "WheelBackLeft"); + wheel_bl.center(); + box = (BoundingBox) wheel_bl.getModelBound(); + player.addWheel(wheel_bl.getParent(), box.getCenter().add(0, -back_wheel_h, 0), + wheelDirection, wheelAxle, 0.2f, wheelRadius, false); + + player.getWheel(2).setFrictionSlip(4); + player.getWheel(3).setFrictionSlip(4); + + rootNode.attachChild(carNode); + getPhysicsSpace().add(player); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Lefts")) { + if (value) { + steeringValue += .5f; + } else { + steeringValue -= .5f; + } + player.steer(steeringValue); + } else if (binding.equals("Rights")) { + if (value) { + steeringValue -= .5f; + } else { + steeringValue += .5f; + } + player.steer(steeringValue); + } // Note that our fancy car actually goes backward. + else if (binding.equals("Ups")) { + if (value) { + accelerationValue -= 800; + } else { + accelerationValue += 800; + } + player.accelerate(accelerationValue); + } else if (binding.equals("Downs")) { + if (value) { + player.brake(40f); + } else { + player.brake(0f); + } + } else if (binding.equals("Reset")) { + if (value) { + System.out.println("Reset"); + player.setPhysicsLocation(Vector3f.ZERO); + player.setPhysicsRotation(new Matrix3f()); + player.setLinearVelocity(Vector3f.ZERO); + player.setAngularVelocity(Vector3f.ZERO); + player.resetSuspension(); + } + } + } + + @Override + public void simpleUpdate(float tpf) { + cam.lookAt(carNode.getWorldTranslation(), Vector3f.UNIT_Y); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java b/jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java new file mode 100644 index 0000000000..2ea1af0ab2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.bullet; + +import com.jme3.app.Application; +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.GhostControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; + +/** + * + * @author tim8dev [at] gmail [dot com] + */ +public class TestGhostObject extends SimpleApplication { + + private BulletAppState bulletAppState; + private GhostControl ghostControl; + + public static void main(String[] args) { + Application app = new TestGhostObject(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + + // Mesh to be shared across several boxes. + Box boxGeom = new Box(1f, 1f, 1f); + // CollisionShape to be shared across several boxes. + CollisionShape shape = new BoxCollisionShape(new Vector3f(1, 1, 1)); + + Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, shape, 1); + physicsBox.setName("box0"); + physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); + rootNode.attachChild(physicsBox); + getPhysicsSpace().add(physicsBox); + + Node physicsBox1 = PhysicsTestHelper.createPhysicsTestNode(assetManager, shape, 1); + physicsBox1.setName("box1"); + physicsBox1.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0, 40, 0)); + rootNode.attachChild(physicsBox1); + getPhysicsSpace().add(physicsBox1); + + Node physicsBox2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); + physicsBox2.setName("box0"); + physicsBox2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.5f, 80, -.8f)); + rootNode.attachChild(physicsBox2); + getPhysicsSpace().add(physicsBox2); + + // the floor, does not move (mass=0) + Node node = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(100, 1, 100)), 0); + node.setName("floor"); + node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); + rootNode.attachChild(node); + getPhysicsSpace().add(node); + + initGhostObject(); + } + + private PhysicsSpace getPhysicsSpace(){ + return bulletAppState.getPhysicsSpace(); + } + + private void initGhostObject() { + Vector3f halfExtents = new Vector3f(3, 4.2f, 1); + ghostControl = new GhostControl(new BoxCollisionShape(halfExtents)); + Node node=new Node("Ghost Object"); + node.addControl(ghostControl); + rootNode.attachChild(node); + getPhysicsSpace().add(ghostControl); + } + + @Override + public void simpleUpdate(float tpf) { + fpsText.setText("Overlapping objects: " + ghostControl.getOverlappingObjects().toString()); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java b/jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java new file mode 100644 index 0000000000..3127ec4a68 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestHoveringTank.java @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.util.CollisionShapeFactory; +import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.renderer.Camera; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Spatial; +import com.jme3.shadow.DirectionalLightShadowRenderer; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; +import java.util.ArrayList; +import java.util.List; + +public class TestHoveringTank extends SimpleApplication implements AnalogListener, + ActionListener { + + private BulletAppState bulletAppState; + private PhysicsHoverControl hoverControl; + private Spatial spaceCraft; + /** + * initial location of the tank (in world/physics-space coordinates) + */ + final private Vector3f startLocation = new Vector3f(-140f, 50f, -23f); + /** + * initial orientation of the tank (in world/physics-space coordinates) + */ + final private Quaternion startOrientation + = new Quaternion(new float[]{0f, 0.01f, 0f}); + + public static void main(String[] args) { + TestHoveringTank app = new TestHoveringTank(); + app.start(); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + private void setupKeys() { + inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addListener(this, "Lefts"); + inputManager.addListener(this, "Rights"); + inputManager.addListener(this, "Ups"); + inputManager.addListener(this, "Downs"); + inputManager.addListener(this, "Space"); + inputManager.addListener(this, "Reset"); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); + stateManager.attach(bulletAppState); + bulletAppState.getPhysicsSpace().setAccuracy(1f/30f); + rootNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", EnvMapType.CubeMap)); + + DirectionalLightShadowRenderer dlsr + = new DirectionalLightShadowRenderer(assetManager, 2048, 3); + dlsr.setLambda(0.55f); + dlsr.setShadowIntensity(0.6f); + dlsr.setEdgeFilteringMode(EdgeFilteringMode.Bilinear); + viewPort.addProcessor(dlsr); + + setupKeys(); + createTerrain(); + buildPlayer(); + + DirectionalLight dl = new DirectionalLight(); + dlsr.setLight(dl); + dl.setColor(new ColorRGBA(1.0f, 0.94f, 0.8f, 1f).multLocal(1.3f)); + dl.setDirection(new Vector3f(-0.5f, -0.3f, -0.3f).normalizeLocal()); + rootNode.addLight(dl); + + Vector3f lightDir2 = new Vector3f(0.70518064f, 0.5902297f, -0.39287305f); + DirectionalLight dl2 = new DirectionalLight(); + dl2.setColor(new ColorRGBA(0.7f, 0.85f, 1.0f, 1f)); + dl2.setDirection(lightDir2); + rootNode.addLight(dl2); + } + + private void buildPlayer() { + spaceCraft = assetManager.loadModel("Models/HoverTank/Tank2.mesh.xml"); + CollisionShape colShape = CollisionShapeFactory.createDynamicMeshShape(spaceCraft); + spaceCraft.setShadowMode(ShadowMode.CastAndReceive); + spaceCraft.setLocalTranslation(startLocation); + spaceCraft.setLocalRotation(startOrientation); + + hoverControl = new PhysicsHoverControl(colShape, 500); + + spaceCraft.addControl(hoverControl); + + + rootNode.attachChild(spaceCraft); + getPhysicsSpace().add(hoverControl); + hoverControl.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02); + + ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); + spaceCraft.addControl(chaseCam); + + flyCam.setEnabled(false); + } + + public void makeMissile() { + Vector3f pos = spaceCraft.getWorldTranslation().clone(); + Quaternion rot = spaceCraft.getWorldRotation(); + Vector3f dir = rot.getRotationColumn(2); + + Spatial missile = assetManager.loadModel("Models/SpaceCraft/Rocket.mesh.xml"); + missile.scale(0.5f); + missile.rotate(0, FastMath.PI, 0); + missile.updateGeometricState(); + + BoundingBox box = (BoundingBox) missile.getWorldBound(); + final Vector3f extent = box.getExtent(null); + + BoxCollisionShape boxShape = new BoxCollisionShape(extent); + + missile.setName("Missile"); + missile.rotate(rot); + missile.setLocalTranslation(pos.addLocal(0, extent.y * 4.5f, 0)); + missile.setLocalRotation(hoverControl.getPhysicsRotation()); + missile.setShadowMode(ShadowMode.Cast); + RigidBodyControl control = new BombControl(assetManager, boxShape, 20); + control.setLinearVelocity(dir.mult(100)); + control.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_03); + missile.addControl(control); + + + rootNode.attachChild(missile); + getPhysicsSpace().add(missile); + } + + @Override + public void onAnalog(String binding, float value, float tpf) { + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Lefts")) { + hoverControl.steer(value ? 50f : 0); + } else if (binding.equals("Rights")) { + hoverControl.steer(value ? -50f : 0); + } else if (binding.equals("Ups")) { + hoverControl.accelerate(value ? 100f : 0); + } else if (binding.equals("Downs")) { + hoverControl.accelerate(value ? -100f : 0); + } else if (binding.equals("Reset")) { + if (value) { + System.out.println("Reset"); + hoverControl.setPhysicsLocation(startLocation); + hoverControl.setPhysicsRotation(startOrientation); + hoverControl.setAngularVelocity(Vector3f.ZERO); + hoverControl.setLinearVelocity(Vector3f.ZERO); + hoverControl.clearForces(); + } else { + } + } else if (binding.equals("Space") && value) { + makeMissile(); + } + } + + public void updateCamera() { + rootNode.updateGeometricState(); + + Vector3f pos = spaceCraft.getWorldTranslation().clone(); + Quaternion rot = spaceCraft.getWorldRotation(); + Vector3f dir = rot.getRotationColumn(2); + + // make it XZ only + Vector3f camPos = new Vector3f(dir); + camPos.setY(0); + camPos.normalizeLocal(); + + // negate and multiply by distance from object + camPos.negateLocal(); + camPos.multLocal(15); + + // add Y distance + camPos.setY(2); + camPos.addLocal(pos); + cam.setLocation(camPos); + + Vector3f lookAt = new Vector3f(dir); + lookAt.multLocal(7); // look at dist + lookAt.addLocal(pos); + cam.lookAt(lookAt, Vector3f.UNIT_Y); + } + + @Override + public void simpleUpdate(float tpf) { + } + + private void createTerrain() { + Material matRock = new Material(assetManager, + "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matRock.setBoolean("useTriPlanarMapping", false); + matRock.setBoolean("WardIso", true); + matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap", grass); + matRock.setFloat("DiffuseMap_0_scale", 64); + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_1", dirt); + matRock.setFloat("DiffuseMap_1_scale", 16); + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_2", rock); + matRock.setFloat("DiffuseMap_2_scale", 128); + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(WrapMode.Repeat); + matRock.setTexture("NormalMap", normalMap0); + matRock.setTexture("NormalMap_1", normalMap1); + matRock.setTexture("NormalMap_2", normalMap2); + + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); + heightmap.load(); + } catch (Exception e) { + e.printStackTrace(); + } + TerrainQuad terrain + = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + List cameras = new ArrayList<>(); + cameras.add(getCamera()); + TerrainLodControl control = new TerrainLodControl(terrain, cameras); + terrain.addControl(control); + terrain.setMaterial(matRock); + terrain.setLocalScale(new Vector3f(2, 2, 2)); + terrain.setLocked(false); // unlock it so we can edit the height + + terrain.setShadowMode(ShadowMode.CastAndReceive); + terrain.addControl(new RigidBodyControl(0)); + rootNode.attachChild(terrain); + getPhysicsSpace().addAll(terrain); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java new file mode 100644 index 0000000000..d374ae5645 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestIssue1120.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.GImpactCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.debug.BulletDebugAppState; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Cylinder; +import com.jme3.system.AppSettings; +import java.util.ArrayList; +import java.util.List; + +/** + * Test demonstrating a GImpactCollisionShape falling through a curved mesh, when using JBullet. Bullet native + * does not experience this issue at the time this test was created. + * + * @author lou + */ +public class TestIssue1120 extends SimpleApplication { + + private BulletAppState bulletAppState; + private final boolean physicsDebug = true; + private BitmapText speedText; + private final List testObjects = new ArrayList<>(); + private static final boolean SKIP_SETTINGS = false;//Used for repeated runs of this test during dev + private float bulletSpeed = 0.5f; + + public static void main(String[] args) { + TestIssue1120 test = new TestIssue1120(); + test.setSettings(new AppSettings(true)); + test.settings.setFrameRate(60); + if (SKIP_SETTINGS) { + test.settings.setWidth(1920); + test.settings.setHeight(1150); + test.showSettings = !SKIP_SETTINGS; + } + test.start(); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(-7.285349f, -2.2638104f, 4.954474f)); + cam.setRotation(new Quaternion(0.07345789f, 0.92521834f, -0.2876841f, 0.23624739f)); + getFlyByCamera().setMoveSpeed(5); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + dl.setColor(ColorRGBA.Green); + rootNode.addLight(dl); + + //Setup interactive test controls + inputManager.addMapping("restart", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("pause", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addMapping("+", new KeyTrigger(KeyInput.KEY_ADD), new KeyTrigger(KeyInput.KEY_EQUALS)); + inputManager.addMapping("-", new KeyTrigger(KeyInput.KEY_SUBTRACT), new KeyTrigger(KeyInput.KEY_MINUS)); + inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { + if (!isPressed) { + return; + } + switch (name) { + case "restart": + cleanup(); + initializeNewTest(); + break; + case "pause": + bulletAppState.setSpeed(bulletAppState.getSpeed() > 0.1 ? 0 : bulletSpeed); + break; + case "+": + bulletSpeed += 0.1f; + if (bulletSpeed > 1f) { + bulletSpeed = 1f; + } + bulletAppState.setSpeed(bulletSpeed); + break; + case "-": + bulletSpeed -= 0.1f; + if (bulletSpeed < 0.1f) { + bulletSpeed = 0.1f; + } + bulletAppState.setSpeed(bulletSpeed); + break; + } + }, "pause", "restart", "+", "-"); + + guiNode = getGuiNode(); + BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText[] testInfo = new BitmapText[2]; + testInfo[0] = new BitmapText(font); + testInfo[1] = new BitmapText(font); + speedText = new BitmapText(font); + + float lineHeight = testInfo[0].getLineHeight(); + testInfo[0].setText("Camera move: W/A/S/D/Q/Z +/-: Increase/Decrease Speed"); + testInfo[0].setLocalTranslation(5, settings.getHeight(), 0); + guiNode.attachChild(testInfo[0]); + testInfo[1].setText("Left Click: Toggle pause Space: Restart test"); + testInfo[1].setLocalTranslation(5, settings.getHeight() - lineHeight, 0); + guiNode.attachChild(testInfo[1]); + + speedText.setLocalTranslation(202, lineHeight * 1, 0); + guiNode.attachChild(speedText); + + initializeNewTest(); + } + + private void initializeNewTest() { + bulletAppState = new BulletAppState(); + bulletAppState.setDebugEnabled(physicsDebug); + stateManager.attach(bulletAppState); + + bulletAppState.setSpeed(bulletSpeed); + + dropTest(); + + Geometry leftFloor = PhysicsTestHelper.createMeshTestFloor(assetManager, 20, new Vector3f(-11, -5, -10)); + addObject(leftFloor); + + //Hide physics debug visualization for floors + if (physicsDebug) { + BulletDebugAppState bulletDebugAppState = stateManager.getState(BulletDebugAppState.class); + bulletDebugAppState.setFilter((Object obj) -> { + return !(obj.equals(leftFloor.getControl(RigidBodyControl.class))); + }); + } + } + + private void addObject(Spatial s) { + testObjects.add(s); + rootNode.attachChild(s); + physicsSpace().add(s); + } + + private void dropTest() { + attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(0f, 2f, -5f), 2); + attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(-1f, 2f, -5f), 2); + attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(-2f, 2f, -5f), 2); + attachTestObject(new Cylinder(2, 16, 0.2f, 2f, true), new Vector3f(-3f, 2f, -5f), 2); + } + + private void attachTestObject(Mesh mesh, Vector3f position, float mass) { + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + Geometry g = new Geometry("mesh", mesh); + g.setLocalTranslation(position); + g.setMaterial(material); + + RigidBodyControl control = new RigidBodyControl(new GImpactCollisionShape(mesh), mass); + g.addControl(control); + addObject(g); + } + + private PhysicsSpace physicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleUpdate(float tpf) { + speedText.setText("Speed: " + String.format("%.1f", bulletSpeed)); + } + + private void cleanup() { + stateManager.detach(bulletAppState); + stateManager.detach(stateManager.getState(BulletDebugAppState.class)); + for (Spatial s : testObjects) { + rootNode.detachChild(s); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java new file mode 100644 index 0000000000..d39c629f6c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestIssue1125.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2019 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.util.CollisionShapeFactory; +import com.jme3.font.BitmapText; +import com.jme3.material.Material; +import com.jme3.material.RenderState; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.terrain.geomipmap.TerrainQuad; +import java.util.logging.Logger; + +/** + * Test case for JME issue #1125: heightfield collision shapes don't match + * TerrainQuad. + *

+ * If successful, just one set of grid diagonals will be visible. If + * unsuccessful, you'll see both green diagonals (the TerrainQuad) and + * perpendicular blue diagonals (physics debug). + *

+ * Use this test with jme3-bullet only; it can yield false success with + * jme3-jbullet due to JME issue #1129. + * + * @author Stephen Gold sgold@sonic.net + */ +public class TestIssue1125 extends SimpleApplication { + // ************************************************************************* + // constants and loggers + + /** + * message logger for this class + */ + final public static Logger logger + = Logger.getLogger(TestIssue1125.class.getName()); + // ************************************************************************* + // fields + + /** + * height array for a small heightfield + */ + final private float[] nineHeights = new float[9]; + /** + * green wireframe material for the TerrainQuad + */ + private Material quadMaterial; + /** + * space for physics simulation + */ + private PhysicsSpace physicsSpace; + // ************************************************************************* + // new methods exposed + + /** + * Main entry point for the TestIssue1125 application. + * + * @param ignored array of command-line arguments (not null) + */ + public static void main(String[] ignored) { + new TestIssue1125().start(); + } + // ************************************************************************* + // SimpleApplication methods + + /** + * Initialize this application. + */ + @Override + public void simpleInitApp() { + configureCamera(); + configureMaterials(); + viewPort.setBackgroundColor(new ColorRGBA(0.5f, 0.2f, 0.2f, 1f)); + configurePhysics(); + initializeHeightData(); + addTerrain(); + showHints(); + } + // ************************************************************************* + // private methods + + /** + * Add 3x3 terrain to the scene and the PhysicsSpace. + */ + private void addTerrain() { + int patchSize = 3; + int mapSize = 3; + TerrainQuad quad + = new TerrainQuad("terrain", patchSize, mapSize, nineHeights); + rootNode.attachChild(quad); + quad.setMaterial(quadMaterial); + + CollisionShape shape = CollisionShapeFactory.createMeshShape(quad); + float massForStatic = 0f; + RigidBodyControl rbc = new RigidBodyControl(shape, massForStatic); + rbc.setPhysicsSpace(physicsSpace); + quad.addControl(rbc); + } + + /** + * Configure the camera during startup. + */ + private void configureCamera() { + float fHeight = cam.getFrustumTop() - cam.getFrustumBottom(); + float fWidth = cam.getFrustumRight() - cam.getFrustumLeft(); + float fAspect = fWidth / fHeight; + float yDegrees = 45f; + float near = 0.02f; + float far = 20f; + cam.setFrustumPerspective(yDegrees, fAspect, near, far); + + flyCam.setMoveSpeed(5f); + + cam.setLocation(new Vector3f(2f, 4.7f, 0.4f)); + cam.setRotation(new Quaternion(0.348f, -0.64f, 0.4f, 0.556f)); + } + + /** + * Configure materials during startup. + */ + private void configureMaterials() { + quadMaterial = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + quadMaterial.setColor("Color", ColorRGBA.Green.clone()); + RenderState ars = quadMaterial.getAdditionalRenderState(); + ars.setWireframe(true); + } + + /** + * Configure physics during startup. + */ + private void configurePhysics() { + BulletAppState bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + physicsSpace = bulletAppState.getPhysicsSpace(); + } + + /** + * Initialize the height data during startup. + */ + private void initializeHeightData() { + nineHeights[0] = 1f; + nineHeights[1] = 0f; + nineHeights[2] = 1f; + nineHeights[3] = 0f; + nineHeights[4] = 0.5f; + nineHeights[5] = 0f; + nineHeights[6] = 1f; + nineHeights[7] = 0f; + nineHeights[8] = 1f; + } + + private void showHints() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + int numLines = 3; + BitmapText lines[] = new BitmapText[numLines]; + for (int i = 0; i < numLines; ++i) { + lines[i] = new BitmapText(guiFont); + } + + String p = "Test for jMonkeyEngine issue #1125"; + if (isNativeBullet()) { + lines[0].setText(p + " with native Bullet"); + } else { + lines[0].setText(p + " with JBullet (may yield false success)"); + } + lines[1].setText("Use W/A/S/D/Q/Z/arrow keys to move the camera."); + lines[2].setText("F5: render stats, C: camera pos, M: mem stats"); + + float textHeight = guiFont.getCharSet().getLineHeight(); + float viewHeight = cam.getHeight(); + float viewWidth = cam.getWidth(); + for (int i = 0; i < numLines; ++i) { + float left = Math.round((viewWidth - lines[i].getLineWidth()) / 2f); + float top = viewHeight - i * textHeight; + lines[i].setLocalTranslation(left, top, 0f); + guiNode.attachChild(lines[i]); + } + } + + /** + * Determine which physics library is in use. + * + * @return true for C++ Bullet, false for JBullet (jme3-jbullet) + */ + private boolean isNativeBullet() { + try { + Class clazz = Class.forName("com.jme3.bullet.util.NativeMeshUtil"); + return clazz != null; + } catch (ClassNotFoundException exception) { + return false; + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java new file mode 100644 index 0000000000..aecdc43a6a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestIssue877.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2018-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.joints.HingeJoint; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; + +/** + * Test case for JME issue #877: multiple hinges. Based on code submitted by + * Daniel Martensson. + * + * If successful, all pendulums will swing at the same frequency, and all the + * free-falling objects will fall straight down. + */ +public class TestIssue877 extends SimpleApplication { + + final private BulletAppState bulletAppState = new BulletAppState(); + final private int numPendulums = 6; + final private int numFalling = 6; + final private Node pivots[] = new Node[numPendulums]; + final private Node bobs[] = new Node[numPendulums]; + final private Node falling[] = new Node[numFalling]; + private float timeToNextPrint = 1f; // in seconds + + public static void main(String[] args) { + TestIssue877 app = new TestIssue877(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setEnabled(false); + cam.setLocation(new Vector3f(-4.77f, -7.55f, 16.52f)); + cam.setRotation(new Quaternion(-0.103433f, 0.889420f, 0.368792f, 0.249449f)); + + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + + float pivotY = 14.6214f; + float bobStartY = 3f; + float length = pivotY - bobStartY; + for (int i = 0; i < numPendulums; i++) { + float x = 6f - 2.5f * i; + Vector3f pivotLocation = new Vector3f(x, pivotY, 0f); + pivots[i] = createTestNode(0f, pivotLocation); + + Vector3f bobLocation = new Vector3f(x, bobStartY, 0f); + bobs[i] = createTestNode(1f, bobLocation); + } + + for (int i = 0; i < numFalling; i++) { + float x = -6f - 2.5f * (i + numPendulums); + Vector3f createLocation = new Vector3f(x, bobStartY, 0f); + falling[i] = createTestNode(1f, createLocation); + } + + for (int i = 0; i < numPendulums; i++) { + HingeJoint joint = new HingeJoint( + pivots[i].getControl(RigidBodyControl.class), + bobs[i].getControl(RigidBodyControl.class), + new Vector3f(0f, 0f, 0f), + new Vector3f(length, 0f, 0f), + Vector3f.UNIT_Z.clone(), + Vector3f.UNIT_Z.clone()); + bulletAppState.getPhysicsSpace().add(joint); + } + } + + Node createTestNode(float mass, Vector3f location) { + float size = 0.1f; + Vector3f halfExtents = new Vector3f(size, size, size); + CollisionShape shape = new BoxCollisionShape(halfExtents); + RigidBodyControl control = new RigidBodyControl(shape, mass); + Node node = new Node(); + node.addControl(control); + rootNode.attachChild(node); + bulletAppState.getPhysicsSpace().add(node); + control.setPhysicsLocation(location); + + return node; + } + + @Override + public void simpleUpdate(float tpf) { + if (timeToNextPrint > 0f) { + timeToNextPrint -= tpf; + return; + } + + if (numFalling > 0) { + Vector3f fallingLocation = falling[0].getWorldTranslation(); + System.out.printf(" falling[0] location(x=%f, z=%f)", + fallingLocation.x, fallingLocation.z); + /* + * If an object is falling vertically, its X- and Z-coordinates + * should not change. + */ + } + if (numPendulums > 0) { + Vector3f bobLocation = bobs[0].getWorldTranslation(); + Vector3f pivotLocation = pivots[0].getWorldTranslation(); + float distance = bobLocation.distance(pivotLocation); + System.out.printf(" bob[0] distance=%f", distance); + /* + * If the hinge is working properly, the distance from the + * pivot to the bob should remain roughly constant. + */ + } + System.out.println(); + timeToNextPrint = 1f; + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java new file mode 100644 index 0000000000..f0e4aec889 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestIssue883.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; + +/** + * Test case for JME issue #883: extra physicsTicks in ThreadingType.PARALLEL. + * + *

If successful, physics time and frame time will advance at the same rate. + */ +public class TestIssue883 extends SimpleApplication { + + private boolean firstPrint = true; + private float timeToNextPrint = 1f; // in seconds + private double frameTime; // in seconds + private double physicsTime; // in seconds + + public static void main(String[] args) { + TestIssue883 app = new TestIssue883(); + app.start(); + } + + @Override + public void simpleInitApp() { + + BulletAppState bulletAppState = new BulletAppState() { + @Override + public void physicsTick(PhysicsSpace space, float timeStep) { + physicsTime += timeStep; + } + }; + bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); + stateManager.attach(bulletAppState); + } + + @Override + public void simpleUpdate(float tpf) { + frameTime += tpf; + + if (timeToNextPrint > 0f) { + timeToNextPrint -= tpf; + return; + } + + if (firstPrint) { // synchronize + frameTime = 0.; + physicsTime = 0.; + firstPrint = false; + } + + System.out.printf(" frameTime= %s physicsTime= %s%n", + frameTime, physicsTime); + timeToNextPrint = 1f; + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java b/jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java new file mode 100644 index 0000000000..f7c0a6811c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.collision.shapes.PlaneCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.math.Plane; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; + +/** + * + * @author Nehon + */ +public class TestKinematicAddToPhysicsSpaceIssue extends SimpleApplication { + + public static void main(String[] args) { + TestKinematicAddToPhysicsSpaceIssue app = new TestKinematicAddToPhysicsSpaceIssue(); + app.start(); + } + private BulletAppState bulletAppState; + + @Override + public void simpleInitApp() { + + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + // Add a physics sphere to the world + Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); + physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); + rootNode.attachChild(physicsSphere); + + //Setting the rigidBody to kinematic before adding it to the physics space + physicsSphere.getControl(RigidBodyControl.class).setKinematic(true); + //adding it to the physics space + getPhysicsSpace().add(physicsSphere); + //Making it not kinematic again, it should fall under gravity, it doesn't + physicsSphere.getControl(RigidBodyControl.class).setKinematic(false); + + // Add a physics sphere to the world using the collision shape from sphere one + Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); + physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(5, 6, 0)); + rootNode.attachChild(physicsSphere2); + + //Adding the rigid body to physics space + getPhysicsSpace().add(physicsSphere2); + //making it kinematic + physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false); + //Making it not kinematic again, it works properly, the rigid body is affected by gravity. + physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false); + + + + // an obstacle mesh, does not move (mass=0) + Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); + node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); + rootNode.attachChild(node2); + getPhysicsSpace().add(node2); + + // the floor mesh, does not move (mass=0) + Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); + node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); + rootNode.attachChild(node3); + getPhysicsSpace().add(node3); + + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java b/jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java new file mode 100644 index 0000000000..3835b1ca03 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestLocalPhysics.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.*; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.math.Plane; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; + +/** + * This is a basic Test of jbullet-jme functions + * + * @author normenhansen + */ +public class TestLocalPhysics extends SimpleApplication { + + private BulletAppState bulletAppState; + + public static void main(String[] args) { + TestLocalPhysics app = new TestLocalPhysics(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + + // Add a physics sphere to the world + Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); + physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); + physicsSphere.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); + rootNode.attachChild(physicsSphere); + getPhysicsSpace().add(physicsSphere); + + // Add a physics sphere to the world using the collision shape from sphere one + Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, physicsSphere.getControl(RigidBodyControl.class).getCollisionShape(), 1); + physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); + physicsSphere2.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); + rootNode.attachChild(physicsSphere2); + getPhysicsSpace().add(physicsSphere2); + + // Add a physics box to the world + Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); + physicsBox.getControl(RigidBodyControl.class).setFriction(0.1f); + physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); + physicsBox.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); + rootNode.attachChild(physicsBox); + getPhysicsSpace().add(physicsBox); + + // Add a physics cylinder to the world + Node physicsCylinder = PhysicsTestHelper.createPhysicsTestNode(assetManager, new CylinderCollisionShape(new Vector3f(1f, 1f, 1.5f)), 1); + physicsCylinder.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2, 2, 0)); + physicsCylinder.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); + rootNode.attachChild(physicsCylinder); + getPhysicsSpace().add(physicsCylinder); + + // an obstacle mesh, does not move (mass=0) + Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); + node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); + node2.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); + rootNode.attachChild(node2); + getPhysicsSpace().add(node2); + + // the floor mesh, does not move (mass=0) + Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); + node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); + node3.getControl(RigidBodyControl.class).setApplyPhysicsLocal(true); + rootNode.attachChild(node3); + getPhysicsSpace().add(node3); + + // Join the physics objects with a Point2Point joint +// PhysicsPoint2PointJoint joint=new PhysicsPoint2PointJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0)); +// PhysicsHingeJoint joint=new PhysicsHingeJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0), Vector3f.UNIT_Z,Vector3f.UNIT_Z); +// getPhysicsSpace().add(joint); + + } + + @Override + public void simpleUpdate(float tpf) { + rootNode.rotate(tpf, 0, 0); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java new file mode 100644 index 0000000000..a4db5ca759 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.CompoundCollisionShape; +import com.jme3.bullet.control.VehicleControl; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Matrix3f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Cylinder; + +public class TestPhysicsCar extends SimpleApplication implements ActionListener { + + private BulletAppState bulletAppState; + private VehicleControl vehicle; + private final float accelerationForce = 1000.0f; + private final float brakeForce = 100.0f; + private float steeringValue = 0; + private float accelerationValue = 0; + final private Vector3f jumpForce = new Vector3f(0, 3000, 0); + + public static void main(String[] args) { + TestPhysicsCar app = new TestPhysicsCar(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); + setupKeys(); + buildPlayer(); + } + + private PhysicsSpace getPhysicsSpace(){ + return bulletAppState.getPhysicsSpace(); + } + + private void setupKeys() { + inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addListener(this, "Lefts"); + inputManager.addListener(this, "Rights"); + inputManager.addListener(this, "Ups"); + inputManager.addListener(this, "Downs"); + inputManager.addListener(this, "Space"); + inputManager.addListener(this, "Reset"); + } + + private void buildPlayer() { + Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + mat.getAdditionalRenderState().setWireframe(true); + mat.setColor("Color", ColorRGBA.Red); + + //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0 + //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0 + CompoundCollisionShape compoundShape = new CompoundCollisionShape(); + BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f)); + compoundShape.addChildShape(box, new Vector3f(0, 1, 0)); + + //create vehicle node + Node vehicleNode=new Node("vehicleNode"); + vehicle = new VehicleControl(compoundShape, 400); + vehicleNode.addControl(vehicle); + + //setting suspension values for wheels, this can be a bit tricky + //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en + float stiffness = 60.0f;//200=f1 car + float compValue = .3f; //(should be lower than damp) + float dampValue = .4f; + vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); + vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); + vehicle.setSuspensionStiffness(stiffness); + vehicle.setMaxSuspensionForce(10000.0f); + + //Create four wheels and add them at their locations + Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0 + Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0 + float radius = 0.5f; + float restLength = 0.3f; + float yOff = 0.5f; + float xOff = 1f; + float zOff = 2f; + + Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true); + + Node node1 = new Node("wheel 1 node"); + Geometry wheels1 = new Geometry("wheel 1", wheelMesh); + node1.attachChild(wheels1); + wheels1.rotate(0, FastMath.HALF_PI, 0); + wheels1.setMaterial(mat); + vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff), + wheelDirection, wheelAxle, restLength, radius, true); + + Node node2 = new Node("wheel 2 node"); + Geometry wheels2 = new Geometry("wheel 2", wheelMesh); + node2.attachChild(wheels2); + wheels2.rotate(0, FastMath.HALF_PI, 0); + wheels2.setMaterial(mat); + vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff), + wheelDirection, wheelAxle, restLength, radius, true); + + Node node3 = new Node("wheel 3 node"); + Geometry wheels3 = new Geometry("wheel 3", wheelMesh); + node3.attachChild(wheels3); + wheels3.rotate(0, FastMath.HALF_PI, 0); + wheels3.setMaterial(mat); + vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff), + wheelDirection, wheelAxle, restLength, radius, false); + + Node node4 = new Node("wheel 4 node"); + Geometry wheels4 = new Geometry("wheel 4", wheelMesh); + node4.attachChild(wheels4); + wheels4.rotate(0, FastMath.HALF_PI, 0); + wheels4.setMaterial(mat); + vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff), + wheelDirection, wheelAxle, restLength, radius, false); + + vehicleNode.attachChild(node1); + vehicleNode.attachChild(node2); + vehicleNode.attachChild(node3); + vehicleNode.attachChild(node4); + rootNode.attachChild(vehicleNode); + + getPhysicsSpace().add(vehicle); + } + + @Override + public void simpleUpdate(float tpf) { + cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Lefts")) { + if (value) { + steeringValue += .5f; + } else { + steeringValue -= .5f; + } + vehicle.steer(steeringValue); + } else if (binding.equals("Rights")) { + if (value) { + steeringValue -= .5f; + } else { + steeringValue += .5f; + } + vehicle.steer(steeringValue); + } else if (binding.equals("Ups")) { + if (value) { + accelerationValue += accelerationForce; + } else { + accelerationValue -= accelerationForce; + } + vehicle.accelerate(accelerationValue); + } else if (binding.equals("Downs")) { + if (value) { + vehicle.brake(brakeForce); + } else { + vehicle.brake(0f); + } + } else if (binding.equals("Space")) { + if (value) { + vehicle.applyImpulse(jumpForce, Vector3f.ZERO); + } + } else if (binding.equals("Reset")) { + if (value) { + System.out.println("Reset"); + vehicle.setPhysicsLocation(Vector3f.ZERO); + vehicle.setPhysicsRotation(new Matrix3f()); + vehicle.setLinearVelocity(Vector3f.ZERO); + vehicle.setAngularVelocity(Vector3f.ZERO); + vehicle.resetSuspension(); + } else { + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java new file mode 100644 index 0000000000..f0f4d7807d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; +import com.jme3.bullet.control.CharacterControl; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.scene.CameraNode; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.control.CameraControl.ControlDirection; + +/** + * A walking physical character followed by a 3rd person camera. (No animation.) + * @author normenhansen, zathras + */ +public class TestPhysicsCharacter extends SimpleApplication implements ActionListener { + + private BulletAppState bulletAppState; + private CharacterControl physicsCharacter; + final private Vector3f walkDirection = new Vector3f(0,0,0); + final private Vector3f viewDirection = new Vector3f(0,0,0); + private boolean leftStrafe = false, rightStrafe = false, forward = false, backward = false, + leftRotate = false, rightRotate = false; + + public static void main(String[] args) { + TestPhysicsCharacter app = new TestPhysicsCharacter(); + app.start(); + } + + private void setupKeys() { + inputManager.addMapping("Strafe Left", + new KeyTrigger(KeyInput.KEY_Q), + new KeyTrigger(KeyInput.KEY_Z)); + inputManager.addMapping("Strafe Right", + new KeyTrigger(KeyInput.KEY_E), + new KeyTrigger(KeyInput.KEY_X)); + inputManager.addMapping("Rotate Left", + new KeyTrigger(KeyInput.KEY_A), + new KeyTrigger(KeyInput.KEY_LEFT)); + inputManager.addMapping("Rotate Right", + new KeyTrigger(KeyInput.KEY_D), + new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addMapping("Walk Forward", + new KeyTrigger(KeyInput.KEY_W), + new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("Walk Backward", + new KeyTrigger(KeyInput.KEY_S), + new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("Jump", + new KeyTrigger(KeyInput.KEY_SPACE), + new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addMapping("Shoot", + new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(this, "Strafe Left", "Strafe Right"); + inputManager.addListener(this, "Rotate Left", "Rotate Right"); + inputManager.addListener(this, "Walk Forward", "Walk Backward"); + inputManager.addListener(this, "Jump", "Shoot"); + } + @Override + public void simpleInitApp() { + // activate physics + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + + // init a physical test scene + PhysicsTestHelper.createPhysicsTestWorldSoccer(rootNode, assetManager, bulletAppState.getPhysicsSpace()); + setupKeys(); + + // Add a physics character to the world + physicsCharacter = new CharacterControl(new CapsuleCollisionShape(0.5f, 1.8f), .1f); + physicsCharacter.setPhysicsLocation(new Vector3f(0, 1, 0)); + Node characterNode = new Node("character node"); + Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); + model.scale(0.25f); + characterNode.addControl(physicsCharacter); + getPhysicsSpace().add(physicsCharacter); + rootNode.attachChild(characterNode); + characterNode.attachChild(model); + + // set forward camera node that follows the character + CameraNode camNode = new CameraNode("CamNode", cam); + camNode.setControlDir(ControlDirection.SpatialToCamera); + camNode.setLocalTranslation(new Vector3f(0, 1, -5)); + camNode.lookAt(model.getLocalTranslation(), Vector3f.UNIT_Y); + characterNode.attachChild(camNode); + + //disable the default 1st-person flyCam (don't forget this!!) + flyCam.setEnabled(false); + + } + + @Override + public void simpleUpdate(float tpf) { + Vector3f camDir = cam.getDirection().mult(0.2f); + Vector3f camLeft = cam.getLeft().mult(0.2f); + camDir.y = 0; + camLeft.y = 0; + viewDirection.set(camDir); + walkDirection.set(0, 0, 0); + if (leftStrafe) { + walkDirection.addLocal(camLeft); + } else + if (rightStrafe) { + walkDirection.addLocal(camLeft.negate()); + } + if (leftRotate) { + viewDirection.addLocal(camLeft.mult(tpf)); + } else + if (rightRotate) { + viewDirection.addLocal(camLeft.mult(tpf).negate()); + } + if (forward) { + walkDirection.addLocal(camDir); + } else + if (backward) { + walkDirection.addLocal(camDir.negate()); + } + physicsCharacter.setWalkDirection(walkDirection); + physicsCharacter.setViewDirection(viewDirection); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Strafe Left")) { + if (value) { + leftStrafe = true; + } else { + leftStrafe = false; + } + } else if (binding.equals("Strafe Right")) { + if (value) { + rightStrafe = true; + } else { + rightStrafe = false; + } + } else if (binding.equals("Rotate Left")) { + if (value) { + leftRotate = true; + } else { + leftRotate = false; + } + } else if (binding.equals("Rotate Right")) { + if (value) { + rightRotate = true; + } else { + rightRotate = false; + } + } else if (binding.equals("Walk Forward")) { + if (value) { + forward = true; + } else { + forward = false; + } + } else if (binding.equals("Walk Backward")) { + if (value) { + backward = true; + } else { + backward = false; + } + } else if (binding.equals("Jump")) { + physicsCharacter.jump(); + } + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleRender(RenderManager rm) { + //TODO: add render code + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java new file mode 100644 index 0000000000..12b18af865 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.joints.HingeJoint; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; + +public class TestPhysicsHingeJoint extends SimpleApplication implements AnalogListener { + private BulletAppState bulletAppState; + private HingeJoint joint; + + public static void main(String[] args) { + TestPhysicsHingeJoint app = new TestPhysicsHingeJoint(); + app.start(); + } + + private void setupKeys() { + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Swing", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this, "Left", "Right", "Swing"); + } + + @Override + public void onAnalog(String binding, float value, float tpf) { + if(binding.equals("Left")){ + joint.enableMotor(true, 1, .1f); + } + else if(binding.equals("Right")){ + joint.enableMotor(true, -1, .1f); + } + else if(binding.equals("Swing")){ + joint.enableMotor(false, 0, 0); + } + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + setupKeys(); + setupJoint(); + } + + private PhysicsSpace getPhysicsSpace(){ + return bulletAppState.getPhysicsSpace(); + } + + public void setupJoint() { + Node holderNode=PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0); + holderNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,0,0f)); + rootNode.attachChild(holderNode); + getPhysicsSpace().add(holderNode); + + Node hammerNode=PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f( .3f, .3f, .3f)),1); + hammerNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,-1,0f)); + rootNode.attachChild(hammerNode); + getPhysicsSpace().add(hammerNode); + + joint=new HingeJoint(holderNode.getControl(RigidBodyControl.class), hammerNode.getControl(RigidBodyControl.class), Vector3f.ZERO, new Vector3f(0f,-1,0f), Vector3f.UNIT_Z, Vector3f.UNIT_Z); + getPhysicsSpace().add(joint); + } + + @Override + public void simpleUpdate(float tpf) { + + } + + +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java new file mode 100644 index 0000000000..9d3a77350e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsRayCast.java @@ -0,0 +1,69 @@ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.PhysicsRayTestResult; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.util.CollisionShapeFactory; +import com.jme3.font.BitmapText; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import java.util.List; + +/** + * + * @author wezrule + */ +public class TestPhysicsRayCast extends SimpleApplication { + + final private BulletAppState bulletAppState = new BulletAppState(); + + public static void main(String[] args) { + new TestPhysicsRayCast().start(); + } + + @Override + public void simpleInitApp() { + stateManager.attach(bulletAppState); + initCrossHair(); + + Spatial s = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml"); + s.setLocalScale(0.1f); + + CollisionShape collisionShape = CollisionShapeFactory.createMeshShape(s); + Node n = new Node("elephant"); + n.addControl(new RigidBodyControl(collisionShape, 1)); + n.getControl(RigidBodyControl.class).setKinematic(true); + bulletAppState.getPhysicsSpace().add(n); + rootNode.attachChild(n); + bulletAppState.setDebugEnabled(true); + } + + @Override + public void simpleUpdate(float tpf) { + float rayLength = 50f; + Vector3f start = cam.getLocation(); + Vector3f end = cam.getDirection().scaleAdd(rayLength, start); + List rayTest + = bulletAppState.getPhysicsSpace().rayTest(start, end); + if (rayTest.size() > 0) { + PhysicsRayTestResult get = rayTest.get(0); + PhysicsCollisionObject collisionObject = get.getCollisionObject(); + // Display the name of the 1st object in place of FPS. + fpsText.setText(collisionObject.getUserObject().toString()); + } else { + // Provide prompt feedback that no collision object was hit. + fpsText.setText("MISSING"); + } + } + + private void initCrossHair() { + BitmapText bitmapText = new BitmapText(guiFont); + bitmapText.setText("+"); + bitmapText.setLocalTranslation((settings.getWidth() - bitmapText.getLineWidth())*0.5f, (settings.getHeight() + bitmapText.getLineHeight())*0.5f, 0); + guiNode.attachChild(bitmapText); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java new file mode 100644 index 0000000000..13c5133524 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsReadWrite.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.bullet; + + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.*; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.joints.HingeJoint; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.export.binary.BinaryImporter; +import com.jme3.math.Plane; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This is a basic Test of jbullet-jme functions + * + * @author normenhansen + */ +public class TestPhysicsReadWrite extends SimpleApplication{ + private BulletAppState bulletAppState; + + public static void main(String[] args){ + TestPhysicsReadWrite app = new TestPhysicsReadWrite(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + Node physicsRootNode = new Node("PhysicsRootNode"); + rootNode.attachChild(physicsRootNode); + + // Add a physics sphere to the world + Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); + physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); + rootNode.attachChild(physicsSphere); + getPhysicsSpace().add(physicsSphere); + + // Add a physics sphere to the world using the collision shape from sphere one + Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, physicsSphere.getControl(RigidBodyControl.class).getCollisionShape(), 1); + physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); + rootNode.attachChild(physicsSphere2); + getPhysicsSpace().add(physicsSphere2); + + // Add a physics box to the world + Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); + physicsBox.getControl(RigidBodyControl.class).setFriction(0.1f); + physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); + rootNode.attachChild(physicsBox); + getPhysicsSpace().add(physicsBox); + + // Add a physics cylinder to the world + Node physicsCylinder = PhysicsTestHelper.createPhysicsTestNode(assetManager, new CylinderCollisionShape(new Vector3f(1f, 1f, 1.5f)), 1); + physicsCylinder.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2, 2, 0)); + rootNode.attachChild(physicsCylinder); + getPhysicsSpace().add(physicsCylinder); + + // an obstacle mesh, does not move (mass=0) + Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); + node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); + rootNode.attachChild(node2); + getPhysicsSpace().add(node2); + + // the floor mesh, does not move (mass=0) + Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); + node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); + rootNode.attachChild(node3); + getPhysicsSpace().add(node3); + + // Join the physics objects with a Point2Point joint + HingeJoint joint=new HingeJoint(physicsSphere.getControl(RigidBodyControl.class), physicsBox.getControl(RigidBodyControl.class), new Vector3f(-2,0,0), new Vector3f(2,0,0), Vector3f.UNIT_Z,Vector3f.UNIT_Z); + getPhysicsSpace().add(joint); + + //save and load the physicsRootNode + try { + //remove all physics objects from physics space + getPhysicsSpace().removeAll(physicsRootNode); + physicsRootNode.removeFromParent(); + //export to byte array + ByteArrayOutputStream bout=new ByteArrayOutputStream(); + BinaryExporter.getInstance().save(physicsRootNode, bout); + //import from byte array + ByteArrayInputStream bin=new ByteArrayInputStream(bout.toByteArray()); + BinaryImporter imp=BinaryImporter.getInstance(); + imp.setAssetManager(assetManager); + Node newPhysicsRootNode=(Node)imp.load(bin); + //add all physics objects to physics space + getPhysicsSpace().addAll(newPhysicsRootNode); + rootNode.attachChild(newPhysicsRootNode); + } catch (IOException ex) { + Logger.getLogger(TestPhysicsReadWrite.class.getName()).log(Level.SEVERE, null, ex); + } + + } + + private PhysicsSpace getPhysicsSpace(){ + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleUpdate(float tpf) { + //TODO: add update code + } + + @Override + public void simpleRender(RenderManager rm) { + //TODO: add render code + } + +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java b/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java new file mode 100644 index 0000000000..9146c8d70b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.asset.plugins.ZipLocator; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.objects.PhysicsCharacter; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.MaterialList; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.plugins.ogre.OgreMeshKey; +import java.io.File; + +public class TestQ3 extends SimpleApplication implements ActionListener { + + private BulletAppState bulletAppState; + private PhysicsCharacter player; + final private Vector3f walkDirection = new Vector3f(); + private static boolean useHttp = false; + private boolean left=false,right=false,up=false,down=false; + + public static void main(String[] args) { + TestQ3 app = new TestQ3(); + app.start(); + } + + @Override + public void simpleInitApp() { + File file = new File("quake3level.zip"); + if (!file.exists()) { + useHttp = true; + } + + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + flyCam.setMoveSpeed(100); + setupKeys(); + + this.cam.setFrustumFar(2000); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White.clone().multLocal(2)); + dl.setDirection(new Vector3f(-1, -1, -1).normalize()); + rootNode.addLight(dl); + + AmbientLight am = new AmbientLight(); + am.setColor(ColorRGBA.White.mult(2)); + rootNode.addLight(am); + + // load the level from zip or http zip + if (useHttp) { + assetManager.registerLocator( + "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/quake3level.zip", + HttpZipLocator.class); + } else { + assetManager.registerLocator("quake3level.zip", ZipLocator.class); + } + + // create the geometry and attach it + MaterialList matList = (MaterialList) assetManager.loadAsset("Scene.material"); + OgreMeshKey key = new OgreMeshKey("main.meshxml", matList); + Node gameLevel = (Node) assetManager.loadAsset(key); + gameLevel.setLocalScale(0.1f); + + // add a physics control, it will generate a MeshCollisionShape based on the gameLevel + gameLevel.addControl(new RigidBodyControl(0)); + + player = new PhysicsCharacter(new SphereCollisionShape(5), .01f); + player.setJumpSpeed(20); + player.setFallSpeed(30); + player.setGravity(30); + + player.setPhysicsLocation(new Vector3f(60, 10, -60)); + + rootNode.attachChild(gameLevel); + + getPhysicsSpace().addAll(gameLevel); + getPhysicsSpace().add(player); + } + + private PhysicsSpace getPhysicsSpace(){ + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleUpdate(float tpf) { + Vector3f camDir = cam.getDirection().clone().multLocal(0.6f); + Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f); + walkDirection.set(0,0,0); + if(left) + walkDirection.addLocal(camLeft); + if(right) + walkDirection.addLocal(camLeft.negate()); + if(up) + walkDirection.addLocal(camDir); + if(down) + walkDirection.addLocal(camDir.negate()); + player.setWalkDirection(walkDirection); + cam.setLocation(player.getPhysicsLocation()); + } + + private void setupKeys() { + inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this,"Lefts"); + inputManager.addListener(this,"Rights"); + inputManager.addListener(this,"Ups"); + inputManager.addListener(this,"Downs"); + inputManager.addListener(this,"Space"); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + + if (binding.equals("Lefts")) { + if(value) + left=true; + else + left=false; + } else if (binding.equals("Rights")) { + if(value) + right=true; + else + right=false; + } else if (binding.equals("Ups")) { + if(value) + up=true; + else + up=false; + } else if (binding.equals("Downs")) { + if(value) + down=true; + else + down=false; + } else if (binding.equals("Space")) { + player.jump(); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java b/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java new file mode 100644 index 0000000000..2c4d81dade --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.joints.ConeJoint; +import com.jme3.bullet.joints.PhysicsJoint; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; + +/** + * + * @author normenhansen + */ +public class TestRagDoll extends SimpleApplication implements ActionListener { + + private BulletAppState bulletAppState; + final private Node ragDoll = new Node(); + private Node shoulders; + final private Vector3f upForce = new Vector3f(0, 200, 0); + private boolean applyForce = false; + + public static void main(String[] args) { + TestRagDoll app = new TestRagDoll(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + inputManager.addMapping("Pull ragdoll up", new MouseButtonTrigger(0)); + inputManager.addListener(this, "Pull ragdoll up"); + PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); + createRagDoll(); + } + + private void createRagDoll() { + shoulders = createLimb(0.2f, 1.0f, new Vector3f(0.00f, 1.5f, 0), true); + Node uArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f, 0.8f, 0), false); + Node uArmR = createLimb(0.2f, 0.5f, new Vector3f(0.75f, 0.8f, 0), false); + Node lArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f, -0.2f, 0), false); + Node lArmR = createLimb(0.2f, 0.5f, new Vector3f(0.75f, -0.2f, 0), false); + Node body = createLimb(0.2f, 1.0f, new Vector3f(0.00f, 0.5f, 0), false); + Node hips = createLimb(0.2f, 0.5f, new Vector3f(0.00f, -0.5f, 0), true); + Node uLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f, -1.2f, 0), false); + Node uLegR = createLimb(0.2f, 0.5f, new Vector3f(0.25f, -1.2f, 0), false); + Node lLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f, -2.2f, 0), false); + Node lLegR = createLimb(0.2f, 0.5f, new Vector3f(0.25f, -2.2f, 0), false); + + join(body, shoulders, new Vector3f(0f, 1.4f, 0)); + join(body, hips, new Vector3f(0f, -0.5f, 0)); + + join(uArmL, shoulders, new Vector3f(-0.75f, 1.4f, 0)); + join(uArmR, shoulders, new Vector3f(0.75f, 1.4f, 0)); + join(uArmL, lArmL, new Vector3f(-0.75f, .4f, 0)); + join(uArmR, lArmR, new Vector3f(0.75f, .4f, 0)); + + join(uLegL, hips, new Vector3f(-.25f, -0.5f, 0)); + join(uLegR, hips, new Vector3f(.25f, -0.5f, 0)); + join(uLegL, lLegL, new Vector3f(-.25f, -1.7f, 0)); + join(uLegR, lLegR, new Vector3f(.25f, -1.7f, 0)); + + ragDoll.attachChild(shoulders); + ragDoll.attachChild(body); + ragDoll.attachChild(hips); + ragDoll.attachChild(uArmL); + ragDoll.attachChild(uArmR); + ragDoll.attachChild(lArmL); + ragDoll.attachChild(lArmR); + ragDoll.attachChild(uLegL); + ragDoll.attachChild(uLegR); + ragDoll.attachChild(lLegL); + ragDoll.attachChild(lLegR); + + rootNode.attachChild(ragDoll); + bulletAppState.getPhysicsSpace().addAll(ragDoll); + } + + private Node createLimb(float width, float height, Vector3f location, boolean rotate) { + int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y; + CapsuleCollisionShape shape = new CapsuleCollisionShape(width, height, axis); + Node node = new Node("Limb"); + RigidBodyControl rigidBodyControl = new RigidBodyControl(shape, 1); + node.setLocalTranslation(location); + node.addControl(rigidBodyControl); + return node; + } + + private PhysicsJoint join(Node A, Node B, Vector3f connectionPoint) { + Vector3f pivotA = A.worldToLocal(connectionPoint, new Vector3f()); + Vector3f pivotB = B.worldToLocal(connectionPoint, new Vector3f()); + ConeJoint joint = new ConeJoint(A.getControl(RigidBodyControl.class), B.getControl(RigidBodyControl.class), pivotA, pivotB); + joint.setLimit(1f, 1f, 0); + return joint; + } + + @Override + public void onAction(String string, boolean bln, float tpf) { + if ("Pull ragdoll up".equals(string)) { + if (bln) { + shoulders.getControl(RigidBodyControl.class).activate(); + applyForce = true; + } else { + applyForce = false; + } + } + } + + @Override + public void simpleUpdate(float tpf) { + if (applyForce) { + shoulders.getControl(RigidBodyControl.class).applyForce(upForce, Vector3f.ZERO); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java b/jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java new file mode 100644 index 0000000000..b457e3b15b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.animation.DynamicAnimControl; +import com.jme3.bullet.animation.RangeOfMotion; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.texture.Texture; + +/** + * @author normenhansen + */ +public class TestRagdollCharacter + extends SimpleApplication + implements ActionListener { + + private AnimComposer composer; + private boolean forward = false, backward = false, + leftRotate = false, rightRotate = false; + private Node model; + private PhysicsSpace physicsSpace; + + public static void main(String[] args) { + TestRagdollCharacter app = new TestRagdollCharacter(); + app.start(); + } + + public void onSliceDone() { + composer.setCurrentAction("IdleTop"); + } + + static void setupSinbad(DynamicAnimControl ragdoll) { + ragdoll.link("Waist", 1f, + new RangeOfMotion(1f, -0.4f, 0.8f, -0.8f, 0.4f, -0.4f)); + ragdoll.link("Chest", 1f, new RangeOfMotion(0.4f, 0f, 0.4f)); + ragdoll.link("Neck", 1f, new RangeOfMotion(0.5f, 1f, 0.7f)); + + ragdoll.link("Clavicle.R", 1f, + new RangeOfMotion(0.3f, -0.6f, 0f, 0f, 0.4f, -0.4f)); + ragdoll.link("Humerus.R", 1f, + new RangeOfMotion(1.6f, -0.8f, 1f, -1f, 1.6f, -1f)); + ragdoll.link("Ulna.R", 1f, new RangeOfMotion(0f, 0f, 1f, -1f, 0f, -2f)); + ragdoll.link("Hand.R", 1f, new RangeOfMotion(0.8f, 0f, 0.2f)); + + ragdoll.link("Clavicle.L", 1f, + new RangeOfMotion(0.6f, -0.3f, 0f, 0f, 0.4f, -0.4f)); + ragdoll.link("Humerus.L", + 1f, new RangeOfMotion(0.8f, -1.6f, 1f, -1f, 1f, -1.6f)); + ragdoll.link("Ulna.L", 1f, new RangeOfMotion(0f, 0f, 1f, -1f, 2f, 0f)); + ragdoll.link("Hand.L", 1f, new RangeOfMotion(0.8f, 0f, 0.2f)); + + ragdoll.link("Thigh.R", 1f, + new RangeOfMotion(0.4f, -1f, 0.4f, -0.4f, 1f, -0.5f)); + ragdoll.link("Calf.R", 1f, new RangeOfMotion(2f, 0f, 0f, 0f, 0f, 0f)); + ragdoll.link("Foot.R", 1f, new RangeOfMotion(0.3f, 0.5f, 0f)); + + ragdoll.link("Thigh.L", 1f, + new RangeOfMotion(0.4f, -1f, 0.4f, -0.4f, 0.5f, -1f)); + ragdoll.link("Calf.L", 1f, new RangeOfMotion(2f, 0f, 0f, 0f, 0f, 0f)); + ragdoll.link("Foot.L", 1f, new RangeOfMotion(0.3f, 0.5f, 0f)); + } + + @Override + public void onAction(String binding, boolean isPressed, float tpf) { + if (binding.equals("Rotate Left")) { + if (isPressed) { + leftRotate = true; + } else { + leftRotate = false; + } + } else if (binding.equals("Rotate Right")) { + if (isPressed) { + rightRotate = true; + } else { + rightRotate = false; + } + } else if (binding.equals("Slice")) { + if (isPressed) { + composer.setCurrentAction("SliceOnce"); + } + } else if (binding.equals("Walk Forward")) { + if (isPressed) { + forward = true; + } else { + forward = false; + } + } else if (binding.equals("Walk Backward")) { + if (isPressed) { + backward = true; + } else { + backward = false; + } + } + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(50f); + cam.setLocation(new Vector3f(-16f, 4.7f, -1.6f)); + cam.setRotation(new Quaternion(0.0484f, 0.804337f, -0.066f, 0.5885f)); + + setupKeys(); + setupLight(); + + BulletAppState bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + //bulletAppState.setDebugEnabled(true); + physicsSpace = bulletAppState.getPhysicsSpace(); + + PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, + physicsSpace); + initWall(2f, 1f, 1f); + + model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); + rootNode.attachChild(model); + model.lookAt(new Vector3f(0f, 0f, -1f), Vector3f.UNIT_Y); + model.setLocalTranslation(4f, 0f, -7f); + + composer = model.getControl(AnimComposer.class); + composer.setCurrentAction("IdleTop"); + + Action slice = composer.action("SliceHorizontal"); + composer.actionSequence("SliceOnce", + slice, Tweens.callMethod(this, "onSliceDone")); + + DynamicAnimControl ragdoll = new DynamicAnimControl(); + setupSinbad(ragdoll); + model.addControl(ragdoll); + physicsSpace.add(ragdoll); + } + + @Override + public void simpleUpdate(float tpf) { + if (forward) { + model.move(model.getLocalRotation().multLocal(new Vector3f(0f, 0f, tpf))); + } else if (backward) { + model.move(model.getLocalRotation().multLocal(new Vector3f(0f, 0f, -tpf))); + } else if (leftRotate) { + model.rotate(0f, tpf, 0f); + } else if (rightRotate) { + model.rotate(0f, -tpf, 0f); + } + } + + private void initWall(float bLength, float bWidth, float bHeight) { + Box brick = new Box(bLength, bHeight, bWidth); + brick.scaleTextureCoordinates(new Vector2f(1f, 0.5f)); + Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + mat2.setTexture("ColorMap", tex); + + float startpt = bLength / 4f; + float height = -5f; + for (int j = 0; j < 15; j++) { + for (int i = 0; i < 4; i++) { + Vector3f ori = new Vector3f(i * bLength * 2f + startpt, bHeight + height, -10f); + Geometry brickGeometry = new Geometry("brick", brick); + brickGeometry.setMaterial(mat2); + brickGeometry.setLocalTranslation(ori); + // for geometry with sphere mesh the physics system automatically uses a sphere collision shape + brickGeometry.addControl(new RigidBodyControl(1.5f)); + brickGeometry.setShadowMode(ShadowMode.CastAndReceive); + brickGeometry.getControl(RigidBodyControl.class).setFriction(0.6f); + this.rootNode.attachChild(brickGeometry); + physicsSpace.add(brickGeometry); + } + startpt = -startpt; + height += 2f * bHeight; + } + } + + private void setupKeys() { + inputManager.addMapping("Rotate Left", + new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("Rotate Right", + new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Walk Backward", + new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("Walk Forward", + new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("Slice", + new KeyTrigger(KeyInput.KEY_SPACE), + new KeyTrigger(KeyInput.KEY_RETURN)); + + inputManager.addListener(this, "Rotate Left", "Rotate Right", "Slice", + "Walk Backward", "Walk Forward"); + } + + private void setupLight() { + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1f).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1f)); + rootNode.addLight(dl); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java b/jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java new file mode 100644 index 0000000000..9cf2808aeb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestSimplePhysics.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.*; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.math.Plane; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; + +/** + * This is a basic Test of jbullet-jme functions + * + * @author normenhansen + */ +public class TestSimplePhysics extends SimpleApplication { + + private BulletAppState bulletAppState; + + public static void main(String[] args) { + TestSimplePhysics app = new TestSimplePhysics(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + bulletAppState.setDebugEnabled(true); + + // Add a physics sphere to the world + Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1); + physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0)); + rootNode.attachChild(physicsSphere); + getPhysicsSpace().add(physicsSphere); + + // Add a physics sphere to the world using the collision shape from sphere one + Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, physicsSphere.getControl(RigidBodyControl.class).getCollisionShape(), 1); + physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0)); + rootNode.attachChild(physicsSphere2); + getPhysicsSpace().add(physicsSphere2); + + // Add a physics box to the world + Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1); + physicsBox.getControl(RigidBodyControl.class).setFriction(0.1f); + physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f)); + rootNode.attachChild(physicsBox); + getPhysicsSpace().add(physicsBox); + + // Add a physics cylinder to the world + Node physicsCylinder = PhysicsTestHelper.createPhysicsTestNode(assetManager, new CylinderCollisionShape(new Vector3f(1f, 1f, 1.5f)), 1); + physicsCylinder.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2, 2, 0)); + rootNode.attachChild(physicsCylinder); + getPhysicsSpace().add(physicsCylinder); + + // an obstacle mesh, does not move (mass=0) + Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0); + node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f)); + rootNode.attachChild(node2); + getPhysicsSpace().add(node2); + + // the floor mesh, does not move (mass=0) + Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0); + node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f)); + rootNode.attachChild(node3); + getPhysicsSpace().add(node3); + + // Join the physics objects with a Point2Point joint +// PhysicsPoint2PointJoint joint=new PhysicsPoint2PointJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0)); +// PhysicsHingeJoint joint=new PhysicsHingeJoint(physicsSphere, physicsBox, new Vector3f(-2,0,0), new Vector3f(2,0,0), Vector3f.UNIT_Z,Vector3f.UNIT_Z); +// getPhysicsSpace().add(joint); + + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java b/jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java new file mode 100644 index 0000000000..5b51b50dad --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestSweepTest.java @@ -0,0 +1,77 @@ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.PhysicsSweepTestResult; +import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.math.Transform; +import com.jme3.scene.Node; +import java.util.List; + +/** + * + * A spatial moves and sweeps its next movement for obstacles before moving + * there Run this example with Vsync enabled + * + * @author wezrule + */ +public class TestSweepTest extends SimpleApplication { + + final private BulletAppState bulletAppState = new BulletAppState(); + private CapsuleCollisionShape capsuleCollisionShape; + private Node capsule; + final private float dist = .5f; + + public static void main(String[] args) { + new TestSweepTest().start(); + } + + @Override + public void simpleInitApp() { + CapsuleCollisionShape obstacleCollisionShape + = new CapsuleCollisionShape(0.3f, 0.5f); + capsuleCollisionShape = new CapsuleCollisionShape(1f, 1f); + + stateManager.attach(bulletAppState); + + capsule = new Node("capsule"); + capsule.move(-2, 0, 0); + capsule.addControl(new RigidBodyControl(capsuleCollisionShape, 1)); + capsule.getControl(RigidBodyControl.class).setKinematic(true); + bulletAppState.getPhysicsSpace().add(capsule); + rootNode.attachChild(capsule); + + Node obstacle = new Node("obstacle"); + obstacle.move(2, 0, 0); + RigidBodyControl bodyControl = new RigidBodyControl(obstacleCollisionShape, 0); + obstacle.addControl(bodyControl); + bulletAppState.getPhysicsSpace().add(obstacle); + rootNode.attachChild(obstacle); + + bulletAppState.setDebugEnabled(true); + } + + @Override + public void simpleUpdate(float tpf) { + + float move = tpf * 1; + boolean colliding = false; + + List sweepTest = bulletAppState.getPhysicsSpace().sweepTest(capsuleCollisionShape, new Transform(capsule.getWorldTranslation()), new Transform(capsule.getWorldTranslation().add(dist, 0, 0))); + + for (PhysicsSweepTestResult result : sweepTest) { + if (result.getCollisionObject().getCollisionShape() != capsuleCollisionShape) { + PhysicsCollisionObject collisionObject = result.getCollisionObject(); + fpsText.setText("Almost colliding with " + collisionObject.getUserObject().toString()); + colliding = true; + } + } + + if (!colliding) { + // if the sweep is clear then move the spatial + capsule.move(move, 0, 0); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java b/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java new file mode 100644 index 0000000000..61f08d25f2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.Armature; +import com.jme3.anim.ArmatureMask; +import com.jme3.anim.SkinningControl; +import com.jme3.anim.tween.Tween; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.PhysicsCollisionEvent; +import com.jme3.bullet.collision.PhysicsCollisionListener; +import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.CharacterControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.util.CollisionShapeFactory; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.effect.shapes.EmitterSphereShape; +import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.renderer.Camera; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.*; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.SkyFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * A walking animated character followed by a 3rd person camera on a terrain with LOD. + * @author normenhansen + */ +public class TestWalkingChar extends SimpleApplication + implements ActionListener, PhysicsCollisionListener { + + private BulletAppState bulletAppState; + //character + private CharacterControl character; + private Node model; + //temp vectors + final private Vector3f walkDirection = new Vector3f(); + //Materials + private Material matBullet; + //animation + private Action standAction; + private Action walkAction; + private AnimComposer composer; + private float airTime = 0; + //camera + private boolean left = false, right = false, up = false, down = false; + //bullet + private Sphere bullet; + private SphereCollisionShape bulletCollisionShape; + //explosion + private ParticleEmitter effect; + //brick wall + private Box brick; + final private float bLength = 0.8f; + final private float bWidth = 0.4f; + final private float bHeight = 0.4f; + + public static void main(String[] args) { + TestWalkingChar app = new TestWalkingChar(); + app.start(); + } + + @Override + public void simpleInitApp() { + bulletAppState = new BulletAppState(); + bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); + stateManager.attach(bulletAppState); + setupKeys(); + prepareBullet(); + prepareEffect(); + createLight(); + createSky(); + createTerrain(); + createWall(); + createCharacter(); + setupChaseCamera(); + setupAnimationController(); + setupFilter(); + } + + private void setupFilter() { + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects); + fpp.addFilter(bloom); + viewPort.addProcessor(fpp); + } + + private PhysicsSpace getPhysicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + private void setupKeys() { + inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addListener(this, "wireframe"); + inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("CharSpace", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this, "CharLeft"); + inputManager.addListener(this, "CharRight"); + inputManager.addListener(this, "CharUp"); + inputManager.addListener(this, "CharDown"); + inputManager.addListener(this, "CharSpace"); + inputManager.addListener(this, "CharShoot"); + } + + private void createWall() { + float xOff = -144; + float zOff = -40; + float startpt = bLength / 4 - xOff; + float height = 6.1f; + brick = new Box(bLength, bHeight, bWidth); + brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); + for (int j = 0; j < 15; j++) { + for (int i = 0; i < 4; i++) { + Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight + height, zOff); + addBrick(vt); + } + startpt = -startpt; + height += 1.01f * bHeight; + } + } + + private void addBrick(Vector3f ori) { + Geometry brickGeometry = new Geometry("brick", brick); + brickGeometry.setMaterial(matBullet); + brickGeometry.setLocalTranslation(ori); + brickGeometry.addControl(new RigidBodyControl(1.5f)); + brickGeometry.setShadowMode(ShadowMode.CastAndReceive); + this.rootNode.attachChild(brickGeometry); + this.getPhysicsSpace().add(brickGeometry); + } + + private void prepareBullet() { + bullet = new Sphere(32, 32, 0.4f, true, false); + bullet.setTextureMode(TextureMode.Projected); + bulletCollisionShape = new SphereCollisionShape(0.4f); + matBullet = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + matBullet.setColor("Color", ColorRGBA.Green); + matBullet.setColor("GlowColor", ColorRGBA.Green); + getPhysicsSpace().addCollisionListener(this); + } + + private void prepareEffect() { + int COUNT_FACTOR = 1; + float COUNT_FACTOR_F = 1f; + effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR); + effect.setSelectRandomImage(true); + effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (1f / COUNT_FACTOR_F))); + effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); + effect.setStartSize(1.3f); + effect.setEndSize(2f); + effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); + effect.setParticlesPerSec(0); + effect.setGravity(0, -5, 0); + effect.setLowLife(.4f); + effect.setHighLife(.5f); + effect.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, 7, 0)); + effect.getParticleInfluencer().setVelocityVariation(1f); + effect.setImagesX(2); + effect.setImagesY(2); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); + effect.setMaterial(mat); +// effect.setLocalScale(100); + rootNode.attachChild(effect); + } + + private void createLight() { + Vector3f direction = new Vector3f(-0.1f, -0.7f, -1).normalizeLocal(); + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(direction); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + } + + private void createSky() { + rootNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + } + + private void createTerrain() { + Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matRock.setBoolean("useTriPlanarMapping", false); + matRock.setBoolean("WardIso", true); + matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap", grass); + matRock.setFloat("DiffuseMap_0_scale", 64); + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_1", dirt); + matRock.setFloat("DiffuseMap_1_scale", 16); + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_2", rock); + matRock.setFloat("DiffuseMap_2_scale", 128); + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(WrapMode.Repeat); + matRock.setTexture("NormalMap", normalMap0); + matRock.setTexture("NormalMap_1", normalMap1); + matRock.setTexture("NormalMap_2", normalMap2); + + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); + heightmap.load(); + + } catch (Exception e) { + e.printStackTrace(); + } + + TerrainQuad terrain + = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + List cameras = new ArrayList<>(); + cameras.add(getCamera()); + TerrainLodControl control = new TerrainLodControl(terrain, cameras); + terrain.addControl(control); + terrain.setMaterial(matRock); + terrain.setLocalScale(new Vector3f(2, 2, 2)); + + RigidBodyControl terrainPhysicsNode + = new RigidBodyControl(CollisionShapeFactory.createMeshShape(terrain), 0); + terrain.addControl(terrainPhysicsNode); + rootNode.attachChild(terrain); + getPhysicsSpace().add(terrainPhysicsNode); + } + + private void createCharacter() { + CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f); + character = new CharacterControl(capsule, 0.01f); + model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + model.addControl(character); + character.setPhysicsLocation(new Vector3f(-140, 40, -10)); + rootNode.attachChild(model); + getPhysicsSpace().add(character); + } + + private void setupChaseCamera() { + flyCam.setEnabled(false); + new ChaseCamera(cam, model, inputManager); + } + + private void setupAnimationController() { + composer = model.getControl(AnimComposer.class); + standAction = composer.action("stand"); + walkAction = composer.action("Walk"); + /* + * Add a "shootOnce" animation action + * that performs the "Dodge" action one time only. + */ + Action dodgeAction = composer.action("Dodge"); + Tween doneTween = Tweens.callMethod(this, "onShootDone"); + composer.actionSequence("shootOnce", dodgeAction, doneTween); + /* + * Define a shooting animation layer + * that animates only the joints of the right arm. + */ + SkinningControl skinningControl + = model.getControl(SkinningControl.class); + Armature armature = skinningControl.getArmature(); + ArmatureMask shootingMask + = ArmatureMask.createMask(armature, "uparm.right"); + composer.makeLayer("shootingLayer", shootingMask); + /* + * Define a walking animation layer + * that animates all joints except those used for shooting. + */ + ArmatureMask walkingMask = new ArmatureMask(); + walkingMask.addBones(armature, "head", "spine", "spinehigh"); + walkingMask.addFromJoint(armature, "hip.left"); + walkingMask.addFromJoint(armature, "hip.right"); + walkingMask.addFromJoint(armature, "uparm.left"); + composer.makeLayer("walkingLayer", walkingMask); + + composer.setCurrentAction("stand", "shootingLayer"); + composer.setCurrentAction("stand", "walkingLayer"); + } + + @Override + public void simpleUpdate(float tpf) { + Vector3f camDir = cam.getDirection().clone().multLocal(0.1f); + Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f); + camDir.y = 0; + camLeft.y = 0; + walkDirection.set(0, 0, 0); + if (left) { + walkDirection.addLocal(camLeft); + } + if (right) { + walkDirection.addLocal(camLeft.negate()); + } + if (up) { + walkDirection.addLocal(camDir); + } + if (down) { + walkDirection.addLocal(camDir.negate()); + } + if (!character.onGround()) { + airTime = airTime + tpf; + } else { + airTime = 0; + } + + Action action = composer.getCurrentAction("walkingLayer"); + if (walkDirection.length() == 0f) { + if (action != standAction) { + composer.setCurrentAction("stand", "walkingLayer"); + } + } else { + character.setViewDirection(walkDirection); + if (airTime > 0.3f) { + if (action != standAction) { + composer.setCurrentAction("stand", "walkingLayer"); + } + } else if (action != walkAction) { + composer.setCurrentAction("Walk", "walkingLayer"); + } + } + character.setWalkDirection(walkDirection); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("CharLeft")) { + if (value) { + left = true; + } else { + left = false; + } + } else if (binding.equals("CharRight")) { + if (value) { + right = true; + } else { + right = false; + } + } else if (binding.equals("CharUp")) { + if (value) { + up = true; + } else { + up = false; + } + } else if (binding.equals("CharDown")) { + if (value) { + down = true; + } else { + down = false; + } + } else if (binding.equals("CharSpace")) { + character.jump(); + } else if (binding.equals("CharShoot") && !value) { + bulletControl(); + } + } + + private void bulletControl() { + composer.setCurrentAction("shootOnce", "shootingLayer"); + + Geometry bulletGeometry = new Geometry("bullet", bullet); + bulletGeometry.setMaterial(matBullet); + bulletGeometry.setShadowMode(ShadowMode.CastAndReceive); + bulletGeometry.setLocalTranslation(character.getPhysicsLocation().add(cam.getDirection().mult(5))); + RigidBodyControl bulletControl = new BombControl(bulletCollisionShape, 1); + bulletControl.setCcdMotionThreshold(0.1f); + bulletControl.setLinearVelocity(cam.getDirection().mult(80)); + bulletGeometry.addControl(bulletControl); + rootNode.attachChild(bulletGeometry); + getPhysicsSpace().add(bulletControl); + } + + @Override + public void collision(PhysicsCollisionEvent event) { + if (event.getObjectA() instanceof BombControl) { + final Spatial node = event.getNodeA(); + effect.killAllParticles(); + effect.setLocalTranslation(node.getLocalTranslation()); + effect.emitAllParticles(); + } else if (event.getObjectB() instanceof BombControl) { + final Spatial node = event.getNodeB(); + effect.killAllParticles(); + effect.setLocalTranslation(node.getLocalTranslation()); + effect.emitAllParticles(); + } + } + + /** + * Callback to indicate that the "shootOnce" animation action has completed. + */ + void onShootDone() { + /* + * Play the "stand" animation action on the shooting layer. + */ + composer.setCurrentAction("stand", "shootingLayer"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/package-info.java b/jme3-examples/src/main/java/jme3test/bullet/package-info.java new file mode 100644 index 0000000000..866ed54fa7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for Bullet physics + */ +package jme3test.bullet; diff --git a/jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java b/jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java new file mode 100644 index 0000000000..f564790411 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/shape/TestGimpactShape.java @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.bullet.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.GImpactCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.debug.BulletDebugAppState; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.PQTorus; +import com.jme3.scene.shape.Torus; +import com.jme3.system.AppSettings; +import java.util.ArrayList; +import java.util.List; +import jme3test.bullet.PhysicsTestHelper; + +/** + * This test demonstrates various GImpactCollisionShapes colliding against two identical curved surfaces. The + * left surface is a MeshCollisionShape, right surface is another GImpactCollisionShape. An ideal result is + * for all objects to land and change to a blue colored mesh indicating they are inactive. Falling through the + * floor, or never going inactive (bouncing forever) are failure conditions. + *

+ * Observations as of June 2019 (JME v3.3.0-alpha2): + *

    + *
  1. + * With default starting parameters, Native Bullet should pass the test parameters above. JBullet fails due to + * the rocket/MeshCollisionShape never going inactive. + *
  2. + *
  3. + * Native Bullet behaves better than JBullet. JBullet sometimes allows objects to "gain too much energy" after + * a collision, such as the rocket or teapot. Native also does this, to a lesser degree. This generally + * appears to happen at larger object scales. + *
  4. + *
  5. + * JBullet allows some objects to get "stuck" inside the floor, which usually results in a fall-through + * eventually, generally a larger scales for this test. + *
  6. + *
  7. + * Some shapes such as PQTorus and signpost never go inactive at larger scales for both Native and JBullet (test + * at 1.5 and 1.9 scale) + *
  8. + *
+ * + * @author lou + */ +public class TestGimpactShape extends SimpleApplication { + + private static TestGimpactShape test; + private BulletAppState bulletAppState; + private int solverNumIterations = 10; + private BitmapText timeElapsedTxt; + private BitmapText solverNumIterationsTxt; + private BitmapText testScale; + private final List testObjects = new ArrayList<>(); + private float testTimer = 0; + private float scaleMod = 1; + private boolean restart = true; + private static final boolean SKIP_SETTINGS = false;//Used for repeated runs of this test during dev + + public static void main(String[] args) { + test = new TestGimpactShape(); + test.setSettings(new AppSettings(true)); + test.settings.setVSync(true); + if (SKIP_SETTINGS) { + test.settings.setWidth(1920); + test.settings.setHeight(1150); + test.showSettings = !SKIP_SETTINGS; + } + test.start(); + } + + @Override + public void simpleInitApp() { + test = this; + getCamera().setLocation(new Vector3f(40, 30, 160)); + getCamera().lookAt(new Vector3f(40, -5, 0), Vector3f.UNIT_Y); + getFlyByCamera().setMoveSpeed(25); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + dl.setColor(ColorRGBA.Green); + rootNode.addLight(dl); + + //Setup test instructions + guiNode = getGuiNode(); + BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText[] testInfo = new BitmapText[2]; + testInfo[0] = new BitmapText(font); + testInfo[1] = new BitmapText(font); + timeElapsedTxt = new BitmapText(font); + solverNumIterationsTxt = new BitmapText(font); + testScale = new BitmapText(font); + + float lineHeight = testInfo[0].getLineHeight(); + testInfo[0].setText("Camera move:W/A/S/D/Q/Z Solver iterations: 1=10, 2=20, 3=30"); + testInfo[0].setLocalTranslation(5, test.settings.getHeight(), 0); + guiNode.attachChild(testInfo[0]); + testInfo[1].setText("P: Toggle pause Inc/Dec object scale: +, - Space: Restart test"); + testInfo[1].setLocalTranslation(5, test.settings.getHeight() - lineHeight, 0); + guiNode.attachChild(testInfo[1]); + + timeElapsedTxt.setLocalTranslation(202, lineHeight * 1, 0); + guiNode.attachChild(timeElapsedTxt); + solverNumIterationsTxt.setLocalTranslation(202, lineHeight * 2, 0); + guiNode.attachChild(solverNumIterationsTxt); + testScale.setLocalTranslation(202, lineHeight * 3, 0); + guiNode.attachChild(testScale); + + //Setup interactive test controls + inputManager.addMapping("restart", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { + restart = true; + }, "restart"); + + inputManager.addMapping("pause", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { + if (!isPressed) { + return; + } + bulletAppState.setSpeed(bulletAppState.getSpeed() > 0.1 ? 0 : 1); + }, "pause"); + + inputManager.addMapping("1", new KeyTrigger(KeyInput.KEY_1)); + inputManager.addMapping("2", new KeyTrigger(KeyInput.KEY_2)); + inputManager.addMapping("3", new KeyTrigger(KeyInput.KEY_3)); + inputManager.addMapping("+", new KeyTrigger(KeyInput.KEY_ADD), new KeyTrigger(KeyInput.KEY_EQUALS)); + inputManager.addMapping("-", new KeyTrigger(KeyInput.KEY_SUBTRACT), new KeyTrigger(KeyInput.KEY_MINUS)); + inputManager.addListener((ActionListener) (String name, boolean isPressed, float tpf) -> { + if (!isPressed) { + return; + } + switch (name) { + case "1": + solverNumIterations = 10; + break; + case "2": + solverNumIterations = 20; + break; + case "3": + solverNumIterations = 30; + break; + case "+": + scaleMod += scaleMod < 1.9f ? 0.1f : 0; + break; + case "-": + scaleMod -= scaleMod > 0.5f ? 0.1f : 0; + break; + } + restart = true; + }, "1", "2", "3", "+", "-"); + + initializeNewTest(); + } + + private void initializeNewTest() { + testScale.setText("Object scale: " + String.format("%.1f", scaleMod)); + solverNumIterationsTxt.setText("Solver Iterations: " + solverNumIterations); + + bulletAppState = new BulletAppState(); + bulletAppState.setDebugEnabled(true); + stateManager.attach(bulletAppState); + bulletAppState.getPhysicsSpace().setSolverNumIterations(solverNumIterations); + + float floorSize = 80; + //Left side test - GImpact objects collide with MeshCollisionShape floor + Vector3f leftFloorPos = new Vector3f(-41, -5, -10); + Vector3f leftFloorCenter = leftFloorPos.add(floorSize / 2, 0, floorSize / 2); + + dropTest1(leftFloorCenter); + dropTest2(leftFloorCenter); + dropPot(leftFloorCenter); + dropSword(leftFloorCenter); + dropSign(leftFloorCenter); + dropRocket(leftFloorCenter); + + Geometry leftFloor = PhysicsTestHelper.createMeshTestFloor(assetManager, floorSize, leftFloorPos); + addObject(leftFloor); + + //Right side test - GImpact objects collide with GImpact floor + Vector3f rightFloorPos = new Vector3f(41, -5, -10); + Vector3f rightFloorCenter = rightFloorPos.add(floorSize / 2, 0, floorSize / 2); + + dropTest1(rightFloorCenter); + dropTest2(rightFloorCenter); + dropPot(rightFloorCenter); + dropSword(rightFloorCenter); + dropSign(rightFloorCenter); + dropRocket(rightFloorCenter); + + Geometry rightFloor = PhysicsTestHelper.createGImpactTestFloor(assetManager, floorSize, rightFloorPos); + addObject(rightFloor); + + //Hide physics debug visualization for floors + BulletDebugAppState bulletDebugAppState = stateManager.getState(BulletDebugAppState.class); + bulletDebugAppState.setFilter((Object obj) -> { + return !(obj.equals(rightFloor.getControl(RigidBodyControl.class)) + || obj.equals(leftFloor.getControl(RigidBodyControl.class))); + }); + } + + private void addObject(Spatial s) { + testObjects.add(s); + rootNode.attachChild(s); + physicsSpace().add(s); + } + + private void dropTest1(Vector3f offset) { + offset = offset.add(-18, 6, -18); + attachTestObject(new Torus(16, 16, 0.15f, 0.5f), new Vector3f(-12f, 0f, 5f).add(offset), 1); + attachTestObject(new PQTorus(2f, 3f, 0.6f, 0.2f, 48, 16), new Vector3f(0, 0, 0).add(offset), 5); + + } + + private void dropTest2(Vector3f offset) { + offset = offset.add(18, 6, -18); + attachTestObject(new Torus(16, 16, 0.3f, 0.8f), new Vector3f(12f, 0f, 5f).add(offset), 3); + attachTestObject(new PQTorus(3f, 5f, 0.8f, 0.2f, 96, 16), new Vector3f(0, 0, 0).add(offset), 10); + } + + private void dropPot(Vector3f offset) { + drop(offset.add(-12, 7, 15), "Models/Teapot/Teapot.mesh.xml", 1.0f, 2); + } + + private void dropSword(Vector3f offset) { + drop(offset.add(-10, 5, 3), "Models/Sinbad/Sword.mesh.xml", 1.0f, 2); + } + + private void dropSign(Vector3f offset) { + drop(offset.add(9, 15, 5), "Models/Sign Post/Sign Post.mesh.xml", 1.0f, 1); + } + + private void dropRocket(Vector3f offset) { + RigidBodyControl c = drop(offset.add(26, 4, 7), "Models/SpaceCraft/Rocket.mesh.xml", 4.0f, 3); + c.setAngularDamping(0.5f); + c.setLinearDamping(0.5f); + } + + private RigidBodyControl drop(Vector3f offset, String model, float scale, float mass) { + scale *= scaleMod; + Node n = (Node) assetManager.loadModel(model); + n.setLocalTranslation(offset); + n.rotate(0, 0, -FastMath.HALF_PI); + + Geometry tp = ((Geometry) n.getChild(0)); + tp.scale(scale); + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + tp.setMaterial(mat); + + Mesh mesh = tp.getMesh(); + GImpactCollisionShape shape = new GImpactCollisionShape(mesh); + shape.setScale(new Vector3f(scale, scale, scale)); + + RigidBodyControl control = new RigidBodyControl(shape, mass); + n.addControl(control); + addObject(n); + return control; + } + + private void attachTestObject(Mesh mesh, Vector3f position, float mass) { + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Geometry g = new Geometry("mesh", mesh); + g.scale(scaleMod); + g.setLocalTranslation(position); + g.setMaterial(material); + + GImpactCollisionShape shape = new GImpactCollisionShape(mesh); + shape.setScale(new Vector3f(scaleMod, scaleMod, scaleMod)); + RigidBodyControl control = new RigidBodyControl(shape, mass); + g.addControl(control); + addObject(g); + } + + private PhysicsSpace physicsSpace() { + return bulletAppState.getPhysicsSpace(); + } + + @Override + public void simpleUpdate(float tpf) { + testTimer += tpf * bulletAppState.getSpeed(); + + if (restart) { + cleanup(); + initializeNewTest(); + restart = false; + testTimer = 0; + } + timeElapsedTxt.setText("Time Elapsed: " + String.format("%.3f", testTimer)); + } + + private void cleanup() { + stateManager.detach(bulletAppState); + stateManager.detach(stateManager.getState(BulletDebugAppState.class)); + for (Spatial s : testObjects) { + rootNode.detachChild(s); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java b/jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java new file mode 100644 index 0000000000..c1adfcb1a4 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/shape/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for specific Bullet-physics collision + * shapes + */ +package jme3test.bullet.shape; diff --git a/jme3-examples/src/main/java/jme3test/collision/RayTrace.java b/jme3-examples/src/main/java/jme3test/collision/RayTrace.java new file mode 100644 index 0000000000..6023b6f132 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/collision/RayTrace.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.collision; + +import com.jme3.collision.CollisionResults; +import com.jme3.math.Ray; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.scene.Spatial; +import java.awt.FlowLayout; +import java.awt.image.BufferedImage; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; + +public class RayTrace { + + final private BufferedImage image; + final private Camera cam; + final private Spatial scene; + final private CollisionResults results = new CollisionResults(); + private JLabel label; + + public RayTrace(Spatial scene, Camera cam, int width, int height){ + image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + this.scene = scene; + this.cam = cam; + } + + public void show(){ + JFrame frame = new JFrame("HDR View"); + label = new JLabel(new ImageIcon(image)); + frame.getContentPane().add(label); + frame.setLayout(new FlowLayout()); + frame.pack(); + frame.setVisible(true); + } + + public void update(){ + int w = image.getWidth(); + int h = image.getHeight(); + + float wr = (float) cam.getWidth() / image.getWidth(); + float hr = (float) cam.getHeight() / image.getHeight(); + + scene.updateGeometricState(); + + for (int y = 0; y < h; y++){ + for (int x = 0; x < w; x++){ + Vector2f v = new Vector2f(x * wr,y * hr); + Vector3f pos = cam.getWorldCoordinates(v, 0.0f); + Vector3f dir = cam.getWorldCoordinates(v, 0.3f); + dir.subtractLocal(pos).normalizeLocal(); + + Ray r = new Ray(pos, dir); + + results.clear(); + scene.collideWith(r, results); + if (results.size() > 0){ + image.setRGB(x, h - y - 1, 0xFFFFFFFF); + }else{ + image.setRGB(x, h - y - 1, 0xFF000000); + } + } + } + + label.repaint(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/collision/TestMousePick.java b/jme3-examples/src/main/java/jme3test/collision/TestMousePick.java new file mode 100644 index 0000000000..9ff54ae532 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/collision/TestMousePick.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.collision; + +import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Ray; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.debug.Arrow; +import com.jme3.scene.shape.Box; + +public class TestMousePick extends SimpleApplication { + + public static void main(String[] args) { + TestMousePick app = new TestMousePick(); + app.start(); + } + + private Node shootables; + private Geometry mark; + + @Override + public void simpleInitApp() { + flyCam.setEnabled(false); + initMark(); + + /* Create four colored boxes and a floor to shoot at: */ + shootables = new Node("Shootables"); + rootNode.attachChild(shootables); + shootables.attachChild(makeCube("a Dragon", -2f, 0f, 1f)); + shootables.attachChild(makeCube("a tin can", 1f, -2f, 0f)); + shootables.attachChild(makeCube("the Sheriff", 0f, 1f, -2f)); + shootables.attachChild(makeCube("the Deputy", 1f, 0f, -4f)); + shootables.attachChild(makeFloor()); + shootables.attachChild(makeCharacter()); + } + + @Override + public void simpleUpdate(float tpf){ + Vector3f origin = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f); + Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f); + direction.subtractLocal(origin).normalizeLocal(); + + Ray ray = new Ray(origin, direction); + CollisionResults results = new CollisionResults(); + shootables.collideWith(ray, results); +// System.out.println("----- Collisions? " + results.size() + "-----"); +// for (int i = 0; i < results.size(); i++) { +// // For each hit, we know distance, impact point, name of geometry. +// float dist = results.getCollision(i).getDistance(); +// Vector3f pt = results.getCollision(i).getWorldContactPoint(); +// String hit = results.getCollision(i).getGeometry().getName(); +// System.out.println("* Collision #" + i); +// System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away."); +// } + if (results.size() > 0) { + CollisionResult closest = results.getClosestCollision(); + mark.setLocalTranslation(closest.getContactPoint()); + + Quaternion q = new Quaternion(); + q.lookAt(closest.getContactNormal(), Vector3f.UNIT_Y); + mark.setLocalRotation(q); + + rootNode.attachChild(mark); + } else { + rootNode.detachChild(mark); + } + } + + /** A cube object for target practice */ + private Geometry makeCube(String name, float x, float y, float z) { + Box box = new Box(1, 1, 1); + Geometry cube = new Geometry(name, box); + cube.setLocalTranslation(x, y, z); + Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.randomColor()); + cube.setMaterial(mat1); + return cube; + } + + /** A floor to show that the "shot" can go through several objects. */ + private Geometry makeFloor() { + Box box = new Box(15, .2f, 15); + Geometry floor = new Geometry("the Floor", box); + floor.setLocalTranslation(0, -4, -5); + Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.Gray); + floor.setMaterial(mat1); + return floor; + } + + /** + * A red arrow to mark the spot being picked. + */ + private void initMark() { + Arrow arrow = new Arrow(Vector3f.UNIT_Z.mult(2f)); + mark = new Geometry("BOOM!", arrow); + Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mark_mat.setColor("Color", ColorRGBA.Red); + mark.setMaterial(mark_mat); + } + + private Spatial makeCharacter() { + // load a character from jme3-testdata + Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + golem.scale(0.5f); + golem.setLocalTranslation(-1.0f, -1.5f, -0.6f); + + // We must add a light to make the model visible + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal()); + golem.addLight(sun); + return golem; + } +} diff --git a/jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java b/jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java new file mode 100644 index 0000000000..e3c1ba136b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/collision/TestRayCasting.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.collision; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingSphere; +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.scene.Mesh; +import com.jme3.scene.Spatial; +import com.jme3.scene.VertexBuffer.Type; + +public class TestRayCasting extends SimpleApplication { + + private RayTrace tracer; + private Spatial teapot; + + public static void main(String[] args){ + TestRayCasting app = new TestRayCasting(); + app.setPauseOnLostFocus(false); + app.start(); + } + + @Override + public void simpleInitApp() { +// flyCam.setEnabled(false); + + // load material + Material mat = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); + + Mesh q = new Mesh(); + q.setBuffer(Type.Position, 3, new float[] + { + 1, 0, 0, + 0, 1.5f, 0, + -1, 0, 0 + } + ); + q.setBuffer(Type.Index, 3, new int[]{ 0, 1, 2 }); + q.setBound(new BoundingSphere()); + q.updateBound(); +// Geometry teapot = new Geometry("MyGeom", q); + + teapot = assetManager.loadModel("Models/Teapot/Teapot.mesh.xml"); +// teapot.scale(2f, 2f, 2f); +// teapot.move(2f, 2f, -.5f); + teapot.rotate(FastMath.HALF_PI, FastMath.HALF_PI, FastMath.HALF_PI); + teapot.setMaterial(mat); + rootNode.attachChild(teapot); + +// cam.setLocation(cam.getLocation().add(0,1,0)); +// cam.lookAt(teapot.getWorldBound().getCenter(), Vector3f.UNIT_Y); + + tracer = new RayTrace(rootNode, cam, 160, 128); + tracer.show(); + tracer.update(); + } + + @Override + public void simpleUpdate(float tpf){ + teapot.rotate(0,tpf,0); + tracer.update(); + } + +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java b/jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java new file mode 100644 index 0000000000..6d20ea1fc2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.collision; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingVolume; +import com.jme3.collision.CollisionResults; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; + +public class TestTriangleCollision extends SimpleApplication { + + private Geometry geom1; + + private Spatial golem; + + public static void main(String[] args) { + TestTriangleCollision app = new TestTriangleCollision(); + app.start(); + } + + @Override + public void simpleInitApp() { + // Create two boxes + Mesh mesh1 = new Box(0.5f, 0.5f, 0.5f); + geom1 = new Geometry("Box", mesh1); + geom1.move(2, 2, -.5f); + Material m1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + m1.setColor("Color", ColorRGBA.Blue); + geom1.setMaterial(m1); + rootNode.attachChild(geom1); + + // load a character from jme3-testdata + golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + golem.scale(0.5f); + golem.setLocalTranslation(-1.0f, -1.5f, -0.6f); + + // We must add a light to make the model visible + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal()); + golem.addLight(sun); + rootNode.attachChild(golem); + + // Create input + inputManager.addMapping("MoveRight", new KeyTrigger(KeyInput.KEY_L)); + inputManager.addMapping("MoveLeft", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("MoveUp", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addMapping("MoveDown", new KeyTrigger(KeyInput.KEY_K)); + + inputManager.addListener(analogListener, new String[]{ + "MoveRight", "MoveLeft", "MoveUp", "MoveDown" + }); + } + final private AnalogListener analogListener = new AnalogListener() { + + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("MoveRight")) { + geom1.move(2 * tpf, 0, 0); + } + + if (name.equals("MoveLeft")) { + geom1.move(-2 * tpf, 0, 0); + } + + if (name.equals("MoveUp")) { + geom1.move(0, 2 * tpf, 0); + } + + if (name.equals("MoveDown")) { + geom1.move(0, -2 * tpf, 0); + } + } + }; + + @Override + public void simpleUpdate(float tpf) { + CollisionResults results = new CollisionResults(); + BoundingVolume bv = geom1.getWorldBound(); + golem.collideWith(bv, results); + + if (results.size() > 0) { + geom1.getMaterial().setColor("Color", ColorRGBA.Red); + }else{ + geom1.getMaterial().setColor("Color", ColorRGBA.Blue); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/collision/package-info.java b/jme3-examples/src/main/java/jme3test/collision/package-info.java new file mode 100644 index 0000000000..10ff40e8f6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/collision/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for picking and non-physics collision + * detection + */ +package jme3test.collision; diff --git a/jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java b/jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java new file mode 100644 index 0000000000..6110469ee0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/conversion/TestMipMapGen.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009-2018 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. + */ + +package jme3test.conversion; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Image; +import com.jme3.texture.Texture; +import com.jme3.util.MipMapGenerator; + +public class TestMipMapGen extends SimpleApplication { + + public static void main(String[] args){ + TestMipMapGen app = new TestMipMapGen(); + app.start(); + } + + @Override + public void simpleInitApp() { + BitmapText txt = guiFont.createLabel("Left: HW Mips"); + txt.setLocalTranslation(0, settings.getHeight() - txt.getLineHeight() * 4, 0); + guiNode.attachChild(txt); + + txt = guiFont.createLabel("Right: AWT Mips"); + txt.setLocalTranslation(0, settings.getHeight() - txt.getLineHeight() * 3, 0); + guiNode.attachChild(txt); + + // create a simple plane/quad + Quad quadMesh = new Quad(1, 1); + quadMesh.updateGeometry(1, 1, false); + quadMesh.updateBound(); + + Geometry quad1 = new Geometry("Textured Quad", quadMesh); + Geometry quad2 = new Geometry("Textured Quad 2", quadMesh); + + Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.png"); + tex.setMinFilter(Texture.MinFilter.Trilinear); + + Texture texCustomMip = tex.clone(); + Image imageCustomMip = texCustomMip.getImage().clone(); + MipMapGenerator.generateMipMaps(imageCustomMip); + texCustomMip.setImage(imageCustomMip); + + Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setTexture("ColorMap", tex); + + Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.setTexture("ColorMap", texCustomMip); + + quad1.setMaterial(mat1); +// quad1.setLocalTranslation(1, 0, 0); + + quad2.setMaterial(mat2); + quad2.setLocalTranslation(1, 0, 0); + + rootNode.attachChild(quad1); + rootNode.attachChild(quad2); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/conversion/package-info.java b/jme3-examples/src/main/java/jme3test/conversion/package-info.java new file mode 100644 index 0000000000..3a49d4c92d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/conversion/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for converting textures + */ +package jme3test.conversion; diff --git a/jme3-examples/src/main/java/jme3test/effect/TestEverything.java b/jme3-examples/src/main/java/jme3test/effect/TestEverything.java new file mode 100644 index 0000000000..b579a03601 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/TestEverything.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.effect; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.ToneMapFilter; +import com.jme3.renderer.Caps; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.Spatial.CullHint; +import com.jme3.scene.shape.Box; +import com.jme3.shadow.DirectionalLightShadowRenderer; +import com.jme3.texture.Texture; +import com.jme3.util.SkyFactory; +import com.jme3.util.TangentBinormalGenerator; + +public class TestEverything extends SimpleApplication { + + private DirectionalLightShadowRenderer dlsr; + private ToneMapFilter toneMapFilter; + final private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); + + public static void main(String[] args){ + TestEverything app = new TestEverything(); + app.start(); + } + + public void setupHdr(){ + if (renderer.getCaps().contains(Caps.GLSL100)){ + toneMapFilter = new ToneMapFilter(); + toneMapFilter.setWhitePoint(new Vector3f(3f, 3f, 3f)); + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(toneMapFilter); + viewPort.addProcessor(fpp); + + // setPauseOnLostFocus(false); + } + } + + public void setupBasicShadow(){ + if (renderer.getCaps().contains(Caps.GLSL100)){ + dlsr = new DirectionalLightShadowRenderer(assetManager, 1024, 1); + viewPort.addProcessor(dlsr); + } + } + + public void setupSkyBox(){ + Texture envMap; + if (renderer.getCaps().contains(Caps.FloatTexture)){ + envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.hdr"); + }else{ + envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.jpg"); + } + rootNode.attachChild(SkyFactory.createSky(assetManager, envMap, + new Vector3f(-1,-1,-1), SkyFactory.EnvMapType.SphereMap)); + } + + public void setupLighting(){ + boolean hdr = false; + if (toneMapFilter != null){ + hdr = toneMapFilter.isEnabled(); + } + + DirectionalLight dl = new DirectionalLight(); + if (dlsr != null) { + dlsr.setLight(dl); + } + dl.setDirection(lightDir); + if (hdr){ + dl.setColor(new ColorRGBA(3, 3, 3, 1)); + }else{ + dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); + } + rootNode.addLight(dl); + + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1, 0, -1).normalizeLocal()); + if (hdr){ + dl.setColor(new ColorRGBA(1, 1, 1, 1)); + }else{ + dl.setColor(new ColorRGBA(.4f, .4f, .4f, 1)); + } + rootNode.addLight(dl); + } + + public void setupFloor(){ + Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); + Box floor = new Box(50, 1f, 50); + TangentBinormalGenerator.generate(floor); + floor.scaleTextureCoordinates(new Vector2f(5, 5)); + Geometry floorGeom = new Geometry("Floor", floor); + floorGeom.setMaterial(mat); + floorGeom.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(floorGeom); + } + +// public void setupTerrain(){ +// Material mat = manager.loadMaterial("Textures/Terrain/Rock/Rock.j3m"); +// mat.getTextureParam("DiffuseMap").getValue().setWrap(WrapMode.Repeat); +// mat.getTextureParam("NormalMap").getValue().setWrap(WrapMode.Repeat); +// try{ +// Geomap map = GeomapLoader.fromImage(TestEverything.class.getResource("/textures/heightmap.png")); +// Mesh m = map.createMesh(new Vector3f(0.35f, 0.0005f, 0.35f), new Vector2f(10, 10), true); +// Logger.getLogger(TangentBinormalGenerator.class.getName()).setLevel(Level.SEVERE); +// TangentBinormalGenerator.generate(m); +// Geometry t = new Geometry("Terrain", m); +// t.setLocalTranslation(85, -15, 0); +// t.setMaterial(mat); +// t.updateModelBound(); +// t.setShadowMode(ShadowMode.Receive); +// rootNode.attachChild(t); +// }catch (IOException ex){ +// ex.printStackTrace(); +// } +// +// } + + public void setupRobotGuy(){ + Node model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + Material mat = assetManager.loadMaterial("Models/Oto/Oto.j3m"); + model.getChild(0).setMaterial(mat); +// model.setAnimation("Walk"); + model.setLocalTranslation(30, 10.5f, 30); + model.setLocalScale(2); + model.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(model); + } + + public void setupSignpost(){ + Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); + Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + signpost.setMaterial(mat); + signpost.rotate(0, FastMath.HALF_PI, 0); + signpost.setLocalTranslation(12, 3.5f, 30); + signpost.setLocalScale(4); + signpost.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(signpost); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(-32.295086f, 54.80136f, 79.59805f)); + cam.setRotation(new Quaternion(0.074364014f, 0.92519957f, -0.24794696f, 0.27748522f)); + cam.update(); + + cam.setFrustumFar(300); + flyCam.setMoveSpeed(30); + + rootNode.setCullHint(CullHint.Never); + + setupBasicShadow(); + setupHdr(); + + setupLighting(); + setupSkyBox(); + +// setupTerrain(); + setupFloor(); +// setupRobotGuy(); + setupSignpost(); + + + } + +} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java b/jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java new file mode 100644 index 0000000000..7f6a32bc81 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/TestExplosionEffect.java @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.effect; + +import com.jme3.app.SimpleApplication; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.effect.shapes.EmitterSphereShape; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; + +public class TestExplosionEffect extends SimpleApplication { + + private float time = 0; + private int state = 0; + final private Node explosionEffect = new Node("explosionFX"); + private ParticleEmitter flame, flash, spark, roundspark, smoketrail, debris, + shockwave; + + + private static final int COUNT_FACTOR = 1; + private static final float COUNT_FACTOR_F = 1f; + + private static final boolean POINT_SPRITE = true; + private static final Type EMITTER_TYPE = POINT_SPRITE ? Type.Point : Type.Triangle; + + public static void main(String[] args){ + TestExplosionEffect app = new TestExplosionEffect(); + app.start(); + } + + private void createFlame(){ + flame = new ParticleEmitter("Flame", EMITTER_TYPE, 32 * COUNT_FACTOR); + flame.setSelectRandomImage(true); + flame.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (1f / COUNT_FACTOR_F))); + flame.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); + flame.setStartSize(1.3f); + flame.setEndSize(2f); + flame.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); + flame.setParticlesPerSec(0); + flame.setGravity(0, -5, 0); + flame.setLowLife(.4f); + flame.setHighLife(.5f); + flame.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 7, 0)); + flame.getParticleInfluencer().setVelocityVariation(1f); + flame.setImagesX(2); + flame.setImagesY(2); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); + mat.setBoolean("PointSprite", POINT_SPRITE); + flame.setMaterial(mat); + explosionEffect.attachChild(flame); + } + + private void createFlash(){ + flash = new ParticleEmitter("Flash", EMITTER_TYPE, 24 * COUNT_FACTOR); + flash.setSelectRandomImage(true); + flash.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1f / COUNT_FACTOR_F)); + flash.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); + flash.setStartSize(.1f); + flash.setEndSize(3.0f); + flash.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); + flash.setParticlesPerSec(0); + flash.setGravity(0, 0, 0); + flash.setLowLife(.2f); + flash.setHighLife(.2f); + flash.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, 5f, 0)); + flash.getParticleInfluencer().setVelocityVariation(1); + flash.setImagesX(2); + flash.setImagesY(2); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flash.png")); + mat.setBoolean("PointSprite", POINT_SPRITE); + flash.setMaterial(mat); + explosionEffect.attachChild(flash); + } + + private void createRoundSpark(){ + roundspark = new ParticleEmitter("RoundSpark", EMITTER_TYPE, 20 * COUNT_FACTOR); + roundspark.setStartColor(new ColorRGBA(1f, 0.29f, 0.34f, (float) (1.0 / COUNT_FACTOR_F))); + roundspark.setEndColor(new ColorRGBA(0, 0, 0, 0.5f / COUNT_FACTOR_F)); + roundspark.setStartSize(1.2f); + roundspark.setEndSize(1.8f); + roundspark.setShape(new EmitterSphereShape(Vector3f.ZERO, 2f)); + roundspark.setParticlesPerSec(0); + roundspark.setGravity(0, -.5f, 0); + roundspark.setLowLife(1.8f); + roundspark.setHighLife(2f); + roundspark.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, 3, 0)); + roundspark.getParticleInfluencer().setVelocityVariation(.5f); + roundspark.setImagesX(1); + roundspark.setImagesY(1); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/roundspark.png")); + mat.setBoolean("PointSprite", POINT_SPRITE); + roundspark.setMaterial(mat); + explosionEffect.attachChild(roundspark); + } + + private void createSpark(){ + spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR); + spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F)); + spark.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); + spark.setStartSize(.5f); + spark.setEndSize(.5f); + spark.setFacingVelocity(true); + spark.setParticlesPerSec(0); + spark.setGravity(0, 5, 0); + spark.setLowLife(1.1f); + spark.setHighLife(1.5f); + spark.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 20, 0)); + spark.getParticleInfluencer().setVelocityVariation(1); + spark.setImagesX(1); + spark.setImagesY(1); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/spark.png")); + spark.setMaterial(mat); + explosionEffect.attachChild(spark); + } + + private void createSmokeTrail(){ + smoketrail = new ParticleEmitter("SmokeTrail", Type.Triangle, 22 * COUNT_FACTOR); + smoketrail.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F)); + smoketrail.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); + smoketrail.setStartSize(.2f); + smoketrail.setEndSize(1f); + +// smoketrail.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); + smoketrail.setFacingVelocity(true); + smoketrail.setParticlesPerSec(0); + smoketrail.setGravity(0, 1, 0); + smoketrail.setLowLife(.4f); + smoketrail.setHighLife(.5f); + smoketrail.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, 12, 0)); + smoketrail.getParticleInfluencer().setVelocityVariation(1); + smoketrail.setImagesX(1); + smoketrail.setImagesY(3); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/smoketrail.png")); + smoketrail.setMaterial(mat); + explosionEffect.attachChild(smoketrail); + } + + private void createDebris(){ + debris = new ParticleEmitter("Debris", Type.Triangle, 15 * COUNT_FACTOR); + debris.setSelectRandomImage(true); + debris.setRandomAngle(true); + debris.setRotateSpeed(FastMath.TWO_PI * 4); + debris.setStartColor(new ColorRGBA(1f, 0.59f, 0.28f, 1.0f / COUNT_FACTOR_F)); + debris.setEndColor(new ColorRGBA(.5f, 0.5f, 0.5f, 0f)); + debris.setStartSize(.2f); + debris.setEndSize(.2f); + +// debris.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); + debris.setParticlesPerSec(0); + debris.setGravity(0, 12f, 0); + debris.setLowLife(1.4f); + debris.setHighLife(1.5f); + debris.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, 15, 0)); + debris.getParticleInfluencer().setVelocityVariation(.60f); + debris.setImagesX(3); + debris.setImagesY(3); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/Debris.png")); + debris.setMaterial(mat); + explosionEffect.attachChild(debris); + } + + private void createShockwave(){ + shockwave = new ParticleEmitter("Shockwave", Type.Triangle, 1 * COUNT_FACTOR); +// shockwave.setRandomAngle(true); + shockwave.setFaceNormal(Vector3f.UNIT_Y); + shockwave.setStartColor(new ColorRGBA(.48f, 0.17f, 0.01f, .8f / COUNT_FACTOR_F)); + shockwave.setEndColor(new ColorRGBA(.48f, 0.17f, 0.01f, 0f)); + + shockwave.setStartSize(0f); + shockwave.setEndSize(7f); + + shockwave.setParticlesPerSec(0); + shockwave.setGravity(0, 0, 0); + shockwave.setLowLife(0.5f); + shockwave.setHighLife(0.5f); + shockwave.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, 0, 0)); + shockwave.getParticleInfluencer().setVelocityVariation(0f); + shockwave.setImagesX(1); + shockwave.setImagesY(1); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/shockwave.png")); + shockwave.setMaterial(mat); + explosionEffect.attachChild(shockwave); + } + + @Override + public void simpleInitApp() { + createFlame(); + createFlash(); + createSpark(); + createRoundSpark(); + createSmokeTrail(); + createDebris(); + createShockwave(); + explosionEffect.setLocalScale(0.5f); + renderManager.preloadScene(explosionEffect); + + cam.setLocation(new Vector3f(0, 3.5135868f, 10)); + cam.setRotation(new Quaternion(1.5714673E-4f, 0.98696727f, -0.16091813f, 9.6381607E-4f)); + + rootNode.attachChild(explosionEffect); + } + + @Override + public void simpleUpdate(float tpf){ + time += tpf / speed; + if (time > 1f && state == 0){ + flash.emitAllParticles(); + spark.emitAllParticles(); + smoketrail.emitAllParticles(); + debris.emitAllParticles(); + shockwave.emitAllParticles(); + state++; + } + if (time > 1f + .05f / speed && state == 1){ + flame.emitAllParticles(); + roundspark.emitAllParticles(); + state++; + } + + // rewind the effect + if (time > 5 / speed && state == 2){ + state = 0; + time = 0; + + flash.killAllParticles(); + spark.killAllParticles(); + smoketrail.killAllParticles(); + debris.killAllParticles(); + flame.killAllParticles(); + roundspark.killAllParticles(); + shockwave.killAllParticles(); + } + } + +} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java b/jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java new file mode 100644 index 0000000000..b466815dfb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/TestIssue1773.java @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package jme3test.effect; + +import com.jme3.animation.LoopMode; +import com.jme3.app.SimpleApplication; +import com.jme3.cinematic.MotionPath; +import com.jme3.cinematic.events.MotionEvent; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.effect.shapes.EmitterMeshVertexShape; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.Trigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.material.Materials; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.post.filters.FXAAFilter; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.CenterQuad; +import com.jme3.scene.shape.Torus; +import com.jme3.shadow.DirectionalLightShadowFilter; +import com.jme3.system.AppSettings; +import com.jme3.texture.Texture; +import java.util.Arrays; + +/** + * Test case for Issue 1773 (Wrong particle position when using + * 'EmitterMeshVertexShape' or 'EmitterMeshFaceShape' and worldSpace + * flag equal to true) + * + * If the test succeeds, the particles will be generated from the vertices + * (for EmitterMeshVertexShape) or from the faces (for EmitterMeshFaceShape) + * of the torus mesh. If the test fails, the particles will appear in the + * center of the torus when worldSpace flag is set to true. + * + * @author capdevon + */ +public class TestIssue1773 extends SimpleApplication implements ActionListener { + + public static void main(String[] args) { + TestIssue1773 app = new TestIssue1773(); + AppSettings settings = new AppSettings(true); + settings.setResolution(1280, 720); + settings.setRenderer(AppSettings.LWJGL_OPENGL32); + app.setSettings(settings); + app.setPauseOnLostFocus(false); + app.setShowSettings(false); + app.start(); + } + + private ParticleEmitter emit; + private Node myModel; + private BitmapText emitUI; + private MotionEvent motionControl; + private boolean playing; + + @Override + public void simpleInitApp() { + + BitmapText hud = createTextUI(ColorRGBA.White, 20, 15); + hud.setText("Play/Pause Motion: KEY_SPACE, InWorldSpace: KEY_I"); + + emitUI = createTextUI(ColorRGBA.Blue, 20, 15 * 2); + + configCamera(); + setupLights(); + setupGround(); + setupCircle(); + createMotionControl(); + setupKeys(); + } + + /** + * Crates particle emitter and adds it to root node. + */ + private void setupCircle() { + myModel = new Node("FieryCircle"); + + Geometry torus = createTorus(1f); + myModel.attachChild(torus); + + emit = createParticleEmitter(torus, true); + myModel.attachChild(emit); + + rootNode.attachChild(myModel); + } + + /** + * Creates torus geometry used for the emitter shape. + */ + private Geometry createTorus(float radius) { + float s = radius / 8f; + Geometry geo = new Geometry("CircleXZ", new Torus(64, 4, s, radius)); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + mat.getAdditionalRenderState().setWireframe(true); + geo.setMaterial(mat); + return geo; + } + + /** + * Creates a particle emitter that will emit the particles from + * the given shape's vertices. + */ + private ParticleEmitter createParticleEmitter(Geometry geo, boolean pointSprite) { + Type type = pointSprite ? Type.Point : Type.Triangle; + ParticleEmitter emitter = new ParticleEmitter("Emitter", type, 1000); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); + mat.setBoolean("PointSprite", pointSprite); + emitter.setMaterial(mat); + emitter.setLowLife(1); + emitter.setHighLife(1); + emitter.setImagesX(15); + emitter.setStartSize(0.04f); + emitter.setEndSize(0.02f); + emitter.setStartColor(ColorRGBA.Orange); + emitter.setEndColor(ColorRGBA.Red); + emitter.setParticlesPerSec(900); + emitter.setGravity(0, 0f, 0); + //emitter.getParticleInfluencer().setVelocityVariation(1); + //emitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, .5f, 0)); + emitter.setShape(new EmitterMeshVertexShape(Arrays.asList(geo.getMesh()))); + //emitter.setShape(new EmitterMeshFaceShape(Arrays.asList(geo.getMesh()))); + return emitter; + } + + /** + * Creates a motion control that will move particle emitter in + * a circular path. + */ + private void createMotionControl() { + + float radius = 5f; + float height = 1.10f; + + MotionPath path = new MotionPath(); + path.setCycle(true); + + for (int i = 0; i < 8; i++) { + float x = FastMath.sin(FastMath.QUARTER_PI * i) * radius; + float z = FastMath.cos(FastMath.QUARTER_PI * i) * radius; + path.addWayPoint(new Vector3f(x, height, z)); + } + //path.enableDebugShape(assetManager, rootNode); + + motionControl = new MotionEvent(myModel, path); + motionControl.setLoopMode(LoopMode.Loop); + //motionControl.setInitialDuration(15f); + //motionControl.setSpeed(2f); + motionControl.setDirectionType(MotionEvent.Direction.Path); + } + + /** + * Use keyboard space key to toggle emitter motion and I key to + * toggle inWorldSpace flag. By default, inWorldSpace flag is on + * and emitter motion is off. + */ + private void setupKeys() { + addMapping("ToggleMotionEvent", new KeyTrigger(KeyInput.KEY_SPACE)); + addMapping("InWorldSpace", new KeyTrigger(KeyInput.KEY_I)); + } + + private void addMapping(String mappingName, Trigger... triggers) { + inputManager.addMapping(mappingName, triggers); + inputManager.addListener(this, mappingName); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("InWorldSpace") && isPressed) { + boolean worldSpace = emit.isInWorldSpace(); + emit.setInWorldSpace(!worldSpace); + + } else if (name.equals("ToggleMotionEvent") && isPressed) { + if (playing) { + playing = false; + motionControl.pause(); + } else { + playing = true; + motionControl.play(); + } + } + } + + @Override + public void simpleUpdate(float tpf) { + emitUI.setText("InWorldSpace: " + emit.isInWorldSpace()); + } + + private void configCamera() { + flyCam.setDragToRotate(true); + flyCam.setMoveSpeed(10); + + cam.setLocation(new Vector3f(0, 6f, 9.2f)); + cam.lookAt(Vector3f.UNIT_Y, Vector3f.UNIT_Y); + + float aspect = (float) cam.getWidth() / cam.getHeight(); + cam.setFrustumPerspective(45, aspect, 0.1f, 1000f); + } + + /** + * Adds a ground to the scene + */ + private void setupGround() { + CenterQuad quad = new CenterQuad(12, 12); + quad.scaleTextureCoordinates(new Vector2f(2, 2)); + Geometry floor = new Geometry("Floor", quad); + Material mat = new Material(assetManager, Materials.LIGHTING); + Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + tex.setWrap(Texture.WrapMode.Repeat); + mat.setTexture("DiffuseMap", tex); + floor.setMaterial(mat); + floor.rotate(-FastMath.HALF_PI, 0, 0); + rootNode.attachChild(floor); + } + + /** + * Adds lights and filters + */ + private void setupLights() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + + AmbientLight ambient = new AmbientLight(); + ambient.setColor(ColorRGBA.White); + //rootNode.addLight(ambient); + + DirectionalLight sun = new DirectionalLight(); + sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal()); + sun.setColor(ColorRGBA.White); + rootNode.addLight(sun); + + DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, 4096, 3); + dlsf.setLight(sun); + dlsf.setShadowIntensity(0.4f); + dlsf.setShadowZExtend(256); + + FXAAFilter fxaa = new FXAAFilter(); + BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(bloom); + fpp.addFilter(dlsf); + fpp.addFilter(fxaa); + viewPort.addProcessor(fpp); + } + + /** + * Creates a bitmap test used for displaying debug info. + */ + private BitmapText createTextUI(ColorRGBA color, float xPos, float yPos) { + BitmapFont font = assetManager.loadFont("Interface/Fonts/Console.fnt"); + BitmapText bmp = new BitmapText(font); + bmp.setSize(font.getCharSet().getRenderedSize()); + bmp.setLocalTranslation(xPos, settings.getHeight() - yPos, 0); + bmp.setColor(color); + guiNode.attachChild(bmp); + return bmp; + } +} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java b/jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java new file mode 100644 index 0000000000..7aee885075 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/TestMovingParticle.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.effect; + +import com.jme3.app.SimpleApplication; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; + +/** + * Particle that moves in a circle. + * + * @author Kirill Vainer + */ +public class TestMovingParticle extends SimpleApplication { + + private ParticleEmitter emit; + private float angle = 0; + + public static void main(String[] args) { + TestMovingParticle app = new TestMovingParticle(); + app.start(); + } + + @Override + public void simpleInitApp() { + emit = new ParticleEmitter("Emitter", Type.Triangle, 300); + emit.setGravity(0, 0, 0); + emit.getParticleInfluencer().setVelocityVariation(1); + emit.setLowLife(1); + emit.setHighLife(1); + emit.getParticleInfluencer() + .setInitialVelocity(new Vector3f(0, .5f, 0)); + emit.setImagesX(15); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); + emit.setMaterial(mat); + + rootNode.attachChild(emit); + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if ("setNum".equals(name) && isPressed) { + emit.setNumParticles(1000); + } + } + }, "setNum"); + + inputManager.addMapping("setNum", new KeyTrigger(KeyInput.KEY_SPACE)); + } + + @Override + public void simpleUpdate(float tpf) { + angle += tpf; + angle %= FastMath.TWO_PI; + float x = FastMath.cos(angle) * 2; + float y = FastMath.sin(angle) * 2; + emit.setLocalTranslation(x, 0, y); + } +} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java b/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java new file mode 100644 index 0000000000..4b75b1e76c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.effect; + +import com.jme3.app.SimpleApplication; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.effect.shapes.EmitterSphereShape; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; + +public class TestParticleExportingCloning extends SimpleApplication { + + public static void main(String[] args){ + TestParticleExportingCloning app = new TestParticleExportingCloning(); + app.start(); + } + + @Override + public void simpleInitApp() { + ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Triangle, 200); + emit.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); + emit.setGravity(0, 0, 0); + emit.setLowLife(5); + emit.setHighLife(10); + emit.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 0, 0)); + emit.setImagesX(15); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); + emit.setMaterial(mat); + + ParticleEmitter emit2 = emit.clone(); + emit2.move(3, 0, 0); + + rootNode.attachChild(emit); + rootNode.attachChild(emit2); + + ParticleEmitter emit3 = BinaryExporter.saveAndLoad(assetManager, emit); + emit3.move(-3, 0, 0); + rootNode.attachChild(emit3); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java b/jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java new file mode 100644 index 0000000000..8543eba0e1 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/TestPointSprite.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.effect; + +import com.jme3.app.SimpleApplication; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.effect.shapes.EmitterBoxShape; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; + +public class TestPointSprite extends SimpleApplication { + + public static void main(String[] args){ + TestPointSprite app = new TestPointSprite(); + app.start(); + } + + @Override + public void simpleInitApp() { + final ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Point, 10000); + emit.setShape(new EmitterBoxShape(new Vector3f(-1.8f, -1.8f, -1.8f), + new Vector3f(1.8f, 1.8f, 1.8f))); + emit.setGravity(0, 0, 0); + emit.setLowLife(60); + emit.setHighLife(60); + emit.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 0, 0)); + emit.setImagesX(15); + emit.setStartSize(0.05f); + emit.setEndSize(0.05f); + emit.setStartColor(ColorRGBA.White); + emit.setEndColor(ColorRGBA.White); + emit.setSelectRandomImage(true); + emit.emitAllParticles(); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setBoolean("PointSprite", true); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); + emit.setMaterial(mat); + + rootNode.attachChild(emit); + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if ("setNum".equals(name) && isPressed) { + emit.setNumParticles(5000); + emit.emitAllParticles(); + } + } + }, "setNum"); + + inputManager.addMapping("setNum", new KeyTrigger(KeyInput.KEY_SPACE)); + + } + +} diff --git a/jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java b/jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java new file mode 100644 index 0000000000..1a50a02a6c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/TestSoftParticles.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.effect; + +import com.jme3.app.SimpleApplication; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh; +import com.jme3.effect.shapes.EmitterSphereShape; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.TranslucentBucketFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; + +/** + * + * @author Nehon + */ +public class TestSoftParticles extends SimpleApplication { + + private boolean softParticles = true; + private FilterPostProcessor fpp; + private Node particleNode; + + public static void main(String[] args) { + TestSoftParticles app = new TestSoftParticles(); + app.start(); + } + + @Override + public void simpleInitApp() { + + cam.setLocation(new Vector3f(-7.2221026f, 4.1183004f, 7.759811f)); + cam.setRotation(new Quaternion(0.06152846f, 0.91236454f, -0.1492115f, 0.37621948f)); + + flyCam.setMoveSpeed(10); + + + // -------- floor + Box b = new Box(10, 0.1f, 10); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Gray); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + geom.setMaterial(mat); + rootNode.attachChild(geom); + + Box b2 = new Box(1, 1, 1); + Geometry geom2 = new Geometry("Box", b2); + Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.setColor("Color", ColorRGBA.DarkGray); + geom2.setMaterial(mat2); + rootNode.attachChild(geom2); + geom2.setLocalScale(0.1f, 0.2f, 1); + + fpp = new FilterPostProcessor(assetManager); + TranslucentBucketFilter tbf = new TranslucentBucketFilter(true); + fpp.addFilter(tbf); + int samples = context.getSettings().getSamples(); + if (samples > 0) { + fpp.setNumSamples(samples); + } + viewPort.addProcessor(fpp); + + particleNode = new Node("particleNode"); + rootNode.attachChild(particleNode); + + createParticles(); + + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(isPressed && name.equals("toggle")){ + // tbf.setEnabled(!tbf.isEnabled()); + softParticles = !softParticles; + if(softParticles){ + viewPort.addProcessor(fpp); + }else{ + viewPort.removeProcessor(fpp); + } + } + } + }, "toggle"); + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + + // emit again + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(isPressed && name.equals("refire")) { + //fpp.removeFilter(tbf); // <-- add back in to fix + particleNode.detachAllChildren(); + createParticles(); + //fpp.addFilter(tbf); + } + } + }, "refire"); + inputManager.addMapping("refire", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + } + + private void createParticles() { + + Material material = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + material.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); + material.setFloat("Softness", 3f); // + + //Fire + ParticleEmitter fire = new ParticleEmitter("Fire", ParticleMesh.Type.Triangle, 30); + fire.setMaterial(material); + fire.setShape(new EmitterSphereShape(Vector3f.ZERO, 0.1f)); + fire.setImagesX(2); + fire.setImagesY(2); // 2x2 texture animation + fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f)); // red + fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow + fire.setStartSize(0.6f); + fire.setEndSize(0.01f); + fire.setGravity(0, -0.3f, 0); + fire.setLowLife(0.5f); + fire.setHighLife(3f); + fire.setLocalTranslation(0, 0.2f, 0); + + particleNode.attachChild(fire); + + + ParticleEmitter smoke = new ParticleEmitter("Smoke", ParticleMesh.Type.Triangle, 30); + smoke.setMaterial(material); + smoke.setShape(new EmitterSphereShape(Vector3f.ZERO, 5)); + smoke.setImagesX(1); + smoke.setImagesY(1); // 2x2 texture animation + smoke.setStartColor(new ColorRGBA(0.1f, 0.1f, 0.1f,1f)); // dark gray + smoke.setEndColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 0.3f)); // gray + smoke.setStartSize(3f); + smoke.setEndSize(5f); + smoke.setGravity(0, -0.001f, 0); + smoke.setLowLife(100f); + smoke.setHighLife(100f); + smoke.setLocalTranslation(0, 0.1f, 0); + smoke.emitAllParticles(); + + particleNode.attachChild(smoke); + } + + +} diff --git a/jme3-examples/src/main/java/jme3test/effect/package-info.java b/jme3-examples/src/main/java/jme3test/effect/package-info.java new file mode 100644 index 0000000000..09f2903c48 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for special effects, including particles + */ +package jme3test.effect; diff --git a/jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java b/jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java new file mode 100644 index 0000000000..42e291da25 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/export/TestAssetLinkNode.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.export; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.MaterialKey; +import com.jme3.asset.ModelKey; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.export.binary.BinaryImporter; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.AssetLinkNode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestAssetLinkNode extends SimpleApplication { + + private float angle; + private PointLight pl; + private Spatial lightMdl; + + public static void main(String[] args){ + TestAssetLinkNode app = new TestAssetLinkNode(); + app.start(); + } + + @Override + public void simpleInitApp() { + AssetLinkNode loaderNode=new AssetLinkNode(); + loaderNode.addLinkedChild(new ModelKey("Models/MonkeyHead/MonkeyHead.mesh.xml")); + //load/attach the children (happens automatically on load) +// loaderNode.attachLinkedChildren(assetManager); +// rootNode.attachChild(loaderNode); + + //save and load the loaderNode + try { + //export to byte array + ByteArrayOutputStream bout=new ByteArrayOutputStream(); + BinaryExporter.getInstance().save(loaderNode, bout); + //import from byte array, automatically loads the monkey head from file + ByteArrayInputStream bin=new ByteArrayInputStream(bout.toByteArray()); + BinaryImporter imp=BinaryImporter.getInstance(); + imp.setAssetManager(assetManager); + Node newLoaderNode=(Node)imp.load(bin); + //attach to rootNode + rootNode.attachChild(newLoaderNode); + } catch (IOException ex) { + Logger.getLogger(TestAssetLinkNode.class.getName()).log(Level.SEVERE, null, ex); + } + + + rootNode.attachChild(loaderNode); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadAsset(new MaterialKey("Common/Materials/RedColor.j3m"))); + rootNode.attachChild(lightMdl); + + // fluorescent main light + pl = new PointLight(); + pl.setColor(new ColorRGBA(0.88f, 0.92f, 0.95f, 1.0f)); + rootNode.addLight(pl); + + // sunset light + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal()); + dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f)); + rootNode.addLight(dl); + + // skylight + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal()); + dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f)); + rootNode.addLight(dl); + + // white ambient light + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal()); + dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); + rootNode.addLight(dl); + } + + @Override + public void simpleUpdate(float tpf){ + angle += tpf * 0.25f; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 6f, 3f, FastMath.sin(angle) * 6f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java b/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java new file mode 100644 index 0000000000..b94fa7a816 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/export/TestIssue2068.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 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. + */ +package jme3test.export; + +import com.jme3.app.SimpleApplication; +import com.jme3.export.JmeExporter; +import com.jme3.export.xml.XMLExporter; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Test case for JME issue: #2068 exporting a Map to XML results in a + * DOMException. + * + *

If the issue is unresolved, the application will exit prematurely with an + * uncaught exception. + * + *

If the issue is resolved, the application will complete normally. + * + * @author Stephen Gold sgold@sonic.net + */ +public class TestIssue2068 extends SimpleApplication { + // ************************************************************************* + // constants and loggers + + /** + * message logger for this class + */ + final public static Logger logger + = Logger.getLogger(TestIssue2068.class.getName()); + // ************************************************************************* + // new methods exposed + + /** + * Main entry point for the TestIssue2068 application. + * + * @param args array of command-line arguments (not null) + */ + public static void main(String[] args) { + TestIssue2068 app = new TestIssue2068(); + app.start(); + } + + /** + * Initialize the application. + */ + @Override + public void simpleInitApp() { + Map map = new HashMap<>(); + map.put("key", "value"); + rootNode.setUserData("map", map); + + String outputFilename = "TestIssue2068.xml"; + File xmlFile = new File(outputFilename); + JmeExporter exporter = XMLExporter.getInstance(); + try { + exporter.save(rootNode, xmlFile); + } catch (IOException exception) { + logger.log(Level.SEVERE, exception.getMessage(), exception); + } + stop(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java b/jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java new file mode 100644 index 0000000000..57dba2fb54 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.export; + +import com.jme3.anim.AnimComposer; +import com.jme3.app.SimpleApplication; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.export.binary.BinaryImporter; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; + +import java.io.*; + +public class TestOgreConvert extends SimpleApplication { + + public static void main(String[] args){ + TestOgreConvert app = new TestOgreConvert(); + app.start(); + } + + @Override + public void simpleInitApp() { + Spatial ogreModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White); + dl.setDirection(new Vector3f(0,-1,-1).normalizeLocal()); + rootNode.addLight(dl); + + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + BinaryExporter exp = new BinaryExporter(); + exp.save(ogreModel, baos); + + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + BinaryImporter imp = new BinaryImporter(); + imp.setAssetManager(assetManager); + Node ogreModelReloaded = (Node) imp.load(bais, null, null); + + AnimComposer composer = ogreModelReloaded.getControl(AnimComposer.class); + composer.setCurrentAction("Walk"); + + rootNode.attachChild(ogreModelReloaded); + } catch (IOException ex){ + ex.printStackTrace(); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/export/package-info.java b/jme3-examples/src/main/java/jme3test/export/package-info.java new file mode 100644 index 0000000000..a30a5e6ca0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/export/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for asset exporting + */ +package jme3test.export; diff --git a/jme3-examples/src/main/java/jme3test/games/CubeField.java b/jme3-examples/src/main/java/jme3test/games/CubeField.java new file mode 100644 index 0000000000..21d060ce0a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/games/CubeField.java @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.games; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingVolume; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Dome; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author Kyle "bonechilla" Williams + */ +public class CubeField extends SimpleApplication implements AnalogListener { + + public static void main(String[] args) { + CubeField app = new CubeField(); + app.start(); + } + + private BitmapFont defaultFont; + + private boolean START; + private int difficulty, Score, colorInt, lowCap; + private Node player; + private Geometry fcube; + private ArrayList cubeField; + private ArrayList obstacleColors; + private float speed, coreTime,coreTime2; + private float camAngle = 0; + private BitmapText fpsScoreText, pressStart; + + private boolean solidBox = true; + private Material playerMaterial; + private Material floorMaterial; + + final private float fpsRate = 1000f / 1f; + + /** + * Initializes game + */ + @Override + public void simpleInitApp() { + Logger.getLogger("com.jme3").setLevel(Level.WARNING); + + flyCam.setEnabled(false); + setDisplayStatView(false); + + Keys(); + + defaultFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + pressStart = new BitmapText(defaultFont); + fpsScoreText = new BitmapText(defaultFont); + + loadText(fpsScoreText, "Current Score: 0", defaultFont, 0, 2, 0); + loadText(pressStart, "PRESS ENTER", defaultFont, 0, 5, 0); + + player = createPlayer(); + rootNode.attachChild(player); + cubeField = new ArrayList(); + obstacleColors = new ArrayList(); + + gameReset(); + } + /** + * Used to reset cubeField + */ + private void gameReset(){ + Score = 0; + lowCap = 10; + colorInt = 0; + difficulty = 40; + + for (Geometry cube : cubeField){ + cube.removeFromParent(); + } + cubeField.clear(); + + if (fcube != null){ + fcube.removeFromParent(); + } + fcube = createFirstCube(); + + obstacleColors.clear(); + obstacleColors.add(ColorRGBA.Orange); + obstacleColors.add(ColorRGBA.Red); + obstacleColors.add(ColorRGBA.Yellow); + renderer.setBackgroundColor(ColorRGBA.White); + speed = lowCap / 400f; + coreTime = 20.0f; + coreTime2 = 10.0f; + player.setLocalTranslation(0,0,0); + } + + @Override + public void simpleUpdate(float tpf) { + camTakeOver(tpf); + if (START){ + gameLogic(tpf); + } + colorLogic(); + } + /** + * Forcefully takes over Camera adding functionality and placing it behind the character + * @param tpf Ticks Per Frame + */ + private void camTakeOver(float tpf) { + cam.setLocation(player.getLocalTranslation().add(-8, 2, 0)); + cam.lookAt(player.getLocalTranslation(), Vector3f.UNIT_Y); + + Quaternion rot = new Quaternion(); + rot.fromAngleNormalAxis(camAngle, Vector3f.UNIT_Z); + cam.setRotation(cam.getRotation().mult(rot)); + camAngle *= FastMath.pow(.99f, fpsRate * tpf); + } + + @Override + public void requestClose(boolean esc) { + if (!esc){ + System.out.println("The game was quit."); + }else{ + System.out.println("Player has Collided. Final Score is " + Score); + } + context.destroy(false); + } + /** + * Randomly Places a cube on the map between 30 and 90 paces away from player + */ + private void randomizeCube() { + Geometry cube = fcube.clone(); + int playerX = (int) player.getLocalTranslation().getX(); + int playerZ = (int) player.getLocalTranslation().getZ(); +// float x = FastMath.nextRandomInt(playerX + difficulty + 10, playerX + difficulty + 150); + float x = FastMath.nextRandomInt(playerX + difficulty + 30, playerX + difficulty + 90); + float z = FastMath.nextRandomInt(playerZ - difficulty - 50, playerZ + difficulty + 50); + cube.getLocalTranslation().set(x, 0, z); + +// playerX+difficulty+30,playerX+difficulty+90 + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + if (!solidBox){ + mat.getAdditionalRenderState().setWireframe(true); + } + mat.setColor("Color", obstacleColors.get(FastMath.nextRandomInt(0, obstacleColors.size() - 1))); + cube.setMaterial(mat); + + rootNode.attachChild(cube); + cubeField.add(cube); + } + + private Geometry createFirstCube() { + Vector3f loc = player.getLocalTranslation(); + loc.addLocal(4, 0, 0); + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + geom.setLocalTranslation(loc); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + geom.setMaterial(mat); + + return geom; + } + + private Node createPlayer() { + Dome b = new Dome(Vector3f.ZERO, 10, 100, 1); + Geometry playerMesh = new Geometry("Box", b); + + playerMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + playerMaterial.setColor("Color", ColorRGBA.Red); + playerMesh.setMaterial(playerMaterial); + playerMesh.setName("player"); + + Box floor = new Box(100, 0, 100); + + Geometry floorMesh = new Geometry("Box", floor); + + Vector3f translation = Vector3f.ZERO.add(playerMesh.getLocalTranslation().getX(), + playerMesh.getLocalTranslation().getY() - 1, 0); + + floorMesh.setLocalTranslation(translation); + + floorMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + floorMaterial.setColor("Color", ColorRGBA.LightGray); + floorMesh.setMaterial(floorMaterial); + floorMesh.setName("floor"); + + Node playerNode = new Node(); + playerNode.attachChild(playerMesh); + playerNode.attachChild(floorMesh); + + return playerNode; + } + + /** + * If Game is Lost display Score and Reset the Game + */ + private void gameLost(){ + START = false; + loadText(pressStart, "You lost! Press enter to try again.", defaultFont, 0, 5, 0); + gameReset(); + } + + /** + * Core Game Logic + */ + private void gameLogic(float tpf){ + //Subtract difficulty level in accordance to speed every 10 seconds + if(timer.getTimeInSeconds()>=coreTime2){ + coreTime2=timer.getTimeInSeconds()+10; + if(difficulty<=lowCap){ + difficulty=lowCap; + } + else if(difficulty>lowCap){ + difficulty-=5; + } + } + + if(speed<.1f){ + speed+=.000001f*tpf*fpsRate; + } + + player.move(speed * tpf * fpsRate, 0, 0); + if (cubeField.size() > difficulty){ + cubeField.remove(0); + }else if (cubeField.size() != difficulty){ + randomizeCube(); + } + + if (cubeField.isEmpty()){ + requestClose(false); + }else{ + for (int i = 0; i < cubeField.size(); i++){ + + //better way to check collision + Geometry playerModel = (Geometry) player.getChild(0); + Geometry cubeModel = cubeField.get(i); + + BoundingVolume pVol = playerModel.getWorldBound(); + BoundingVolume vVol = cubeModel.getWorldBound(); + + if (pVol.intersects(vVol)){ + gameLost(); + return; + } + //Remove cube if 10 world units behind player + if (cubeField.get(i).getLocalTranslation().getX() + 10 < player.getLocalTranslation().getX()){ + cubeField.get(i).removeFromParent(); + cubeField.remove(cubeField.get(i)); + } + + } + } + + Score += fpsRate * tpf; + fpsScoreText.setText("Current Score: "+Score); + } + /** + * Sets up the keyboard bindings + */ + private void Keys() { + inputManager.addMapping("START", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addListener(this, "START", "Left", "Right"); + } + + @Override + public void onAnalog(String binding, float value, float tpf) { + if (binding.equals("START") && !START){ + START = true; + guiNode.detachChild(pressStart); + System.out.println("START"); + }else if (START == true && binding.equals("Left")){ + player.move(0, 0, -(speed / 2f) * value * fpsRate); + camAngle -= value*tpf; + }else if (START == true && binding.equals("Right")){ + player.move(0, 0, (speed / 2f) * value * fpsRate); + camAngle += value*tpf; + } + } + + /** + * Determines the colors of the player, floor, obstacle and background + */ + private void colorLogic() { + if (timer.getTimeInSeconds() >= coreTime){ + + colorInt++; + coreTime = timer.getTimeInSeconds() + 20; + + + switch (colorInt){ + case 1: + obstacleColors.clear(); + solidBox = false; + obstacleColors.add(ColorRGBA.Green); + renderer.setBackgroundColor(ColorRGBA.Black); + playerMaterial.setColor("Color", ColorRGBA.White); + floorMaterial.setColor("Color", ColorRGBA.Black); + break; + case 2: + obstacleColors.set(0, ColorRGBA.Black); + solidBox = true; + renderer.setBackgroundColor(ColorRGBA.White); + playerMaterial.setColor("Color", ColorRGBA.Gray); + floorMaterial.setColor("Color", ColorRGBA.LightGray); + break; + case 3: + obstacleColors.set(0, ColorRGBA.Pink); + break; + case 4: + obstacleColors.set(0, ColorRGBA.Cyan); + obstacleColors.add(ColorRGBA.Magenta); + renderer.setBackgroundColor(ColorRGBA.Gray); + floorMaterial.setColor("Color", ColorRGBA.Gray); + playerMaterial.setColor("Color", ColorRGBA.White); + break; + case 5: + obstacleColors.remove(0); + renderer.setBackgroundColor(ColorRGBA.Pink); + solidBox = false; + playerMaterial.setColor("Color", ColorRGBA.White); + break; + case 6: + obstacleColors.set(0, ColorRGBA.White); + solidBox = true; + renderer.setBackgroundColor(ColorRGBA.Black); + playerMaterial.setColor("Color", ColorRGBA.Gray); + floorMaterial.setColor("Color", ColorRGBA.LightGray); + break; + case 7: + obstacleColors.set(0, ColorRGBA.Green); + renderer.setBackgroundColor(ColorRGBA.Gray); + playerMaterial.setColor("Color", ColorRGBA.Black); + floorMaterial.setColor("Color", ColorRGBA.Orange); + break; + case 8: + obstacleColors.set(0, ColorRGBA.Red); + floorMaterial.setColor("Color", ColorRGBA.Pink); + break; + case 9: + obstacleColors.set(0, ColorRGBA.Orange); + obstacleColors.add(ColorRGBA.Red); + obstacleColors.add(ColorRGBA.Yellow); + renderer.setBackgroundColor(ColorRGBA.White); + playerMaterial.setColor("Color", ColorRGBA.Red); + floorMaterial.setColor("Color", ColorRGBA.Gray); + colorInt=0; + break; + default: + break; + } + } + } + /** + * Sets up a BitmapText to be displayed + * @param txt the Bitmap Text + * @param text the + * @param font the font of the text + * @param x + * @param y + * @param z + */ + private void loadText(BitmapText txt, String text, BitmapFont font, float x, float y, float z) { + txt.setSize(font.getCharSet().getRenderedSize()); + txt.setLocalTranslation(txt.getLineWidth() * x, txt.getLineHeight() * y, z); + txt.setText(text); + guiNode.attachChild(txt); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java b/jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java new file mode 100644 index 0000000000..fe47ad43c0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/games/RollingTheMonkey.java @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.games; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.PhysicsCollisionEvent; +import com.jme3.bullet.collision.PhysicsCollisionListener; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; +import com.jme3.bullet.collision.shapes.CompoundCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.GhostControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.DirectionalLightShadowFilter; +import java.util.concurrent.Callable; + +/** + * Physics based marble game. + * + * @author SkidRunner (Mark E. Picknell) + */ +public class RollingTheMonkey extends SimpleApplication implements ActionListener, PhysicsCollisionListener { + + private static final String MESSAGE = "Thanks for Playing!"; + private static final String INFO_MESSAGE = "Collect all the spinning cubes!\nPress the 'R' key any time to reset!"; + + private static final float PLAYER_DENSITY = 1200; // OLK(Java LOL) = 1200, STEEL = 8000, RUBBER = 1000 + private static final float PLAYER_REST = 0.1f; // OLK = 0.1f, STEEL = 0.0f, RUBBER = 1.0f I made these up. + + private static final float PLAYER_RADIUS = 2.0f; + private static final float PLAYER_ACCEL = 1.0f; + + private static final float PICKUP_SIZE = 0.5f; + private static final float PICKUP_RADIUS = 15.0f; + private static final int PICKUP_COUNT = 16; + private static final float PICKUP_SPEED = 5.0f; + + private static final float PLAYER_VOLUME = (FastMath.pow(PLAYER_RADIUS, 3) * FastMath.PI) / 3; // V = 4/3 * PI * R pow 3 + private static final float PLAYER_MASS = PLAYER_DENSITY * PLAYER_VOLUME; + private static final float PLAYER_FORCE = 80000 * PLAYER_ACCEL; // F = M(4m diameter steel ball) * A + private static final Vector3f PLAYER_START = new Vector3f(0.0f, PLAYER_RADIUS * 2, 0.0f); + + private static final String INPUT_MAPPING_FORWARD = "INPUT_MAPPING_FORWARD"; + private static final String INPUT_MAPPING_BACKWARD = "INPUT_MAPPING_BACKWARD"; + private static final String INPUT_MAPPING_LEFT = "INPUT_MAPPING_LEFT"; + private static final String INPUT_MAPPING_RIGHT = "INPUT_MAPPING_RIGHT"; + private static final String INPUT_MAPPING_RESET = "INPUT_MAPPING_RESET"; + + public static void main(String[] args) { + RollingTheMonkey app = new RollingTheMonkey(); + app.start(); + } + + private boolean keyForward; + private boolean keyBackward; + private boolean keyLeft; + private boolean keyRight; + private RigidBodyControl player; + private int score; + + private Node pickUps; + private BitmapText scoreText; + private BitmapText messageText; + + @Override + public void simpleInitApp() { + flyCam.setEnabled(false); + cam.setLocation(new Vector3f(0.0f, 12.0f, 21.0f)); + viewPort.setBackgroundColor(new ColorRGBA(0.2118f, 0.0824f, 0.6549f, 1.0f)); + + // init physics + BulletAppState bulletState = new BulletAppState(); + stateManager.attach(bulletState); + PhysicsSpace space = bulletState.getPhysicsSpace(); + space.addCollisionListener(this); + + // create light + DirectionalLight sun = new DirectionalLight(); + sun.setDirection((new Vector3f(-0.7f, -0.3f, -0.5f)).normalizeLocal()); + System.out.println("Here We Go: " + sun.getDirection()); + sun.setColor(ColorRGBA.White); + rootNode.addLight(sun); + + // create materials + Material materialRed = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + materialRed.setBoolean("UseMaterialColors",true); + materialRed.setBoolean("HardwareShadows", true); + materialRed.setColor("Diffuse", new ColorRGBA(0.9451f, 0.0078f, 0.0314f, 1.0f)); + materialRed.setColor("Specular", ColorRGBA.White); + materialRed.setFloat("Shininess", 64.0f); + + Material materialGreen = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + materialGreen.setBoolean("UseMaterialColors",true); + materialGreen.setBoolean("HardwareShadows", true); + materialGreen.setColor("Diffuse", new ColorRGBA(0.0431f, 0.7725f, 0.0078f, 1.0f)); + materialGreen.setColor("Specular", ColorRGBA.White); + materialGreen.setFloat("Shininess", 64.0f); + + Material logoMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + logoMaterial.setBoolean("UseMaterialColors",true); + logoMaterial.setBoolean("HardwareShadows", true); + logoMaterial.setTexture("DiffuseMap", assetManager.loadTexture("com/jme3/app/Monkey.png")); + logoMaterial.setColor("Diffuse", ColorRGBA.White); + logoMaterial.setColor("Specular", ColorRGBA.White); + logoMaterial.setFloat("Shininess", 32.0f); + + Material materialYellow = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + materialYellow.setBoolean("UseMaterialColors",true); + materialYellow.setBoolean("HardwareShadows", true); + materialYellow.setColor("Diffuse", new ColorRGBA(0.9529f, 0.7843f, 0.0078f, 1.0f)); + materialYellow.setColor("Specular", ColorRGBA.White); + materialYellow.setFloat("Shininess", 64.0f); + + // create level spatial + // TODO: create your own level mesh + Node level = new Node("level"); + level.setShadowMode(ShadowMode.CastAndReceive); + + Geometry floor = new Geometry("floor", new Box(22.0f, 0.5f, 22.0f)); + floor.setShadowMode(ShadowMode.Receive); + floor.setLocalTranslation(0.0f, -0.5f, 0.0f); + floor.setMaterial(materialGreen); + + Geometry wallNorth = new Geometry("wallNorth", new Box(22.0f, 2.0f, 0.5f)); + wallNorth.setLocalTranslation(0.0f, 2.0f, 21.5f); + wallNorth.setMaterial(materialRed); + + Geometry wallSouth = new Geometry("wallSouth", new Box(22.0f, 2.0f, 0.5f)); + wallSouth.setLocalTranslation(0.0f, 2.0f, -21.5f); + wallSouth.setMaterial(materialRed); + + Geometry wallEast = new Geometry("wallEast", new Box(0.5f, 2.0f, 21.0f)); + wallEast.setLocalTranslation(-21.5f, 2.0f, 0.0f); + wallEast.setMaterial(materialRed); + + Geometry wallWest = new Geometry("wallWest", new Box(0.5f, 2.0f, 21.0f)); + wallWest.setLocalTranslation(21.5f, 2.0f, 0.0f); + wallWest.setMaterial(materialRed); + + level.attachChild(floor); + level.attachChild(wallNorth); + level.attachChild(wallSouth); + level.attachChild(wallEast); + level.attachChild(wallWest); + + // The easy way: level.addControl(new RigidBodyControl(0)); + + // create level Shape + CompoundCollisionShape levelShape = new CompoundCollisionShape(); + BoxCollisionShape floorShape = new BoxCollisionShape(new Vector3f(22.0f, 0.5f, 22.0f)); + BoxCollisionShape wallNorthShape = new BoxCollisionShape(new Vector3f(22.0f, 2.0f, 0.5f)); + BoxCollisionShape wallSouthShape = new BoxCollisionShape(new Vector3f(22.0f, 2.0f, 0.5f)); + BoxCollisionShape wallEastShape = new BoxCollisionShape(new Vector3f(0.5f, 2.0f, 21.0f)); + BoxCollisionShape wallWestShape = new BoxCollisionShape(new Vector3f(0.5f, 2.0f, 21.0f)); + + levelShape.addChildShape(floorShape, new Vector3f(0.0f, -0.5f, 0.0f)); + levelShape.addChildShape(wallNorthShape, new Vector3f(0.0f, 2.0f, -21.5f)); + levelShape.addChildShape(wallSouthShape, new Vector3f(0.0f, 2.0f, 21.5f)); + levelShape.addChildShape(wallEastShape, new Vector3f(-21.5f, 2.0f, 0.0f)); + levelShape.addChildShape(wallEastShape, new Vector3f(21.5f, 2.0f, 0.0f)); + + level.addControl(new RigidBodyControl(levelShape, 0)); + + rootNode.attachChild(level); + space.addAll(level); + + // create Pickups + // TODO: create your own pickUp mesh + // create single mesh for all pickups + // HINT: think particles. + pickUps = new Node("pickups"); + + Quaternion rotation = new Quaternion(); + Vector3f translation = new Vector3f(0.0f, PICKUP_SIZE * 1.5f, -PICKUP_RADIUS); + int index = 0; + float amount = FastMath.TWO_PI / PICKUP_COUNT; + for(float angle = 0; angle < FastMath.TWO_PI; angle += amount) { + Geometry pickUp = new Geometry("pickUp" + (index++), new Box(PICKUP_SIZE,PICKUP_SIZE, PICKUP_SIZE)); + pickUp.setShadowMode(ShadowMode.CastAndReceive); + pickUp.setMaterial(materialYellow); + pickUp.setLocalRotation(rotation.fromAngles( + FastMath.rand.nextFloat() * FastMath.TWO_PI, + FastMath.rand.nextFloat() * FastMath.TWO_PI, + FastMath.rand.nextFloat() * FastMath.TWO_PI)); + + rotation.fromAngles(0.0f, angle, 0.0f); + rotation.mult(translation, pickUp.getLocalTranslation()); + pickUps.attachChild(pickUp); + + pickUp.addControl(new GhostControl(new SphereCollisionShape(PICKUP_SIZE))); + + + space.addAll(pickUp); + //space.addCollisionListener(pickUpControl); + } + rootNode.attachChild(pickUps); + + // Create player + // TODO: create your own player mesh + Geometry playerGeometry = new Geometry("player", new Sphere(16, 32, PLAYER_RADIUS)); + playerGeometry.setShadowMode(ShadowMode.CastAndReceive); + playerGeometry.setLocalTranslation(PLAYER_START.clone()); + playerGeometry.setMaterial(logoMaterial); + + // Store control for applying forces + // TODO: create your own player control + player = new RigidBodyControl(new SphereCollisionShape(PLAYER_RADIUS), PLAYER_MASS); + player.setRestitution(PLAYER_REST); + + playerGeometry.addControl(player); + + rootNode.attachChild(playerGeometry); + space.addAll(playerGeometry); + + inputManager.addMapping(INPUT_MAPPING_FORWARD, new KeyTrigger(KeyInput.KEY_UP) + , new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping(INPUT_MAPPING_BACKWARD, new KeyTrigger(KeyInput.KEY_DOWN) + , new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping(INPUT_MAPPING_LEFT, new KeyTrigger(KeyInput.KEY_LEFT) + , new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping(INPUT_MAPPING_RIGHT, new KeyTrigger(KeyInput.KEY_RIGHT) + , new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping(INPUT_MAPPING_RESET, new KeyTrigger(KeyInput.KEY_R)); + inputManager.addListener(this, INPUT_MAPPING_FORWARD, INPUT_MAPPING_BACKWARD + , INPUT_MAPPING_LEFT, INPUT_MAPPING_RIGHT, INPUT_MAPPING_RESET); + + // init UI + BitmapText infoText = new BitmapText(guiFont); + infoText.setText(INFO_MESSAGE); + guiNode.attachChild(infoText); + + scoreText = new BitmapText(guiFont); + scoreText.setText("Score: 0"); + guiNode.attachChild(scoreText); + + messageText = new BitmapText(guiFont); + messageText.setText(MESSAGE); + messageText.setLocalScale(0.0f); + guiNode.attachChild(messageText); + + infoText.setLocalTranslation(0.0f, cam.getHeight(), 0.0f); + scoreText.setLocalTranslation((cam.getWidth() - scoreText.getLineWidth()) / 2.0f, + scoreText.getLineHeight(), 0.0f); + messageText.setLocalTranslation((cam.getWidth() - messageText.getLineWidth()) / 2.0f, + (cam.getHeight() - messageText.getLineHeight()) / 2, 0.0f); + + // init shadows + FilterPostProcessor processor = new FilterPostProcessor(assetManager); + DirectionalLightShadowFilter filter = new DirectionalLightShadowFilter(assetManager, 2048, 1); + filter.setLight(sun); + processor.addFilter(filter); + viewPort.addProcessor(processor); + + } + + @Override + public void simpleUpdate(float tpf) { + // Update and position the score + scoreText.setText("Score: " + score); + scoreText.setLocalTranslation((cam.getWidth() - scoreText.getLineWidth()) / 2.0f, + scoreText.getLineHeight(), 0.0f); + + // Rotate all the pickups + float pickUpSpeed = PICKUP_SPEED * tpf; + for(Spatial pickUp : pickUps.getChildren()) { + pickUp.rotate(pickUpSpeed, pickUpSpeed, pickUpSpeed); + } + + Vector3f centralForce = new Vector3f(); + + if(keyForward) centralForce.addLocal(cam.getDirection()); + if(keyBackward) centralForce.addLocal(cam.getDirection().negate()); + if(keyLeft) centralForce.addLocal(cam.getLeft()); + if(keyRight) centralForce.addLocal(cam.getLeft().negate()); + + if(!Vector3f.ZERO.equals(centralForce)) { + centralForce.setY(0); // stop ball from pushing down or flying up + centralForce.normalizeLocal(); // normalize force + centralForce.multLocal(PLAYER_FORCE); // scale vector to force + + player.applyCentralForce(centralForce); // apply force to player + } + + cam.lookAt(player.getPhysicsLocation(), Vector3f.UNIT_Y); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + switch(name) { + case INPUT_MAPPING_FORWARD: + keyForward = isPressed; + break; + case INPUT_MAPPING_BACKWARD: + keyBackward = isPressed; + break; + case INPUT_MAPPING_LEFT: + keyLeft = isPressed; + break; + case INPUT_MAPPING_RIGHT: + keyRight = isPressed; + break; + case INPUT_MAPPING_RESET: + enqueue(new Callable() { + @Override + public Void call() { + reset(); + return null; + } + }); + break; + } + } + @Override + public void collision(PhysicsCollisionEvent event) { + Spatial nodeA = event.getNodeA(); + Spatial nodeB = event.getNodeB(); + + String nameA = nodeA == null ? "" : nodeA.getName(); + String nameB = nodeB == null ? "" : nodeB.getName(); + + if(nameA.equals("player") && nameB.startsWith("pickUp")) { + GhostControl pickUpControl = nodeB.getControl(GhostControl.class); + if(pickUpControl != null && pickUpControl.isEnabled()) { + pickUpControl.setEnabled(false); + nodeB.removeFromParent(); + nodeB.setLocalScale(0.0f); + score += 1; + if(score >= PICKUP_COUNT) { + messageText.setLocalScale(1.0f); + } + } + } else if(nameA.startsWith("pickUp") && nameB.equals("player")) { + GhostControl pickUpControl = nodeA.getControl(GhostControl.class); + if(pickUpControl != null && pickUpControl.isEnabled()) { + pickUpControl.setEnabled(false); + nodeA.setLocalScale(0.0f); + score += 1; + if(score >= PICKUP_COUNT) { + messageText.setLocalScale(1.0f); + } + } + } + } + + private void reset() { + // Reset the pickups + for(Spatial pickUp : pickUps.getChildren()) { + GhostControl pickUpControl = pickUp.getControl(GhostControl.class); + if(pickUpControl != null) { + pickUpControl.setEnabled(true); + } + pickUp.setLocalScale(1.0f); + } + // Reset the player + player.setPhysicsLocation(PLAYER_START.clone()); + player.setAngularVelocity(Vector3f.ZERO.clone()); + player.setLinearVelocity(Vector3f.ZERO.clone()); + // Reset the score + score = 0; + // Reset the message + messageText.setLocalScale(0.0f); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/games/WorldOfInception.java b/jme3-examples/src/main/java/jme3test/games/WorldOfInception.java new file mode 100644 index 0000000000..04aca57e8f --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/games/WorldOfInception.java @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.games; + +import com.jme3.app.Application; +import com.jme3.app.SimpleApplication; +import com.jme3.app.state.AbstractAppState; +import com.jme3.app.state.AppStateManager; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.debug.DebugTools; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Ray; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.FogFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * WorldOfInception - Find the galaxy center ;) + * + * @author normenhansen + */ +public class WorldOfInception extends SimpleApplication implements AnalogListener { + + //Assumptions: POI radius in world == 1, only one player, vector3f hash describes enough worlds + private static final Logger logger = Logger.getLogger(WorldOfInception.class.getName()); + private static final Random random = new Random(System.currentTimeMillis()); + private static final float scaleDist = 10; + private static final float poiRadius = 100; + private static final int poiCount = 30; + private static Material poiMaterial; + private static Mesh poiMesh; + private static Material ballMaterial; + private static Mesh ballMesh; + private static CollisionShape poiHorizonCollisionShape; + private static CollisionShape poiCollisionShape; + private static CollisionShape ballCollisionShape; + private InceptionLevel currentLevel; + private final Vector3f walkDirection = new Vector3f(); + private static DebugTools debugTools; + + public WorldOfInception() { + //base level vector position hash == seed + super(new InceptionLevel(null, Vector3f.ZERO)); + currentLevel = super.getStateManager().getState(InceptionLevel.class); + currentLevel.takeOverParent(); + currentLevel.getRootNode().setLocalScale(Vector3f.UNIT_XYZ); + currentLevel.getRootNode().setLocalTranslation(Vector3f.ZERO); + } + + public static void main(String[] args) { + WorldOfInception app = new WorldOfInception(); + app.start(); + } + + @Override + public void simpleInitApp() { + //set far frustum only so we see the outer world longer + cam.setFrustumFar(10000); + cam.setLocation(Vector3f.ZERO); + debugTools = new DebugTools(assetManager); + rootNode.attachChild(debugTools.debugNode); + poiMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + poiMaterial.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + poiMesh = new Sphere(16, 16, 1f); + + ballMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + ballMaterial.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + ballMaterial.setColor("Color", ColorRGBA.Red); + ballMesh = new Sphere(16, 16, 1.0f); + + poiHorizonCollisionShape = new MeshCollisionShape(new Sphere(128, 128, poiRadius)); + poiCollisionShape = new SphereCollisionShape(1f); + ballCollisionShape = new SphereCollisionShape(1f); + setupKeys(); + setupDisplay(); + setupFog(); + } + + private void setupKeys() { + inputManager.addMapping("StrafeLeft", new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("StrafeRight", new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("Forward", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Back", new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("StrafeUp", new KeyTrigger(KeyInput.KEY_Q)); + inputManager.addMapping("StrafeDown", new KeyTrigger(KeyInput.KEY_Z), new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("Return", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addMapping("Esc", new KeyTrigger(KeyInput.KEY_ESCAPE)); + inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addListener(this, "StrafeLeft", "StrafeRight", "Forward", "Back", "StrafeUp", "StrafeDown", "Space", "Reset", "Esc", "Up", "Down", "Left", "Right"); + } + + private void setupDisplay() { + if (fpsText == null) { + fpsText = new BitmapText(guiFont); + } + fpsText.setLocalScale(0.7f, 0.7f, 0.7f); + fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0); + fpsText.setText(""); + fpsText.setCullHint(Spatial.CullHint.Never); + guiNode.attachChild(fpsText); + } + + private void setupFog() { + // use fog to give more sense of depth + FilterPostProcessor fpp; + FogFilter fog; + fpp=new FilterPostProcessor(assetManager); + fog=new FogFilter(); + fog.setFogColor(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)); + fog.setFogDistance(poiRadius); + fog.setFogDensity(2.0f); + fpp.addFilter(fog); + viewPort.addProcessor(fpp); + } + + @Override + public void onAnalog(String name, float value, float tpf) { + Vector3f left = rootNode.getLocalRotation().mult(Vector3f.UNIT_X.negate()); + Vector3f forward = rootNode.getLocalRotation().mult(Vector3f.UNIT_Z.negate()); + Vector3f up = rootNode.getLocalRotation().mult(Vector3f.UNIT_Y); + //TODO: properly scale input based on current scaling level + tpf = tpf * (10 - (9.0f * currentLevel.getCurrentScaleAmount())); + if (name.equals("StrafeLeft") && value > 0) { + walkDirection.addLocal(left.mult(tpf)); + } else if (name.equals("StrafeRight") && value > 0) { + walkDirection.addLocal(left.negate().multLocal(tpf)); + } else if (name.equals("Forward") && value > 0) { + walkDirection.addLocal(forward.mult(tpf)); + } else if (name.equals("Back") && value > 0) { + walkDirection.addLocal(forward.negate().multLocal(tpf)); + } else if (name.equals("StrafeUp") && value > 0) { + walkDirection.addLocal(up.mult(tpf)); + } else if (name.equals("StrafeDown") && value > 0) { + walkDirection.addLocal(up.negate().multLocal(tpf)); + } else if (name.equals("Up") && value > 0) { + //TODO: rotate rootNode, needs to be global + } else if (name.equals("Down") && value > 0) { + } else if (name.equals("Left") && value > 0) { + } else if (name.equals("Right") && value > 0) { + } else if (name.equals("Esc")) { + stop(); + } + } + + @Override + public void simpleUpdate(float tpf) { + currentLevel = currentLevel.getCurrentLevel(); + currentLevel.move(walkDirection); + fpsText.setText("Location: " + currentLevel.getCoordinates()); + walkDirection.set(Vector3f.ZERO); + } + + public static class InceptionLevel extends AbstractAppState { + + private final InceptionLevel parent; + private final Vector3f inParentPosition; + private SimpleApplication application; + private BulletAppState physicsState; + private Node rootNode; + private Vector3f playerPos; + private InceptionLevel currentActiveChild; + private InceptionLevel currentReturnLevel; + private float curScaleAmount = 0; + + public InceptionLevel(InceptionLevel parent, Vector3f inParentPosition) { + this.parent = parent; + this.inParentPosition = inParentPosition; + } + + @Override + public void update(float tpf) { + super.update(tpf); + if (currentReturnLevel != this) { + return; + } + debugTools.setYellowArrow(new Vector3f(0, 0, -2), playerPos.divide(poiRadius)); + float curLocalDist = getPlayerPosition().length(); + // If we are outside the range of one point of interest, move out to + // the next upper level + if (curLocalDist > poiRadius + FastMath.ZERO_TOLERANCE) { //DAFUQ normalize? + if (parent == null) { + //TODO: could add new nodes coming in instead for literally endless space + logger.log(Level.INFO, "Hit event horizon"); + currentReturnLevel = this; + return; + } + //give to parent + logger.log(Level.INFO, "give to parent"); + parent.takeOverChild(inParentPosition.add(playerPos.normalize())); + application.getStateManager().attach(parent); + currentReturnLevel = parent; + return; + } + + AppStateManager stateManager = application.getStateManager(); + // We create child positions based on the parent position hash, so we + // should in practice get the same galaxy w/o too many doubles + // with each run with the same root vector. + Vector3f[] vectors = getPositions(poiCount, inParentPosition.hashCode()); + for (int i = 0; i < vectors.length; i++) { + Vector3f vector3f = vectors[i]; + //negative rootNode location is our actual player position + Vector3f distVect = vector3f.subtract(playerPos); + float distance = distVect.length(); + if (distance <= 1) { + checkActiveChild(vector3f); + float percent = 0; + curScaleAmount = 0; + this.scaleAsParent(percent, playerPos, distVect); + currentActiveChild.scaleAsChild(percent, distVect); + logger.log(Level.INFO, "Give over to child {0}", currentActiveChild); + currentActiveChild.takeOverParent(); + stateManager.detach(this); + currentReturnLevel = currentActiveChild; + return; + } else if (distance <= 1 + scaleDist) { + debugTools.setRedArrow(Vector3f.ZERO, distVect); + checkActiveChild(vector3f); + //TODO: scale percent nicer for less of an "explosion" effect + float percent = 1 - mapValue(distance - 1, 0, scaleDist, 0, 1); + curScaleAmount = percent; + rootNode.getChild(i).setCullHint(Spatial.CullHint.Always); + this.scaleAsParent(percent, playerPos, distVect); + currentActiveChild.scaleAsChild(percent, distVect); + currentReturnLevel = this; + return; + } else if (currentActiveChild != null && currentActiveChild.getPositionInParent().equals(vector3f)) { + //TODO: doing this here causes problems when close to multiple POIs + rootNode.getChild(i).setCullHint(Spatial.CullHint.Inherit); + } + } + checkActiveChild(null); + curScaleAmount = 0; + rootNode.setLocalScale(1); + rootNode.setLocalTranslation(playerPos.negate()); + debugTools.setRedArrow(Vector3f.ZERO, Vector3f.ZERO); + debugTools.setBlueArrow(Vector3f.ZERO, Vector3f.ZERO); + debugTools.setGreenArrow(Vector3f.ZERO, Vector3f.ZERO); + } + + private void checkActiveChild(Vector3f vector3f) { + AppStateManager stateManager = application.getStateManager(); + if(vector3f == null){ + if(currentActiveChild != null){ + logger.log(Level.INFO, "Detach child {0}", currentActiveChild); + stateManager.detach(currentActiveChild); + currentActiveChild = null; + } + return; + } + if (currentActiveChild == null) { + currentActiveChild = new InceptionLevel(this, vector3f); + stateManager.attach(currentActiveChild); + logger.log(Level.INFO, "Attach child {0}", currentActiveChild); + } else if (!currentActiveChild.getPositionInParent().equals(vector3f)) { + logger.log(Level.INFO, "Switching from child {0}", currentActiveChild); + stateManager.detach(currentActiveChild); + currentActiveChild = new InceptionLevel(this, vector3f); + stateManager.attach(currentActiveChild); + logger.log(Level.INFO, "Attach child {0}", currentActiveChild); + } + } + + private void scaleAsChild(float percent, Vector3f dist) { + float childScale = mapValue(percent, 1.0f / poiRadius, 1); + Vector3f distToHorizon = dist.normalize(); + Vector3f scaledDistToHorizon = distToHorizon.mult(childScale * poiRadius); + Vector3f rootOff = dist.add(scaledDistToHorizon); + debugTools.setBlueArrow(Vector3f.ZERO, rootOff); + getRootNode().setLocalScale(childScale); + getRootNode().setLocalTranslation(rootOff); + //prepare player position already + Vector3f playerPosition = dist.normalize().mult(-poiRadius); + setPlayerPosition(playerPosition); + } + + private void scaleAsParent(float percent, Vector3f playerPos, Vector3f dist) { + float scale = mapValue(percent, 1.0f, poiRadius); + Vector3f distToHorizon = dist.subtract(dist.normalize()); + Vector3f offLocation = playerPos.add(distToHorizon); + Vector3f rootOff = offLocation.mult(scale).negate(); + rootOff.addLocal(dist); + debugTools.setGreenArrow(Vector3f.ZERO, offLocation); + getRootNode().setLocalScale(scale); + getRootNode().setLocalTranslation(rootOff); + } + + public void takeOverParent() { + //got playerPos from scaleAsChild before + getPlayerPosition().normalizeLocal().multLocal(poiRadius); + currentReturnLevel = this; + } + + public void takeOverChild(Vector3f playerPos) { + this.playerPos.set(playerPos); + currentReturnLevel = this; + } + + public InceptionLevel getLastLevel(Ray pickRay) { + // TODO: get a level based on positions getting ever more accurate, + // from any given position + return null; + } + + public InceptionLevel getLevel(Vector3f... location) { + // TODO: get a level based on positions getting ever more accurate, + // from any given position + return null; + } + + private void initData() { + getRootNode(); + physicsState = new BulletAppState(); + physicsState.startPhysics(); + physicsState.getPhysicsSpace().setGravity(Vector3f.ZERO); + //horizon + physicsState.getPhysicsSpace().add(new RigidBodyControl(poiHorizonCollisionShape, 0)); + int hashCode = inParentPosition.hashCode(); + Vector3f[] positions = getPositions(poiCount, hashCode); + for (int i = 0; i < positions.length; i++) { + Vector3f vector3f = positions[i]; + Geometry poiGeom = new Geometry("poi", poiMesh); + poiGeom.setLocalTranslation(vector3f); + poiGeom.setMaterial(poiMaterial); + RigidBodyControl control = new RigidBodyControl(poiCollisionShape, 0); + //!!! Important + control.setApplyPhysicsLocal(true); + poiGeom.addControl(control); + physicsState.getPhysicsSpace().add(poiGeom); + rootNode.attachChild(poiGeom); + + } + //add balls after so first 10 geoms == locations + for (int i = 0; i < positions.length; i++) { + Vector3f vector3f = positions[i]; + Geometry ball = getRandomBall(vector3f); + physicsState.getPhysicsSpace().add(ball); + rootNode.attachChild(ball); + } + + } + + private Geometry getRandomBall(Vector3f location) { + Vector3f localLocation = new Vector3f(); + localLocation.set(location); + localLocation.addLocal(new Vector3f(random.nextFloat() - 0.5f, random.nextFloat() - 0.5f, random.nextFloat() - 0.5f).normalize().mult(3)); + Geometry poiGeom = new Geometry("ball", ballMesh); + poiGeom.setLocalTranslation(localLocation); + poiGeom.setMaterial(ballMaterial); + RigidBodyControl control = new RigidBodyControl(ballCollisionShape, 1); + //!!! Important + control.setApplyPhysicsLocal(true); + poiGeom.addControl(control); + float x = (random.nextFloat() - 0.5f) * 100; + float y = (random.nextFloat() - 0.5f) * 100; + float z = (random.nextFloat() - 0.5f) * 100; + control.setLinearVelocity(new Vector3f(x, y, z)); + return poiGeom; + } + + private void cleanupData() { + physicsState.stopPhysics(); + //TODO: remove all objects? + physicsState = null; + rootNode = null; + } + + @Override + public void initialize(AppStateManager stateManager, Application app) { + super.initialize(stateManager, app); + //only generate data and attach node when we are actually attached (or picking) + initData(); + application = (SimpleApplication) app; + application.getRootNode().attachChild(getRootNode()); + application.getStateManager().attach(physicsState); + } + + @Override + public void cleanup() { + super.cleanup(); + //detach everything when we are detached + application.getRootNode().detachChild(rootNode); + application.getStateManager().detach(physicsState); + cleanupData(); + } + + public Node getRootNode() { + if (rootNode == null) { + rootNode = new Node("ZoomLevel"); + if (parent != null) { + rootNode.setLocalScale(1.0f / poiRadius); + } + } + return rootNode; + } + + public Vector3f getPositionInParent() { + return inParentPosition; + } + + public Vector3f getPlayerPosition() { + if (playerPos == null) { + playerPos = new Vector3f(); + } + return playerPos; + } + + public void setPlayerPosition(Vector3f vec) { + if (playerPos == null) { + playerPos = new Vector3f(); + } + playerPos.set(vec); + } + + public void move(Vector3f dir) { + if (playerPos == null) { + playerPos = new Vector3f(); + } + playerPos.addLocal(dir); + } + + public float getCurrentScaleAmount() { + return curScaleAmount; + } + + public InceptionLevel getParent() { + return parent; + } + + public InceptionLevel getCurrentLevel() { + return currentReturnLevel; + } + + public String getCoordinates() { + InceptionLevel cur = this; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.insert(0, this.getPlayerPosition()); + stringBuilder.insert(0, this.getPositionInParent() + " / "); + cur = cur.getParent(); + while (cur != null) { + stringBuilder.insert(0, cur.getPositionInParent() + " / "); + cur = cur.getParent(); + } + return stringBuilder.toString(); + } + } + + public static Vector3f[] getPositions(int count, long seed) { + Random rnd = new Random(seed); + Vector3f[] vectors = new Vector3f[count]; + for (int i = 0; i < count; i++) { + vectors[i] = new Vector3f((rnd.nextFloat() - 0.5f) * poiRadius, + (rnd.nextFloat() - 0.5f) * poiRadius, + (rnd.nextFloat() - 0.5f) * poiRadius); + } + return vectors; + } + + /** + * Maps a value from 0-1 to a range from min to max. + * + * @param x + * @param min + * @param max + * @return the mapped value + */ + private static float mapValue(float x, float min, float max) { + return mapValue(x, 0, 1, min, max); + } + + /** + * Maps a value from inputMin to inputMax to a range from min to max. + * + * @param x + * @param inputMin + * @param inputMax + * @param min + * @param max + * @return the mapped value + */ + private static float mapValue(float x, float inputMin, float inputMax, float min, float max) { + return (x - inputMin) * (max - min) / (inputMax - inputMin) + min; + } +} diff --git a/jme3-examples/src/main/java/jme3test/games/package-info.java b/jme3-examples/src/main/java/jme3test/games/package-info.java new file mode 100644 index 0000000000..37b6b362a4 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/games/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * simple example games + */ +package jme3test.games; diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java new file mode 100644 index 0000000000..96bc5db0b6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFont.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.font.LineWrapMode; +import com.jme3.font.Rectangle; +import com.jme3.input.KeyInput; +import com.jme3.input.RawInputListener; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.event.*; + +public class TestBitmapFont extends SimpleApplication { + + private String txtB = + "ABCDEFGHIKLMNOPQRSTUVWXYZ1234567 890`~!@#$%^&*()-=_+[]\\;',./{}|:<>?"; + + private BitmapText txt; + private BitmapText txt3; + + public static void main(String[] args){ + TestBitmapFont app = new TestBitmapFont(); + app.start(); + } + + @Override + public void simpleInitApp() { + inputManager.addMapping("WordWrap", new KeyTrigger(KeyInput.KEY_TAB)); + inputManager.addListener(keyListener, "WordWrap"); + inputManager.addRawInputListener(textListener); + + BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); + txt = new BitmapText(fnt); + txt.setBox(new Rectangle(0, 0, settings.getWidth(), settings.getHeight())); + txt.setSize(fnt.getPreferredSize() * 2f); + txt.setText(txtB); + txt.setLocalTranslation(0, txt.getHeight(), 0); + guiNode.attachChild(txt); + + BitmapText txt2 = new BitmapText(fnt); + txt2.setSize(fnt.getPreferredSize() * 1.2f); + txt2.setText("Text without restriction. \nText without restriction. Text without restriction. Text without restriction"); + txt2.setLocalTranslation(0, txt2.getHeight(), 0); + guiNode.attachChild(txt2); + + txt3 = new BitmapText(fnt); + txt3.setBox(new Rectangle(0, 0, settings.getWidth(), 0)); + txt3.setText("Press Tab to toggle word-wrap. type text and enter to input text"); + txt3.setLocalTranslation(0, settings.getHeight()/2, 0); + guiNode.attachChild(txt3); + } + + private ActionListener keyListener = new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("WordWrap") && !isPressed) { + txt.setLineWrapMode( txt.getLineWrapMode() == LineWrapMode.Word ? + LineWrapMode.NoWrap : LineWrapMode.Word ); + } + } + }; + + final private RawInputListener textListener = new RawInputListener() { + final private StringBuilder str = new StringBuilder(); + + @Override + public void onMouseMotionEvent(MouseMotionEvent evt) { } + + @Override + public void onMouseButtonEvent(MouseButtonEvent evt) { } + + @Override + public void onKeyEvent(KeyInputEvent evt) { + if (evt.isReleased()) + return; + if (evt.getKeyChar() == '\n' || evt.getKeyChar() == '\r') { + txt3.setText(str.toString()); + str.setLength(0); + } else { + str.append(evt.getKeyChar()); + } + } + + @Override + public void onJoyButtonEvent(JoyButtonEvent evt) { } + + @Override + public void onJoyAxisEvent(JoyAxisEvent evt) { } + + @Override + public void endInput() { } + + @Override + public void beginInput() { } + + @Override + public void onTouchEvent(TouchEvent evt) { } + + }; + +} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java new file mode 100644 index 0000000000..d6bc143d62 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontAlignment.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2009-2019 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. + */ + +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.font.Rectangle; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; + +public class TestBitmapFontAlignment extends SimpleApplication { + + public static void main(String[] args) { + TestBitmapFontAlignment test = new TestBitmapFontAlignment(); + test.start(); + } + + @Override + public void simpleInitApp() { + int width = getCamera().getWidth(); + int height = getCamera().getHeight(); + + // VAlign.Top + BitmapText labelAlignTop = guiFont.createLabel("This text has VAlign.Top."); + Rectangle textboxAlignTop = new Rectangle(width * 0.2f, height * 0.7f, 120, 120); + labelAlignTop.setBox(textboxAlignTop); + labelAlignTop.setVerticalAlignment(BitmapFont.VAlign.Top); + getGuiNode().attachChild(labelAlignTop); + + Geometry backgroundBoxAlignTop = new Geometry("", new Quad(textboxAlignTop.width, -textboxAlignTop.height)); + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setColor("Color", ColorRGBA.Blue); + backgroundBoxAlignTop.setMaterial(material); + backgroundBoxAlignTop.setLocalTranslation(textboxAlignTop.x, textboxAlignTop.y, -1); + getGuiNode().attachChild(backgroundBoxAlignTop); + + // VAlign.Center + BitmapText labelAlignCenter = guiFont.createLabel("This text has VAlign.Center"); + Rectangle textboxAlignCenter = new Rectangle(width * 0.4f, height * 0.7f, 120, 120); + labelAlignCenter.setBox(textboxAlignCenter); + labelAlignCenter.setVerticalAlignment(BitmapFont.VAlign.Center); + getGuiNode().attachChild(labelAlignCenter); + + Geometry backgroundBoxAlignCenter = backgroundBoxAlignTop.clone(false); + backgroundBoxAlignCenter.setLocalTranslation(textboxAlignCenter.x, textboxAlignCenter.y, -1); + getGuiNode().attachChild(backgroundBoxAlignCenter); + + // VAlign.Bottom + BitmapText labelAlignBottom = guiFont.createLabel("This text has VAlign.Bottom"); + Rectangle textboxAlignBottom = new Rectangle(width * 0.6f, height * 0.7f, 120, 120); + labelAlignBottom.setBox(textboxAlignBottom); + labelAlignBottom.setVerticalAlignment(BitmapFont.VAlign.Bottom); + getGuiNode().attachChild(labelAlignBottom); + + Geometry backgroundBoxAlignBottom = backgroundBoxAlignTop.clone(false); + backgroundBoxAlignBottom.setLocalTranslation(textboxAlignBottom.x, textboxAlignBottom.y, -1); + getGuiNode().attachChild(backgroundBoxAlignBottom); + + // VAlign.Top + Align.Right + BitmapText labelAlignTopRight = guiFont.createLabel("This text has VAlign.Top and Align.Right"); + Rectangle textboxAlignTopRight = new Rectangle(width * 0.2f, height * 0.3f, 120, 120); + labelAlignTopRight.setBox(textboxAlignTopRight); + labelAlignTopRight.setVerticalAlignment(BitmapFont.VAlign.Top); + labelAlignTopRight.setAlignment(BitmapFont.Align.Right); + getGuiNode().attachChild(labelAlignTopRight); + + Geometry backgroundBoxAlignTopRight = backgroundBoxAlignTop.clone(false); + backgroundBoxAlignTopRight.setLocalTranslation(textboxAlignTopRight.x, textboxAlignTopRight.y, -1); + getGuiNode().attachChild(backgroundBoxAlignTopRight); + + // VAlign.Center + Align.Center + BitmapText labelAlignCenterCenter = guiFont.createLabel("This text has VAlign.Center and Align.Center"); + Rectangle textboxAlignCenterCenter = new Rectangle(width * 0.4f, height * 0.3f, 120, 120); + labelAlignCenterCenter.setBox(textboxAlignCenterCenter); + labelAlignCenterCenter.setVerticalAlignment(BitmapFont.VAlign.Center); + labelAlignCenterCenter.setAlignment(BitmapFont.Align.Center); + getGuiNode().attachChild(labelAlignCenterCenter); + + Geometry backgroundBoxAlignCenterCenter = backgroundBoxAlignCenter.clone(false); + backgroundBoxAlignCenterCenter.setLocalTranslation(textboxAlignCenterCenter.x, textboxAlignCenterCenter.y, -1); + getGuiNode().attachChild(backgroundBoxAlignCenterCenter); + + // VAlign.Bottom + Align.Left + BitmapText labelAlignBottomLeft = guiFont.createLabel("This text has VAlign.Bottom and Align.Left"); + Rectangle textboxAlignBottomLeft = new Rectangle(width * 0.6f, height * 0.3f, 120, 120); + labelAlignBottomLeft.setBox(textboxAlignBottomLeft); + labelAlignBottomLeft.setVerticalAlignment(BitmapFont.VAlign.Bottom); + labelAlignBottomLeft.setAlignment(BitmapFont.Align.Left); + getGuiNode().attachChild(labelAlignBottomLeft); + + Geometry backgroundBoxAlignBottomLeft = backgroundBoxAlignBottom.clone(false); + backgroundBoxAlignBottomLeft.setLocalTranslation(textboxAlignBottomLeft.x, textboxAlignBottomLeft.y, -1); + getGuiNode().attachChild(backgroundBoxAlignBottomLeft); + + // Large quad with VAlign.Center and Align.Center + BitmapText label = guiFont.createLabel("This text is centered, both horizontally and vertically."); + Rectangle box = new Rectangle(width * 0.05f, height * 0.95f, width * 0.9f, height * 0.1f); + label.setBox(box); + label.setAlignment(BitmapFont.Align.Center); + label.setVerticalAlignment(BitmapFont.VAlign.Center); + getGuiNode().attachChild(label); + + Geometry background = new Geometry("background", new Quad(box.width, -box.height)); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Green); + background.setMaterial(mat); + background.setLocalTranslation(box.x, box.y, -1); + getGuiNode().attachChild(background); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java new file mode 100644 index 0000000000..6d2ad6f37b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestBitmapFontLayout.java @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2018-2021 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +package jme3test.gui; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontFormatException; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.*; + +import com.jme3.app.DebugKeysAppState; +import com.jme3.app.StatsAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.app.state.ScreenshotAppState; +import com.jme3.bounding.BoundingBox; +import com.jme3.font.BitmapCharacterSet; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.*; +import com.jme3.scene.debug.WireBox; +import com.jme3.scene.shape.*; +import com.jme3.texture.Image; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import com.jme3.texture.plugins.AWTLoader; + +/** + * + * @author pspeed42 + */ +public class TestBitmapFontLayout extends SimpleApplication { + + public static final String SCROLL_UP = "scroll up"; + public static final String SCROLL_DOWN = "scroll down"; + public static final String SCROLL_LEFT = "scroll left"; + public static final String SCROLL_RIGHT = "scroll right"; + public static final String ZOOM_IN = "zoom in"; + public static final String ZOOM_OUT = "zoom out"; + public static final String RESET_ZOOM = "reset zoom"; + public static final String RESET_VIEW = "reset view"; + + public static final float ZOOM_SPEED = 0.1f; + public static final float SCROLL_SPEED = 50; + + final private Node testRoot = new Node("test root"); + final private Node scrollRoot = new Node("scroll root"); + final private Vector3f scroll = new Vector3f(0, 0, 0); + final private Vector3f zoom = new Vector3f(0, 0, 0); + + public static void main(String[] args){ + TestBitmapFontLayout app = new TestBitmapFontLayout(); + app.start(); + } + + public TestBitmapFontLayout() { + super(new StatsAppState(), + new DebugKeysAppState(), + new ScreenshotAppState("", System.currentTimeMillis())); + } + + public static Font loadTtf( String resource ) { + try { + return Font.createFont(Font.TRUETYPE_FONT, + TestBitmapFontLayout.class.getResourceAsStream(resource)); + } catch( FontFormatException | IOException e ) { + throw new RuntimeException("Error loading resource:" + resource, e); + } + } + + private Texture renderAwtFont( TestConfig test, int width, int height, BitmapFont bitmapFont ) { + + BitmapCharacterSet charset = bitmapFont.getCharSet(); + + // Create an image at least as big as our JME text + System.out.println("Creating image size:" + width + ", " + height); + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = (Graphics2D)image.getGraphics(); + + g2.setColor(Color.lightGray); + g2.fillRect(0, 0, width, height); + g2.setColor(Color.cyan); + g2.drawRect(0, 0, width, height); + + g2.setColor(new Color(0, 0, 128)); + //g2.drawLine(0, 0, 50, 50); + //g2.drawLine(xFont, yFont, xFont + 30, yFont); + //g2.drawLine(xFont, yFont, xFont, yFont + 30); + + //g2.drawString("Testing", 0, 10); + + Font font = test.awtFont; + System.out.println("Java font:" + font); + + float size = font.getSize2D(); + FontMetrics fm = g2.getFontMetrics(font); + System.out.println("Java font metrics:" + fm); + + String[] lines = test.text.split("\n"); + + g2.setFont(font); + g2.setRenderingHint( + RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + int y = fm.getLeading() + fm.getMaxAscent(); + for( String s : lines ) { + g2.drawString(s, 0, y); + y += fm.getHeight(); + } + + g2.dispose(); + + Image jmeImage = new AWTLoader().load(image, true); + return new Texture2D(jmeImage); + } + + private Node createVisual( TestConfig test ) { + Node result = new Node(test.name); + + // For reasons I have trouble articulating, I want the visual's 0,0,0 to be + // the same as the JME rendered text. All other things will then be positioned relative + // to that. + // JME BitmapText (currently) renders from what it thinks the top of the letter is + // down. The actual bitmap text bounds may extend upwards... so we need to account + // for that in any labeling we add above it. + // Thus we add and set up the main test text first. + + BitmapFont bitmapFont = assetManager.loadFont(test.jmeFont); + BitmapCharacterSet charset = bitmapFont.getCharSet(); + + System.out.println("Test name:" + test.name); + System.out.println("Charset line height:" + charset.getLineHeight()); + System.out.println(" base:" + charset.getBase()); + System.out.println(" rendered size:" + charset.getRenderedSize()); + System.out.println(" width:" + charset.getWidth() + " height:" + charset.getHeight()); + + BitmapText bitmapText = new BitmapText(bitmapFont); + bitmapText.setText(test.text); + bitmapText.setColor(ColorRGBA.Black); + result.attachChild(bitmapText); + + // And force it to update because BitmapText builds itself lazily. + result.updateLogicalState(0.1f); + BoundingBox bb = (BoundingBox)bitmapText.getWorldBound(); + + BitmapText label = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt")); + label.setText("Test:" + test.name); + // Move the label up by its own size plus whatever extra headspace + // that the test text might have... plus a couple pixels of padding. + float yOffset = Math.max(0, bb.getCenter().y + bb.getYExtent()); + label.move(0, label.getSize() + yOffset + 2, 0); + label.setColor(new ColorRGBA(0, 0.2f, 0, 1f)); + result.attachChild(label); + + + // Bitmap text won't update itself automatically... it's lazy. + // That means it won't be able to tell us its bounding volume, etc... so + // we'll force it to update. + result.updateLogicalState(0.1f); + + // Add a bounding box visual + WireBox box = new WireBox(bb.getXExtent(), bb.getYExtent(), bb.getZExtent()); + Geometry geom = new Geometry(test.name + " bounds", box); + geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + geom.getMaterial().setColor("Color", ColorRGBA.Red); + geom.setLocalTranslation(bb.getCenter()); + result.attachChild(geom); + + // Add a box to show 0,0 + font size + float size = bitmapText.getLineHeight() * 0.5f; + box = new WireBox(size, size, 0); + geom = new Geometry(test.name + " metric", box); + geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + geom.getMaterial().setColor("Color", ColorRGBA.Blue); + geom.setLocalTranslation(size, -size, 0); + result.attachChild(geom); + + float yBaseline = -charset.getBase(); + Line line = new Line(new Vector3f(0, yBaseline, 0), new Vector3f(50, yBaseline, 0)); + geom = new Geometry(test.name + " base", line); + geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + geom.getMaterial().setColor("Color", ColorRGBA.Green); + result.attachChild(geom); + + System.out.println("text bb:" + bb); + // We want the width and the height to cover the whole potential area + // for the font. So it can't just be the rendered bounds but must encompass + // the whole abstract font space... 0, 0, to center + extents. + //int width = (int)Math.round(bb.getCenter().x + bb.getXExtent()); + //int height = (int)Math.round(-bb.getCenter().y + bb.getYExtent()); + // No, that's not right either because in case like this: + // text bb:BoundingBox [Center: (142.0, -15.5, 0.0) xExtent: 142.0 yExtent: 20.5 zExtent: 0.0] + // We get: + // Creating image size:284, 36 + // ...when it should be at least 41 high. + float x1 = bb.getCenter().x - bb.getXExtent(); + float x2 = bb.getCenter().x + bb.getXExtent(); + float y1 = bb.getCenter().y - bb.getYExtent(); + float y2 = bb.getCenter().y + bb.getYExtent(); + System.out.println("xy1:" + x1 + ", " + y1 + " xy2:" + x2 + ", " + y2); + int width = Math.round(x2 - Math.min(0, x1)); + int height = Math.round(y2 - Math.min(0, y1)); + + Texture awtText = renderAwtFont(test, width, height, bitmapFont); + Quad quad = new Quad(width, height); + geom = new Geometry(test.name + " awt1", quad); + geom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + geom.getMaterial().setTexture("ColorMap", awtText); + // Quads render from the lower left corner up + geom.move(0, -height, 0); + + // That quad is now positioned directly over where the bitmap text is. + // We'll clone it and move one right and one down + Geometry right = geom.clone(); + right.move(width, 0, 0); + result.attachChild(right); + + Geometry down = geom.clone(); + down.move(0, bb.getCenter().y - bb.getYExtent() - 1, 0); + result.attachChild(down); + + return result; + } + + @Override + public void simpleInitApp() { + setPauseOnLostFocus(false); + setDisplayStatView(false); + setDisplayFps(false); + viewPort.setBackgroundColor(ColorRGBA.LightGray); + + setupTestScene(); + setupUserInput(); + + setupInstructionsNote(); + } + + protected void setupInstructionsNote() { + // Add some instructional text + String instructions = "WASD/Cursor Keys = scroll\n" + + "+/- = zoom\n" + + "space = reset view\n" + + "0 = reset zoom\n"; + BitmapText note = new BitmapText(guiFont); + note.setText(instructions); + note.setColor(new ColorRGBA(0, 0.3f, 0, 1)); + note.updateLogicalState(0.1f); + + BoundingBox bb = (BoundingBox)note.getWorldBound(); + + note.setLocalTranslation(cam.getWidth() - bb.getXExtent() * 2 - 20, + cam.getHeight() - 20, 10); + + guiNode.attachChild(note); + + BitmapText note2 = note.clone(); + note2.setColor(ColorRGBA.Black); + note2.move(1, -1, -2); + guiNode.attachChild(note2); + + BitmapText note3 = note.clone(); + note3.setColor(ColorRGBA.White); + note3.move(-1, 1, -1); + guiNode.attachChild(note3); + + } + + protected void setupTestScene() { + String fox = "The quick brown fox jumps over the lazy dog."; + String loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; + String foxIpsum = fox + "\n" + loremIpsum; + + List tests = new ArrayList<>(); + + + // Note: for some Java fonts we reduce the point size to more closely + // match the pixel size... other than the Java-rendered fonts from Hiero, it will never + // be exact because of different font engines. + tests.add(new TestConfig("Hiero Java FreeSerif-16-Italic", + foxIpsum, + "jme3test/font/FreeSerif16I.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 16f))); + + tests.add(new TestConfig("Hiero FreeType FreeSerif-16-Italic", + foxIpsum, + "jme3test/font/FT-FreeSerif16I.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 14f))); + + tests.add(new TestConfig("Hiero Native FreeSerif-16-Italic", + foxIpsum, + "jme3test/font/Native-FreeSerif16I.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 15f))); + + tests.add(new TestConfig("AngelCode FreeSerif-16-Italic", + foxIpsum, + "jme3test/font/BM-FreeSerif16I.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 12f))); + // It's actually between 12 and 13 but Java rounds up. + + tests.add(new TestConfig("Hiero Padded FreeSerif-16-Italic", + foxIpsum, + "jme3test/font/FreeSerif16Ipad5555.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 16f))); + + tests.add(new TestConfig("AngelCode Padded FreeSerif-16-Italic", + foxIpsum, + "jme3test/font/BM-FreeSerif16Ipad5555.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 12f))); + // It's actually between 12 and 13 but Java rounds up. + + tests.add(new TestConfig("Hiero FreeSerif-32", + foxIpsum, + "jme3test/font/FreeSerif32.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(32f))); + + tests.add(new TestConfig("AngelCode FreeSerif-32", + foxIpsum, + "jme3test/font/BM-FreeSerif32.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(25f))); + + tests.add(new TestConfig("Hiero FreeSerif-64-Italic", + foxIpsum, + "jme3test/font/FreeSerif64I.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 64f))); + + tests.add(new TestConfig("AngelCode FreeSerif-64-Italic", + foxIpsum, + "jme3test/font/BM-FreeSerif64I.fnt", + loadTtf("/jme3test/font/FreeSerif.ttf").deriveFont(Font.ITALIC, 50f))); + + + /*tests.add(new TestConfig("Japanese", + "\u3042\u3047\u3070\u3090\u309E\u3067\u308A\u3089\n"+ + "\u3042\u3047\u3070\u3090\u309E\u3067\u308A\u3089", + "jme3test/font/DJapaSubset.fnt", + loadTtf("/jme3test/font/DroidSansFallback.ttf").deriveFont(32f)));*/ + + /*tests.add(new TestConfig("DroidSansMono-32", + "Ă㥹ĔĕĖėχψωӮӯ₴₵₹\n"+ + "Ă㥹ĔĕĖėχψωӮӯ₴₵₹", + "jme3test/font/DMono32BI.fnt", + loadTtf("/jme3test/font/DroidSansMono.ttf").deriveFont(32f)));*/ + + /*tests.add(new TestConfig("DroidSansMono-32", + "Ă㥹ĔĕĖėχψωӮӯ\n"+ + "Ă㥹ĔĕĖėχψωӮӯ", + "jme3test/font/DMono32BI.fnt", + loadTtf("/jme3test/font/DroidSansMono.ttf").deriveFont(Font.BOLD | Font.ITALIC, 32f))); + */ + + // Set up the test root node so that y = 0 is the top of the screen + testRoot.setLocalTranslation(0, cam.getHeight(), 0); + testRoot.attachChild(scrollRoot); + guiNode.attachChild(testRoot); + + float y = 0; //cam.getHeight(); + + for( TestConfig test : tests ) { + System.out.println("y:" + y); + + Node vis = createVisual(test); + + BoundingBox bb = (BoundingBox)vis.getWorldBound(); + System.out.println("bb:" + bb); + + // Render it relative to y, projecting down + vis.setLocalTranslation(1 + bb.getCenter().x - bb.getXExtent(), + y - bb.getCenter().y - bb.getYExtent(), + 0); + //vis.setLocalTranslation(1, y, 0); + scrollRoot.attachChild(vis); + + // Position to render the next one + y -= bb.getYExtent() * 2; + + // plus 5 pixels of padding + y -= 5; + } + } + + protected void resetZoom() { + testRoot.setLocalScale(1, 1, 1); + } + + protected void resetView() { + resetZoom(); + scrollRoot.setLocalTranslation(0, 0, 0); + } + + protected void setupUserInput() { + + inputManager.addMapping(SCROLL_UP, new KeyTrigger(KeyInput.KEY_UP), + new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping(SCROLL_DOWN, new KeyTrigger(KeyInput.KEY_DOWN), + new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping(SCROLL_LEFT, new KeyTrigger(KeyInput.KEY_LEFT), + new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping(SCROLL_RIGHT, new KeyTrigger(KeyInput.KEY_RIGHT), + new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping(ZOOM_IN, new KeyTrigger(KeyInput.KEY_ADD), + new KeyTrigger(KeyInput.KEY_EQUALS), + new KeyTrigger(KeyInput.KEY_Q)); + inputManager.addMapping(ZOOM_OUT, new KeyTrigger(KeyInput.KEY_MINUS), + new KeyTrigger(KeyInput.KEY_SUBTRACT), + new KeyTrigger(KeyInput.KEY_Z)); + inputManager.addMapping(RESET_VIEW, new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping(RESET_ZOOM, new KeyTrigger(KeyInput.KEY_0)); + + inputManager.addListener(new KeyStateListener(), + RESET_VIEW, RESET_ZOOM, + SCROLL_UP, SCROLL_DOWN, SCROLL_LEFT, SCROLL_RIGHT, + ZOOM_IN, ZOOM_OUT); + } + + @Override + public void simpleUpdate( float tpf ) { + if( scroll.lengthSquared() != 0 ) { + scrollRoot.move(scroll.mult(tpf)); + } + if( zoom.lengthSquared() != 0 ) { + Vector3f current = testRoot.getLocalScale(); + testRoot.setLocalScale(current.add(zoom.mult(tpf))); + } + } + + private class KeyStateListener implements ActionListener { + @Override + public void onAction(String name, boolean value, float tpf) { + switch( name ) { + case RESET_VIEW: + // Only on the up + if( !value ) { + resetView(); + } + break; + case RESET_ZOOM: + // Only on the up + if( !value ) { + resetZoom(); + } + break; + case ZOOM_IN: + if( value ) { + zoom.set(ZOOM_SPEED, ZOOM_SPEED, 0); + } else { + zoom.set(0, 0, 0); + } + break; + case ZOOM_OUT: + if( value ) { + zoom.set(-ZOOM_SPEED, -ZOOM_SPEED, 0); + } else { + zoom.set(0, 0, 0); + } + break; + case SCROLL_UP: + if( value ) { + scroll.set(0, -SCROLL_SPEED, 0); + } else { + scroll.set(0, 0, 0); + } + break; + case SCROLL_DOWN: + if( value ) { + scroll.set(0, SCROLL_SPEED, 0); + } else { + scroll.set(0, 0, 0); + } + break; + case SCROLL_LEFT: + if( value ) { + scroll.set(SCROLL_SPEED, 0, 0); + } else { + scroll.set(0, 0, 0); + } + break; + case SCROLL_RIGHT: + if( value ) { + scroll.set(-SCROLL_SPEED, 0, 0); + } else { + scroll.set(0, 0, 0); + } + break; + } + } + } + + private class TestConfig { + String name; + String jmeFont; + Font awtFont; + String text; + + public TestConfig( String name, String text, String jmeFont, Font awtFont ) { + this.name = name; + this.text = text; + this.jmeFont = jmeFont; + this.awtFont = awtFont; + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java b/jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java new file mode 100644 index 0000000000..e895cfba75 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestBitmapText3D.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.font.Rectangle; +import com.jme3.renderer.queue.RenderQueue.Bucket; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; + +public class TestBitmapText3D extends SimpleApplication { + + final private String txtB = + "ABCDEFGHIKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()-=_+[]\\;',./{}|:<>?"; + + public static void main(String[] args){ + TestBitmapText3D app = new TestBitmapText3D(); + app.start(); + } + + @Override + public void simpleInitApp() { + Quad q = new Quad(6, 3); + Geometry g = new Geometry("quad", q); + g.setLocalTranslation(0, -3, -0.0001f); + g.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + rootNode.attachChild(g); + + BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText txt = new BitmapText(fnt); + txt.setBox(new Rectangle(0, 0, 6, 3)); + txt.setQueueBucket(Bucket.Transparent); + txt.setSize( 0.5f ); + txt.setText(txtB); + rootNode.attachChild(txt); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestCursor.java b/jme3-examples/src/main/java/jme3test/gui/TestCursor.java new file mode 100644 index 0000000000..3ba14216d7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestCursor.java @@ -0,0 +1,77 @@ +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.cursors.plugins.JmeCursor; +import java.util.ArrayList; + +/** + * This test class demonstrate how to change cursor in jME3. + * + * NOTE: This will not work on Android as it does not support cursors. + * + * Cursor test + * @author MadJack + */ +public class TestCursor extends SimpleApplication { + + final private ArrayList cursors = new ArrayList<>(); + private long sysTime; + private int count = 0; + + public static void main(String[] args){ + TestCursor app = new TestCursor(); + + app.setShowSettings(false); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setEnabled(false); + // We need the cursor to be visible. If it is not visible the cursor + // will still be "used" and loaded, you just won't see it on the screen. + inputManager.setCursorVisible(true); + + /* + * To make jME3 use a custom cursor it is as simple as putting the + * .cur/.ico/.ani file in an asset directory. Here we use + * "Textures/GUI/Cursors". + * + * For the purpose of this demonstration we load 3 different cursors and add them + * into an array list and switch cursor every 8 seconds. + * + * The first ico has been made by Sirea and the set can be found here: + * http://www.rw-designer.com/icon-set/nyan-cat + * + * The second cursor has been made by Virum64 and is Public Domain. + * http://www.rw-designer.com/cursor-set/memes-faces-v64 + * + * The animated cursor has been made by Pointer Adic and can be found here: + * http://www.rw-designer.com/cursor-set/monkey + */ + cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/meme.cur")); + cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/nyancat.ico")); + cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/monkey.ani")); + + sysTime = System.currentTimeMillis(); + inputManager.setMouseCursor(cursors.get(count)); + } + + @Override + public void simpleUpdate(float tpf) { + long currentTime = System.currentTimeMillis(); + + if (currentTime - sysTime > 8000) { + count++; + if (count >= cursors.size()) { + count = 0; + } + sysTime = currentTime; + // 8 seconds have passed, + // tell jME3 to switch to a different cursor. + inputManager.setMouseCursor(cursors.get(count)); + } + + } +} + diff --git a/jme3-examples/src/main/java/jme3test/gui/TestOrtho.java b/jme3-examples/src/main/java/jme3test/gui/TestOrtho.java new file mode 100644 index 0000000000..dc61e9e2c5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestOrtho.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.ui.Picture; + +public class TestOrtho extends SimpleApplication { + + public static void main(String[] args){ + TestOrtho app = new TestOrtho(); + app.start(); + } + + @Override + public void simpleInitApp() { + Picture p = new Picture("Picture"); + p.move(0, 0, -1); // make it appear behind stats view + p.setPosition(0, 0); + p.setWidth(settings.getWidth()); + p.setHeight(settings.getHeight()); + p.setImage(assetManager, "Interface/Logo/Monkey.png", false); + + // attach geometry to orthoNode + guiNode.attachChild(p); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java b/jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java new file mode 100644 index 0000000000..0b9ae4bab9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestRtlBitmapText.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.app.StatsAppState; +import com.jme3.font.*; + +/** + * Test case for JME issue #1158: BitmapText right to left line wrapping not work + */ +public class TestRtlBitmapText extends SimpleApplication { + + private String text = "This is a test right to left text."; + private BitmapFont fnt; + private BitmapText txt; + + public static void main(String[] args) { + TestRtlBitmapText app = new TestRtlBitmapText(); + app.start(); + } + + @Override + public void simpleInitApp() { + float x = 400; + float y = 500; + getStateManager().detach(stateManager.getState(StatsAppState.class)); + fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); + fnt.setRightToLeft(true); + + // A right to left BitmapText + txt = new BitmapText(fnt); + txt.setBox(new Rectangle(0, 0, 150, 0)); + txt.setLineWrapMode(LineWrapMode.Word); + txt.setAlignment(BitmapFont.Align.Right); + txt.setText(text); + + txt.setLocalTranslation(x, y, 0); + guiNode.attachChild(txt); + } +} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java b/jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java new file mode 100644 index 0000000000..e1baf0b5c7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestSoftwareMouse.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.RawInputListener; +import com.jme3.input.event.*; +import com.jme3.math.FastMath; +import com.jme3.math.Vector2f; +import com.jme3.system.AppSettings; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import com.jme3.ui.Picture; + +public class TestSoftwareMouse extends SimpleApplication { + + private Picture cursor; + + final private RawInputListener inputListener = new RawInputListener() { + + @Override + public void beginInput() { + } + @Override + public void endInput() { + } + @Override + public void onJoyAxisEvent(JoyAxisEvent evt) { + } + @Override + public void onJoyButtonEvent(JoyButtonEvent evt) { + } + @Override + public void onMouseMotionEvent(MouseMotionEvent evt) { + float x = evt.getX(); + float y = evt.getY(); + + // Prevent mouse from leaving screen + AppSettings settings = TestSoftwareMouse.this.settings; + x = FastMath.clamp(x, 0, settings.getWidth()); + y = FastMath.clamp(y, 0, settings.getHeight()); + + // adjust for hotspot + cursor.setPosition(x, y - 64); + } + @Override + public void onMouseButtonEvent(MouseButtonEvent evt) { + } + @Override + public void onKeyEvent(KeyInputEvent evt) { + } + @Override + public void onTouchEvent(TouchEvent evt) { + } + }; + + public static void main(String[] args){ + TestSoftwareMouse app = new TestSoftwareMouse(); + +// AppSettings settings = new AppSettings(true); +// settings.setFrameRate(60); +// app.setSettings(settings); + + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setEnabled(false); +// inputManager.setCursorVisible(false); + + Texture tex = assetManager.loadTexture("Interface/Logo/Cursor.png"); + + cursor = new Picture("cursor"); + cursor.setTexture(assetManager, (Texture2D) tex, true); + cursor.setWidth(64); + cursor.setHeight(64); + guiNode.attachChild(cursor); + /* + * Position the software cursor + * so that its upper-left corner is at the hotspot. + */ + Vector2f initialPosition = inputManager.getCursorPosition(); + cursor.setPosition(initialPosition.x, initialPosition.y - 64f); + + inputManager.addRawInputListener(inputListener); + +// Image img = tex.getImage(); +// ByteBuffer data = img.getData(0); +// IntBuffer image = BufferUtils.createIntBuffer(64 * 64); +// for (int y = 0; y < 64; y++){ +// for (int x = 0; x < 64; x++){ +// int rgba = data.getInt(); +// image.put(rgba); +// } +// } +// image.clear(); +// +// try { +// Cursor cur = new Cursor(64, 64, 2, 62, 1, image, null); +// Mouse.setNativeCursor(cur); +// } catch (LWJGLException ex) { +// Logger.getLogger(TestSoftwareMouse.class.getName()).log(Level.SEVERE, null, ex); +// } + } +} diff --git a/jme3-examples/src/main/java/jme3test/gui/TestZOrder.java b/jme3-examples/src/main/java/jme3test/gui/TestZOrder.java new file mode 100644 index 0000000000..6d9ed9768d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/TestZOrder.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.gui; + +import com.jme3.app.SimpleApplication; +import com.jme3.ui.Picture; + +public class TestZOrder extends SimpleApplication { + + public static void main(String[] args){ + TestZOrder app = new TestZOrder(); + app.start(); + } + + @Override + public void simpleInitApp() { + Picture p = new Picture("Picture1"); + p.move(0,0,-1); + p.setPosition(100, 100); + p.setWidth(100); + p.setHeight(100); + p.setImage(assetManager, "Interface/Logo/Monkey.png", false); + guiNode.attachChild(p); + + Picture p2 = new Picture("Picture2"); + p2.move(0,0,1.001f); + p2.setPosition(150, 150); + p2.setWidth(100); + p2.setHeight(100); + p2.setImage(assetManager, "Interface/Logo/Monkey.png", false); + guiNode.attachChild(p2); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/gui/package-info.java b/jme3-examples/src/main/java/jme3test/gui/package-info.java new file mode 100644 index 0000000000..33e0fc2cf7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/gui/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for native graphical user-interface + * (GUI) support + */ +package jme3test.gui; diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java new file mode 100644 index 0000000000..5af191916d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.tween.Tween; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; +import com.jme3.anim.tween.action.BlendSpace; +import com.jme3.anim.tween.action.LinearBlendSpace; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; + +/** + * Sample 7 - Load an OgreXML model and play some of its animations. + */ +public class HelloAnimation extends SimpleApplication { + + private Action advance; + private AnimComposer control; + + public static void main(String[] args) { + HelloAnimation app = new HelloAnimation(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.LightGray); + initKeys(); + + /* Add a light source so we can see the model */ + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -1f, -1).normalizeLocal()); + rootNode.addLight(dl); + + /* Load a model that contains animation */ + Node player = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + player.setLocalScale(0.5f); + rootNode.attachChild(player); + + /* Use the model's AnimComposer to play its "stand" animation clip. */ + control = player.getControl(AnimComposer.class); + control.setCurrentAction("stand"); + + /* Compose an animation action named "halt" + that transitions from "Walk" to "stand" in half a second. */ + BlendSpace quickBlend = new LinearBlendSpace(0f, 0.5f); + Action halt = control.actionBlended("halt", quickBlend, "stand", "Walk"); + halt.setLength(0.5); + + /* Compose an animation action named "advance" + that walks for one cycle, then halts, then invokes onAdvanceDone(). */ + Action walk = control.action("Walk"); + Tween doneTween = Tweens.callMethod(this, "onAdvanceDone"); + advance = control.actionSequence("advance", walk, halt, doneTween); + } + + /** + * Callback to indicate that the "advance" animation action has completed. + */ + void onAdvanceDone() { + /* + * Play the "stand" animation action. + */ + control.setCurrentAction("stand"); + } + + /** + * Map the spacebar to the "Walk" input action, and add a listener to initiate + * the "advance" animation action each time it's pressed. + */ + private void initKeys() { + inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE)); + + ActionListener handler = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (keyPressed && control.getCurrentAction() != advance) { + control.setCurrentAction("advance"); + } + } + }; + inputManager.addListener(handler, "Walk"); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java new file mode 100644 index 0000000000..d062ed8e98 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloAssets.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; + +/** Sample 3 - how to load an OBJ model, and OgreXML model, + * a material/texture, or text. */ +public class HelloAssets extends SimpleApplication { + + public static void main(String[] args) { + HelloAssets app = new HelloAssets(); + app.start(); + } + + @Override + public void simpleInitApp() { + + /* Load a teapot model (OBJ file from jme3-testdata) */ + Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); + Material mat_default = new Material( assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + teapot.setMaterial(mat_default); + rootNode.attachChild(teapot); + + /* Create a wall (Box with material and texture from jme3-testdata) */ + Box box = new Box(2.5f, 2.5f, 1.0f); + Spatial wall = new Geometry("Box", box ); + Material mat_brick = new Material( assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat_brick.setTexture("ColorMap", assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg")); + wall.setMaterial(mat_brick); + wall.setLocalTranslation(2.0f,-2.5f,0.0f); + rootNode.attachChild(wall); + + /* Display a line of text (default font from jme3-testdata) */ + setDisplayStatView(false); + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText helloText = new BitmapText(guiFont); + helloText.setSize(guiFont.getCharSet().getRenderedSize()); + helloText.setText("Hello World"); + helloText.setLocalTranslation(300, helloText.getLineHeight(), 0); + guiNode.attachChild(helloText); + + /* Load a Ninja model (OgreXML + material + texture from test_data) */ + Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml"); + ninja.scale(0.05f, 0.05f, 0.05f); + ninja.rotate(0.0f, -3.0f, 0.0f); + ninja.setLocalTranslation(0.0f, -5.0f, -2.0f); + rootNode.attachChild(ninja); + /* You must add a light to make the model visible. */ + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal()); + rootNode.addLight(sun); + } +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java new file mode 100644 index 0000000000..228fc53d83 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloAudio.java @@ -0,0 +1,84 @@ +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.audio.AudioData.DataType; +import com.jme3.audio.AudioNode; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +/** Sample 11 - playing 3D audio. */ +public class HelloAudio extends SimpleApplication { + + private AudioNode audio_gun; + + public static void main(String[] args) { + HelloAudio app = new HelloAudio(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(40); + + /* just a blue box floating in space */ + Box box1 = new Box(1, 1, 1); + Geometry player = new Geometry("Player", box1); + Material mat1 = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.Blue); + player.setMaterial(mat1); + rootNode.attachChild(player); + + /* custom init methods, see below */ + initKeys(); + initAudio(); + } + + /** We create two audio nodes. */ + private void initAudio() { + /* gun shot sound is to be triggered by a mouse click. */ + audio_gun = new AudioNode(assetManager, + "Sound/Effects/Gun.wav", DataType.Buffer); + audio_gun.setPositional(false); + audio_gun.setLooping(false); + audio_gun.setVolume(2); + rootNode.attachChild(audio_gun); + + /* nature sound - keeps playing in a loop. */ + AudioNode audio_nature = new AudioNode(assetManager, + "Sound/Environment/Ocean Waves.ogg", DataType.Stream); + audio_nature.setLooping(true); // activate continuous playing + audio_nature.setPositional(true); + audio_nature.setVolume(3); + rootNode.attachChild(audio_nature); + audio_nature.play(); // play continuously! + } + + /** Declaring "Shoot" action, mapping it to a trigger (mouse left click). */ + private void initKeys() { + inputManager.addMapping("Shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(actionListener, "Shoot"); + } + + /** Defining the "Shoot" action: Play a gun sound. */ + final private ActionListener actionListener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("Shoot") && !keyPressed) { + audio_gun.playInstance(); // play each instance once! + } + } + }; + + /** Move the listener with the camera - for 3-D audio. */ + @Override + public void simpleUpdate(float tpf) { + listener.setLocation(cam.getLocation()); + listener.setRotation(cam.getRotation()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java new file mode 100644 index 0000000000..518e479b76 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.control.CharacterControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.util.CollisionShapeFactory; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; + +/** + * Example 9 - How to make walls and floors solid. + * This collision code uses Physics and a custom Action Listener. + * @author normen, with edits by Zathras + */ +public class HelloCollision extends SimpleApplication + implements ActionListener { + + private CharacterControl player; + final private Vector3f walkDirection = new Vector3f(); + private boolean left = false, right = false, up = false, down = false; + + //Temporary vectors used on each frame. + //They here to avoid instantiating new vectors on each frame + final private Vector3f camDir = new Vector3f(); + final private Vector3f camLeft = new Vector3f(); + + public static void main(String[] args) { + HelloCollision app = new HelloCollision(); + app.start(); + } + + @Override + public void simpleInitApp() { + /* Set up physics */ + BulletAppState bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + + // We re-use the flyby camera for rotation, while positioning is handled by physics + viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); + flyCam.setMoveSpeed(100); + setUpKeys(); + setUpLight(); + + // We load the scene from the zip file and adjust its size. + assetManager.registerLocator( + "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/town.zip", + HttpZipLocator.class); + Spatial sceneModel = assetManager.loadModel("main.scene"); + sceneModel.setLocalScale(2f); + + // We set up collision detection for the scene by creating a + // compound collision shape and a static RigidBodyControl with mass zero. + CollisionShape sceneShape = + CollisionShapeFactory.createMeshShape(sceneModel); + RigidBodyControl landscape = new RigidBodyControl(sceneShape, 0); + sceneModel.addControl(landscape); + + // We set up collision detection for the player by creating + // a capsule collision shape and a CharacterControl. + // The CharacterControl offers extra settings for + // size, step height, jumping, falling, and gravity. + // We also put the player in its starting position. + CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1); + player = new CharacterControl(capsuleShape, 0.05f); + player.setJumpSpeed(20); + player.setFallSpeed(30); + player.setGravity(30); + player.setPhysicsLocation(new Vector3f(0, 10, 0)); + + // We attach the scene and the player to the rootnode and the physics space, + // to make them appear in the game world. + rootNode.attachChild(sceneModel); + bulletAppState.getPhysicsSpace().add(landscape); + bulletAppState.getPhysicsSpace().add(player); + } + + private void setUpLight() { + // We add light so we see the scene + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(1.3f)); + rootNode.addLight(al); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White); + dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal()); + rootNode.addLight(dl); + } + + /** We over-write some navigational key mappings here, so we can + * add physics-controlled walking and jumping: */ + private void setUpKeys() { + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this, "Left"); + inputManager.addListener(this, "Right"); + inputManager.addListener(this, "Up"); + inputManager.addListener(this, "Down"); + inputManager.addListener(this, "Jump"); + } + + /** These are our custom actions triggered by key presses. + * We do not walk yet, we just keep track of the direction the user pressed. */ + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Left")) { + if (value) { left = true; } else { left = false; } + } else if (binding.equals("Right")) { + if (value) { right = true; } else { right = false; } + } else if (binding.equals("Up")) { + if (value) { up = true; } else { up = false; } + } else if (binding.equals("Down")) { + if (value) { down = true; } else { down = false; } + } else if (binding.equals("Jump")) { + player.jump(); + } + } + + /** + * This is the main event loop--walking happens here. + * We check in which direction the player is walking by interpreting + * the camera direction forward (camDir) and to the side (camLeft). + * The setWalkDirection() command is what lets a physics-controlled player walk. + * We also make sure here that the camera moves with player. + */ + @Override + public void simpleUpdate(float tpf) { + camDir.set(cam.getDirection()).multLocal(0.6f); + camLeft.set(cam.getLeft()).multLocal(0.4f); + walkDirection.set(0, 0, 0); + if (left) { + walkDirection.addLocal(camLeft); + } + if (right) { + walkDirection.addLocal(camLeft.negate()); + } + if (up) { + walkDirection.addLocal(camDir); + } + if (down) { + walkDirection.addLocal(camDir.negate()); + } + player.setWalkDirection(walkDirection); + cam.setLocation(player.getPhysicsLocation()); + } +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java new file mode 100644 index 0000000000..1210c7040e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloEffects.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; + +/** Sample 11 - how to create fire, water, and explosion effects. */ +public class HelloEffects extends SimpleApplication { + + public static void main(String[] args) { + HelloEffects app = new HelloEffects(); + app.start(); + } + + @Override + public void simpleInitApp() { + ParticleEmitter fire = + new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30); + Material mat_red = new Material(assetManager, + "Common/MatDefs/Misc/Particle.j3md"); + mat_red.setTexture("Texture", assetManager.loadTexture( + "Effects/Explosion/flame.png")); + fire.setMaterial(mat_red); + fire.setImagesX(2); + fire.setImagesY(2); // 2x2 texture animation + fire.setEndColor( new ColorRGBA(1f, 0f, 0f, 1f)); // red + fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow + fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0)); + fire.setStartSize(1.5f); + fire.setEndSize(0.1f); + fire.setGravity(0, 0, 0); + fire.setLowLife(1f); + fire.setHighLife(3f); + fire.getParticleInfluencer().setVelocityVariation(0.3f); + rootNode.attachChild(fire); + + ParticleEmitter debris = + new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10); + Material debris_mat = new Material(assetManager, + "Common/MatDefs/Misc/Particle.j3md"); + debris_mat.setTexture("Texture", assetManager.loadTexture( + "Effects/Explosion/Debris.png")); + debris.setMaterial(debris_mat); + debris.setImagesX(3); + debris.setImagesY(3); // 3x3 texture animation + debris.setSelectRandomImage(true); + debris.setRotateSpeed(4); + debris.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 4, 0)); + debris.setStartColor(ColorRGBA.White); + debris.setGravity(0, 6, 0); + debris.getParticleInfluencer().setVelocityVariation(.60f); + rootNode.attachChild(debris); + debris.emitAllParticles(); + +// ParticleEmitter water = +// new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 20); +// Material mat_blue = new Material(assetManager, +// "Common/MatDefs/Misc/Particle.j3md"); +// mat_blue.setTexture("Texture", assetManager.loadTexture( +// "Effects/Explosion/flame.png")); +// water.setMaterial(mat_blue); +// water.setImagesX(2); +// water.setImagesY(2); // 2x2 texture animation +// water.setStartColor( ColorRGBA.Blue); +// water.setEndColor( ColorRGBA.Cyan); +// water.getParticleInfluencer().setInitialVelocity(new Vector3f(0, -4, 0)); +// water.setStartSize(1f); +// water.setEndSize(1.5f); +// water.setGravity(0,1,0); +// water.setLowLife(1f); +// water.setHighLife(1f); +// water.getParticleInfluencer().setVelocityVariation(0.1f); +// water.setLocalTranslation(0, 6, 0); +// rootNode.attachChild(water); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java new file mode 100644 index 0000000000..0796bd7ce8 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloInput.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +/** Sample 5 - how to map keys and mouse buttons to actions */ +public class HelloInput extends SimpleApplication { + + public static void main(String[] args) { + HelloInput app = new HelloInput(); + app.start(); + } + private Geometry player; + private Boolean isRunning=true; + + @Override + public void simpleInitApp() { + Box b = new Box(1, 1, 1); + player = new Geometry("Player", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + player.setMaterial(mat); + rootNode.attachChild(player); + initKeys(); // load my custom keybinding + } + + /** Custom Keybinding: Map named actions to inputs. */ + private void initKeys() { + /* You can map one or several inputs to one named mapping. */ + inputManager.addMapping("Pause", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Rotate", new KeyTrigger(KeyInput.KEY_SPACE), // spacebar! + new MouseButtonTrigger(MouseInput.BUTTON_LEFT) ); // left click! + /* Add the named mappings to the action listeners. */ + inputManager.addListener(actionListener,"Pause"); + inputManager.addListener(analogListener,"Left", "Right", "Rotate"); + } + + /** Use this listener for KeyDown/KeyUp events */ + final private ActionListener actionListener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("Pause") && !keyPressed) { + isRunning = !isRunning; + } + } + }; + + /** Use this listener for continuous events */ + final private AnalogListener analogListener = new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + if (isRunning) { + if (name.equals("Rotate")) { + player.rotate(0, value, 0); + } + if (name.equals("Right")) { + player.move((new Vector3f(value, 0,0)) ); + } + if (name.equals("Left")) { + player.move(new Vector3f(-value, 0,0)); + } + } else { + System.out.println("Press P to unpause."); + } + } + }; + +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java new file mode 100644 index 0000000000..ba6d075e31 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloJME3.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +/** Sample 1 - how to get started with the most simple JME 3 application. + * Display a blue 3D cube and view from all sides by + * moving the mouse and pressing the WASD keys. */ +public class HelloJME3 extends SimpleApplication { + + public static void main(String[] args){ + HelloJME3 app = new HelloJME3(); + app.start(); // start the game + } + + @Override + public void simpleInitApp() { + Box b = new Box(1, 1, 1); // create cube shape + Geometry geom = new Geometry("Box", b); // create cube geometry from the shape + Material mat = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material + mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue + geom.setMaterial(mat); // set the cube's material + rootNode.attachChild(geom); // make the cube appear in the scene + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java new file mode 100644 index 0000000000..5bdec52016 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloLoop.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +/** Sample 4 - how to trigger repeating actions from the main event loop. + * In this example, you use the loop to make the player character + * rotate continuously. */ +public class HelloLoop extends SimpleApplication { + + public static void main(String[] args){ + HelloLoop app = new HelloLoop(); + app.start(); + } + + private Geometry player; + + @Override + public void simpleInitApp() { + /* This blue box is our player character. */ + Box b = new Box(1, 1, 1); + player = new Geometry("blue cube", b); + Material mat = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + player.setMaterial(mat); + rootNode.attachChild(player); + } + + /* Use the main event loop to trigger repeating actions. */ + @Override + public void simpleUpdate(float tpf) { + // make the player rotate: + player.rotate(0, 2*tpf, 0); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java new file mode 100644 index 0000000000..e12fef4569 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.Bucket; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.texture.Texture; +import com.jme3.util.TangentBinormalGenerator; + +/** Sample 6 - how to give an object's surface a material and texture. + * How to make objects transparent. How to make bumpy and shiny surfaces. */ +public class HelloMaterial extends SimpleApplication { + + public static void main(String[] args) { + HelloMaterial app = new HelloMaterial(); + app.start(); + } + + @Override + public void simpleInitApp() { + + /* A simple textured cube -- in good MIP map quality. */ + Box cube1Mesh = new Box( 1f,1f,1f); + Geometry cube1Geo = new Geometry("My Textured Box", cube1Mesh); + cube1Geo.setLocalTranslation(new Vector3f(-3f,1.1f,0f)); + Material cube1Mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + Texture cube1Tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + cube1Mat.setTexture("ColorMap", cube1Tex); + cube1Geo.setMaterial(cube1Mat); + rootNode.attachChild(cube1Geo); + + /* A translucent/transparent texture, similar to a window frame. */ + Box cube2Mesh = new Box( 1f,1f,0.01f); + Geometry cube2Geo = new Geometry("window frame", cube2Mesh); + Material cube2Mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + cube2Mat.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png")); + cube2Mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); // activate transparency + cube2Geo.setQueueBucket(Bucket.Transparent); + cube2Geo.setMaterial(cube2Mat); + rootNode.attachChild(cube2Geo); + + /* A bumpy rock with a shiny light effect. To make bumpy objects you must create a NormalMap. */ + Sphere sphereMesh = new Sphere(32,32, 2f); + Geometry sphereGeo = new Geometry("Shiny rock", sphereMesh); + sphereMesh.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres + TangentBinormalGenerator.generate(sphereMesh); // for lighting effect + Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + sphereMat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg")); + sphereMat.setTexture("NormalMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png")); + sphereMat.setBoolean("UseMaterialColors",true); + sphereMat.setColor("Diffuse",ColorRGBA.White); + sphereMat.setColor("Specular",ColorRGBA.White); + sphereMat.setFloat("Shininess", 64f); // [0,128] + sphereGeo.setMaterial(sphereMat); + //sphereGeo.setMaterial((Material) assetManager.loadMaterial("Materials/MyCustomMaterial.j3m")); + sphereGeo.setLocalTranslation(0,2,-2); // Move it a bit + sphereGeo.rotate(1.6f, 0, 0); // Rotate it a bit + rootNode.attachChild(sphereGeo); + + /* Must add a light to make the lit object visible! */ + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(1,0,-2).normalizeLocal()); + sun.setColor(ColorRGBA.White); + rootNode.addLight(sun); + } +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java new file mode 100644 index 0000000000..12bf60f950 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloNode.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; + +/** Sample 2 - How to use nodes as handles to manipulate objects in the scene. + * You can rotate, translate, and scale objects by manipulating their parent nodes. + * The Root Node is special: Only what is attached to the Root Node appears in the scene. */ +public class HelloNode extends SimpleApplication { + + public static void main(String[] args){ + HelloNode app = new HelloNode(); + app.start(); + } + + @Override + public void simpleInitApp() { + + /* create a blue box at coordinates (1,-1,1) */ + Box box1 = new Box(1,1,1); + Geometry blue = new Geometry("Box", box1); + blue.setLocalTranslation(new Vector3f(1,-1,1)); + Material mat1 = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.Blue); + blue.setMaterial(mat1); + + /* create a red box straight above the blue one at (1,3,1) */ + Box box2 = new Box(1,1,1); + Geometry red = new Geometry("Box", box2); + red.setLocalTranslation(new Vector3f(1,3,1)); + Material mat2 = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.setColor("Color", ColorRGBA.Red); + red.setMaterial(mat2); + + /* Create a pivot node at (0,0,0) and attach it to the root node */ + Node pivot = new Node("pivot"); + rootNode.attachChild(pivot); // put this node in the scene + + /* Attach the two boxes to the *pivot* node. (And transitively to the root node.) */ + pivot.attachChild(blue); + pivot.attachChild(red); + /* Rotate the pivot node: Note that both boxes have rotated! */ + pivot.rotate(.4f,.4f,0f); + } +} + diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java new file mode 100644 index 0000000000..ec566e3909 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloPhysics.java @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.font.BitmapText; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Sphere.TextureMode; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; + +/** + * Example 12 - how to give objects physical properties, so they bounce and fall. + * @author base code by double1984, updated by zathras + */ +public class HelloPhysics extends SimpleApplication { + + public static void main(String args[]) { + HelloPhysics app = new HelloPhysics(); + app.start(); + } + + /** Prepare the Physics Application State (jBullet) */ + private BulletAppState bulletAppState; + + /** Prepare Materials */ + private Material wall_mat; + private Material stone_mat; + private Material floor_mat; + + /** Prepare geometries for bricks and cannonballs. */ + private static final Box box; + private static final Sphere sphere; + private static final Box floor; + + /** dimensions used for bricks and wall */ + private static final float brickLength = 0.48f; + private static final float brickWidth = 0.24f; + private static final float brickHeight = 0.12f; + + static { + /* Initialize the cannonball geometry */ + sphere = new Sphere(32, 32, 0.4f, true, false); + sphere.setTextureMode(TextureMode.Projected); + /* Initialize the brick geometry */ + box = new Box(brickLength, brickHeight, brickWidth); + box.scaleTextureCoordinates(new Vector2f(1f, .5f)); + /* Initialize the floor geometry */ + floor = new Box(10f, 0.1f, 5f); + floor.scaleTextureCoordinates(new Vector2f(3, 6)); + } + + @Override + public void simpleInitApp() { + /* Set up Physics Game */ + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + /* Configure cam to look at scene */ + cam.setLocation(new Vector3f(0, 4f, 6f)); + cam.lookAt(new Vector3f(2, 2, 0), Vector3f.UNIT_Y); + /* Initialize the scene, materials, inputs, and physics space */ + initInputs(); + initMaterials(); + initWall(); + initFloor(); + initCrossHairs(); + } + + /** Add InputManager action: Left click triggers shooting. */ + private void initInputs() { + inputManager.addMapping("shoot", + new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(actionListener, "shoot"); + } + + /** + * Every time the shoot action is triggered, a new cannonball is produced. + * The ball is set up to fly from the camera position in the camera direction. + */ + final private ActionListener actionListener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("shoot") && !keyPressed) { + makeCannonBall(); + } + } + }; + + /** Initialize the materials used in this scene. */ + public void initMaterials() { + wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + wall_mat.setTexture("ColorMap", tex); + + stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); + key2.setGenerateMips(true); + Texture tex2 = assetManager.loadTexture(key2); + stone_mat.setTexture("ColorMap", tex2); + + floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); + key3.setGenerateMips(true); + Texture tex3 = assetManager.loadTexture(key3); + tex3.setWrap(WrapMode.Repeat); + floor_mat.setTexture("ColorMap", tex3); + } + + /** Make a solid floor and add it to the scene. */ + public void initFloor() { + Geometry floor_geo = new Geometry("Floor", floor); + floor_geo.setMaterial(floor_mat); + floor_geo.setLocalTranslation(0, -0.1f, 0); + this.rootNode.attachChild(floor_geo); + /* Make the floor physical with mass 0.0f! */ + RigidBodyControl floor_phy = new RigidBodyControl(0.0f); + floor_geo.addControl(floor_phy); + bulletAppState.getPhysicsSpace().add(floor_phy); + } + + /** This loop builds a wall out of individual bricks. */ + public void initWall() { + float startX = brickLength / 4; + float height = 0; + for (int j = 0; j < 15; j++) { + for (int i = 0; i < 6; i++) { + Vector3f vt = + new Vector3f(i * brickLength * 2 + startX, brickHeight + height, 0); + makeBrick(vt); + } + startX = -startX; + height += 2 * brickHeight; + } + } + + /** Creates one physical brick. */ + private void makeBrick(Vector3f loc) { + /* Create a brick geometry and attach it to the scene graph. */ + Geometry brick_geo = new Geometry("brick", box); + brick_geo.setMaterial(wall_mat); + rootNode.attachChild(brick_geo); + /* Position the brick geometry. */ + brick_geo.setLocalTranslation(loc); + /* Make brick physical with a mass > 0. */ + RigidBodyControl brick_phy = new RigidBodyControl(2f); + /* Add physical brick to physics space. */ + brick_geo.addControl(brick_phy); + bulletAppState.getPhysicsSpace().add(brick_phy); + } + + /** Creates one physical cannonball. + * By default, the ball is accelerated and flies + * from the camera position in the camera direction.*/ + public void makeCannonBall() { + /* Create a cannonball geometry and attach to scene graph. */ + Geometry ball_geo = new Geometry("cannon ball", sphere); + ball_geo.setMaterial(stone_mat); + rootNode.attachChild(ball_geo); + /* Position the cannonball. */ + ball_geo.setLocalTranslation(cam.getLocation()); + /* Make the ball physical with a mass > 0.0f */ + RigidBodyControl ball_phy = new RigidBodyControl(1f); + /* Add physical ball to physics space. */ + ball_geo.addControl(ball_phy); + bulletAppState.getPhysicsSpace().add(ball_phy); + /* Accelerate the physical ball to shoot it. */ + ball_phy.setLinearVelocity(cam.getDirection().mult(25)); + } + + /** A plus sign used as crosshairs to help the player with aiming.*/ + protected void initCrossHairs() { + setDisplayStatView(false); + //guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // fake crosshairs :) + ch.setLocalTranslation( // center + settings.getWidth() / 2, + settings.getHeight() / 2, 0); + guiNode.attachChild(ch); + } +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java new file mode 100644 index 0000000000..90e187a9a9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloPicking.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Ray; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; + +/** Sample 8 - how to let the user pick (select) objects in the scene + * using the mouse or key presses. Can be used for shooting, opening doors, etc. */ +public class HelloPicking extends SimpleApplication { + + public static void main(String[] args) { + HelloPicking app = new HelloPicking(); + app.start(); + } + private Node shootables; + private Geometry mark; + + @Override + public void simpleInitApp() { + initCrossHairs(); // a "+" in the middle of the screen to help aiming + initKeys(); // load custom key mappings + initMark(); // a red sphere to mark the hit + + /* Create four colored boxes and a floor to shoot at: */ + shootables = new Node("Shootables"); + rootNode.attachChild(shootables); + shootables.attachChild(makeCube("a Dragon", -2f, 0f, 1f)); + shootables.attachChild(makeCube("a tin can", 1f, -2f, 0f)); + shootables.attachChild(makeCube("the Sheriff", 0f, 1f, -2f)); + shootables.attachChild(makeCube("the Deputy", 1f, 0f, -4f)); + shootables.attachChild(makeFloor()); + shootables.attachChild(makeCharacter()); + } + + /** Declaring the "Shoot" action and mapping to its triggers. */ + private void initKeys() { + inputManager.addMapping("Shoot", + new KeyTrigger(KeyInput.KEY_SPACE), // trigger 1: spacebar + new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); // trigger 2: left-button click + inputManager.addListener(actionListener, "Shoot"); + } + /** Defining the "Shoot" action: Determine what was hit and how to respond. */ + final private ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("Shoot") && !keyPressed) { + // 1. Reset results list. + CollisionResults results = new CollisionResults(); + // 2. Aim the ray from cam loc to cam direction. + Ray ray = new Ray(cam.getLocation(), cam.getDirection()); + // 3. Collect intersections between Ray and Shootables in results list. + shootables.collideWith(ray, results); + // 4. Print the results + System.out.println("----- Collisions? " + results.size() + "-----"); + for (int i = 0; i < results.size(); i++) { + // For each hit, we know distance, impact point, name of geometry. + float dist = results.getCollision(i).getDistance(); + Vector3f pt = results.getCollision(i).getContactPoint(); + String hit = results.getCollision(i).getGeometry().getName(); + System.out.println("* Collision #" + i); + System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away."); + } + // 5. Use the results (we mark the hit object) + if (results.size() > 0) { + // The closest collision point is what was truly hit: + CollisionResult closest = results.getClosestCollision(); + // Let's interact - we mark the hit with a red dot. + mark.setLocalTranslation(closest.getContactPoint()); + rootNode.attachChild(mark); + } else { + // No hits? Then remove the red mark. + rootNode.detachChild(mark); + } + } + } + }; + + /** A cube object for target practice */ + private Geometry makeCube(String name, float x, float y, float z) { + Box box = new Box(1, 1, 1); + Geometry cube = new Geometry(name, box); + cube.setLocalTranslation(x, y, z); + Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.randomColor()); + cube.setMaterial(mat1); + return cube; + } + + /** A floor to show that the "shot" can go through several objects. */ + private Geometry makeFloor() { + Box box = new Box(15, .2f, 15); + Geometry floor = new Geometry("the Floor", box); + floor.setLocalTranslation(0, -4, -5); + Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setColor("Color", ColorRGBA.Gray); + floor.setMaterial(mat1); + return floor; + } + + /** A red ball that marks the last spot that was "hit" by the "shot". */ + private void initMark() { + Sphere sphere = new Sphere(30, 30, 0.2f); + mark = new Geometry("BOOM!", sphere); + Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mark_mat.setColor("Color", ColorRGBA.Red); + mark.setMaterial(mark_mat); + } + + /** A centred plus sign to help the player aim. */ + private void initCrossHairs() { + setDisplayStatView(false); + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2 - ch.getLineWidth()/2, settings.getHeight() / 2 + ch.getLineHeight()/2, 0); + guiNode.attachChild(ch); + } + + private Spatial makeCharacter() { + // load a character from jme3-testdata + Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + golem.scale(0.5f); + golem.setLocalTranslation(-1.0f, -1.5f, -0.6f); + + // We must add a light to make the model visible + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f)); + golem.addLight(sun); + return golem; + } +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java new file mode 100644 index 0000000000..f6032faf36 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrain.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; + +public class HelloTerrain extends SimpleApplication { + + public static void main(String[] args) { + HelloTerrain app = new HelloTerrain(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(50); + + /* 1. Create terrain material and load four textures into it. */ + Material mat_terrain = new Material(assetManager, + "Common/MatDefs/Terrain/Terrain.j3md"); + + /* 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ + mat_terrain.setTexture("Alpha", assetManager.loadTexture( + "Textures/Terrain/splat/alphamap.png")); + + /* 1.2) Add GRASS texture into the red layer (Tex1). */ + Texture grass = assetManager.loadTexture( + "Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("Tex1", grass); + mat_terrain.setFloat("Tex1Scale", 64f); + + /* 1.3) Add DIRT texture into the green layer (Tex2) */ + Texture dirt = assetManager.loadTexture( + "Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("Tex2", dirt); + mat_terrain.setFloat("Tex2Scale", 32f); + + /* 1.4) Add ROAD texture into the blue layer (Tex3) */ + Texture rock = assetManager.loadTexture( + "Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("Tex3", rock); + mat_terrain.setFloat("Tex3Scale", 128f); + + /* 2.a Create a custom height map from an image */ + AbstractHeightMap heightmap = null; + Texture heightMapImage = assetManager.loadTexture( + "Textures/Terrain/splat/mountains512.png"); + heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); + +/* 2.b Create a random height map */ +// HillHeightMap heightmap = null; +// HillHeightMap.NORMALIZE_RANGE = 100; +// try { +// heightmap = new HillHeightMap(513, 1000, 50, 100, (byte) 3); +// } catch (Exception ex) { +// ex.printStackTrace(); +// } + + heightmap.load(); + + /* 3. We have prepared material and heightmap. + * Now we create the actual terrain: + * 3.1) Create a TerrainQuad and name it "my terrain". + * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65. + * 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. + * 3.4) As LOD step scale we supply Vector3f(1,1,1). + * 3.5) We supply the prepared heightmap itself. + */ + int patchSize = 65; + TerrainQuad terrain + = new TerrainQuad("my terrain", patchSize, 513, heightmap.getHeightMap()); + + /* 4. We give the terrain its material, position & scale it, and attach it. */ + terrain.setMaterial(mat_terrain); + terrain.setLocalTranslation(0, -100, 0); + terrain.setLocalScale(2f, 1f, 2f); + rootNode.attachChild(terrain); + + /* 5. The LOD (level of detail) depends on were the camera is: */ + TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); + control.setLodCalculator( new DistanceLodCalculator(patchSize, 2.7f) ); // patch size, and a multiplier + terrain.addControl(control); + } +} diff --git a/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java b/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java new file mode 100644 index 0000000000..739a93ff76 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/HelloTerrainCollision.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.helloworld; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; +import com.jme3.bullet.control.CharacterControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import java.util.ArrayList; +import java.util.List; + +/** + * This demo shows a terrain with collision detection, + * that you can walk around in with a first-person perspective. + * This code combines HelloCollision and HelloTerrain. + */ +public class HelloTerrainCollision extends SimpleApplication + implements ActionListener { + + private BulletAppState bulletAppState; + private CharacterControl player; + final private Vector3f walkDirection = new Vector3f(); + private boolean left = false, right = false, up = false, down = false; + //Temporary vectors used on each frame. + //They here to avoid instantiating new vectors on each frame + final private Vector3f camDir = new Vector3f(); + final private Vector3f camLeft = new Vector3f(); + + public static void main(String[] args) { + HelloTerrainCollision app = new HelloTerrainCollision(); + app.start(); + } + + @Override + public void simpleInitApp() { + /* Set up physics */ + bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + + flyCam.setMoveSpeed(100); + setUpKeys(); + + /* 1. Create terrain material and load four textures into it. */ + Material mat_terrain = new Material(assetManager, + "Common/MatDefs/Terrain/Terrain.j3md"); + + /* 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ + mat_terrain.setTexture("Alpha", assetManager.loadTexture( + "Textures/Terrain/splat/alphamap.png")); + + /* 1.2) Add GRASS texture into the red layer (Tex1). */ + Texture grass = assetManager.loadTexture( + "Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("Tex1", grass); + mat_terrain.setFloat("Tex1Scale", 64f); + + /* 1.3) Add DIRT texture into the green layer (Tex2) */ + Texture dirt = assetManager.loadTexture( + "Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("Tex2", dirt); + mat_terrain.setFloat("Tex2Scale", 32f); + + /* 1.4) Add ROAD texture into the blue layer (Tex3) */ + Texture rock = assetManager.loadTexture( + "Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("Tex3", rock); + mat_terrain.setFloat("Tex3Scale", 128f); + + /* 2. Create the height map */ + AbstractHeightMap heightmap = null; + Texture heightMapImage = assetManager.loadTexture( + "Textures/Terrain/splat/mountains512.png"); + heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); + heightmap.load(); + + /* 3. We have prepared material and heightmap. + * Now we create the actual terrain: + * 3.1) Create a TerrainQuad and name it "my terrain". + * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65. + * 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. + * 3.4) As LOD step scale we supply Vector3f(1,1,1). + * 3.5) We supply the prepared heightmap itself. + */ + TerrainQuad terrain + = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap()); + + /* 4. We give the terrain its material, position & scale it, and attach it. */ + terrain.setMaterial(mat_terrain); + terrain.setLocalTranslation(0, -100, 0); + terrain.setLocalScale(2f, 1f, 2f); + rootNode.attachChild(terrain); + + /* 5. The LOD (level of detail) depends on were the camera is: */ + List cameras = new ArrayList<>(); + cameras.add(getCamera()); + TerrainLodControl control = new TerrainLodControl(terrain, cameras); + terrain.addControl(control); + + /* 6. Add physics: */ + /* We set up collision detection for the scene by creating a static + * RigidBodyControl with mass zero.*/ + terrain.addControl(new RigidBodyControl(0)); + + // We set up collision detection for the player by creating + // a capsule collision shape and a CharacterControl. + // The CharacterControl offers extra settings for + // size, step height, jumping, falling, and gravity. + // We also put the player in its starting position. + CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1); + player = new CharacterControl(capsuleShape, 0.05f); + player.setJumpSpeed(20); + player.setFallSpeed(30); + player.setGravity(30); + player.setPhysicsLocation(new Vector3f(-10, 10, 10)); + + // We attach the scene and the player to the rootnode and the physics space, + // to make them appear in the game world. + bulletAppState.getPhysicsSpace().add(terrain); + bulletAppState.getPhysicsSpace().add(player); + + } + /** We over-write some navigational key mappings here, so we can + * add physics-controlled walking and jumping: */ + private void setUpKeys() { + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this, "Left"); + inputManager.addListener(this, "Right"); + inputManager.addListener(this, "Up"); + inputManager.addListener(this, "Down"); + inputManager.addListener(this, "Jump"); + } + + /** These are our custom actions triggered by key presses. + * We do not walk yet, we just keep track of the direction the user pressed. */ + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Left")) { + if (value) { left = true; } else { left = false; } + } else if (binding.equals("Right")) { + if (value) { right = true; } else { right = false; } + } else if (binding.equals("Up")) { + if (value) { up = true; } else { up = false; } + } else if (binding.equals("Down")) { + if (value) { down = true; } else { down = false; } + } else if (binding.equals("Jump")) { + player.jump(); + } + } + + /** + * This is the main event loop--walking happens here. + * We check in which direction the player is walking by interpreting + * the camera direction forward (camDir) and to the side (camLeft). + * The setWalkDirection() command is what lets a physics-controlled player walk. + * We also make sure here that the camera moves with player. + */ + @Override + public void simpleUpdate(float tpf) { + camDir.set(cam.getDirection()).multLocal(0.6f); + camLeft.set(cam.getLeft()).multLocal(0.4f); + walkDirection.set(0, 0, 0); + if (left) { + walkDirection.addLocal(camLeft); + } + if (right) { + walkDirection.addLocal(camLeft.negate()); + } + if (up) { + walkDirection.addLocal(camDir); + } + if (down) { + walkDirection.addLocal(camDir.negate()); + } + player.setWalkDirection(walkDirection); + cam.setLocation(player.getPhysicsLocation()); + } +} + diff --git a/jme3-examples/src/main/java/jme3test/helloworld/package-info.java b/jme3-examples/src/main/java/jme3test/helloworld/package-info.java new file mode 100644 index 0000000000..34b47f9c11 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/helloworld/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps used in the beginners tutorial + */ +package jme3test.helloworld; diff --git a/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java b/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java new file mode 100644 index 0000000000..e4f4d8f263 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.input; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.*; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.CameraNode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.CameraControl.ControlDirection; +import com.jme3.scene.shape.RectangleMesh; +import com.jme3.system.AppSettings; + +/** + * A 3rd-person camera node follows a target (teapot). Follow the teapot with + * WASD keys, rotate by dragging the mouse. + */ +public class TestCameraNode extends SimpleApplication implements AnalogListener, ActionListener { + + private Node teaNode; + private boolean rotate = false; + final private Vector3f direction = new Vector3f(); + + public static void main(String[] args) { + TestCameraNode app = new TestCameraNode(); + AppSettings s = new AppSettings(true); + s.setFrameRate(100); + app.setSettings(s); + app.start(); + } + + @Override + public void simpleInitApp() { + // load a teapot model + Geometry teaGeom + = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + teaGeom.setMaterial(mat); + //create a node to attach the geometry and the camera node + teaNode = new Node("teaNode"); + teaNode.attachChild(teaGeom); + rootNode.attachChild(teaNode); + // create a floor + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Geometry ground = new Geometry("ground", new RectangleMesh( + new Vector3f(-25, -1, 25), + new Vector3f(25, -1, 25), + new Vector3f(-25, -1, -25))); + ground.setMaterial(mat); + rootNode.attachChild(ground); + + //creating the camera Node + CameraNode camNode = new CameraNode("CamNode", cam); + // Set the direction to SpatialToCamera, which means the camera will copy the movements of the Node. + camNode.setControlDir(ControlDirection.SpatialToCamera); + //attaching the camNode to the teaNode + teaNode.attachChild(camNode); + //setting the local translation of the cam node to move it away from the tea Node a bit + camNode.setLocalTranslation(new Vector3f(-10, 0, 0)); + //setting the camNode to look at the teaNode + camNode.lookAt(teaNode.getLocalTranslation(), Vector3f.UNIT_Y); + + //disable the default 1st-person flyCam (don't forget this!!) + flyCam.setEnabled(false); + + registerInput(); + } + + public void registerInput() { + inputManager.addMapping("moveForward", new KeyTrigger(KeyInput.KEY_UP), new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("moveBackward", new KeyTrigger(KeyInput.KEY_DOWN), new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("moveRight", new KeyTrigger(KeyInput.KEY_RIGHT), new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("moveLeft", new KeyTrigger(KeyInput.KEY_LEFT), new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("toggleRotate", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addMapping("rotateRight", new MouseAxisTrigger(MouseInput.AXIS_X, true)); + inputManager.addMapping("rotateLeft", new MouseAxisTrigger(MouseInput.AXIS_X, false)); + inputManager.addListener(this, "moveForward", "moveBackward", "moveRight", "moveLeft"); + inputManager.addListener(this, "rotateRight", "rotateLeft", "toggleRotate"); + } + + @Override + public void onAnalog(String name, float value, float tpf) { + //computing the normalized direction of the cam to move the teaNode + direction.set(cam.getDirection()).normalizeLocal(); + if (name.equals("moveForward")) { + direction.multLocal(5 * tpf); + teaNode.move(direction); + } + if (name.equals("moveBackward")) { + direction.multLocal(-5 * tpf); + teaNode.move(direction); + } + if (name.equals("moveRight")) { + direction.crossLocal(Vector3f.UNIT_Y).multLocal(5 * tpf); + teaNode.move(direction); + } + if (name.equals("moveLeft")) { + direction.crossLocal(Vector3f.UNIT_Y).multLocal(-5 * tpf); + teaNode.move(direction); + } + if (name.equals("rotateRight") && rotate) { + teaNode.rotate(0, 5 * tpf, 0); + } + if (name.equals("rotateLeft") && rotate) { + teaNode.rotate(0, -5 * tpf, 0); + } + + } + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + //toggling rotation on or off + if (name.equals("toggleRotate") && keyPressed) { + rotate = true; + inputManager.setCursorVisible(false); + } + if (name.equals("toggleRotate") && !keyPressed) { + rotate = false; + inputManager.setCursorVisible(true); + } + + } +} diff --git a/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java b/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java new file mode 100644 index 0000000000..fc787458cf --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.input; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.RectangleMesh; + +/** A 3rd-person chase camera orbits a target (teapot). + * Follow the teapot with WASD keys, rotate by dragging the mouse. */ +public class TestChaseCamera extends SimpleApplication implements AnalogListener, ActionListener { + + private Geometry teaGeom; + + public static void main(String[] args) { + TestChaseCamera app = new TestChaseCamera(); + app.start(); + } + + @Override + public void simpleInitApp() { + // Load a teapot model + teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + Material mat_tea = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + teaGeom.setMaterial(mat_tea); + rootNode.attachChild(teaGeom); + + // Load a floor model + Material mat_ground = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat_ground.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Geometry ground = new Geometry("ground", new RectangleMesh( + new Vector3f(-25, -1, 25), + new Vector3f(25, -1, 25), + new Vector3f(-25, -1, -25))); + ground.setMaterial(mat_ground); + rootNode.attachChild(ground); + + // Disable the default first-person cam! + flyCam.setEnabled(false); + + // Enable a chase cam + ChaseCamera chaseCam = new ChaseCamera(cam, teaGeom, inputManager); + + //Uncomment this to invert the camera's vertical rotation Axis + //chaseCam.setInvertVerticalAxis(true); + + //Uncomment this to invert the camera's horizontal rotation Axis + //chaseCam.setInvertHorizontalAxis(true); + + //Comment this to disable smooth camera motion + chaseCam.setSmoothMotion(true); + + //Uncomment this to disable trailing of the camera + //WARNING, trailing only works with smooth motion enabled. It is true by default. + //chaseCam.setTrailingEnabled(false); + + //Uncomment this to look 3 world units above the target + //chaseCam.setLookAtOffset(Vector3f.UNIT_Y.mult(3)); + + //Uncomment this to enable rotation when the middle mouse button is pressed (like Blender) + // WARNING: setting this trigger disables the rotation on right and left mouse button click + //chaseCam.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); + + //Uncomment this to set multiple triggers to enable rotation of the cam + // Here spacebar and middle mouse button + //chaseCam.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE),new KeyTrigger(KeyInput.KEY_SPACE)); + + //registering inputs for target's movement + registerInput(); + + } + + public void registerInput() { + inputManager.addMapping("moveForward", new KeyTrigger(KeyInput.KEY_UP), new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("moveBackward", new KeyTrigger(KeyInput.KEY_DOWN), new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("moveRight", new KeyTrigger(KeyInput.KEY_RIGHT), new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("moveLeft", new KeyTrigger(KeyInput.KEY_LEFT), new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("displayPosition", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addListener(this, "moveForward", "moveBackward", "moveRight", "moveLeft"); + inputManager.addListener(this, "displayPosition"); + } + + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("moveForward")) { + teaGeom.move(0, 0, -5 * tpf); + } + if (name.equals("moveBackward")) { + teaGeom.move(0, 0, 5 * tpf); + } + if (name.equals("moveRight")) { + teaGeom.move(5 * tpf, 0, 0); + } + if (name.equals("moveLeft")) { + teaGeom.move(-5 * tpf, 0, 0); + + } + + } + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("displayPosition") && keyPressed) { + teaGeom.move(10, 10, 10); + + } + } + + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + + // teaGeom.move(new Vector3f(0.001f, 0, 0)); + // pivot.rotate(0, 0.00001f, 0); + // rootNode.updateGeometricState(); + } +// public void update() { +// super.update(); +//// render the viewports +// float tpf = timer.getTimePerFrame(); +// state.getRootNode().rotate(0, 0.000001f, 0); +// stateManager.update(tpf); +// stateManager.render(renderManager); +// renderManager.render(tpf); +// } +} diff --git a/jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java b/jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java new file mode 100644 index 0000000000..00dcae46aa --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/TestChaseCameraAppState.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.input; + +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.FlyCamAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; + +/** A 3rd-person chase camera orbits a target (teapot). + * Follow the teapot with WASD keys, rotate by dragging the mouse. */ +public class TestChaseCameraAppState extends SimpleApplication implements AnalogListener, ActionListener { + + private Geometry teaGeom; + + public static void main(String[] args) { + TestChaseCameraAppState app = new TestChaseCameraAppState(); + app.start(); + } + + @Override + public void simpleInitApp() { + // Load a teapot model + teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + Material mat_tea = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + teaGeom.setMaterial(mat_tea); + rootNode.attachChild(teaGeom); + + // Load a floor model + Material mat_ground = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat_ground.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Geometry ground = new Geometry("ground", new Quad(50, 50)); + ground.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X)); + ground.setLocalTranslation(-25, -1, 25); + ground.setMaterial(mat_ground); + rootNode.attachChild(ground); + + //disable the flyCam + stateManager.detach(stateManager.getState(FlyCamAppState.class)); + + // Enable a chase cam + ChaseCameraAppState chaseCamAS = new ChaseCameraAppState(); + chaseCamAS.setTarget(teaGeom); + stateManager.attach(chaseCamAS); + + //Uncomment this to invert the camera's vertical rotation Axis + //chaseCamAS.setInvertVerticalAxis(true); + + //Uncomment this to invert the camera's horizontal rotation Axis + //chaseCamAS.setInvertHorizontalAxis(true); + + //Uncomment this to enable rotation when the middle mouse button is pressed (like Blender) + // WARNING: setting this trigger disables the rotation on right and left mouse button click + //chaseCamAS.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); + + //Uncomment this to set multiple triggers to enable rotation of the cam + //Here space bar and middle mouse button + //chaseCamAS.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE),new KeyTrigger(KeyInput.KEY_SPACE)); + + //registering inputs for target's movement + registerInput(); + + } + + public void registerInput() { + inputManager.addMapping("moveForward", new KeyTrigger(KeyInput.KEY_UP), new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("moveBackward", new KeyTrigger(KeyInput.KEY_DOWN), new KeyTrigger(KeyInput.KEY_S)); + inputManager.addMapping("moveRight", new KeyTrigger(KeyInput.KEY_RIGHT), new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("moveLeft", new KeyTrigger(KeyInput.KEY_LEFT), new KeyTrigger(KeyInput.KEY_A)); + inputManager.addMapping("displayPosition", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addListener(this, "moveForward", "moveBackward", "moveRight", "moveLeft"); + inputManager.addListener(this, "displayPosition"); + } + + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("moveForward")) { + teaGeom.move(0, 0, -5 * tpf); + } + if (name.equals("moveBackward")) { + teaGeom.move(0, 0, 5 * tpf); + } + if (name.equals("moveRight")) { + teaGeom.move(5 * tpf, 0, 0); + } + if (name.equals("moveLeft")) { + teaGeom.move(-5 * tpf, 0, 0); + + } + + } + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("displayPosition") && keyPressed) { + teaGeom.move(10, 10, 10); + + } + } + + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + + // teaGeom.move(new Vector3f(0.001f, 0, 0)); + // pivot.rotate(0, 0.00001f, 0); + // rootNode.updateGeometricState(); + } +// public void update() { +// super.update(); +//// render the viewports +// float tpf = timer.getTimePerFrame(); +// state.getRootNode().rotate(0, 0.000001f, 0); +// stateManager.update(tpf); +// stateManager.render(renderManager); +// renderManager.render(tpf); +// } +} diff --git a/jme3-examples/src/main/java/jme3test/input/TestControls.java b/jme3-examples/src/main/java/jme3test/input/TestControls.java new file mode 100644 index 0000000000..9f3fa28559 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/TestControls.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.input; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseAxisTrigger; + +public class TestControls extends SimpleApplication { + + final private ActionListener actionListener = new ActionListener(){ + @Override + public void onAction(String name, boolean pressed, float tpf){ + System.out.println(name + " = " + pressed); + } + }; + final private AnalogListener analogListener = new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + System.out.println(name + " = " + value); + } + }; + + public static void main(String[] args){ + TestControls app = new TestControls(); + app.start(); + } + + @Override + public void simpleInitApp() { + // Test multiple inputs per mapping + inputManager.addMapping("My Action", + new KeyTrigger(KeyInput.KEY_SPACE), + new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false)); + + // Test multiple listeners per mapping + inputManager.addListener(actionListener, "My Action"); + inputManager.addListener(analogListener, "My Action"); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/input/TestIssue1692.java b/jme3-examples/src/main/java/jme3test/input/TestIssue1692.java new file mode 100644 index 0000000000..cb63e3a70a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/TestIssue1692.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.input; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; + +/** + * A test for issue https://github.com/jMonkeyEngine/jmonkeyengine/pull/1692. + * We are testing to see if disabling then re-enabling the chase camera keeps the correct flags + * set so that we can still rotate without dragging + */ +public class TestIssue1692 extends SimpleApplication implements ActionListener { + + private ChaseCamera chaseCam; + private BitmapText cameraStatus; + + public static void main(String[] args) { + TestIssue1692 app = new TestIssue1692(); + app.start(); + } + + @Override + public void simpleInitApp() { + // Load a teapot model, we will chase this with the camera + Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + Material teapotMaterial = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + teaGeom.setMaterial(teapotMaterial); + rootNode.attachChild(teaGeom); + + // Load a floor model + Material floorMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + floorMaterial.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Geometry ground = new Geometry("ground", new Quad(50, 50)); + ground.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X)); + ground.setLocalTranslation(-25, -1, 25); + ground.setMaterial(floorMaterial); + rootNode.attachChild(ground); + + // Disable the default first-person cam! + flyCam.setEnabled(false); + + // Enable a chase cam + chaseCam = new ChaseCamera(cam, teaGeom, inputManager); + /* + * Explicitly set drag to rotate to false. + * We are testing to see if disabling then re-enabling the camera keeps the correct flags + * set so that we can still rotate without dragging. + */ + chaseCam.setDragToRotate(false); + + // Show instructions + int yTop = settings.getHeight(); + int size = guiFont.getCharSet().getRenderedSize(); + BitmapText hudText = new BitmapText(guiFont); + hudText.setSize(size); + hudText.setColor(ColorRGBA.Blue); + hudText.setText("This test is for issue 1692.\n" + + "We are testing to see if drag to rotate stays disabled" + + "after disabling and re-enabling the chase camera.\n" + + "For this test, use the SPACE key to disable and re-enable the camera."); + hudText.setLocalTranslation(0, yTop - (hudText.getLineHeight() * 3), 0); + guiNode.attachChild(hudText); + + // Show camera status + cameraStatus = new BitmapText(guiFont); + cameraStatus.setSize(size); + cameraStatus.setColor(ColorRGBA.Blue); + cameraStatus.setLocalTranslation(0, yTop - cameraStatus.getLineHeight(), 0); // position + guiNode.attachChild(cameraStatus); + + // Register inputs + registerInput(); + } + + @Override + public void simpleUpdate(float tpf) { + // Update chaseCam status + cameraStatus.setText("chaseCam " + (chaseCam.isEnabled() ? "enabled" : "disabled")); + } + + private void registerInput() { + inputManager.addMapping("toggleCamera", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this, "toggleCamera"); + } + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggleCamera") && keyPressed) { + // Toggle chase camera + chaseCam.setEnabled(!chaseCam.isEnabled()); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/input/TestJoystick.java b/jme3-examples/src/main/java/jme3test/input/TestJoystick.java new file mode 100644 index 0000000000..3f25532d50 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/TestJoystick.java @@ -0,0 +1,493 @@ +package jme3test.input; + +import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; +import com.jme3.font.BitmapText; +import com.jme3.input.Joystick; +import com.jme3.input.JoystickAxis; +import com.jme3.input.JoystickButton; +import com.jme3.input.MouseInput; +import com.jme3.input.RawInputListener; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.input.event.JoyAxisEvent; +import com.jme3.input.event.JoyButtonEvent; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.input.event.MouseButtonEvent; +import com.jme3.input.event.MouseMotionEvent; +import com.jme3.input.event.TouchEvent; +import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Ray; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Quad; +import com.jme3.system.AppSettings; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; + +public class TestJoystick extends SimpleApplication { + + private Joystick viewedJoystick; + private GamepadView gamepad; + private Node joystickInfo; + private float yInfo = 0; + private JoystickButton lastButton; + + public static void main(String[] args){ + TestJoystick app = new TestJoystick(); + AppSettings settings = new AppSettings(true); + settings.setUseJoysticks(true); + app.setSettings(settings); + app.start(); + } + + @Override + public void simpleInitApp() { + getFlyByCamera().setEnabled(false); + + Joystick[] joysticks = inputManager.getJoysticks(); + if (joysticks == null) + throw new IllegalStateException("Cannot find any joysticks!"); + + try { + PrintWriter out = new PrintWriter( new FileWriter( "joysticks-" + System.currentTimeMillis() + ".txt" ) ); + dumpJoysticks( joysticks, out ); + out.close(); + } catch( IOException e ) { + throw new RuntimeException( "Error writing joystick dump", e ); + } + + + int gamepadSize = cam.getHeight() / 2; + float scale = gamepadSize / 512.0f; + gamepad = new GamepadView(); + gamepad.setLocalTranslation( cam.getWidth() - gamepadSize - (scale * 20), 0, 0 ); + gamepad.setLocalScale( scale, scale, scale ); + guiNode.attachChild(gamepad); + + joystickInfo = new Node( "joystickInfo" ); + joystickInfo.setLocalTranslation( 0, cam.getHeight(), 0 ); + guiNode.attachChild( joystickInfo ); + + // Add a raw listener because it's easier to get all joystick events + // this way. + inputManager.addRawInputListener( new JoystickEventListener() ); + + // add action listener for mouse click + // to all easier custom mapping + inputManager.addMapping("mouseClick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(isPressed){ + pickGamePad(getInputManager().getCursorPosition()); + } + } + }, "mouseClick"); + } + + protected void dumpJoysticks( Joystick[] joysticks, PrintWriter out ) { + for( Joystick j : joysticks ) { + out.println( "Joystick[" + j.getJoyId() + "]:" + j.getName() ); + out.println( " buttons:" + j.getButtonCount() ); + for( JoystickButton b : j.getButtons() ) { + out.println( " " + b ); + } + + out.println( " axes:" + j.getAxisCount() ); + for( JoystickAxis axis : j.getAxes() ) { + out.println( " " + axis ); + } + } + } + + protected void addInfo( String info, int column ) { + + BitmapText t = new BitmapText(guiFont); + t.setText( info ); + t.setLocalTranslation( column * 200, yInfo, 0 ); + joystickInfo.attachChild(t); + yInfo -= t.getHeight(); + } + + protected void setViewedJoystick( Joystick stick ) { + if( this.viewedJoystick == stick ) + return; + + if( this.viewedJoystick != null ) { + joystickInfo.detachAllChildren(); + } + + this.viewedJoystick = stick; + + if( this.viewedJoystick != null ) { + // Draw the hud + yInfo = 0; + + addInfo( "Joystick:\"" + stick.getName() + "\" id:" + stick.getJoyId(), 0 ); + + yInfo -= 5; + + float ySave = yInfo; + + // Column one for the buttons + addInfo( "Buttons:", 0 ); + for( JoystickButton b : stick.getButtons() ) { + addInfo( " '" + b.getName() + "' id:'" + b.getLogicalId() + "'", 0 ); + } + yInfo = ySave; + + // Column two for the axes + addInfo( "Axes:", 1 ); + for( JoystickAxis a : stick.getAxes() ) { + addInfo( " '" + a.getName() + "' id:'" + a.getLogicalId() + "' analog:" + a.isAnalog(), 1 ); + } + + } + } + + /** + * Easier to watch for all button and axis events with a raw input listener. + */ + protected class JoystickEventListener implements RawInputListener { + + final private Map lastValues = new HashMap<>(); + + @Override + public void onJoyAxisEvent(JoyAxisEvent evt) { + Float last = lastValues.remove(evt.getAxis()); + float value = evt.getValue(); + + // Check the axis dead zone. InputManager normally does this + // by default but not for raw events like we get here. + float effectiveDeadZone = Math.max(inputManager.getAxisDeadZone(), evt.getAxis().getDeadZone()); + if( Math.abs(value) < effectiveDeadZone ) { + if( last == null ) { + // Just skip the event + return; + } + // Else set the value to 0 + lastValues.remove(evt.getAxis()); + value = 0; + } + setViewedJoystick( evt.getAxis().getJoystick() ); + gamepad.setAxisValue( evt.getAxis(), value ); + if( value != 0 ) { + lastValues.put(evt.getAxis(), value); + } + } + + @Override + public void onJoyButtonEvent(JoyButtonEvent evt) { + setViewedJoystick( evt.getButton().getJoystick() ); + gamepad.setButtonValue( evt.getButton(), evt.isPressed() ); + } + + @Override + public void beginInput() {} + @Override + public void endInput() {} + @Override + public void onMouseMotionEvent(MouseMotionEvent evt) {} + @Override + public void onMouseButtonEvent(MouseButtonEvent evt) {} + @Override + public void onKeyEvent(KeyInputEvent evt) {} + @Override + public void onTouchEvent(TouchEvent evt) {} + } + + protected class GamepadView extends Node { + + private float xAxis = 0; + private float yAxis = 0; + private float zAxis = 0; + private float zRotation = 0; + + private float lastPovX = 0; + private float lastPovY = 0; + + final private Geometry leftStick; + final private Geometry rightStick; + + final private Map buttons = new HashMap<>(); + + public GamepadView() { + super( "gamepad" ); + + // Sizes naturally for the texture size. All positions will + // be in that space because it's easier. + int size = 512; + + Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-buttons.png" ) ); + m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); + Geometry buttonPanel = new Geometry( "buttons", new Quad(size, size) ); + buttonPanel.setLocalTranslation( 0, 0, -1 ); + buttonPanel.setMaterial(m); + attachChild(buttonPanel); + + m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-frame.png" ) ); + m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); + Geometry frame = new Geometry( "frame", new Quad(size, size) ); + frame.setMaterial(m); + attachChild(frame); + + m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + m.setTexture( "ColorMap", assetManager.loadTexture( "Interface/Joystick/gamepad-stick.png" ) ); + m.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); + leftStick = new Geometry( "leftStick", new Quad(64, 64) ); + leftStick.setMaterial(m); + attachChild(leftStick); + rightStick = new Geometry( "rightStick", new Quad(64, 64) ); + rightStick.setMaterial(m); + attachChild(rightStick); + + // A "standard" mapping... fits a majority of my game pads + addButton( JoystickButton.BUTTON_0, 371, 512 - 176, 42, 42 ); + addButton( JoystickButton.BUTTON_1, 407, 512 - 212, 42, 42 ); + addButton( JoystickButton.BUTTON_2, 371, 512 - 248, 42, 42 ); + addButton( JoystickButton.BUTTON_3, 334, 512 - 212, 42, 42 ); + + // Front buttons Some of these have the top ones and the bottoms ones flipped. + addButton( JoystickButton.BUTTON_4, 67, 512 - 111, 95, 21 ); + addButton( JoystickButton.BUTTON_5, 348, 512 - 111, 95, 21 ); + addButton( JoystickButton.BUTTON_6, 67, 512 - 89, 95, 21 ); + addButton( JoystickButton.BUTTON_7, 348, 512 - 89, 95, 21 ); + + // Select and start buttons + addButton( JoystickButton.BUTTON_8, 206, 512 - 198, 48, 30 ); + addButton( JoystickButton.BUTTON_9, 262, 512 - 198, 48, 30 ); + + // Joystick push buttons + addButton( JoystickButton.BUTTON_10, 147, 512 - 300, 75, 70 ); + addButton( JoystickButton.BUTTON_11, 285, 512 - 300, 75, 70 ); + + // Fake button highlights for the POV axes + // + // +Y + // -X +X + // -Y + // + addButton( "POV +Y", 96, 512 - 174, 40, 38 ); + addButton( "POV +X", 128, 512 - 208, 40, 38 ); + addButton( "POV -Y", 96, 512 - 239, 40, 38 ); + addButton( "POV -X", 65, 512 - 208, 40, 38 ); + + resetPositions(); + } + + private void addButton( String name, float x, float y, float width, float height ) { + ButtonView b = new ButtonView(name, x, y, width, height); + attachChild(b); + buttons.put(name, b); + } + + public void setAxisValue( JoystickAxis axis, float value ) { + + System.out.println( "Axis:" + axis.getName() + "(id:" + axis.getLogicalId() + ")=" + value ); + if( axis == axis.getJoystick().getXAxis() ) { + setXAxis(value); + } else if( axis == axis.getJoystick().getYAxis() ) { + setYAxis(-value); + } else if( axis == axis.getJoystick().getAxis(JoystickAxis.Z_AXIS) ) { + // Note: in the above condition, we could check the axis name, but + // I have at least one joystick that reports 2 "Z Axis" axes. + // In this particular case, the first one is the right one so + // a name based lookup will find the proper one. It's a problem + // because the erroneous axis sends a constant stream of values. + setZAxis(value); + } else if( axis == axis.getJoystick().getAxis(JoystickAxis.Z_ROTATION) ) { + setZRotation(-value); + } else if( axis == axis.getJoystick().getAxis(JoystickAxis.LEFT_TRIGGER) ) { + if( axis.getJoystick().getButton(JoystickButton.BUTTON_6) == null ) { + // left/right triggers sometimes only show up as axes + boolean pressed = value != 0; + if( pressed != buttons.get(JoystickButton.BUTTON_6).isDown() ) { + setButtonValue(JoystickButton.BUTTON_6, pressed); + } + } + } else if( axis == axis.getJoystick().getAxis(JoystickAxis.RIGHT_TRIGGER) ) { + if( axis.getJoystick().getButton(JoystickButton.BUTTON_7) == null ) { + // left/right triggers sometimes only show up as axes + boolean pressed = value != 0; + if( pressed != buttons.get(JoystickButton.BUTTON_7).isDown() ) { + setButtonValue(JoystickButton.BUTTON_7, pressed); + } + } + } else if( axis == axis.getJoystick().getPovXAxis() ) { + if( lastPovX < 0 ) { + setButtonValue( "POV -X", false ); + } else if( lastPovX > 0 ) { + setButtonValue( "POV +X", false ); + } + if( value < 0 ) { + setButtonValue( "POV -X", true ); + } else if( value > 0 ) { + setButtonValue( "POV +X", true ); + } + lastPovX = value; + } else if( axis == axis.getJoystick().getPovYAxis() ) { + if( lastPovY < 0 ) { + setButtonValue( "POV -Y", false ); + } else if( lastPovY > 0 ) { + setButtonValue( "POV +Y", false ); + } + if( value < 0 ) { + setButtonValue( "POV -Y", true ); + } else if( value > 0 ) { + setButtonValue( "POV +Y", true ); + } + lastPovY = value; + } + } + + public void setButtonValue( JoystickButton button, boolean isPressed ) { + System.out.println( "Button:" + button.getName() + "=" + (isPressed ? "Down" : "Up") ); + setButtonValue( button.getLogicalId(), isPressed ); + lastButton = button; + } + + protected void setButtonValue( String name, boolean isPressed ) { + ButtonView view = buttons.get(name); + if( view != null ) { + if( isPressed ) { + view.down(); + } else { + view.up(); + } + } + } + + public void setXAxis( float f ) { + xAxis = f; + resetPositions(); + } + + public void setYAxis( float f ) { + yAxis = f; + resetPositions(); + } + + public void setZAxis( float f ) { + zAxis = f; + resetPositions(); + } + + public void setZRotation( float f ) { + zRotation = f; + resetPositions(); + } + + private void resetPositions() { + + float xBase = 155; + float yBase = 212; + + Vector2f dir = new Vector2f(xAxis, yAxis); + float length = Math.min(1, dir.length()); + dir.normalizeLocal(); + + float angle = dir.getAngle(); + float x = FastMath.cos(angle) * length * 10; + float y = FastMath.sin(angle) * length * 10; + leftStick.setLocalTranslation( xBase + x, yBase + y, 0 ); + + + xBase = 291; + dir = new Vector2f(zAxis, zRotation); + length = Math.min(1, dir.length()); + dir.normalizeLocal(); + + angle = dir.getAngle(); + x = FastMath.cos(angle) * length * 10; + y = FastMath.sin(angle) * length * 10; + rightStick.setLocalTranslation( xBase + x, yBase + y, 0 ); + } + } + + protected class ButtonView extends Node { + + private int state = 0; + final private Material material; + final private ColorRGBA hilite = new ColorRGBA( 0.0f, 0.75f, 0.75f, 0.5f ); + + public ButtonView( String name, float x, float y, float width, float height ) { + super( "Button:" + name ); + setLocalTranslation( x, y, -0.5f ); + + material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setColor( "Color", hilite ); + material.getAdditionalRenderState().setBlendMode( BlendMode.Alpha ); + + Geometry g = new Geometry( "highlight", new Quad(width, height) ); + g.setMaterial(material); + attachChild(g); + + resetState(); + } + + private void resetState() { + if( state <= 0 ) { + setCullHint( CullHint.Always ); + } else { + setCullHint( CullHint.Dynamic ); + } + + System.out.println( getName() + " state:" + state ); + } + + public boolean isDown() { + return state > 0; + } + + public void down() { + state++; + resetState(); + } + + public void up() { + state--; + resetState(); + } + } + + private void pickGamePad(Vector2f mouseLoc){ + if (lastButton != null) { + CollisionResults results = pick(cam, mouseLoc, gamepad); + for (CollisionResult cr : results) { + Node n = cr.getGeometry().getParent(); + if (n != null && (n instanceof ButtonView)) { + String b = n.getName().substring("Button:".length()); + String name = lastButton.getJoystick().getName().replaceAll(" ", "\\\\ "); + String id = lastButton.getLogicalId().replaceAll(" ", "\\\\ "); + System.out.println(name + "." + id + "=" + b); + return; + } + } + } + } + + private static CollisionResults pick(Camera cam, Vector2f mouseLoc, Node node) { + CollisionResults results = new CollisionResults(); + Ray ray = new Ray(); + Vector3f pos = new Vector3f(mouseLoc.x, mouseLoc.y, -1); + Vector3f dir = new Vector3f(mouseLoc.x, mouseLoc.y, 1); + dir.subtractLocal(pos).normalizeLocal(); + ray.setOrigin(pos); + ray.setDirection(dir); + node.collideWith(ray, results); + return results; + } +} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java b/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java new file mode 100644 index 0000000000..2ad86bef36 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMove.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.input.combomoves; + +import java.util.ArrayList; +import java.util.List; + +public class ComboMove { + + public static class ComboMoveState { + + final private String[] pressedMappings; + final private String[] unpressedMappings; + final private float timeElapsed; + + public ComboMoveState(String[] pressedMappings, String[] unpressedMappings, float timeElapsed) { + this.pressedMappings = pressedMappings; + this.unpressedMappings = unpressedMappings; + this.timeElapsed = timeElapsed; + } + + public String[] getUnpressedMappings() { + return unpressedMappings; + } + + public String[] getPressedMappings() { + return pressedMappings; + } + + public float getTimeElapsed() { + return timeElapsed; + } + + } + + final private String moveName; + final private List states = new ArrayList<>(); + private boolean useFinalState = true; + private float priority = 1; + private float castTime = 0.8f; + + private transient String[] pressed, unpressed; + private transient float timeElapsed; + + public ComboMove(String moveName){ + this.moveName = moveName; + } + + public float getPriority() { + return priority; + } + + public void setPriority(float priority) { + this.priority = priority; + } + + public float getCastTime() { + return castTime; + } + + public void setCastTime(float castTime) { + this.castTime = castTime; + } + + public boolean useFinalState() { + return useFinalState; + } + + public void setUseFinalState(boolean useFinalState) { + this.useFinalState = useFinalState; + } + + public ComboMove press(String ... pressedMappings){ + this.pressed = pressedMappings; + return this; + } + + public ComboMove notPress(String ... unpressedMappings){ + this.unpressed = unpressedMappings; + return this; + } + + public ComboMove timeElapsed(float time){ + this.timeElapsed = time; + return this; + } + + public void done(){ + if (pressed == null) + pressed = new String[0]; + + if (unpressed == null) + unpressed = new String[0]; + + states.add(new ComboMoveState(pressed, unpressed, timeElapsed)); + pressed = null; + unpressed = null; + timeElapsed = -1; + } + + public ComboMoveState getState(int num){ + return states.get(num); + } + + public int getNumStates(){ + return states.size(); + } + + public String getMoveName() { + return moveName; + } + +} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java b/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java new file mode 100644 index 0000000000..1e1049ab89 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/combomoves/ComboMoveExecution.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.input.combomoves; + +import java.util.Arrays; +import java.util.HashSet; +import jme3test.input.combomoves.ComboMove.ComboMoveState; + +public class ComboMoveExecution { + + private static final float TIME_LIMIT = 0.3f; + + final private ComboMove moveDef; + private int state; + private float moveTime; + private boolean finalState = false; + + private String debugString = ""; // for debug only + + public ComboMoveExecution(ComboMove move){ + moveDef = move; + } + + private boolean isStateSatisfied(HashSet pressedMappings, float time, + ComboMoveState state){ + + if (state.getTimeElapsed() != -1f){ + // check if an appropriate amount of time has passed + // if the state requires it + if (moveTime + state.getTimeElapsed() >= time){ + return false; + } + } + for (String mapping : state.getPressedMappings()){ + if (!pressedMappings.contains(mapping)) + return false; + } + for (String mapping : state.getUnpressedMappings()){ + if (pressedMappings.contains(mapping)) + return false; + } + return true; + } + + public String getDebugString(){ + return debugString; + } + + public void updateExpiration(float time){ + if (!finalState && moveTime > 0 && moveTime + TIME_LIMIT < time){ + state = 0; + moveTime = 0; + finalState = false; + + // reset debug string. + debugString = ""; + } + } + + /** + * Check if move needs to be executed. + * @param pressedMappings Which mappings are currently pressed + * @param time Current time since start of app + * @return True if move needs to be executed. + */ + public boolean updateState(HashSet pressedMappings, float time){ + ComboMoveState currentState = moveDef.getState(state); + if (isStateSatisfied(pressedMappings, time, currentState)){ + state ++; + moveTime = time; + + if (state >= moveDef.getNumStates()){ + finalState = false; + state = 0; + + moveTime = time+0.5f; // this is for the reset of the debug string only. + debugString += ", -CASTING " + moveDef.getMoveName().toUpperCase() + "-"; + return true; + } + + // the following for debug only. + if (currentState.getPressedMappings().length > 0){ + if (!debugString.equals("")) + debugString += ", "; + + debugString += Arrays.toString(currentState.getPressedMappings()).replace(", ", "+"); + } + + if (moveDef.useFinalState() && state == moveDef.getNumStates() - 1){ + finalState = true; + } + } + return false; + } + +} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java b/jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java new file mode 100644 index 0000000000..f5723434f0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/combomoves/TestComboMoves.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.input.combomoves; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.math.ColorRGBA; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +public class TestComboMoves extends SimpleApplication implements ActionListener { + + final private HashSet pressedMappings = new HashSet<>(); + + private ComboMove fireball; + private ComboMoveExecution fireballExec; + private BitmapText fireballText; + + private ComboMove shuriken; + private ComboMoveExecution shurikenExec; + private BitmapText shurikenText; + + private ComboMove jab; + private ComboMoveExecution jabExec; + private BitmapText jabText; + + private ComboMove punch; + private ComboMoveExecution punchExec; + private BitmapText punchText; + + private ComboMove currentMove = null; + private float currentMoveCastTime = 0; + private float time = 0; + + public static void main(String[] args){ + TestComboMoves app = new TestComboMoves(); + app.start(); + } + + @Override + public void simpleInitApp() { + setDisplayFps(false); + setDisplayStatView(false); + + // Create debug text + BitmapText helpText = new BitmapText(guiFont); + helpText.setLocalTranslation(0, settings.getHeight(), 0); + helpText.setText("Moves:\n" + + "Fireball: Down, Down+Right, Right\n"+ + "Shuriken: Left, Down, Attack1(Z)\n"+ + "Jab: Attack1(Z)\n"+ + "Punch: Attack1(Z), Attack1(Z)\n"); + guiNode.attachChild(helpText); + + fireballText = new BitmapText(guiFont); + fireballText.setColor(ColorRGBA.Orange); + fireballText.setLocalTranslation(0, fireballText.getLineHeight(), 0); + guiNode.attachChild(fireballText); + + shurikenText = new BitmapText(guiFont); + shurikenText.setColor(ColorRGBA.Cyan); + shurikenText.setLocalTranslation(0, shurikenText.getLineHeight()*2f, 0); + guiNode.attachChild(shurikenText); + + jabText = new BitmapText(guiFont); + jabText.setColor(ColorRGBA.Red); + jabText.setLocalTranslation(0, jabText.getLineHeight()*3f, 0); + guiNode.attachChild(jabText); + + punchText = new BitmapText(guiFont); + punchText.setColor(ColorRGBA.Green); + punchText.setLocalTranslation(0, punchText.getLineHeight()*4f, 0); + guiNode.attachChild(punchText); + + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("Attack1", new KeyTrigger(KeyInput.KEY_Z)); + inputManager.addListener(this, "Left", "Right", "Up", "Down", "Attack1"); + + fireball = new ComboMove("Fireball"); + fireball.press("Down").notPress("Right").done(); + fireball.press("Right", "Down").done(); + fireball.press("Right").notPress("Down").done(); + fireball.notPress("Right", "Down").done(); + fireball.setUseFinalState(false); // no waiting on final state + + shuriken = new ComboMove("Shuriken"); + shuriken.press("Left").notPress("Down", "Attack1").done(); + shuriken.press("Down").notPress("Attack1").timeElapsed(0.11f).done(); + shuriken.press("Attack1").notPress("Left").timeElapsed(0.11f).done(); + shuriken.notPress("Left", "Down", "Attack1").done(); + + jab = new ComboMove("Jab"); + jab.setPriority(0.5f); // make jab less important than other moves + jab.press("Attack1").done(); + + punch = new ComboMove("Punch"); + punch.press("Attack1").done(); + punch.notPress("Attack1").done(); + punch.press("Attack1").done(); + + fireballExec = new ComboMoveExecution(fireball); + shurikenExec = new ComboMoveExecution(shuriken); + jabExec = new ComboMoveExecution(jab); + punchExec = new ComboMoveExecution(punch); + } + + @Override + public void simpleUpdate(float tpf){ + time += tpf; + + // check every frame if any executions are expired + shurikenExec.updateExpiration(time); + shurikenText.setText("Shuriken Exec: " + shurikenExec.getDebugString()); + + fireballExec.updateExpiration(time); + fireballText.setText("Fireball Exec: " + fireballExec.getDebugString()); + + jabExec.updateExpiration(time); + jabText.setText("Jab Exec: " + jabExec.getDebugString()); + + punchExec.updateExpiration(time); + punchText.setText("Punch Exec: " + punchExec.getDebugString()); + + if (currentMove != null){ + currentMoveCastTime -= tpf; + if (currentMoveCastTime <= 0){ + System.out.println("DONE CASTING " + currentMove.getMoveName()); + currentMoveCastTime = 0; + currentMove = null; + } + } + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed){ + pressedMappings.add(name); + }else{ + pressedMappings.remove(name); + } + + // the pressed mappings was changed. update combo executions + List invokedMoves = new ArrayList<>(); + if (shurikenExec.updateState(pressedMappings, time)){ + invokedMoves.add(shuriken); + } + + if (fireballExec.updateState(pressedMappings, time)){ + invokedMoves.add(fireball); + } + + if (jabExec.updateState(pressedMappings, time)){ + invokedMoves.add(jab); + } + + if (punchExec.updateState(pressedMappings, time)){ + invokedMoves.add(punch); + } + + if (invokedMoves.size() > 0){ + // Choose the move with the highest priority. + float priority = 0; + ComboMove toExec = null; + for (ComboMove move : invokedMoves){ + if (move.getPriority() > priority){ + priority = move.getPriority(); + toExec = move; + } + } + if (currentMove != null && currentMove.getPriority() > toExec.getPriority()){ + return; + } + + currentMove = toExec; + currentMoveCastTime = currentMove.getCastTime(); + //System.out.println("CASTING " + currentMove.getMoveName()); + } + } + +} diff --git a/jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java b/jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java new file mode 100644 index 0000000000..287475f74e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/combomoves/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for "combos" (user-input sequences) + */ +package jme3test.input.combomoves; diff --git a/jme3-examples/src/main/java/jme3test/input/package-info.java b/jme3-examples/src/main/java/jme3test/input/package-info.java new file mode 100644 index 0000000000..4fa1b11446 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/input/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for user input + */ +package jme3test.input; diff --git a/jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java b/jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java new file mode 100644 index 0000000000..9181ca00b0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/ShadowTestUIManager.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.asset.AssetManager; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.input.InputManager; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Node; +import com.jme3.shadow.AbstractShadowFilter; +import com.jme3.shadow.AbstractShadowRenderer; +import com.jme3.shadow.CompareMode; +import com.jme3.shadow.EdgeFilteringMode; + +/** + * + * @author Nehon + */ +public class ShadowTestUIManager implements ActionListener { + + final private BitmapText shadowTypeText; + final private BitmapText shadowCompareText; + final private BitmapText shadowFilterText; + final private BitmapText shadowIntensityText; + private final static String TYPE_TEXT = "(Space) Shadow type : "; + private final static String COMPARE_TEXT = "(enter) Shadow compare "; + private final static String FILTERING_TEXT = "(f) Edge filtering : "; + private final static String INTENSITY_TEXT = "(t:up, g:down) Shadow intensity : "; + private boolean hardwareShadows = true; + final private AbstractShadowRenderer plsr; + final private AbstractShadowFilter plsf; + final private ViewPort viewPort; + private int filteringIndex = 0; + private int renderModeIndex = 0; + + + public ShadowTestUIManager(AssetManager assetManager,AbstractShadowRenderer plsr, AbstractShadowFilter plsf, + Node guiNode, InputManager inputManager, ViewPort viewPort) { + this.plsr = plsr; + this.plsf = plsf; + this.viewPort = viewPort; + BitmapFont guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + shadowTypeText = createText(guiFont); + shadowCompareText = createText(guiFont); + shadowFilterText = createText(guiFont); + shadowIntensityText = createText(guiFont); + + shadowTypeText.setText(TYPE_TEXT + "Processor"); + shadowCompareText.setText(COMPARE_TEXT + (hardwareShadows ? "Hardware" : "Software")); + shadowFilterText.setText(FILTERING_TEXT + plsr.getEdgeFilteringMode().toString()); + shadowIntensityText.setText(INTENSITY_TEXT + plsr.getShadowIntensity()); + + shadowTypeText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 20, 0); + shadowCompareText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 40, 0); + shadowFilterText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 60, 0); + shadowIntensityText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 80, 0); + + guiNode.attachChild(shadowTypeText); + guiNode.attachChild(shadowCompareText); + guiNode.attachChild(shadowFilterText); + guiNode.attachChild(shadowIntensityText); + + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("changeFiltering", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addMapping("ShadowUp", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addMapping("ShadowDown", new KeyTrigger(KeyInput.KEY_G)); + inputManager.addMapping("ThicknessUp", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("ThicknessDown", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("toggleHW", new KeyTrigger(KeyInput.KEY_RETURN)); + + + inputManager.addListener(this, "toggleHW", "toggle", "ShadowUp", "ShadowDown", "ThicknessUp", "ThicknessDown", "changeFiltering"); + + } + + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggle") && keyPressed) { + renderModeIndex += 1; + renderModeIndex %= 3; + + switch (renderModeIndex) { + case 0: + viewPort.addProcessor(plsr); + shadowTypeText.setText(TYPE_TEXT + "Processor"); + break; + case 1: + viewPort.removeProcessor(plsr); + plsf.setEnabled(true); + shadowTypeText.setText(TYPE_TEXT + "Filter"); + break; + case 2: + plsf.setEnabled(false); + shadowTypeText.setText(TYPE_TEXT + "None"); + break; + } + + + + } else if (name.equals("toggleHW") && keyPressed) { + hardwareShadows = !hardwareShadows; + plsr.setShadowCompareMode(hardwareShadows ? CompareMode.Hardware : CompareMode.Software); + plsf.setShadowCompareMode(hardwareShadows ? CompareMode.Hardware : CompareMode.Software); + + shadowCompareText.setText(COMPARE_TEXT + (hardwareShadows ? "Hardware" : "Software")); + } + + + if (name.equals("changeFiltering") && keyPressed) { + filteringIndex = plsr.getEdgeFilteringMode().ordinal(); + filteringIndex = (filteringIndex + 1) % EdgeFilteringMode.values().length; + EdgeFilteringMode m = EdgeFilteringMode.values()[filteringIndex]; + plsr.setEdgeFilteringMode(m); + plsf.setEdgeFilteringMode(m); + shadowFilterText.setText(FILTERING_TEXT + m.toString()); + } + + if (name.equals("ShadowUp") && keyPressed) { + plsr.setShadowIntensity(plsr.getShadowIntensity() + 0.1f); + plsf.setShadowIntensity(plsf.getShadowIntensity() + 0.1f); + + shadowIntensityText.setText(INTENSITY_TEXT + plsr.getShadowIntensity()); + } + if (name.equals("ShadowDown") && keyPressed) { + plsr.setShadowIntensity(plsr.getShadowIntensity() - 0.1f); + plsf.setShadowIntensity(plsf.getShadowIntensity() - 0.1f); + shadowIntensityText.setText(INTENSITY_TEXT + plsr.getShadowIntensity()); + } + if (name.equals("ThicknessUp") && keyPressed) { + plsr.setEdgesThickness(plsr.getEdgesThickness() + 1); + plsf.setEdgesThickness(plsf.getEdgesThickness() + 1); + System.out.println("Shadow thickness : " + plsr.getEdgesThickness()); + } + if (name.equals("ThicknessDown") && keyPressed) { + plsr.setEdgesThickness(plsr.getEdgesThickness() - 1); + plsf.setEdgesThickness(plsf.getEdgesThickness() - 1); + System.out.println("Shadow thickness : " + plsr.getEdgesThickness()); + } + + } + + private BitmapText createText(BitmapFont guiFont) { + BitmapText t = new BitmapText(guiFont); + t.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f); + return t; + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestColorApp.java b/jme3-examples/src/main/java/jme3test/light/TestColorApp.java new file mode 100644 index 0000000000..3db910498a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestColorApp.java @@ -0,0 +1,88 @@ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.light.DirectionalLight; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.shadow.DirectionalLightShadowRenderer; + +public class TestColorApp extends SimpleApplication { + public static void main(String[] args) { + TestColorApp app = new TestColorApp(); + app.start(); + } + + @Override + public void simpleInitApp() { + // Lights + DirectionalLight sun = new DirectionalLight(); + Vector3f sunPosition = new Vector3f(1, -1, 1); + sun.setDirection(sunPosition); + sun.setColor(new ColorRGBA(1f,1f,1f,1f)); + rootNode.addLight(sun); + + //DirectionalLightShadowFilter sun_renderer = new DirectionalLightShadowFilter(assetManager, 2048, 4); + DirectionalLightShadowRenderer sun_renderer = new DirectionalLightShadowRenderer(assetManager, 2048, 1); + sun_renderer.setLight(sun); + viewPort.addProcessor(sun_renderer); + +// FilterPostProcessor fpp = new FilterPostProcessor(assetManager); +// fpp.addFilter(sun_renderer); +// viewPort.addProcessor(fpp); + + rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + + // Camera + viewPort.setBackgroundColor(new ColorRGBA(.6f, .6f, .6f, 1f)); + ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); + + + // Objects + // Ground Object + final Geometry groundBoxWhite = new Geometry("Box", new Box(7.5f, 7.5f, .25f)); + float[] f = {-FastMath.PI / 2, 3 * FastMath.PI / 2, 0f}; + groundBoxWhite.setLocalRotation(new Quaternion(f)); + groundBoxWhite.move(7.5f, -.75f, 7.5f); + final Material groundMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + groundMaterial.setColor("Diffuse", new ColorRGBA(.9f, .9f, .9f, .9f)); + groundBoxWhite.setMaterial(groundMaterial); + groundBoxWhite.addControl(chaseCam); + rootNode.attachChild(groundBoxWhite); + + // Planter + Geometry planterBox = new Geometry("Box", new Box(.5f, .5f, .5f)); + final Material planterMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + planterMaterial.setTexture("DiffuseMap", assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg")); + planterBox.setMaterial(groundMaterial); + planterBox.setLocalTranslation(10, 0, 9); + rootNode.attachChild(planterBox); + + // Action! + inputManager.addMapping("on", new KeyTrigger(KeyInput.KEY_Z)); + inputManager.addMapping("off", new KeyTrigger(KeyInput.KEY_X)); + + inputManager.addListener(new AnalogListener() { + @Override + public void onAnalog(String s, float v, float v1) { + if (s.equals("on")) { + groundBoxWhite.setMaterial(planterMaterial); + } + if (s.equals("off")) { + groundBoxWhite.setMaterial(groundMaterial); + } + } + }, "on", "off"); + + inputEnabled = true; + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java b/jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java new file mode 100644 index 0000000000..0f2605839c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestConeVSFrustum.java @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseAxisTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.renderer.Camera; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.control.LightControl; +import com.jme3.scene.debug.Grid; +import com.jme3.scene.debug.WireFrustum; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Cylinder; +import com.jme3.shadow.ShadowUtil; +import com.jme3.texture.Texture; +import com.jme3.util.TempVars; + +public class TestConeVSFrustum extends SimpleApplication { + + public static void main(String[] args) { + TestConeVSFrustum app = new TestConeVSFrustum(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + frustumCam = cam.clone(); + frustumCam.setFrustumFar(25); + Vector3f[] points = new Vector3f[8]; + for (int i = 0; i < 8; i++) { + points[i] = new Vector3f(); + } + ShadowUtil.updateFrustumPoints2(frustumCam, points); + WireFrustum frustumShape = new WireFrustum(points); + Geometry frustum = new Geometry("frustum", frustumShape); + frustum.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + rootNode.attachChild(frustum); + + rootNode.addLight(new DirectionalLight()); + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.2f)); + rootNode.addLight(al); + + Grid grid = new Grid(50, 50, 5); + Geometry gridGeom = new Geometry("grid", grid); + gridGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + gridGeom.getMaterial().setColor("Color", ColorRGBA.Gray); + rootNode.attachChild(gridGeom); + gridGeom.setLocalTranslation(-125, -25, -125); + +// flyCam.setMoveSpeed(30); +// flyCam.setDragToRotate(true); +// cam.setLocation(new Vector3f(56.182674f, 19.037334f, 7.093905f)); +// cam.setRotation(new Quaternion(0.0816657f, -0.82228005f, 0.12213967f, 0.5497892f)); + spotLight = new SpotLight(); + spotLight.setSpotRange(25); + spotLight.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); + + float radius = FastMath.tan(spotLight.getSpotOuterAngle()) * spotLight.getSpotRange(); + + Cylinder cylinder = new Cylinder(5, 16, 0.01f, radius, spotLight.getSpotRange(), true, false); + geom = new Geometry("light", cylinder); + geom.setMaterial(new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md")); + geom.getMaterial().setColor("Diffuse", ColorRGBA.White); + geom.getMaterial().setColor("Ambient", ColorRGBA.DarkGray); + geom.getMaterial().setBoolean("UseMaterialColors", true); + + final Node ln = new Node("lb"); + LightControl lightControl = new LightControl(spotLight); + ln.addControl(lightControl); + ln.attachChild(geom); + + geom.setLocalTranslation(0, -spotLight.getSpotRange() / 2f, 0); + geom.rotate(-FastMath.HALF_PI, 0, 0); + rootNode.attachChild(ln); +// ln.rotate(FastMath.QUARTER_PI, 0, 0); + // ln.setLocalTranslation(0, 0, -16); + + inputManager.addMapping("click", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + inputManager.addMapping("shift", new KeyTrigger(KeyInput.KEY_LSHIFT), new KeyTrigger(KeyInput.KEY_RSHIFT)); + inputManager.addMapping("middleClick", new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); + inputManager.addMapping("up", new MouseAxisTrigger(MouseInput.AXIS_Y, false)); + inputManager.addMapping("down", new MouseAxisTrigger(MouseInput.AXIS_Y, true)); + inputManager.addMapping("left", new MouseAxisTrigger(MouseInput.AXIS_X, true)); + inputManager.addMapping("right", new MouseAxisTrigger(MouseInput.AXIS_X, false)); + + + final Node camTarget = new Node("CamTarget"); + rootNode.attachChild(camTarget); + + ChaseCameraAppState chaser = new ChaseCameraAppState(); + chaser.setTarget(camTarget); + chaser.setMaxDistance(150); + chaser.setDefaultDistance(70); + chaser.setDefaultHorizontalRotation(FastMath.HALF_PI); + chaser.setMinVerticalRotation(-FastMath.PI); + chaser.setMaxVerticalRotation(FastMath.PI * 2); + chaser.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + stateManager.attach(chaser); + flyCam.setEnabled(false); + + inputManager.addListener(new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + Spatial s = null; + float mult = 1; + if (moving) { + s = ln; + } + if (panning) { + s = camTarget; + mult = -1; + } + if ((moving || panning) && s!=null) { + if (shift) { + if (name.equals("left")) { + tmp.set(cam.getDirection()); + s.rotate(tmpQuat.fromAngleAxis(value, tmp)); + } + if (name.equals("right")) { + tmp.set(cam.getDirection()); + s.rotate(tmpQuat.fromAngleAxis(-value, tmp)); + } + } else { + value *= MOVE_SPEED * mult; + if (name.equals("up")) { + tmp.set(cam.getUp()).multLocal(value); + s.move(tmp); + } + if (name.equals("down")) { + tmp.set(cam.getUp()).multLocal(-value); + s.move(tmp); + } + if (name.equals("left")) { + tmp.set(cam.getLeft()).multLocal(value); + s.move(tmp); + } + if (name.equals("right")) { + tmp.set(cam.getLeft()).multLocal(-value); + s.move(tmp); + } + } + } + } + }, "up", "down", "left", "right"); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("click")) { + if (isPressed) { + moving = true; + } else { + moving = false; + } + } + if (name.equals("middleClick")) { + if (isPressed) { + panning = true; + } else { + panning = false; + } + } + if (name.equals("shift")) { + if (isPressed) { + shift = true; + } else { + shift = false; + } + } + } + }, "click", "middleClick", "shift"); + /* + * An unshaded textured cube. + * Uses texture from jme3-testdata library! + */ + Box boxMesh = new Box(1f, 1f, 1f); + Geometry boxGeo = new Geometry("A Textured Box", boxMesh); + Material boxMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + Texture monkeyTex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + boxMat.setTexture("ColorMap", monkeyTex); + boxGeo.setMaterial(boxMat); + System.err.println("light " + spotLight.getPosition()); + + } + + private final static float MOVE_SPEED = 60; + final private Vector3f tmp = new Vector3f(); + final private Quaternion tmpQuat = new Quaternion(); + private boolean moving, shift; + private boolean panning; + private Geometry geom; + private SpotLight spotLight; + private Camera frustumCam; + + @Override + public void simpleUpdate(float tpf) { + TempVars vars = TempVars.get(); + boolean intersect = spotLight.intersectsFrustum(frustumCam, vars); + + + if (intersect) { + geom.getMaterial().setColor("Diffuse", ColorRGBA.Green); + } else { + geom.getMaterial().setColor("Diffuse", ColorRGBA.White); + } + Vector3f farPoint = vars.vect1.set(spotLight.getPosition()).addLocal(vars.vect2.set(spotLight.getDirection()).multLocal(spotLight.getSpotRange())); + + //computing the radius of the base disc + float farRadius = (spotLight.getSpotRange() / FastMath.cos(spotLight.getSpotOuterAngle())) * FastMath.sin(spotLight.getSpotOuterAngle()); + //computing the projection direction : perpendicular to the light direction and coplanar with the direction vector and the normal vector + Vector3f perpDirection = vars.vect2.set(spotLight.getDirection()).crossLocal(frustumCam.getWorldPlane(3).getNormal()).normalizeLocal().crossLocal(spotLight.getDirection()); + //projecting the far point on the base disc perimeter + Vector3f projectedPoint = vars.vect3.set(farPoint).addLocal(perpDirection.multLocal(farRadius)); + + + vars.release(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java b/jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java new file mode 100644 index 0000000000..81a268fdf4 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.DirectionalLightShadowFilter; +import com.jme3.shadow.DirectionalLightShadowRenderer; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; +import com.jme3.util.TangentBinormalGenerator; + +public class TestDirectionalLightShadow extends SimpleApplication implements ActionListener, AnalogListener { + + public static final int SHADOWMAP_SIZE = 1024; + private DirectionalLightShadowRenderer dlsr; + private DirectionalLightShadowFilter dlsf; + private Geometry ground; + private Material matGroundU; + private Material matGroundL; + private AmbientLight al; + + public static void main(String[] args) { + TestDirectionalLightShadow app = new TestDirectionalLightShadow(); + app.start(); + } + private float frustumSize = 100; + + @Override + public void onAnalog(String name, float value, float tpf) { + if (cam.isParallelProjection()) { + // Instead of moving closer/farther to object, we zoom in/out. + if (name.equals("Size-")) { + frustumSize += 5f * tpf; + } else { + frustumSize -= 5f * tpf; + } + + float aspect = (float) cam.getWidth() / cam.getHeight(); + cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); + } + } + + public void loadScene() { + Spatial[] obj = new Spatial[2]; + // Setup first view + + + Material[] mat = new Material[2]; + mat[0] = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + mat[1] = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + mat[1].setBoolean("UseMaterialColors", true); + mat[1].setColor("Ambient", ColorRGBA.White); + mat[1].setColor("Diffuse", ColorRGBA.White.clone()); + + + obj[0] = new Geometry("sphere", new Sphere(30, 30, 2)); + obj[0].setShadowMode(ShadowMode.CastAndReceive); + obj[1] = new Geometry("cube", new Box(1.0f, 1.0f, 1.0f)); + obj[1].setShadowMode(ShadowMode.CastAndReceive); + TangentBinormalGenerator.generate(obj[1]); + TangentBinormalGenerator.generate(obj[0]); + + Spatial t = obj[0].clone(false); + t.setLocalScale(10f); + t.setMaterial(mat[1]); + rootNode.attachChild(t); + t.setLocalTranslation(0, 25, 0); + + for (int i = 0; i < 60; i++) { + t = obj[FastMath.nextRandomInt(0, obj.length - 1)].clone(false); + t.setLocalScale(FastMath.nextRandomFloat() * 10f); + t.setMaterial(mat[FastMath.nextRandomInt(0, mat.length - 1)]); + rootNode.attachChild(t); + t.setLocalTranslation(FastMath.nextRandomFloat() * 200f, FastMath.nextRandomFloat() * 30f + 20, 30f * (i + 2f)); + } + + Box b = new Box(1000, 2, 1000); + b.scaleTextureCoordinates(new Vector2f(10, 10)); + ground = new Geometry("soil", b); + ground.setLocalTranslation(0, 10, 550); + matGroundU = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matGroundU.setColor("Color", ColorRGBA.Green); + + + matGroundL = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matGroundL.setTexture("DiffuseMap", grass); + + ground.setMaterial(matGroundL); + + ground.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(ground); + + l = new DirectionalLight(); + //l.setDirection(new Vector3f(0.5973172f, -0.16583486f, 0.7846725f).normalizeLocal()); + l.setDirection(new Vector3f(-1, -1, -1)); + rootNode.addLight(l); + + + al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.02f)); + rootNode.addLight(al); + + Spatial sky = SkyFactory.createSky(assetManager, + "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); + sky.setLocalScale(350); + + rootNode.attachChild(sky); + } + private DirectionalLight l; + + @Override + public void simpleInitApp() { + // put the camera in a bad position +// cam.setLocation(new Vector3f(65.25412f, 44.38738f, 9.087874f)); +// cam.setRotation(new Quaternion(0.078139365f, 0.050241485f, -0.003942559f, 0.9956679f)); + + cam.setLocation(new Vector3f(3.3720117f, 42.838284f, -83.43792f)); + cam.setRotation(new Quaternion(0.13833192f, -0.08969371f, 0.012581267f, 0.9862358f)); + + flyCam.setMoveSpeed(100); + + loadScene(); + + dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 3); + dlsr.setLight(l); + dlsr.setLambda(0.55f); + dlsr.setShadowIntensity(0.8f); + dlsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest); + dlsr.displayDebug(); + viewPort.addProcessor(dlsr); + + dlsf = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3); + dlsf.setLight(l); + dlsf.setLambda(0.55f); + dlsf.setShadowIntensity(0.8f); + dlsf.setEdgeFilteringMode(EdgeFilteringMode.Nearest); + dlsf.setEnabled(false); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(dlsf); + + viewPort.addProcessor(fpp); + + initInputs(); + } + + private void initInputs() { + inputManager.addMapping("lambdaUp", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("lambdaDown", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("switchGroundMat", new KeyTrigger(KeyInput.KEY_M)); + inputManager.addMapping("debug", new KeyTrigger(KeyInput.KEY_X)); + inputManager.addMapping("stabilize", new KeyTrigger(KeyInput.KEY_B)); + inputManager.addMapping("distance", new KeyTrigger(KeyInput.KEY_N)); + + + inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_NUMPAD8)); + inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_NUMPAD2)); + inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_NUMPAD6)); + inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_NUMPAD4)); + inputManager.addMapping("fwd", new KeyTrigger(KeyInput.KEY_PGUP)); + inputManager.addMapping("back", new KeyTrigger(KeyInput.KEY_PGDN)); + inputManager.addMapping("pp", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addMapping("backShadows", new KeyTrigger(KeyInput.KEY_K)); + + + inputManager.addListener(this, "lambdaUp", "lambdaDown", + "switchGroundMat", "debug", "up", "down", "right", "left", "fwd", "back", "pp", "stabilize", "distance", "ShadowUp", "ShadowDown", "backShadows"); + + ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, dlsr, dlsf, guiNode, inputManager, viewPort); + + inputManager.addListener(this, "Size+", "Size-"); + inputManager.addMapping("Size+", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Size-", new KeyTrigger(KeyInput.KEY_S)); + + shadowStabilizationText = new BitmapText(guiFont); + shadowStabilizationText.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f); + shadowStabilizationText.setText("(b:on/off) Shadow stabilization : " + dlsr.isEnabledStabilization()); + shadowStabilizationText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 100, 0); + guiNode.attachChild(shadowStabilizationText); + + + shadowZfarText = new BitmapText(guiFont); + shadowZfarText.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f); + shadowZfarText.setText("(n:on/off) Shadow extend to 500 and fade to 50 : " + (dlsr.getShadowZExtend() > 0)); + shadowZfarText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 120, 0); + guiNode.attachChild(shadowZfarText); + } + private BitmapText shadowStabilizationText; + private BitmapText shadowZfarText; + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + + + if (name.equals("pp") && keyPressed) { + if (cam.isParallelProjection()) { + cam.setFrustumPerspective(45, (float) cam.getWidth() / cam.getHeight(), 1, 1000); + } else { + cam.setParallelProjection(true); + float aspect = (float) cam.getWidth() / cam.getHeight(); + cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); + + } + } + + if (name.equals("lambdaUp") && keyPressed) { + dlsr.setLambda(dlsr.getLambda() + 0.01f); + dlsf.setLambda(dlsr.getLambda() + 0.01f); + System.out.println("Lambda : " + dlsr.getLambda()); + } else if (name.equals("lambdaDown") && keyPressed) { + dlsr.setLambda(dlsr.getLambda() - 0.01f); + dlsf.setLambda(dlsr.getLambda() - 0.01f); + System.out.println("Lambda : " + dlsr.getLambda()); + } + if ((name.equals("ShadowUp") || name.equals("ShadowDown")) && keyPressed) { + al.setColor(ColorRGBA.White.mult((1 - dlsr.getShadowIntensity()) * 0.2f)); + } + + if (name.equals("debug") && keyPressed) { + dlsr.displayFrustum(); + } + + if (name.equals("backShadows") && keyPressed) { + dlsr.setRenderBackFacesShadows(!dlsr.isRenderBackFacesShadows()); + dlsf.setRenderBackFacesShadows(!dlsf.isRenderBackFacesShadows()); + } + + if (name.equals("stabilize") && keyPressed) { + dlsr.setEnabledStabilization(!dlsr.isEnabledStabilization()); + dlsf.setEnabledStabilization(!dlsf.isEnabledStabilization()); + shadowStabilizationText.setText("(b:on/off) Shadow stabilization : " + dlsr.isEnabledStabilization()); + } + if (name.equals("distance") && keyPressed) { + if (dlsr.getShadowZExtend() > 0) { + dlsr.setShadowZExtend(0); + dlsr.setShadowZFadeLength(0); + dlsf.setShadowZExtend(0); + dlsf.setShadowZFadeLength(0); + + } else { + dlsr.setShadowZExtend(500); + dlsr.setShadowZFadeLength(50); + dlsf.setShadowZExtend(500); + dlsf.setShadowZFadeLength(50); + } + shadowZfarText.setText("(n:on/off) Shadow extend to 500 and fade to 50 : " + (dlsr.getShadowZExtend() > 0)); + + } + + if (name.equals("switchGroundMat") && keyPressed) { + if (ground.getMaterial() == matGroundL) { + ground.setMaterial(matGroundU); + } else { + ground.setMaterial(matGroundL); + } + } + + if (name.equals("up")) { + up = keyPressed; + } + if (name.equals("down")) { + down = keyPressed; + } + if (name.equals("right")) { + right = keyPressed; + } + if (name.equals("left")) { + left = keyPressed; + } + if (name.equals("fwd")) { + fwd = keyPressed; + } + if (name.equals("back")) { + back = keyPressed; + } + + } + private boolean up = false; + private boolean down = false; + private boolean left = false; + private boolean right = false; + private boolean fwd = false; + private boolean back = false; + final private float s = 1f; + + @Override + public void simpleUpdate(float tpf) { + if (up) { + Vector3f v = l.getDirection(); + v.y += tpf / s; + setDir(v); + } + if (down) { + Vector3f v = l.getDirection(); + v.y -= tpf / s; + setDir(v); + } + if (right) { + Vector3f v = l.getDirection(); + v.x += tpf / s; + setDir(v); + } + if (left) { + Vector3f v = l.getDirection(); + v.x -= tpf / s; + setDir(v); + } + if (fwd) { + Vector3f v = l.getDirection(); + v.z += tpf / s; + setDir(v); + } + if (back) { + Vector3f v = l.getDirection(); + v.z -= tpf / s; + setDir(v); + } + + } + + private void setDir(Vector3f v) { + l.setDirection(v); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java b/jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java new file mode 100644 index 0000000000..846acfce40 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestEnvironmentMapping.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.input.ChaseCamera; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.texture.Texture; +import com.jme3.util.SkyFactory; + +/** + * test + * @author nehon + */ +public class TestEnvironmentMapping extends SimpleApplication { + + public static void main(String[] args) { + TestEnvironmentMapping app = new TestEnvironmentMapping(); + app.start(); + } + + @Override + public void simpleInitApp() { + final Node buggy = (Node) assetManager.loadModel("Models/Buggy/Buggy.j3o"); + + TextureKey key = new TextureKey("Textures/Sky/Bright/BrightSky.dds", true); + key.setGenerateMips(true); + key.setTextureTypeHint(Texture.Type.CubeMap); + final Texture tex = assetManager.loadTexture(key); + + for (Spatial geom : buggy.getChildren()) { + if (geom instanceof Geometry) { + Material m = ((Geometry) geom).getMaterial(); + m.setTexture("EnvMap", tex); + m.setVector3("FresnelParams", new Vector3f(0.05f, 0.18f, 0.11f)); + } + } + + flyCam.setEnabled(false); + + ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); + chaseCam.setLookAtOffset(new Vector3f(0,0.5f,-1.0f)); + buggy.addControl(chaseCam); + rootNode.attachChild(buggy); + rootNode.attachChild(SkyFactory.createSky(assetManager, tex, + SkyFactory.EnvMapType.CubeMap)); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + BloomFilter bf = new BloomFilter(BloomFilter.GlowMode.Objects); + bf.setBloomIntensity(2.3f); + bf.setExposurePower(0.6f); + + fpp.addFilter(bf); + + DirectionalLight l = new DirectionalLight(); + l.setDirection(new Vector3f(0, -1, -1)); + rootNode.addLight(l); + + viewPort.addProcessor(fpp); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java b/jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java new file mode 100644 index 0000000000..8b2244399f --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestGltfUnlit.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; + +/** + * Tests the GLTF scene containing an unlit material. If it works, it should use the + * Common/MatDefs/Misc/Unshaded.j3md material definition for those objects. + * + * @author Markil 3 + * @version 3.3.0-SNAPSHOT + */ +public class TestGltfUnlit extends SimpleApplication { + public static void main(String[] args) { + TestGltfUnlit testUnlit = new TestGltfUnlit(); + testUnlit.start(); + } + + @Override + public void simpleInitApp() { + ColorRGBA skyColor = new ColorRGBA(0.5f, 0.6f, 0.7f, 0.0f); + + flyCam.setMoveSpeed(20); + viewPort.setBackgroundColor(skyColor.mult(0.9f)); + + cam.setLocation(new Vector3f(0, 10, 20)); + rootNode.attachChild(getAssetManager().loadModel("jme3test/scenes/unlit.gltf")); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java b/jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java new file mode 100644 index 0000000000..84d0f651e9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestLightControl2Directional.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.LightControl; +import com.jme3.scene.shape.Cylinder; +import com.jme3.scene.shape.Dome; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TempVars; + +/** + * Similar to {@link TestLightControlDirectional}, except that the spatial is controlled by the light this + * time. + * + * @author Markil 3 + */ +public class TestLightControl2Directional extends SimpleApplication { + private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); + private final float[] angles = new float[3]; + + private Node lightNode; + private DirectionalLight direction; + + public static void main(String[] args) { + TestLightControl2Directional app = new TestLightControl2Directional(); + app.start(); + } + + public void setupLighting() { + Geometry lightMdl; + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(2f)); + rootNode.addLight(al); + + direction = new DirectionalLight(); + direction.setColor(ColorRGBA.White.mult(10)); + rootNode.addLight(direction); + + lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); + lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); + rootNode.attachChild(lightMdl); + + /* + * We need this Dome doesn't have a "floor." + */ + Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); + lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightFloor.getMaterial().setColor("Color", ColorRGBA.White); + + lightNode = new Node(); + lightNode.addControl(new LightControl(direction, LightControl.ControlDirection.LightToSpatial)); + lightNode.attachChild(lightMdl); + lightNode.attachChild(lightFloor); + + rootNode.attachChild(lightNode); + } + + public void setupDome() { + Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); + dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); + dome.setLocalTranslation(new Vector3f(0, 0, 0)); + rootNode.attachChild(dome); + } + + @Override + public void simpleInitApp() { + this.cam.setLocation(new Vector3f(-50, 20, 50)); + this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + flyCam.setMoveSpeed(30); + + setupLighting(); + setupDome(); + } + + @Override + public void simpleUpdate(float tpf) { + final Vector3f INIT_DIR = Vector3f.UNIT_Z.negate(); + /* + * In Radians per second + */ + final float ROT_SPEED = FastMath.PI / 2; + /* + * 360 degree rotation + */ + final float FULL_ROT = FastMath.PI * 2; + + TempVars vars = TempVars.get(); + Vector3f lightDirection = vars.vect2, nodeDirection = vars.vect3; + float length; + + angles[0] += rotAxis.x * ROT_SPEED * tpf; + angles[1] += rotAxis.y * ROT_SPEED * tpf; + angles[2] += rotAxis.z * ROT_SPEED * tpf; + direction.setDirection(new Quaternion().fromAngles(angles).mult(INIT_DIR)); + super.simpleUpdate(tpf); + + /* + * Make sure they are equal. + */ + lightDirection.set(direction.getDirection()); + lightDirection.normalizeLocal(); + lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); + nodeDirection.negateLocal().normalizeLocal(); + length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); + length = FastMath.abs(length); + if (length > .1F) { + System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); + } + + if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { + direction.setDirection(INIT_DIR); + angles[0] = 0; + angles[1] = 0; + angles[2] = 0; + if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { + rotAxis.set(0, 1, 0); + } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { + rotAxis.set(0, 0, 1); + } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { + rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); + } else { + rotAxis.set(1, 0, 0); + } + } + + vars.release(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java b/jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java new file mode 100644 index 0000000000..717a397b50 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestLightControl2Spot.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.LightControl; +import com.jme3.scene.shape.Cylinder; +import com.jme3.scene.shape.Dome; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TempVars; + +/** + * Similar to {@link TestLightControlSpot}, except that the spatial is controlled by the light this + * time. + * + * @author Markil 3 + */ +public class TestLightControl2Spot extends SimpleApplication { + private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); + private final float[] angles = new float[3]; + + private Node lightNode; + private SpotLight spot; + + public static void main(String[] args) { + TestLightControl2Spot app = new TestLightControl2Spot(); + app.start(); + } + + public void setupLighting() { + Geometry lightMdl; + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(2f)); + rootNode.addLight(al); + + spot = new SpotLight(); + spot.setSpotRange(1000); + spot.setSpotInnerAngle(5 * FastMath.DEG_TO_RAD); + spot.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); + spot.setColor(ColorRGBA.White.mult(10)); + rootNode.addLight(spot); + + lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); + lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); + rootNode.attachChild(lightMdl); + + /* + * We need this Dome doesn't have a "floor." + */ + Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); + lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightFloor.getMaterial().setColor("Color", ColorRGBA.White); + + lightNode = new Node(); + lightNode.addControl(new LightControl(spot, LightControl.ControlDirection.LightToSpatial)); + lightNode.attachChild(lightMdl); + lightNode.attachChild(lightFloor); + + rootNode.attachChild(lightNode); + } + + public void setupDome() { + Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); + dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); + dome.setLocalTranslation(new Vector3f(0, 0, 0)); + rootNode.attachChild(dome); + } + + @Override + public void simpleInitApp() { + this.cam.setLocation(new Vector3f(-50, 20, 50)); + this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + flyCam.setMoveSpeed(30); + + setupLighting(); + setupDome(); + } + + @Override + public void simpleUpdate(float tpf) { + final Vector3f INIT_DIR = Vector3f.UNIT_Z.negate(); + /* + * In Radians per second + */ + final float ROT_SPEED = FastMath.PI / 2; + /* + * 360 degree rotation + */ + final float FULL_ROT = FastMath.PI * 2; + + TempVars vars = TempVars.get(); + Vector3f lightPosition = vars.vect1, lightDirection = vars.vect2, nodeDirection = vars.vect3; + float length; + + angles[0] += rotAxis.x * ROT_SPEED * tpf; + angles[1] += rotAxis.y * ROT_SPEED * tpf; + angles[2] += rotAxis.z * ROT_SPEED * tpf; + spot.setDirection(new Quaternion().fromAngles(angles).mult(INIT_DIR)); + super.simpleUpdate(tpf); + + /* + * Make sure they are equal. + */ + lightPosition.set(spot.getPosition()); + lightPosition.subtractLocal(lightNode.getWorldTranslation()); + length = lightPosition.lengthSquared(); + if (length > 0.1F) { + System.err.printf("Translation not equal: is %s (%s), needs to be %s\n", lightNode.getWorldTranslation(), lightNode.getLocalTranslation(), spot.getPosition()); + } + lightDirection.set(spot.getDirection()); + lightDirection.normalizeLocal(); + lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); + nodeDirection.negateLocal().normalizeLocal(); + length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); + length = FastMath.abs(length); + if (length > .1F) { + System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); + } + + if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { + spot.setDirection(INIT_DIR); + angles[0] = 0; + angles[1] = 0; + angles[2] = 0; + if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { + rotAxis.set(0, 1, 0); + } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { + rotAxis.set(0, 0, 1); + } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { + rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); + } else { + rotAxis.set(1, 0, 0); + } + } + + vars.release(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java b/jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java new file mode 100644 index 0000000000..5353403a4e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestLightControlDirectional.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.LightControl; +import com.jme3.scene.shape.Cylinder; +import com.jme3.scene.shape.Dome; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TempVars; + +/** + * Creates a directional light controlled by rotating a node. The light will shine on a surrounding sphere. + * The light will rotate on each axis, then on a random axis, then return to the X + * axis. + * + * @author Markil 3 + */ +public class TestLightControlDirectional extends SimpleApplication { + private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); + private final float[] angles = new float[3]; + + private Node lightNode; + private DirectionalLight direction; + + public static void main(String[] args) { + TestLightControlDirectional app = new TestLightControlDirectional(); + app.start(); + } + + public void setupLighting() { + Geometry lightMdl; + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(2f)); + rootNode.addLight(al); + + direction = new DirectionalLight(); + direction.setColor(ColorRGBA.White.mult(10)); + rootNode.addLight(direction); + + lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); + lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); + rootNode.attachChild(lightMdl); + + /* + * We need this Dome doesn't have a "floor." + */ + Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); + lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightFloor.getMaterial().setColor("Color", ColorRGBA.White); + + lightNode = new Node(); + lightNode.addControl(new LightControl(direction)); + lightNode.attachChild(lightMdl); + lightNode.attachChild(lightFloor); + rootNode.attachChild(lightNode); + } + + public void setupDome() { + Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); + dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); + dome.setLocalTranslation(new Vector3f(0, 0, 0)); + rootNode.attachChild(dome); + } + + @Override + public void simpleInitApp() { + this.cam.setLocation(new Vector3f(-50, 20, 50)); + this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + flyCam.setMoveSpeed(30); + + setupLighting(); + setupDome(); + } + + @Override + public void simpleUpdate(float tpf) { + /* + * In Radians per second + */ + final float ROT_SPEED = FastMath.PI / 2; + /* + * 360 degree rotation + */ + final float FULL_ROT = FastMath.PI * 2; + + TempVars vars = TempVars.get(); + Vector3f lightDirection = vars.vect2, nodeDirection = vars.vect3; + float length; + + angles[0] += rotAxis.x * ROT_SPEED * tpf; + angles[1] += rotAxis.y * ROT_SPEED * tpf; + angles[2] += rotAxis.z * ROT_SPEED * tpf; + lightNode.setLocalRotation(new Quaternion().fromAngles(angles)); + super.simpleUpdate(tpf); + + /* + * Make sure they are equal. + */ + lightDirection.set(direction.getDirection()); + lightDirection.normalize(); + lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); + nodeDirection.negateLocal().normalizeLocal(); + length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); + length = FastMath.abs(length); + if (length > .1F) { + System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); + } + + if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { + lightNode.setLocalRotation(Quaternion.DIRECTION_Z); + angles[0] = 0; + angles[1] = 0; + angles[2] = 0; + if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { + rotAxis.set(0, 1, 0); + } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { + rotAxis.set(0, 0, 1); + } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { + rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); + } else { + rotAxis.set(1, 0, 0); + } + } + + vars.release(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java b/jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java new file mode 100644 index 0000000000..2e08481cde --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestLightControlSpot.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.LightControl; +import com.jme3.scene.shape.Cylinder; +import com.jme3.scene.shape.Dome; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TempVars; + +/** + * Creates a spotlight controlled by rotating a node. The light will shine on a surrounding sphere. + * The light will rotate on each axis, then on a random axis, then return to the X + * axis. + * + * @author Markil 3 + */ +public class TestLightControlSpot extends SimpleApplication { + private final Vector3f rotAxis = new Vector3f(Vector3f.UNIT_X); + private final float[] angles = new float[3]; + + private Node lightNode; + private SpotLight spot; + + public static void main(String[] args) { + TestLightControlSpot app = new TestLightControlSpot(); + app.start(); + } + + public void setupLighting() { + Geometry lightMdl; + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(2f)); + rootNode.addLight(al); + + spot = new SpotLight(); + + spot.setSpotRange(1000); + spot.setSpotInnerAngle(5 * FastMath.DEG_TO_RAD); + spot.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); + spot.setColor(ColorRGBA.White.mult(10)); + rootNode.addLight(spot); + + lightMdl = new Geometry("Light", new Dome(Vector3f.ZERO, 2, 32, 5, false)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setLocalTranslation(new Vector3f(0, 0, 0)); + lightMdl.setLocalRotation(new Quaternion().fromAngles(FastMath.PI / 2F, 0, 0)); + rootNode.attachChild(lightMdl); + + /* + * We need this Dome doesn't have a "floor." + */ + Geometry lightFloor = new Geometry("LightFloor", new Cylinder(2, 32, 5, .1F, true)); + lightFloor.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightFloor.getMaterial().setColor("Color", ColorRGBA.White); + + lightNode = new Node(); + lightNode.addControl(new LightControl(spot)); + lightNode.attachChild(lightMdl); + lightNode.attachChild(lightFloor); + rootNode.attachChild(lightNode); + } + + public void setupDome() { + Geometry dome = new Geometry("Dome", new Sphere(16, 32, 30, false, true)); + dome.setMaterial(new Material(this.assetManager, "Common/MatDefs/Light/PBRLighting.j3md")); + dome.setLocalTranslation(new Vector3f(0, 0, 0)); + rootNode.attachChild(dome); + } + + @Override + public void simpleInitApp() { + this.cam.setLocation(new Vector3f(-50, 20, 50)); + this.cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + flyCam.setMoveSpeed(30); + + setupLighting(); + setupDome(); + } + + @Override + public void simpleUpdate(float tpf) { + /* + * In Radians per second + */ + final float ROT_SPEED = FastMath.PI / 2; + /* + * 360 degree rotation + */ + final float FULL_ROT = FastMath.PI * 2; + + TempVars vars = TempVars.get(); + Vector3f lightPosition = vars.vect1, lightDirection = vars.vect2, nodeDirection = vars.vect3; + float length; + + angles[0] += rotAxis.x * ROT_SPEED * tpf; + angles[1] += rotAxis.y * ROT_SPEED * tpf; + angles[2] += rotAxis.z * ROT_SPEED * tpf; + lightNode.setLocalRotation(new Quaternion().fromAngles(angles)); + super.simpleUpdate(tpf); + + /* + * Make sure they are equal. + */ + lightPosition.set(spot.getPosition()); + length = lightPosition.subtract(lightNode.getWorldTranslation(), vars.vect4).lengthSquared(); + if (length > 0.1F) { + System.err.printf("Translation not equal: is %s, needs to be %s\n", lightNode.getWorldTranslation(), spot.getPosition()); + } + lightDirection.set(spot.getDirection()); + lightDirection.normalizeLocal(); + lightNode.getWorldRotation().mult(Vector3f.UNIT_Z, nodeDirection); + nodeDirection.negateLocal().normalizeLocal(); + length = lightDirection.subtract(nodeDirection, vars.vect4).lengthSquared(); + length = FastMath.abs(length); + if (length > .1F) { + System.err.printf("Rotation not equal: is %s, needs to be %s (%f)\n", nodeDirection, lightDirection, length); + } + + if (angles[0] >= FULL_ROT || angles[1] >= FULL_ROT || angles[2] >= FULL_ROT) { + lightNode.setLocalRotation(Quaternion.DIRECTION_Z); + angles[0] = 0; + angles[1] = 0; + angles[2] = 0; + if (rotAxis.x > 0 && rotAxis.y == 0 && rotAxis.z == 0) { + rotAxis.set(0, 1, 0); + } else if (rotAxis.y > 0 && rotAxis.x == 0 && rotAxis.z == 0) { + rotAxis.set(0, 0, 1); + } else if (rotAxis.z > 0 && rotAxis.x == 0 && rotAxis.y == 0) { + rotAxis.set(FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1, FastMath.nextRandomFloat() % 1); + } else { + rotAxis.set(1, 0, 0); + } + } + + vars.release(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightRadius.java b/jme3-examples/src/main/java/jme3test/light/TestLightRadius.java new file mode 100644 index 0000000000..26b56e6610 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestLightRadius.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Sphere; +import com.jme3.scene.shape.Torus; + +public class TestLightRadius extends SimpleApplication { + + private float pos, vel=1; + private PointLight pl; + private Geometry lightMdl; + + public static void main(String[] args){ + TestLightRadius app = new TestLightRadius(); + app.start(); + } + + @Override + public void simpleInitApp() { + Torus torus = new Torus(10, 6, 1, 3); +// Torus torus = new Torus(50, 30, 1, 3); + Geometry g = new Geometry("Torus Geom", torus); + g.rotate(-FastMath.HALF_PI, 0, 0); + g.center(); +// g.move(0, 1, 0); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + mat.setFloat("Shininess", 32f); + mat.setBoolean("UseMaterialColors", true); + mat.setColor("Ambient", ColorRGBA.Black); + mat.setColor("Diffuse", ColorRGBA.White); + mat.setColor("Specular", ColorRGBA.White); +// mat.setBoolean("VertexLighting", true); +// mat.setBoolean("LowQuality", true); + g.setMaterial(mat); + + rootNode.attachChild(g); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + rootNode.attachChild(lightMdl); + + pl = new PointLight(); + pl.setColor(ColorRGBA.Green); + pl.setRadius(4f); + rootNode.addLight(pl); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.Red); + dl.setDirection(new Vector3f(0, 1, 0)); + rootNode.addLight(dl); + } + + @Override + public void simpleUpdate(float tpf){ +// cam.setLocation(new Vector3f(5.0347548f, 6.6481347f, 3.74853f)); +// cam.setRotation(new Quaternion(-0.19183293f, 0.80776674f, -0.37974006f, -0.40805697f)); + + pos += tpf * vel * 5f; + if (pos > 15){ + vel *= -1; + }else if (pos < -15){ + vel *= -1; + } + + pl.setPosition(new Vector3f(pos, 2, 0)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestLightingFog.java b/jme3-examples/src/main/java/jme3test/light/TestLightingFog.java new file mode 100644 index 0000000000..b142dfc417 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestLightingFog.java @@ -0,0 +1,79 @@ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.material.Materials; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Sphere; + +public class TestLightingFog extends SimpleApplication implements ActionListener { + + private Material material; + final private Vector2f linear = new Vector2f(25, 120); + final private float exp = 0.015f; + final private float expsq = 0.02f; + + public static void main(String[] args) { + TestLightingFog testLightingFog = new TestLightingFog(); + testLightingFog.start(); + } + + @Override + public void simpleInitApp() { + + ColorRGBA skyColor = new ColorRGBA(0.5f, 0.6f, 0.7f, 0.0f); + + flyCam.setMoveSpeed(20); + viewPort.setBackgroundColor(skyColor.mult(0.9f)); + + DirectionalLight directionalLight = new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()); + rootNode.addLight(directionalLight); + + material = new Material(assetManager, Materials.LIGHTING); + material.setBoolean("UseFog", true); + material.setColor("FogColor", skyColor); + material.setVector2("LinearFog", linear); + + int distance = -3; + + for (int i = 0; i < 100; i++) { + Geometry geometry = new Geometry("Sphere", new Sphere(32, 32, 2)); + geometry.setMaterial(material); + + geometry.setLocalTranslation((FastMath.nextRandomFloat() - 0.5f) * 45, 0, i * distance); + rootNode.attachChild(geometry); + } + + inputManager.addMapping("Linear", new KeyTrigger(KeyInput.KEY_1)); + inputManager.addMapping("Exponential", new KeyTrigger(KeyInput.KEY_2)); + inputManager.addMapping("ExponentialSquared", new KeyTrigger(KeyInput.KEY_3)); + inputManager.addListener(this, "Linear", "Exponential", "ExponentialSquared"); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("Linear") && !isPressed) { + material.setVector2("LinearFog", linear); + material.clearParam("ExpFog"); + material.clearParam("ExpSqFog"); + } + else if (name.equals("Exponential") && !isPressed) { + material.clearParam("LinearFog"); + material.setFloat("ExpFog", exp); + material.clearParam("ExpSqFog"); + } + else if (name.equals("ExponentialSquared") && !isPressed) { + material.clearParam("LinearFog"); + material.clearParam("ExpFog"); + material.setFloat("ExpSqFog", expsq); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestManyLights.java b/jme3-examples/src/main/java/jme3test/light/TestManyLights.java new file mode 100644 index 0000000000..644344b023 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestManyLights.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.scene.Node; + +public class TestManyLights extends SimpleApplication { + + public static void main(String[] args){ + TestManyLights app = new TestManyLights(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10); + + Node scene = (Node) assetManager.loadModel("Scenes/ManyLights/Main.scene"); + rootNode.attachChild(scene); +// guiNode.setCullHint(CullHint.Always); + } + +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java b/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java new file mode 100644 index 0000000000..ca9365cb88 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.BasicProfilerState; +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.light.Light; +import com.jme3.light.LightList; +import com.jme3.light.PointLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.material.TechniqueDef; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.control.AbstractControl; +import com.jme3.scene.shape.Box; +import com.jme3.util.MaterialDebugAppState; + +public class TestManyLightsSingle extends SimpleApplication { + + public static void main(String[] args) { + TestManyLightsSingle app = new TestManyLightsSingle(); + app.start(); + } + + /** + * Switch mode with space bar at run time + */ + private TechniqueDef.LightMode lm = TechniqueDef.LightMode.SinglePass; + + @Override + public void simpleInitApp() { + renderManager.setPreferredLightMode(lm); + renderManager.setSinglePassLightBatchSize(6); + + flyCam.setMoveSpeed(10); + + Node scene = (Node) assetManager.loadModel("Scenes/ManyLights/Main.scene"); + rootNode.attachChild(scene); + Node n = (Node) rootNode.getChild(0); + final LightList lightList = n.getWorldLightList(); + final Geometry g = (Geometry) n.getChild("Grid-geom-1"); + + g.getMaterial().setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); + + /* A colored lit cube. Needs light source! */ + Box boxMesh = new Box(1f, 1f, 1f); + final Geometry boxGeo = new Geometry("Colored Box", boxMesh); + Material boxMat = g.getMaterial().clone(); + boxMat.clearParam("DiffuseMap"); + boxMat.setBoolean("UseMaterialColors", true); + boxMat.setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); + boxMat.setColor("Diffuse", ColorRGBA.Blue); + boxGeo.setMaterial(boxMat); + + final Node cubeNodes = new Node(); + n.attachChild(cubeNodes); + int nb = 0; + for (Light light : lightList) { + nb++; + PointLight p = (PointLight) light; + if (nb > 60) { + n.removeLight(light); + } else { + int rand = FastMath.nextRandomInt(0, 3); + switch (rand) { + case 0: + light.setColor(ColorRGBA.Red); + break; + case 1: + light.setColor(ColorRGBA.Yellow); + break; + case 2: + light.setColor(ColorRGBA.Green); + break; + case 3: + light.setColor(ColorRGBA.Orange); + break; + } + } + Geometry b = boxGeo.clone(false); + cubeNodes.attachChild(b); + b.setLocalTranslation(p.getPosition().x, 2, p.getPosition().z); + + } + + +// cam.setLocation(new Vector3f(3.1893547f, 17.977385f, 30.8378f)); +// cam.setRotation(new Quaternion(0.14317635f, 0.82302624f, -0.23777823f, 0.49557027f)); + + cam.setLocation(new Vector3f(-1.8901939f, 29.34097f, 73.07533f)); + cam.setRotation(new Quaternion(0.0021000702f, 0.971012f, -0.23886925f, 0.008527749f)); + + + BasicProfilerState profiler = new BasicProfilerState(true); + profiler.setGraphScale(1000f); + + // getStateManager().attach(profiler); +// guiNode.setCullHint(CullHint.Always); + + + flyCam.setDragToRotate(true); + flyCam.setMoveSpeed(50); + + final MaterialDebugAppState debug = new MaterialDebugAppState(); + stateManager.attach(debug); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("toggle") && isPressed) { + if (lm == TechniqueDef.LightMode.SinglePass) { + lm = TechniqueDef.LightMode.MultiPass; + helloText.setText("(Multi pass)"); + } else { + lm = TechniqueDef.LightMode.SinglePass; + helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); + } + renderManager.setPreferredLightMode(lm); + reloadScene(g, boxGeo, cubeNodes); + } + if (name.equals("lightsUp") && isPressed) { + renderManager.setSinglePassLightBatchSize(renderManager.getSinglePassLightBatchSize() + 1); + helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); + } + if (name.equals("lightsDown") && isPressed) { + renderManager.setSinglePassLightBatchSize(renderManager.getSinglePassLightBatchSize() - 1); + helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); + } + if (name.equals("toggleOnOff") && isPressed) { + for (final Light light : lightList) { + if (light instanceof AmbientLight) { + continue; + } + + light.setEnabled(!light.isEnabled()); + } + } + } + }, "toggle", "lightsUp", "lightsDown", "toggleOnOff"); + + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("lightsUp", new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("lightsDown", new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("toggleOnOff", new KeyTrigger(KeyInput.KEY_L)); + + + SpotLight spot = new SpotLight(); + spot.setDirection(new Vector3f(-1f, -1f, -1f).normalizeLocal()); + spot.setColor(ColorRGBA.Blue.mult(5)); + spot.setSpotOuterAngle(FastMath.DEG_TO_RAD * 20); + spot.setSpotInnerAngle(FastMath.DEG_TO_RAD * 5); + spot.setPosition(new Vector3f(10, 10, 20)); + rootNode.addLight(spot); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, 1)); + rootNode.addLight(dl); + + AmbientLight al = new AmbientLight(); + al.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); + rootNode.addLight(al); + + + /* + * Write text on the screen (HUD) + */ + guiNode.detachAllChildren(); + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + helloText = new BitmapText(guiFont); + helloText.setSize(guiFont.getCharSet().getRenderedSize()); + helloText.setText("(Single pass) nb lights per batch : " + renderManager.getSinglePassLightBatchSize()); + helloText.setLocalTranslation(300, helloText.getLineHeight(), 0); + guiNode.attachChild(helloText); + } + + protected void reloadScene(Geometry g, Geometry boxGeo, Node cubeNodes) { + MaterialDebugAppState debug = stateManager.getState(MaterialDebugAppState.class); + Material m = debug.reloadMaterial(g.getMaterial()); + if (m != null) { + g.setMaterial(m); + } + m = debug.reloadMaterial(boxGeo.getMaterial()); + if (m != null) { + cubeNodes.setMaterial(m); + } + } + + private BitmapText helloText; + + @Override + public void simpleUpdate(float tpf) { +// if (nbFrames == 4000) { +// startTime = System.nanoTime(); +// } +// if (nbFrames > 4000) { +// time = System.nanoTime(); +// float average = ((float) time - (float) startTime) / ((float) nbFrames - 4000f); +// helloText.setText("Average = " + average); +// } +// nbFrames++; + } + + class MoveControl extends AbstractControl { + + final private float direction; + final private Vector3f origPos = new Vector3f(); + + public MoveControl(float direction) { + this.direction = direction; + } + + @Override + public void setSpatial(Spatial spatial) { + super.setSpatial(spatial); //To change body of generated methods, choose Tools | Templates. + origPos.set(spatial.getLocalTranslation()); + } + private float time = 0; + + @Override + protected void controlUpdate(float tpf) { + time += tpf; + spatial.setLocalTranslation(origPos.x + FastMath.cos(time) * direction, origPos.y, origPos.z + FastMath.sin(time) * direction); + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp) { + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java b/jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java new file mode 100644 index 0000000000..d98619a2b2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestObbVsBounds.java @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.bounding.BoundingSphere; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.*; +import com.jme3.light.*; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.renderer.Camera; +import com.jme3.scene.*; +import com.jme3.scene.debug.Grid; +import com.jme3.scene.debug.WireFrustum; +import com.jme3.scene.shape.*; +import com.jme3.shadow.ShadowUtil; +import com.jme3.util.TempVars; + + +public class TestObbVsBounds extends SimpleApplication { + + private Node ln; + final private BoundingBox aabb = new BoundingBox(); + final private BoundingSphere sphere = new BoundingSphere(10, new Vector3f(-30, 0, -60)); + + private final static float MOVE_SPEED = 60; + final private Vector3f tmp = new Vector3f(); + final private Quaternion tmpQuat = new Quaternion(); + private boolean moving, shift; + private boolean panning; + + final private OrientedBoxProbeArea area = new OrientedBoxProbeArea(); + private Camera frustumCam; + + private Geometry areaGeom; + private Geometry frustumGeom; + private Geometry aabbGeom; + private Geometry sphereGeom; + + public static void main(String[] args) { + TestObbVsBounds app = new TestObbVsBounds(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + frustumCam = cam.clone(); + frustumCam.setFrustumFar(25); + makeCamFrustum(); + aabb.setCenter(20, 10, -60); + aabb.setXExtent(10); + aabb.setYExtent(5); + aabb.setZExtent(3); + makeBoxWire(aabb); + makeSphereWire(sphere); + + rootNode.addLight(new DirectionalLight()); + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.2f)); + rootNode.addLight(al); + + Grid grid = new Grid(50, 50, 5); + Geometry gridGeom = new Geometry("grid", grid); + gridGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + gridGeom.getMaterial().setColor("Color", ColorRGBA.Gray); + rootNode.attachChild(gridGeom); + gridGeom.setLocalTranslation(-125, -25, -125); + + area.setCenter(Vector3f.ZERO); + area.setExtent(new Vector3f(4, 8, 5)); + makeAreaGeom(); + + ln = new Node("lb"); + ln.setLocalRotation(new Quaternion(-0.18826798f, -0.38304946f, -0.12780227f, 0.895261f)); + ln.attachChild(areaGeom); + ln.setLocalScale(4,8,5); + rootNode.attachChild(ln); + + inputManager.addMapping("click", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + inputManager.addMapping("shift", new KeyTrigger(KeyInput.KEY_LSHIFT), new KeyTrigger(KeyInput.KEY_RSHIFT)); + inputManager.addMapping("middleClick", new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)); + inputManager.addMapping("up", new MouseAxisTrigger(MouseInput.AXIS_Y, false)); + inputManager.addMapping("down", new MouseAxisTrigger(MouseInput.AXIS_Y, true)); + inputManager.addMapping("left", new MouseAxisTrigger(MouseInput.AXIS_X, true)); + inputManager.addMapping("right", new MouseAxisTrigger(MouseInput.AXIS_X, false)); + + + final Node camTarget = new Node("CamTarget"); + rootNode.attachChild(camTarget); + + ChaseCameraAppState chaser = new ChaseCameraAppState(); + chaser.setTarget(camTarget); + chaser.setMaxDistance(150); + chaser.setDefaultDistance(70); + chaser.setDefaultHorizontalRotation(FastMath.HALF_PI); + chaser.setMinVerticalRotation(-FastMath.PI); + chaser.setMaxVerticalRotation(FastMath.PI * 2); + chaser.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + stateManager.attach(chaser); + flyCam.setEnabled(false); + + inputManager.addListener(new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + Spatial s = null; + float mult = 1; + if (moving) { + s = ln; + } + if (panning) { + s = camTarget; + mult = -1; + } + if ((moving || panning) && s != null) { + if (shift) { + if (name.equals("left")) { + tmp.set(cam.getDirection()); + s.rotate(tmpQuat.fromAngleAxis(value, tmp)); + } + if (name.equals("right")) { + tmp.set(cam.getDirection()); + s.rotate(tmpQuat.fromAngleAxis(-value, tmp)); + } + } else { + value *= MOVE_SPEED * mult; + if (name.equals("up")) { + tmp.set(cam.getUp()).multLocal(value); + s.move(tmp); + } + if (name.equals("down")) { + tmp.set(cam.getUp()).multLocal(-value); + s.move(tmp); + } + if (name.equals("left")) { + tmp.set(cam.getLeft()).multLocal(value); + s.move(tmp); + } + if (name.equals("right")) { + tmp.set(cam.getLeft()).multLocal(-value); + s.move(tmp); + } + } + } + } + }, "up", "down", "left", "right"); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("click")) { + if (isPressed) { + moving = true; + } else { + moving = false; + } + } + if (name.equals("middleClick")) { + if (isPressed) { + panning = true; + } else { + panning = false; + } + } + if (name.equals("shift")) { + if (isPressed) { + shift = true; + } else { + shift = false; + } + } + } + }, "click", "middleClick", "shift"); + + } + + public void makeAreaGeom() { + + Vector3f[] points = new Vector3f[8]; + + for (int i = 0; i < points.length; i++) { + points[i] = new Vector3f(); + } + + points[0].set(-1, -1, 1); + points[1].set(-1, 1, 1); + points[2].set(1, 1, 1); + points[3].set(1, -1, 1); + + points[4].set(-1, -1, -1); + points[5].set(-1, 1, -1); + points[6].set(1, 1, -1); + points[7].set(1, -1, -1); + + Mesh box = WireFrustum.makeFrustum(points); + areaGeom = new Geometry("light", box); + areaGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + areaGeom.getMaterial().setColor("Color", ColorRGBA.White); + } + + public void makeCamFrustum() { + Vector3f[] points = new Vector3f[8]; + for (int i = 0; i < 8; i++) { + points[i] = new Vector3f(); + } + ShadowUtil.updateFrustumPoints2(frustumCam, points); + WireFrustum frustumShape = new WireFrustum(points); + frustumGeom = new Geometry("frustum", frustumShape); + frustumGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + rootNode.attachChild(frustumGeom); + } + + public void makeBoxWire(BoundingBox box) { + Vector3f[] points = new Vector3f[8]; + for (int i = 0; i < 8; i++) { + points[i] = new Vector3f(); + } + points[0].set(-1, -1, 1); + points[1].set(-1, 1, 1); + points[2].set(1, 1, 1); + points[3].set(1, -1, 1); + + points[4].set(-1, -1, -1); + points[5].set(-1, 1, -1); + points[6].set(1, 1, -1); + points[7].set(1, -1, -1); + + WireFrustum frustumShape = new WireFrustum(points); + aabbGeom = new Geometry("box", frustumShape); + aabbGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + aabbGeom.getMaterial().getAdditionalRenderState().setWireframe(true); + aabbGeom.setLocalTranslation(box.getCenter()); + aabbGeom.setLocalScale(box.getXExtent(), box.getYExtent(), box.getZExtent()); + rootNode.attachChild(aabbGeom); + } + + public void makeSphereWire(BoundingSphere sphere) { + + sphereGeom = new Geometry("box", new Sphere(16, 16, 10)); + sphereGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + sphereGeom.getMaterial().getAdditionalRenderState().setWireframe(true); + sphereGeom.setLocalTranslation(sphere.getCenter()); + rootNode.attachChild(sphereGeom); + } + + + @Override + public void simpleUpdate(float tpf) { + + area.setCenter(ln.getLocalTranslation()); + area.setRotation(ln.getLocalRotation()); + + TempVars vars = TempVars.get(); + boolean intersectBox = area.intersectsBox(aabb, vars); + boolean intersectFrustum = area.intersectsFrustum(frustumCam, vars); + boolean intersectSphere = area.intersectsSphere(sphere, vars); + vars.release(); + + boolean intersect = intersectBox || intersectFrustum || intersectSphere; + + areaGeom.getMaterial().setColor("Color", intersect ? ColorRGBA.Green : ColorRGBA.White); + sphereGeom.getMaterial().setColor("Color", intersectSphere ? ColorRGBA.Cyan : ColorRGBA.White); + frustumGeom.getMaterial().setColor("Color", intersectFrustum ? ColorRGBA.Cyan : ColorRGBA.White); + aabbGeom.getMaterial().setColor("Color", intersectBox ? ColorRGBA.Cyan : ColorRGBA.White); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java b/jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java new file mode 100644 index 0000000000..332c0ae893 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestPointDirectionalAndSpotLightShadows.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.light.SpotLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.DirectionalLightShadowFilter; +import com.jme3.shadow.DirectionalLightShadowRenderer; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.shadow.PointLightShadowFilter; +import com.jme3.shadow.PointLightShadowRenderer; +import com.jme3.shadow.SpotLightShadowFilter; +import com.jme3.shadow.SpotLightShadowRenderer; + +public class TestPointDirectionalAndSpotLightShadows extends SimpleApplication { + public static final int SHADOWMAP_SIZE = 512; + + public static void main(String[] args) { + TestPointDirectionalAndSpotLightShadows app = new TestPointDirectionalAndSpotLightShadows(); + app.start(); + } + private Node lightNode; + private SpotLight spotLight; + + final private boolean useFilter = false; + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10); + cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f)); + cam.setRotation(new Quaternion(4.3868728E-5f, 0.9999293f, -0.011230096f, 0.0039059948f)); + + + Node scene = (Node) assetManager.loadModel("Models/Test/CornellBox.j3o"); + scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + rootNode.attachChild(scene); + rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive); + lightNode = (Node) rootNode.getChild("Lamp"); + Geometry lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setShadowMode(RenderQueue.ShadowMode.Off); + lightNode.attachChild(lightMdl); + //lightMdl.setLocalTranslation(lightNode.getLocalTranslation()); + + + Geometry box = new Geometry("box", new Box(0.2f, 0.2f, 0.2f)); + //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); + box.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + box.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + rootNode.attachChild(box); + box.setLocalTranslation(-1f, 0.5f, -2); + + scene.getLocalLightList().get(0).setColor(ColorRGBA.Red); + + PointLightShadowRenderer plsr + = new PointLightShadowRenderer(assetManager, SHADOWMAP_SIZE); + plsr.setLight((PointLight) scene.getLocalLightList().get(0)); + plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + + PointLightShadowFilter plsf + = new PointLightShadowFilter(assetManager, SHADOWMAP_SIZE); + plsf.setLight((PointLight) scene.getLocalLightList().get(0)); + plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + plsf.setEnabled(useFilter); + + //DIRECTIONAL LIGHT + DirectionalLight directionalLight = new DirectionalLight(); + rootNode.addLight(directionalLight); + directionalLight.setColor(ColorRGBA.Blue); + directionalLight.setDirection(new Vector3f(-1f, -.2f, 0f)); + + DirectionalLightShadowRenderer dlsr + = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE*2, 4); + dlsr.setLight(directionalLight); + dlsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + + DirectionalLightShadowFilter dlsf + = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE*2, 4); + dlsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + dlsf.setLight(directionalLight); + dlsf.setEnabled(useFilter); + + //SPOT LIGHT + spotLight = new SpotLight(); + spotLight.setDirection(new Vector3f(1f,-1f,0f)); + spotLight.setPosition(new Vector3f(-1f,3f,0f)); + spotLight.setSpotOuterAngle(0.5f); + spotLight.setColor(ColorRGBA.Green); + Sphere sphere = new Sphere(8, 8, .1f); + Geometry sphereGeometry = new Geometry("Sphere", sphere); + sphereGeometry.setLocalTranslation(-1f, 3f, 0f); + sphereGeometry.setMaterial(assetManager.loadMaterial("Common/Materials/WhiteColor.j3m")); + rootNode.attachChild(sphereGeometry); + rootNode.addLight(spotLight); + + SpotLightShadowRenderer slsr + = new SpotLightShadowRenderer(assetManager, SHADOWMAP_SIZE); + slsr.setLight(spotLight); + slsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + + SpotLightShadowFilter slsf + = new SpotLightShadowFilter(assetManager, SHADOWMAP_SIZE); + slsf.setLight(spotLight); + slsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + slsf.setEnabled(useFilter); + + + + if (!useFilter)viewPort.addProcessor(slsr); + if (!useFilter)viewPort.addProcessor(plsr); + if (!useFilter)viewPort.addProcessor(dlsr); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(plsf); + fpp.addFilter(dlsf); + fpp.addFilter(slsf); + viewPort.addProcessor(fpp); + + ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort); + ShadowTestUIManager uiManPls = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort); + ShadowTestUIManager uiManDls = new ShadowTestUIManager(assetManager, dlsr, dlsf, guiNode, inputManager, viewPort); + ShadowTestUIManager uiManSls = new ShadowTestUIManager(assetManager, slsr, slsf, guiNode, inputManager, viewPort); + + } + + private float timeElapsed = 0.0f; + @Override + public void simpleUpdate(float tpf) { + timeElapsed += tpf; + lightNode.setLocalTranslation(FastMath.cos(timeElapsed), lightNode.getLocalTranslation().y, FastMath.sin(timeElapsed)); + spotLight.setDirection(new Vector3f(FastMath.cos(-timeElapsed*.7f), -1.0f, FastMath.sin(-timeElapsed*.7f))); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java b/jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java new file mode 100644 index 0000000000..762e11df4a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestPointLightShadows.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.controls.ActionListener; +import com.jme3.light.AmbientLight; +import com.jme3.light.PointLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.shadow.PointLightShadowFilter; +import com.jme3.shadow.PointLightShadowRenderer; + +public class TestPointLightShadows extends SimpleApplication implements ActionListener{ + public static final int SHADOWMAP_SIZE = 512; + + public static void main(String[] args) { + TestPointLightShadows app = new TestPointLightShadows(); + app.start(); + } + private PointLightShadowRenderer plsr; + private AmbientLight al; + + @Override + public void simpleInitApp () { + flyCam.setMoveSpeed(10); + cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f)); + cam.setRotation(new Quaternion(4.3868728E-5f, 0.9999293f, -0.011230096f, 0.0039059948f)); + + al = new AmbientLight(ColorRGBA.White.mult(0.02f)); + rootNode.addLight(al); + + + + + Node scene = (Node) assetManager.loadModel("Models/Test/CornellBox.j3o"); + scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + rootNode.attachChild(scene); + rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive); + Node lightNode = (Node) rootNode.getChild("Lamp"); + Geometry lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setShadowMode(RenderQueue.ShadowMode.Off); + lightNode.attachChild(lightMdl); + //lightMdl.setLocalTranslation(lightNode.getLocalTranslation()); + + + Geometry box = new Geometry("box", new Box(0.2f, 0.2f, 0.2f)); + //Geometry lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f)); + box.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + box.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + rootNode.attachChild(box); + box.setLocalTranslation(-1f, 0.5f, -2); + + + plsr = new PointLightShadowRenderer(assetManager, SHADOWMAP_SIZE); + plsr.setLight((PointLight) scene.getLocalLightList().get(0)); + plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + plsr.setShadowZExtend(15); + plsr.setShadowZFadeLength(5); + plsr.setShadowIntensity(0.9f); + // plsr.setFlushQueues(false); + //plsr.displayFrustum(); + plsr.displayDebug(); + viewPort.addProcessor(plsr); + + PointLightShadowFilter plsf + = new PointLightShadowFilter(assetManager, SHADOWMAP_SIZE); + plsf.setLight((PointLight) scene.getLocalLightList().get(0)); + plsf.setShadowZExtend(15); + plsf.setShadowZFadeLength(5); + plsf.setShadowIntensity(0.8f); + plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + plsf.setEnabled(false); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(plsf); + viewPort.addProcessor(fpp); + inputManager.addListener(this,"ShadowUp","ShadowDown"); + ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort); + + } + + @Override + public void simpleUpdate(float tpf) { + // lightNode.move(FastMath.cos(tpf) * 0.4f, 0, FastMath.sin(tpf) * 0.4f); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if ((name.equals("ShadowUp") || name.equals("ShadowDown")) && isPressed) { + al.setColor(ColorRGBA.White.mult((1 - plsr.getShadowIntensity()) * 0.2f)); + } + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestShadowBug.java b/jme3-examples/src/main/java/jme3test/light/TestShadowBug.java new file mode 100644 index 0000000000..acf2d6df13 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestShadowBug.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2015 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. + */ +package jme3test.light; + + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.shadow.PointLightShadowRenderer; +import com.jme3.shadow.SpotLightShadowRenderer; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; + + +public class TestShadowBug extends SimpleApplication { + public static void main(String[] args) { + TestShadowBug app = new TestShadowBug(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(100f); + rootNode.attachChild(makeFloor()); + + Node characters = new Node("Characters"); + characters.setShadowMode(ShadowMode.Cast); + rootNode.attachChild(characters); + + Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + golem.scale(0.5f); + golem.setLocalTranslation(200.0f, -6f, 200f); + golem.setShadowMode(ShadowMode.CastAndReceive); + characters.attachChild(golem); + + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-1f, -1f, 1f)); + sun.setColor(ColorRGBA.White.mult(1.3f)); + rootNode.addLight(sun); + characters.addLight(sun); + + SpotLight spot = new SpotLight(); + spot.setSpotRange(13f); // distance + spot.setSpotInnerAngle(15f * FastMath.DEG_TO_RAD); // inner light cone (central beam) + spot.setSpotOuterAngle(20f * FastMath.DEG_TO_RAD); // outer light cone (edge of the light) + spot.setColor(ColorRGBA.White.mult(1.3f)); // light color + spot.setPosition(new Vector3f(192.0f, -1f, 192f)); + spot.setDirection(new Vector3f(1, -0.5f, 1)); + rootNode.addLight(spot); + + PointLight lamp_light = new PointLight(); + lamp_light.setColor(ColorRGBA.Yellow); + lamp_light.setRadius(20f); + lamp_light.setPosition(new Vector3f(210.0f, 0f, 210f)); + rootNode.addLight(lamp_light); + + SpotLightShadowRenderer slsr = new SpotLightShadowRenderer(assetManager, 512); + slsr.setLight(spot); + slsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest); + slsr.setShadowIntensity(0.6f); + viewPort.addProcessor(slsr); + + PointLightShadowRenderer plsr = new PointLightShadowRenderer(assetManager, 512); + plsr.setLight(lamp_light); + plsr.setShadowIntensity(0.6f); + plsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest); + viewPort.addProcessor(plsr); + + viewPort.getCamera().setLocation(new Vector3f(192.0f, 10f, 192f)); + float[] angles = new float[]{3.14f/2, 3.14f/2, 0}; + viewPort.getCamera().setRotation(new Quaternion(angles)); + } + + protected Geometry makeFloor() { + Box box = new Box(220, .2f, 220); + box.scaleTextureCoordinates(new Vector2f(10, 10)); + Geometry floor = new Geometry("the Floor", box); + floor.setLocalTranslation(200, -9, 200); + Material matGroundL = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matGroundL.setTexture("DiffuseMap", grass); + floor.setMaterial(matGroundL); + floor.setShadowMode(ShadowMode.CastAndReceive); + return floor; + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java b/jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java new file mode 100644 index 0000000000..857d4374fe --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.DirectionalLightShadowRenderer; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.util.TangentBinormalGenerator; + +public class TestShadowsPerf extends SimpleApplication { + + public static void main(String[] args) { + TestShadowsPerf app = new TestShadowsPerf(); + app.start(); + } + private Geometry sphere; + private Material mat; + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(50); + flyCam.setEnabled(false); + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + cam.setLocation(new Vector3f(-53.952988f, 27.15874f, -32.875023f)); + cam.setRotation(new Quaternion(0.1564309f, 0.6910534f, -0.15713608f, 0.6879555f)); + +// cam.setLocation(new Vector3f(53.64627f, 130.56f, -11.247704f)); +// cam.setRotation(new Quaternion(-6.5737107E-4f, 0.76819664f, -0.64021313f, -7.886125E-4f)); +//// + cam.setFrustumFar(500); + + mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + + Box b = new Box(800, 1, 700); + b.scaleTextureCoordinates(new Vector2f(50, 50)); + Geometry ground = new Geometry("ground", b); + ground.setMaterial(mat); + rootNode.attachChild(ground); + ground.setShadowMode(ShadowMode.Receive); + + Sphere sphMesh = new Sphere(32, 32, 1); + sphMesh.setTextureMode(Sphere.TextureMode.Projected); + sphMesh.updateGeometry(32, 32, 1, false, false); + TangentBinormalGenerator.generate(sphMesh); + + sphere = new Geometry("Rock Ball", sphMesh); + sphere.setLocalTranslation(0, 5, 0); + sphere.setMaterial(mat); + sphere.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(sphere); + + + + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(0, -1, 0).normalizeLocal()); + dl.setColor(ColorRGBA.White); + rootNode.addLight(dl); + + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.7f)); + rootNode.addLight(al); + //rootNode.setShadowMode(ShadowMode.CastAndReceive); + + createBalls(); + + final DirectionalLightShadowRenderer pssmRenderer = new DirectionalLightShadowRenderer(assetManager, 1024, 4); + viewPort.addProcessor(pssmRenderer); +// +// final PssmShadowFilter pssmRenderer = new PssmShadowFilter(assetManager, 1024, 4); +// FilterPostProcessor fpp = new FilterPostProcessor(assetManager); +// fpp.addFilter(pssmRenderer); +// viewPort.addProcessor(fpp); + + pssmRenderer.setLight(dl); + pssmRenderer.setLambda(0.55f); + pssmRenderer.setShadowIntensity(0.55f); + pssmRenderer.setShadowCompareMode(com.jme3.shadow.CompareMode.Software); + pssmRenderer.setEdgeFilteringMode(EdgeFilteringMode.PCF4); + //pssmRenderer.displayDebug(); + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("display") && isPressed) { + //pssmRenderer.debugFrustrums(); + System.out.println("tetetetet"); + } + if (name.equals("add") && isPressed) { + createBalls(); + } + } + }, "display", "add"); + inputManager.addMapping("display", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("add", new KeyTrigger(KeyInput.KEY_RETURN)); + } + private int val = 0; + + private void createBalls() { + System.out.println((frames / time) + ";" + val); + + + for (int i = val; i < val+1 ; i++) { + + Geometry s = sphere.clone().clone(false); + s.setMaterial(mat); + s.setLocalTranslation(i - 30, 5, (((i) * 2) % 40) - 50); + s.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(s); + } + if (val == 300) { + stop(); + } + val += 1; + time = 0; + frames = 0; + } + private float time; + private float frames = 0; + + @Override + public void simpleUpdate(float tpf) { + time += tpf; + frames++; + if (time > 1) { + createBalls(); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java b/jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java new file mode 100644 index 0000000000..535db645d3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.MaterialDebugAppState; +import com.jme3.util.TangentBinormalGenerator; + +public class TestSimpleLighting extends SimpleApplication { + + private float angle; + private PointLight pl; + private Geometry lightMdl; + + public static void main(String[] args){ + TestSimpleLighting app = new TestSimpleLighting(); + app.start(); + } + + @Override + public void simpleInitApp() { + Geometry teapot = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + TangentBinormalGenerator.generate(teapot.getMesh(), true); + + teapot.setLocalScale(2f); + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); +// mat.selectTechnique("GBuf"); + mat.setFloat("Shininess", 25); + mat.setBoolean("UseMaterialColors", true); + cam.setLocation(new Vector3f(0.015041917f, 0.4572918f, 5.2874837f)); + cam.setRotation(new Quaternion(-1.8875003E-4f, 0.99882424f, 0.04832061f, 0.0039016632f)); + +// mat.setTexture("ColorRamp", assetManager.loadTexture("Textures/ColorRamp/cloudy.png")); +// +// mat.setBoolean("VTangent", true); +// mat.setBoolean("Minnaert", true); +// mat.setBoolean("WardIso", true); +// mat.setBoolean("VertexLighting", true); +// mat.setBoolean("LowQuality", true); +// mat.setBoolean("HighQuality", true); + + mat.setColor("Ambient", ColorRGBA.Black); + mat.setColor("Diffuse", ColorRGBA.Gray); + mat.setColor("Specular", ColorRGBA.Gray); + + teapot.setMaterial(mat); + rootNode.attachChild(teapot); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.getMesh().setStatic(); + rootNode.attachChild(lightMdl); + + pl = new PointLight(); + pl.setColor(ColorRGBA.White); + pl.setRadius(4f); + rootNode.addLight(pl); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + dl.setColor(ColorRGBA.Green); + rootNode.addLight(dl); + + + MaterialDebugAppState debug = new MaterialDebugAppState(); + debug.registerBinding("Common/ShaderLib/BlinnPhongLighting.glsllib", teapot); + stateManager.attach(debug); + setPauseOnLostFocus(false); + flyCam.setDragToRotate(true); + + } + + @Override + public void simpleUpdate(float tpf){ +// cam.setLocation(new Vector3f(2.0632997f, 1.9493936f, 2.6885238f)); +// cam.setRotation(new Quaternion(-0.053555284f, 0.9407851f, -0.17754152f, -0.28378546f)); + + angle += tpf; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 2f, 0.5f, FastMath.sin(angle) * 2f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSpotLight.java b/jme3-examples/src/main/java/jme3test/light/TestSpotLight.java new file mode 100644 index 0000000000..e65c1763da --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestSpotLight.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.TangentBinormalGenerator; + +public class TestSpotLight extends SimpleApplication { + + final private Vector3f lightTarget = new Vector3f(12, 3.5f, 30); + + public static void main(String[] args){ + TestSpotLight app = new TestSpotLight(); + app.start(); + } + + private SpotLight spot; + private Geometry lightMdl; + public void setupLighting(){ + AmbientLight al=new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.02f)); + rootNode.addLight(al); + + spot=new SpotLight(); + + spot.setSpotRange(1000); + spot.setSpotInnerAngle(5*FastMath.DEG_TO_RAD); + spot.setSpotOuterAngle(10*FastMath.DEG_TO_RAD); + spot.setPosition(new Vector3f(77.70334f, 34.013165f, 27.1017f)); + spot.setDirection(lightTarget.subtract(spot.getPosition())); + spot.setColor(ColorRGBA.White.mult(2)); + rootNode.addLight(spot); + + +// PointLight pl=new PointLight(); +// pl.setPosition(new Vector3f(77.70334f, 34.013165f, 27.1017f)); +// pl.setRadius(1000); +// pl.setColor(ColorRGBA.White.mult(2)); +// rootNode.addLight(pl); + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setLocalTranslation(new Vector3f(77.70334f, 34.013165f, 27.1017f)); + lightMdl.setLocalScale(5); + rootNode.attachChild(lightMdl); + +// DirectionalLight dl = new DirectionalLight(); +// dl.setDirection(lightTarget.subtract(new Vector3f(77.70334f, 34.013165f, 27.1017f))); +// dl.setColor(ColorRGBA.White.mult(2)); +// rootNode.addLight(dl); + + + } + + public void setupFloor(){ + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat); + mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat); + // mat.getTextureParam("ParallaxMap").getTextureValue().setWrap(WrapMode.Repeat); + mat.setFloat("Shininess",3); + // mat.setBoolean("VertexLighting", true); + + + Box floor = new Box(50, 1f, 50); + TangentBinormalGenerator.generate(floor); + floor.scaleTextureCoordinates(new Vector2f(5, 5)); + Geometry floorGeom = new Geometry("Floor", floor); + floorGeom.setMaterial(mat); + floorGeom.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(floorGeom); + } + + + + public void setupSignpost(){ + Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); + Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + // mat.setBoolean("VertexLighting", true); + signpost.setMaterial(mat); + signpost.rotate(0, FastMath.HALF_PI, 0); + signpost.setLocalTranslation(12, 3.5f, 30); + signpost.setLocalScale(4); + signpost.setShadowMode(ShadowMode.CastAndReceive); + TangentBinormalGenerator.generate(signpost); + rootNode.attachChild(signpost); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(27.492603f, 29.138166f, -13.232513f)); + cam.setRotation(new Quaternion(0.25168246f, -0.10547892f, 0.02760565f, 0.96164864f)); + flyCam.setMoveSpeed(30); + + setupLighting(); + setupFloor(); + setupSignpost(); + + + } + + private float angle; + + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + angle += tpf; + angle %= FastMath.TWO_PI; + + spot.setPosition(new Vector3f(FastMath.cos(angle) * 30f, 34.013165f, FastMath.sin(angle) * 30f)); + lightMdl.setLocalTranslation(spot.getPosition()); + spot.setDirection(lightTarget.subtract(spot.getPosition())); + } + + + +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java b/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java new file mode 100644 index 0000000000..3c6c653102 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.shadow.SpotLightShadowFilter; +import com.jme3.shadow.SpotLightShadowRenderer; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.TangentBinormalGenerator; + +public class TestSpotLightShadows extends SimpleApplication { + + final private Vector3f lightTarget = new Vector3f(12, 3.5f, 30); + + public static void main(String[] args) { + TestSpotLightShadows app = new TestSpotLightShadows(); + app.start(); + } + private SpotLight spot; + private Geometry lightMdl; + + public void setupLighting() { + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.02f)); + rootNode.addLight(al); + + rootNode.setShadowMode(ShadowMode.CastAndReceive); + + spot = new SpotLight(); + + spot.setSpotRange(1000); + spot.setSpotInnerAngle(5f * FastMath.DEG_TO_RAD); + spot.setSpotOuterAngle(10 * FastMath.DEG_TO_RAD); + spot.setPosition(new Vector3f(70.70334f, 34.013165f, 27.1017f)); + spot.setDirection(lightTarget.subtract(spot.getPosition()).normalizeLocal()); + spot.setColor(ColorRGBA.White.mult(2)); + rootNode.addLight(spot); + + +// PointLight pl=new PointLight(); +// pl.setPosition(new Vector3f(77.70334f, 34.013165f, 27.1017f)); +// pl.setRadius(1000); +// pl.setColor(ColorRGBA.White.mult(2)); +// rootNode.addLight(pl); + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.setLocalTranslation(new Vector3f(77.70334f, 34.013165f, 27.1017f)); + lightMdl.setLocalScale(5); + rootNode.attachChild(lightMdl); + +// DirectionalLight dl = new DirectionalLight(); +// dl.setDirection(lightTarget.subtract(new Vector3f(77.70334f, 34.013165f, 27.1017f))); +// dl.setColor(ColorRGBA.White.mult(0.7f)); +// rootNode.addLight(dl); + + + final SpotLightShadowRenderer slsr = new SpotLightShadowRenderer(assetManager, 512); + slsr.setLight(spot); + slsr.setShadowIntensity(0.5f); + slsr.setShadowZExtend(100); + slsr.setShadowZFadeLength(5); + slsr.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON); + viewPort.addProcessor(slsr); + + SpotLightShadowFilter slsf = new SpotLightShadowFilter(assetManager, 512); + slsf.setLight(spot); + slsf.setShadowIntensity(0.5f); + slsf.setShadowZExtend(100); + slsf.setShadowZFadeLength(5); + slsf.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON); + slsf.setEnabled(false); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(slsf); + viewPort.addProcessor(fpp); + + ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, slsr, slsf, guiNode, inputManager, viewPort); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("stop") && isPressed) { + stop = !stop; + // slsr.displayFrustum(); + System.out.println("pos : " + spot.getPosition()); + System.out.println("dir : " + spot.getDirection()); + } + } + }, "stop"); + + inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_1)); + flyCam.setDragToRotate(true); + } + + public void setupFloor() { + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat); + mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat); + mat.setBoolean("UseMaterialColors", true); + mat.setColor("Diffuse", ColorRGBA.White.clone()); + mat.setColor("Ambient", ColorRGBA.White.clone()); + // mat.setColor("Specular", ColorRGBA.White.clone()); + // mat.getTextureParam("ParallaxMap").getTextureValue().setWrap(WrapMode.Repeat); + mat.setFloat("Shininess", 0); + // mat.setBoolean("VertexLighting", true); + + + Box floor = new Box(50, 1f, 50); + TangentBinormalGenerator.generate(floor); + floor.scaleTextureCoordinates(new Vector2f(5, 5)); + Geometry floorGeom = new Geometry("Floor", floor); + floorGeom.setMaterial(mat); + floorGeom.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(floorGeom); + } + + public void setupSignpost() { + Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); + Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + // mat.setBoolean("VertexLighting", true); + signpost.setMaterial(mat); + signpost.rotate(0, FastMath.HALF_PI, 0); + signpost.setLocalTranslation(12, 3.5f, 30); + signpost.setLocalScale(4); + signpost.setShadowMode(ShadowMode.CastAndReceive); + TangentBinormalGenerator.generate(signpost); + rootNode.attachChild(signpost); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(27.492603f, 29.138166f, -13.232513f)); + cam.setRotation(new Quaternion(0.25168246f, -0.10547892f, 0.02760565f, 0.96164864f)); + flyCam.setMoveSpeed(30); + + setupLighting(); + setupFloor(); + setupSignpost(); + + + } + private float angle; + private boolean stop = true; + + @Override + public void simpleUpdate(float tpf) { + if (!stop) { + super.simpleUpdate(tpf); + angle += tpf; + angle %= FastMath.TWO_PI; + + spot.setPosition(new Vector3f(FastMath.cos(angle) * 30f, 34.013165f, FastMath.sin(angle) * 30f)); + lightMdl.setLocalTranslation(spot.getPosition()); + spot.setDirection(lightTarget.subtract(spot.getPosition())); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java b/jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java new file mode 100644 index 0000000000..9fa5a0ea36 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestSpotLightTerrain.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.light.AmbientLight; +import com.jme3.light.SpotLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.SkyFactory; + +/** + * Uses the terrain's lighting texture with normal maps and lights. + * + * @author bowens + */ +public class TestSpotLightTerrain extends SimpleApplication { + + final private float grassScale = 64; + final private float dirtScale = 16; + final private float rockScale = 128; + private SpotLight sl; + + public static void main(String[] args) { + TestSpotLightTerrain app = new TestSpotLightTerrain(); + app.start(); + } + + + @Override + public void simpleInitApp() { + makeTerrain(); + flyCam.setMoveSpeed(50); + + sl = new SpotLight(); + sl.setSpotRange(100); + sl.setSpotOuterAngle(20 * FastMath.DEG_TO_RAD); + sl.setSpotInnerAngle(15 * FastMath.DEG_TO_RAD); + sl.setDirection(new Vector3f(-0.39820394f, -0.73094344f, 0.55421597f)); + sl.setPosition(new Vector3f(-64.61567f, -87.615425f, -202.41328f)); + rootNode.addLight(sl); + + AmbientLight ambLight = new AmbientLight(); + ambLight.setColor(ColorRGBA.Black); + rootNode.addLight(ambLight); + + cam.setLocation(new Vector3f(-41.219646f, 0.8363f, -171.67267f)); + cam.setRotation(new Quaternion(-0.04562731f, 0.89917684f, -0.09668826f, -0.4243236f)); + sl.setDirection(cam.getDirection()); + sl.setPosition(cam.getLocation()); + + } + + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + sl.setDirection(cam.getDirection()); + sl.setPosition(cam.getLocation()); + + } + + private void makeTerrain() { + // TERRAIN TEXTURE material + Material matTerrain = new Material(assetManager, + "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matTerrain.setBoolean("useTriPlanarMapping", false); + matTerrain.setBoolean("WardIso", true); + + // ALPHA map (for splat textures) + matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); + matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); + + // HEIGHTMAP image (for the terrain heightmap) + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + + + // GRASS texture + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap", grass); + matTerrain.setFloat("DiffuseMap_0_scale", grassScale); + + // DIRT texture + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_1", dirt); + matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); + + // ROCK texture + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_2", rock); + matTerrain.setFloat("DiffuseMap_2_scale", rockScale); + + // BRICK texture + Texture brick = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"); + brick.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_3", brick); + matTerrain.setFloat("DiffuseMap_3_scale", rockScale); + + // RIVER ROCK texture + Texture riverRock = assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"); + riverRock.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_4", riverRock); + matTerrain.setFloat("DiffuseMap_4_scale", rockScale); + + + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(WrapMode.Repeat); + matTerrain.setTexture("NormalMap", normalMap0); + matTerrain.setTexture("NormalMap_1", normalMap1); + matTerrain.setTexture("NormalMap_2", normalMap2); + matTerrain.setTexture("NormalMap_4", normalMap2); + + // WIREFRAME material + Material matWire = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + matWire.getAdditionalRenderState().setWireframe(true); + matWire.setColor("Color", ColorRGBA.Green); + + createSky(); + + // CREATE HEIGHTMAP + AbstractHeightMap heightmap = null; + try { + //heightmap = new HillHeightMap(1025, 1000, 50, 100, (byte) 3); + + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f); + heightmap.load(); + + } catch (Exception e) { + e.printStackTrace(); + } + + TerrainQuad terrain + = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations + TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); + control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); + terrain.addControl(control); + terrain.setMaterial(matTerrain); + terrain.setModelBound(new BoundingBox()); + terrain.updateModelBound(); + terrain.setLocalTranslation(0, -100, 0); + terrain.setLocalScale(1f, 1f, 1f); + rootNode.attachChild(terrain); + } + + private void createSky() { + Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg"); + Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg"); + Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg"); + Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg"); + Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg"); + Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg"); + + Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down); + rootNode.attachChild(sky); + } + + +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentCube.java b/jme3-examples/src/main/java/jme3test/light/TestTangentCube.java new file mode 100644 index 0000000000..13841f986f --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestTangentCube.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009-2015 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. + */ +package jme3test.light; + +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.util.TangentBinormalGenerator; + +/** + * + * @author Nehon + */ +public class TestTangentCube extends SimpleApplication { + + public static void main(String... args) { + TestTangentCube app = new TestTangentCube(); + app.start(); + } + + @Override + public void simpleInitApp() { + Box aBox = new Box(1, 1, 1); + Geometry aGeometry = new Geometry("Box", aBox); + TangentBinormalGenerator.generate(aBox); + + Material aMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + aMaterial.setTexture("DiffuseMap", + assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg")); + aMaterial.setTexture("NormalMap", + assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall_normal.jpg")); + aMaterial.setBoolean("UseMaterialColors", false); + aMaterial.setColor("Diffuse", ColorRGBA.White); + aMaterial.setColor("Specular", ColorRGBA.White); + aMaterial.setFloat("Shininess", 64f); + aGeometry.setMaterial(aMaterial); + + // Rotate 45 degrees to see multiple faces + aGeometry.rotate(FastMath.QUARTER_PI, FastMath.QUARTER_PI, 0.0f); + rootNode.attachChild(aGeometry); + + /* + * Must add a light to make the lit object visible! + */ + PointLight aLight = new PointLight(); + aLight.setPosition(new Vector3f(0, 3, 3)); + aLight.setColor(ColorRGBA.Red); + rootNode.addLight(aLight); +// +// AmbientLight bLight = new AmbientLight(); +// bLight.setColor(ColorRGBA.Gray); +// rootNode.addLight(bLight); + + + ChaseCameraAppState chaser = new ChaseCameraAppState(); + chaser.setTarget(aGeometry); + getStateManager().attach(chaser); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentGen.java b/jme3-examples/src/main/java/jme3test/light/TestTangentGen.java new file mode 100644 index 0000000000..80fd44084c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestTangentGen.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Mesh.Mode; +import com.jme3.scene.Spatial; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.scene.shape.Quad; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.BufferUtils; +import com.jme3.util.TangentBinormalGenerator; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + + +public class TestTangentGen extends SimpleApplication { + + public static void main(String[] args){ + TestTangentGen app = new TestTangentGen(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(20); + Sphere sphereMesh = new Sphere(32, 32, 1); + sphereMesh.setTextureMode(Sphere.TextureMode.Projected); + sphereMesh.updateGeometry(32, 32, 1, false, false); + addMesh("Sphere", sphereMesh, new Vector3f(-1, 0, 0)); + + Quad quadMesh = new Quad(1, 1); + quadMesh.updateGeometry(1, 1); + addMesh("Quad", quadMesh, new Vector3f(1, 0, 0)); + + Mesh strip = createTriangleStripMesh(); + addMesh("strip", strip, new Vector3f(0, -3, 0)); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1, -1, -1).normalizeLocal()); + dl.setColor(ColorRGBA.White); + rootNode.addLight(dl); + } + + private void addMesh(String name, Mesh mesh, Vector3f translation) { + TangentBinormalGenerator.generate(mesh); + + Geometry testGeom = new Geometry(name, mesh); + Material mat = assetManager.loadMaterial("Textures/BumpMapTest/Tangent.j3m"); + testGeom.setMaterial(mat); + testGeom.getLocalTranslation().set(translation); + rootNode.attachChild(testGeom); + + Geometry debug = new Geometry( + "Debug " + name, + TangentBinormalGenerator.genTbnLines(mesh, 0.08f) + ); + Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m"); + debug.setMaterial(debugMat); + debug.setCullHint(Spatial.CullHint.Never); + debug.getLocalTranslation().set(translation); + rootNode.attachChild(debug); + } + + @Override + public void simpleUpdate(float tpf){ + } + + private Mesh createTriangleStripMesh() { + Mesh strip = new Mesh(); + strip.setMode(Mode.TriangleStrip); + FloatBuffer vb = BufferUtils.createFloatBuffer(3*3*3); // 3 rows * 3 columns * 3 floats + vb.rewind(); + vb.put(new float[]{0,2,0}); vb.put(new float[]{1,2,0}); vb.put(new float[]{2,2,0}); + vb.put(new float[]{0,1,0}); vb.put(new float[]{1,1,0}); vb.put(new float[]{2,1,0}); + vb.put(new float[]{0,0,0}); vb.put(new float[]{1,0,0}); vb.put(new float[]{2,0,0}); + FloatBuffer nb = BufferUtils.createFloatBuffer(3*3*3); + nb.rewind(); + nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); + nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); + nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); nb.put(new float[]{0,0,1}); + FloatBuffer tb = BufferUtils.createFloatBuffer(3*3*2); + tb.rewind(); + tb.put(new float[]{0,0}); tb.put(new float[]{0.5f,0}); tb.put(new float[]{1,0}); + tb.put(new float[]{0,0.5f}); tb.put(new float[]{0.5f,0.5f}); tb.put(new float[]{1,0.5f}); + tb.put(new float[]{0,1}); tb.put(new float[]{0.5f,1}); tb.put(new float[]{1,1}); + int[] indexes = new int[]{0,3,1,4,2,5, 5,3, 3,6,4,7,5,8}; + IntBuffer ib = BufferUtils.createIntBuffer(indexes.length); + ib.put(indexes); + strip.setBuffer(Type.Position, 3, vb); + strip.setBuffer(Type.Normal, 3, nb); + strip.setBuffer(Type.TexCoord, 2, tb); + strip.setBuffer(Type.Index, 3, ib); + strip.updateBound(); + return strip; + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java b/jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java new file mode 100644 index 0000000000..9121d09154 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TangentBinormalGenerator; + +public class TestTangentGenBadUV extends SimpleApplication { + + private float angle; + private PointLight pl; + private Geometry lightMdl; + + public static void main(String[] args){ + TestTangentGenBadUV app = new TestTangentGenBadUV(); + app.start(); + } + + @Override + public void simpleInitApp() { + Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); + if (teapot instanceof Geometry){ + Geometry g = (Geometry) teapot; + TangentBinormalGenerator.generate(g.getMesh()); + }else{ + throw new RuntimeException(); + } + teapot.setLocalScale(2f); + Material mat = assetManager.loadMaterial("Textures/BumpMapTest/Tangent.j3m"); + teapot.setMaterial(mat); + rootNode.attachChild(teapot); + + Geometry debug = new Geometry( + "Debug Teapot", + TangentBinormalGenerator.genTbnLines(((Geometry) teapot).getMesh(), 0.03f) + ); + Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m"); + debug.setMaterial(debugMat); + debug.setCullHint(Spatial.CullHint.Never); + debug.getLocalTranslation().set(teapot.getLocalTranslation()); + debug.getLocalScale().set(teapot.getLocalScale()); + rootNode.attachChild(debug); + + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1,-1,-1).normalizeLocal()); + dl.setColor(ColorRGBA.White); + rootNode.addLight(dl); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.getMesh().setStatic(); + rootNode.attachChild(lightMdl); + + pl = new PointLight(); + pl.setColor(ColorRGBA.White); + //pl.setRadius(3f); + rootNode.addLight(pl); + } + + @Override + public void simpleUpdate(float tpf){ + angle += tpf; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 2f, 0.5f, FastMath.sin(angle) * 2f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java b/jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java new file mode 100644 index 0000000000..f4cd8c4215 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.*; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.util.TangentBinormalGenerator; +import com.jme3.util.mikktspace.MikktspaceTangentGenerator; + +/** + * test + * + * @author normenhansen + */ +public class TestTangentSpace extends SimpleApplication { + + public static void main(String[] args) { + TestTangentSpace app = new TestTangentSpace(); + app.start(); + } + + final private Node debugNode = new Node("debug"); + + @Override + public void simpleInitApp() { + renderManager.setSinglePassLightBatchSize(2); + renderManager.setPreferredLightMode(TechniqueDef.LightMode.SinglePass); + initView(); + + Spatial s = assetManager.loadModel("Models/Test/BasicCubeLow.obj"); + rootNode.attachChild(s); + + Material m = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + m.setTexture("NormalMap", assetManager.loadTexture("Models/Test/Normal_pixel.png")); + + Geometry g = (Geometry)s; + Geometry g2 = (Geometry) g.deepClone(); + g2.move(5, 0, 0); + g.getParent().attachChild(g2); + + g.setMaterial(m); + g2.setMaterial(m); + + //Regular tangent generation (left geom) + TangentBinormalGenerator.generate(g2.getMesh(), true); + + //MikkTSPace Tangent generation (right geom) + + MikktspaceTangentGenerator.generate(g); + + createDebugTangents(g2); + createDebugTangents(g); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("toggleDebug") && isPressed) { + if (debugNode.getParent() == null) { + rootNode.attachChild(debugNode); + } else { + debugNode.removeFromParent(); + } + } + } + }, "toggleDebug"); + + inputManager.addMapping("toggleDebug", new KeyTrigger(KeyInput.KEY_SPACE)); + + + DirectionalLight dl = new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()); + rootNode.addLight(dl); + } + + private void initView() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + cam.setLocation(new Vector3f(8.569681f, 3.335546f, 5.4372444f)); + cam.setRotation(new Quaternion(-0.07608022f, 0.9086564f, -0.18992864f, -0.3639813f)); + flyCam.setMoveSpeed(10); + } + + private void createDebugTangents(Geometry geom) { + Geometry debug = new Geometry( + "Debug " + geom.getName(), + TangentBinormalGenerator.genTbnLines(geom.getMesh(), 0.8f) + ); + Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m"); + debug.setMaterial(debugMat); + debug.setCullHint(Spatial.CullHint.Never); + debug.getLocalTranslation().set(geom.getWorldTranslation()); + debugNode.attachChild(debug); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java b/jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java new file mode 100644 index 0000000000..b013dc6c1d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +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.scene.shape.RectangleMesh; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.CompareMode; +import com.jme3.shadow.DirectionalLightShadowRenderer; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.util.TangentBinormalGenerator; + +public class TestTransparentShadow extends SimpleApplication { + + public static void main(String[] args){ + TestTransparentShadow app = new TestTransparentShadow(); + app.start(); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(5.700248f, 6.161693f, 5.1404157f)); + cam.setRotation(new Quaternion(-0.09441641f, 0.8993388f, -0.24089815f, -0.35248178f)); + + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + RectangleMesh rm = new RectangleMesh( + new Vector3f(-10, 0, 10), + new Vector3f(10, 0, 10), + new Vector3f(-10, 0, -10) + ); + rm.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10)); + TangentBinormalGenerator.generate(rm); + + Geometry geom = new Geometry("floor", rm); + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + geom.setMaterial(mat); + geom.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(geom); + + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.7f)); + rootNode.addLight(al); + + DirectionalLight dl1 = new DirectionalLight(); + dl1.setDirection(new Vector3f(0, -1, 0.5f).normalizeLocal()); + dl1.setColor(ColorRGBA.White.mult(1.5f)); + rootNode.addLight(dl1); + + // create the geometry and attach it + Spatial tree = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); + tree.setQueueBucket(Bucket.Transparent); + tree.setShadowMode(ShadowMode.CastAndReceive); + + rootNode.attachChild(tree); + + // Uses Texture from jme3-testdata library! + ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30); + Material mat_red = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat_red.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); + fire.setShadowMode(ShadowMode.Cast); + fire.setMaterial(mat_red); + fire.setImagesX(2); + fire.setImagesY(2); // 2x2 texture animation + fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f)); // red + fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow + fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0)); + fire.setStartSize(0.6f); + fire.setEndSize(0.1f); + fire.setGravity(0, 0, 0); + fire.setLowLife(0.5f); + fire.setHighLife(1.5f); + fire.getParticleInfluencer().setVelocityVariation(0.3f); + fire.setLocalTranslation(5.0f, 0, 1.0f); + fire.setLocalScale(0.3f); + fire.setQueueBucket(Bucket.Translucent); + rootNode.attachChild(fire); + + Material mat2 = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + + Geometry ball = new Geometry("sphere", new Sphere(16, 16, 0.5f)); + ball.setMaterial(mat2); + ball.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(ball); + ball.setLocalTranslation(-1.0f, 1.5f, 1.0f); + + final DirectionalLightShadowRenderer dlsRenderer = new DirectionalLightShadowRenderer(assetManager, 1024, 1); + dlsRenderer.setLight(dl1); + dlsRenderer.setLambda(0.55f); + dlsRenderer.setShadowIntensity(0.8f); + dlsRenderer.setShadowCompareMode(CompareMode.Software); + dlsRenderer.setEdgeFilteringMode(EdgeFilteringMode.Nearest); + dlsRenderer.displayDebug(); + viewPort.addProcessor(dlsRenderer); + inputManager.addMapping("stabilize", new KeyTrigger(KeyInput.KEY_B)); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("stabilize") && isPressed) { + dlsRenderer.setEnabledStabilization(!dlsRenderer.isEnabledStabilization()) ; + } + } + }, "stabilize"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java b/jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java new file mode 100644 index 0000000000..e5dfdc754c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.light; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.material.RenderState; +import com.jme3.material.TechniqueDef; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TangentBinormalGenerator; + +/** + * Checks two-sided lighting capability. + * + * @author Kirill Vainer + */ +public class TestTwoSideLighting extends SimpleApplication { + + private float angle; + private PointLight pl; + private Geometry lightMdl; + + public static void main(String[] args){ + TestTwoSideLighting app = new TestTwoSideLighting(); + app.start(); + } + + @Override + public void simpleInitApp() { + // Two-sided lighting requires single pass. + renderManager.setPreferredLightMode(TechniqueDef.LightMode.SinglePass); + renderManager.setSinglePassLightBatchSize(4); + + cam.setLocation(new Vector3f(5.936224f, 3.3759952f, -3.3202777f)); + cam.setRotation(new Quaternion(0.16265652f, -0.4811838f, 0.09137692f, 0.8565368f)); + + Geometry quadGeom = new Geometry("quad", new Quad(1, 1)); + quadGeom.move(1, 0, 0); + Material mat1 = assetManager.loadMaterial("Textures/BumpMapTest/SimpleBump.j3m"); + + // Display both front and back faces. + mat1.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off); + + quadGeom.setMaterial(mat1); + // SimpleBump material requires tangents. + TangentBinormalGenerator.generate(quadGeom); + rootNode.attachChild(quadGeom); + + Geometry teapot = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + teapot.move(-1, 0, 0); + teapot.setLocalScale(2f); + Material mat2 = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + mat2.setFloat("Shininess", 25); + mat2.setBoolean("UseMaterialColors", true); + mat2.setColor("Ambient", ColorRGBA.Black); + mat2.setColor("Diffuse", ColorRGBA.Gray); + mat2.setColor("Specular", ColorRGBA.Gray); + + // Only display backfaces. + mat2.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Front); + + teapot.setMaterial(mat2); + rootNode.attachChild(teapot); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + lightMdl.getMesh().setStatic(); + rootNode.attachChild(lightMdl); + + pl = new PointLight(); + pl.setColor(ColorRGBA.White); + pl.setRadius(4f); + rootNode.addLight(pl); + } + + @Override + public void simpleUpdate(float tpf){ + angle += tpf; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 3f, 0.5f, FastMath.sin(angle) * 3f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/package-info.java b/jme3-examples/src/main/java/jme3test/light/package-info.java new file mode 100644 index 0000000000..a896fc8170 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for lighting + */ +package jme3test.light; diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java b/jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java new file mode 100644 index 0000000000..038fca3fe6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/ConsoleProgressReporter.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light.pbr; + +import com.jme3.environment.generation.JobProgressAdapter; +import com.jme3.light.LightProbe; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * A basic logger for environment map rendering progress. + * @author nehon + */ +public class ConsoleProgressReporter extends JobProgressAdapter{ + + private static final Logger logger = Logger.getLogger(ConsoleProgressReporter.class.getName()); + + private long time; + + @Override + public void start() { + time = System.currentTimeMillis(); + logger.log(Level.INFO,"Starting generation"); + } + + @Override + public void progress(double value) { + if (logger.isLoggable(Level.INFO)) { + logger.log(Level.INFO, "Progress : {0}%", (value * 100)); + } + } + + @Override + public void step(String message) { + logger.info(message); + } + + @Override + public void done(LightProbe result) { + long end = System.currentTimeMillis(); + if (logger.isLoggable(Level.INFO)) { + logger.log(Level.INFO, "Generation done in {0}", (end - time) / 1000f); + } + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java b/jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java new file mode 100644 index 0000000000..ff32877ad8 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/RefEnv.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.light.pbr; + +import com.jme3.app.SimpleApplication; +import com.jme3.environment.EnvironmentCamera; +import com.jme3.environment.LightProbeFactory; +import com.jme3.environment.generation.JobProgressAdapter; +import com.jme3.environment.util.EnvMapUtils; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.LightProbe; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.scene.*; +import com.jme3.ui.Picture; +import com.jme3.util.SkyFactory; + +/** + * test + * + * @author nehon + */ +public class RefEnv extends SimpleApplication { + + private Node tex; + private Node ref; + private Picture refImg; + + public static void main(String[] args) { + RefEnv app = new RefEnv(); + app.start(); + } + + @Override + public void simpleInitApp() { + + cam.setLocation(new Vector3f(-17.95047f, 4.917353f, -17.970531f)); + cam.setRotation(new Quaternion(0.11724457f, 0.29356146f, -0.03630452f, 0.94802815f)); +// cam.setLocation(new Vector3f(14.790441f, 7.164179f, 19.720007f)); +// cam.setRotation(new Quaternion(-0.038261678f, 0.9578362f, -0.15233073f, -0.24058504f)); + flyCam.setDragToRotate(true); + flyCam.setMoveSpeed(5); + Spatial sc = assetManager.loadModel("Scenes/PBR/ref/scene.gltf"); + rootNode.attachChild(sc); + Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap); + rootNode.attachChild(sky); + rootNode.getChild(0).setCullHint(Spatial.CullHint.Always); + + ref = new Node("reference pictures"); + refImg = new Picture("refImg"); + refImg.setHeight(cam.getHeight()); + refImg.setWidth(cam.getWidth()); + refImg.setImage(assetManager, "jme3test/light/pbr/ref.png", false); + + ref.attachChild(refImg); + + stateManager.attach(new EnvironmentCamera(256, Vector3f.ZERO)); + + inputManager.addMapping("tex", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("switch", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addMapping("ref", new KeyTrigger(KeyInput.KEY_R)); + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("tex") && isPressed) { + if (tex == null) { + tex = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(stateManager.getState(EnvironmentCamera.class).debugEnv, assetManager); + } + if (tex.getParent() == null) { + guiNode.attachChild(tex); + } else { + tex.removeFromParent(); + } + } + + if (name.equals("switch") && isPressed) { + switchMat(rootNode.getChild("Scene")); + } + if (name.equals("ref") && isPressed) { + if (ref.getParent() == null) { + guiNode.attachChild(ref); + } else { + ref.removeFromParent(); + } + } + } + }, "tex", "switch", "ref"); + + } + + private void switchMat(Spatial s) { + if (s instanceof Node) { + Node n = (Node) s; + for (Spatial children : n.getChildren()) { + switchMat(children); + } + } else if (s instanceof Geometry) { + Geometry g = (Geometry) s; + Material mat = g.getMaterial(); + if (((Float) mat.getParam("Metallic").getValue()) == 1f) { + mat.setFloat("Metallic", 0); + mat.setColor("BaseColor", ColorRGBA.Black); + ref.attachChild(refImg); + } else { + mat.setFloat("Metallic", 1); + mat.setColor("BaseColor", ColorRGBA.White); + refImg.removeFromParent(); + } + } + } + + private int frame = 0; + + @Override + public void simpleUpdate(float tpf) { + frame++; + + EnvironmentCamera eCam = stateManager.getState(EnvironmentCamera.class); + if (frame == 2) { + final LightProbe probe = LightProbeFactory.makeProbe(eCam, rootNode, EnvMapUtils.GenerationType.Fast, new JobProgressAdapter() { + + @Override + public void done(LightProbe result) { + System.err.println("Done rendering env maps"); + tex = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(result.getPrefilteredEnvMap(), assetManager); + rootNode.getChild(0).setCullHint(Spatial.CullHint.Dynamic); + } + }); + probe.getArea().setRadius(100); + rootNode.addLight(probe); + + } + + if (eCam.isBusy()) { + System.out.println("EnvironmentCamera busy as of frame " + frame); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java new file mode 100644 index 0000000000..9a9c79d2eb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1340.java @@ -0,0 +1,92 @@ +package jme3test.light.pbr; + +import com.jme3.anim.SkinningControl; +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.UrlLocator; +import com.jme3.environment.EnvironmentCamera; +import com.jme3.environment.LightProbeFactory; +import com.jme3.environment.generation.JobProgressAdapter; +import com.jme3.light.DirectionalLight; +import com.jme3.light.LightProbe; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.system.AppSettings; + +/** + * This test case validates a shader compilation fix with a model using a PBR material in combination with a + * SkinningControl. When you run this application and don't see a RenderException, the test is successful. + * For a detailed explanation consult the GitHub issue: https://github.com/jMonkeyEngine/jmonkeyengine/issues/1340 + * -rvandoosselaer + */ +public class TestIssue1340 extends SimpleApplication { + + private Spatial model; + private int frame; + + public static void main(String[] args) { + TestIssue1340 testIssue1340 = new TestIssue1340(); + testIssue1340.setSettings(createSettings()); + testIssue1340.start(); + } + + private static AppSettings createSettings() { + AppSettings settings = new AppSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL32); + return settings; + } + + @Override + public void simpleInitApp() { + stateManager.attach(new EnvironmentCamera(32)); + + DirectionalLight light = new DirectionalLight(Vector3f.UNIT_Y.negate(), ColorRGBA.White); + rootNode.addLight(light); + + assetManager.registerLocator("https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/RiggedFigure/", UrlLocator.class); + + model = assetManager.loadModel("/glTF-Embedded/RiggedFigure.gltf"); + SkinningControl skinningControl = getSkinningControl(model); + if (skinningControl == null || !skinningControl.isHardwareSkinningPreferred()) { + throw new IllegalArgumentException("This test case requires a model with a SkinningControl and with Hardware skinning preferred!"); + } + + viewPort.setBackgroundColor(ColorRGBA.LightGray); + } + + @Override + public void simpleUpdate(float tpf) { + frame++; + if (frame == 2) { + LightProbeFactory.makeProbe(stateManager.getState(EnvironmentCamera.class), rootNode, new JobProgressAdapter() { + @Override + public void done(LightProbe result) { + enqueue(() -> { + rootNode.attachChild(model); + rootNode.addLight(result); + }); + } + }); + } + } + + private SkinningControl getSkinningControl(Spatial model) { + SkinningControl control = model.getControl(SkinningControl.class); + if (control != null) { + return control; + } + + if (model instanceof Node) { + for (Spatial child : ((Node) model).getChildren()) { + SkinningControl skinningControl = getSkinningControl(child); + if (skinningControl != null) { + return skinningControl; + } + } + } + + return null; + } + +} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java new file mode 100644 index 0000000000..e169d27850 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Compat.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023 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. + */ +package jme3test.light.pbr; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.LightProbe; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.shape.CenterQuad; +import com.jme3.system.AppSettings; + +/** + * Reproduces an issue where PBR materials render much darker with the Core 3.2 + * profile than with the Compatibility profile. + * + *

This test relies on AppSettings set in main(), so it shouldn't be run + * from the jme3-examples TestChooser! + * + *

Compare the window rendered by this test with that rendered by + * TestIssue1903Core. If they differ, you have reproduced the issue. + * If they are identical, then you haven't reproduced it. + */ +public class TestIssue1903Compat extends SimpleApplication { + /** + * Main entry point for the TestIssue1903Compat application. + * + * @param unused array of command-line arguments + */ + public static void main(String[] unused) { + boolean loadDefaults = true; + AppSettings appSettings = new AppSettings(loadDefaults); + appSettings.setGammaCorrection(true); + appSettings.setRenderer(AppSettings.LWJGL_OPENGL2); // Compatibility profile + appSettings.setTitle("Compatibility"); + + TestIssue1903Compat application = new TestIssue1903Compat(); + application.setSettings(appSettings); + application.setShowSettings(false); // to speed up testing + application.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setEnabled(false); + + // Attach a 9x9 quad at the origin. + Mesh mesh = new CenterQuad(9f, 9f); + Geometry quad = new Geometry("quad", mesh); + rootNode.attachChild(quad); + + // Apply a PBR material to the quad. + String materialAssetPath = "TestIssue1903.j3m"; + Material material = assetManager.loadMaterial(materialAssetPath); + quad.setMaterial(material); + + // Add a LightProbe. + String lightProbePath = "Scenes/LightProbes/quarry_Probe.j3o"; + LightProbe probe = (LightProbe) assetManager.loadAsset(lightProbePath); + rootNode.addLight(probe); + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java new file mode 100644 index 0000000000..22bcc18e26 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/TestIssue1903Core.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023 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. + */ +package jme3test.light.pbr; + +import com.jme3.app.SimpleApplication; +import com.jme3.system.AppSettings; + +/** + * Reproduces an issue where PBR materials render much darker with the Core 3.2 + * profile than with the Compatibility profile. + * + *

This test relies on AppSettings set in main(), so it shouldn't be run + * from the jme3-examples TestChooser! + * + *

Compare the window rendered by this test with that rendered by + * TestIssue1903Compat. If they differ, you have reproduced the issue. + * If they are identical, then you haven't reproduced it. + */ +public class TestIssue1903Core extends SimpleApplication { + /** + * Main entry point for the TestIssue1903Core application. + * + * @param unused array of command-line arguments + */ + public static void main(String[] unused) { + boolean loadDefaults = true; + AppSettings appSettings = new AppSettings(loadDefaults); + appSettings.setGammaCorrection(true); + appSettings.setRenderer(AppSettings.LWJGL_OPENGL32); // Core 3.2 profile + appSettings.setTitle("Core 3.2"); + + TestIssue1903Compat application = new TestIssue1903Compat(); + application.setSettings(appSettings); + application.setShowSettings(false); // to speed up testing + application.start(); + } + + @Override + public void simpleInitApp() { + throw new AssertionError(); // never reached + } +} diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java new file mode 100644 index 0000000000..d9f3aef763 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRDirectLighting.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2009-2015 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. + */ +package jme3test.light.pbr; + +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.scene.*; +import com.jme3.scene.shape.Sphere; + +/** + * A test case for PBR lighting. + * Still experimental. + * + * @author nehon + */ +public class TestPBRDirectLighting extends SimpleApplication { + + public static void main(String[] args) { + TestPBRDirectLighting app = new TestPBRDirectLighting(); + app.start(); + } + + private DirectionalLight dl; + + private float roughness = 0.0f; + + @Override + public void simpleInitApp() { + + + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + rootNode.addLight(dl); + dl.setColor(ColorRGBA.White); + + ChaseCameraAppState chaser = new ChaseCameraAppState(); + chaser.setDragToRotate(true); + chaser.setMinVerticalRotation(-FastMath.HALF_PI); + chaser.setMaxDistance(1000); + chaser.setInvertVerticalAxis(true); + getStateManager().attach(chaser); + chaser.setTarget(rootNode); + flyCam.setEnabled(false); + + Geometry sphere = new Geometry("sphere", new Sphere(32, 32, 1)); + final Material m = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md"); + m.setColor("BaseColor", ColorRGBA.Black); + m.setFloat("Metallic", 0f); + m.setFloat("Roughness", roughness); + sphere.setMaterial(m); + rootNode.attachChild(sphere); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + + if (name.equals("rup") && isPressed) { + roughness = FastMath.clamp(roughness + 0.1f, 0.0f, 1.0f); + m.setFloat("Roughness", roughness); + } + if (name.equals("rdown") && isPressed) { + roughness = FastMath.clamp(roughness - 0.1f, 0.0f, 1.0f); + m.setFloat("Roughness", roughness); + } + + if (name.equals("light") && isPressed) { + dl.setDirection(cam.getDirection().normalize()); + } + } + }, "light", "rup", "rdown"); + + + inputManager.addMapping("light", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addMapping("rup", new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("rdown", new KeyTrigger(KeyInput.KEY_DOWN)); + + + } + + @Override + public void simpleUpdate(float tpf) { + } + +} + diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java b/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java new file mode 100644 index 0000000000..7de1e456c7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/TestPBRLighting.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.light.pbr; + +import com.jme3.app.SimpleApplication; +import com.jme3.environment.EnvironmentCamera; +import com.jme3.environment.LightProbeFactory; +import com.jme3.environment.generation.JobProgressAdapter; +import com.jme3.environment.util.EnvMapUtils; +import com.jme3.environment.util.LightsDebugState; +import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.*; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.ToneMapFilter; +import com.jme3.scene.*; +import com.jme3.texture.plugins.ktx.KTXLoader; +import com.jme3.util.MaterialDebugAppState; +import com.jme3.util.SkyFactory; +import com.jme3.util.mikktspace.MikktspaceTangentGenerator; + +/** + * A test case for PBR lighting. + * Still experimental. + * + * @author nehon + */ +public class TestPBRLighting extends SimpleApplication { + + public static void main(String[] args) { + TestPBRLighting app = new TestPBRLighting(); + app.start(); + } + + private Node tex; + + private Geometry model; + private DirectionalLight dl; + private Node modelNode; + private int frame = 0; + private Material pbrMat; + private float roughness = 1.0f; + + @Override + public void simpleInitApp() { + assetManager.registerLoader(KTXLoader.class, "ktx"); + + viewPort.setBackgroundColor(ColorRGBA.White); + modelNode = new Node("modelNode"); + model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o"); + MikktspaceTangentGenerator.generate(model); + modelNode.attachChild(model); + + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + rootNode.addLight(dl); + dl.setColor(ColorRGBA.White); + rootNode.attachChild(modelNode); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + int numSamples = context.getSettings().getSamples(); + if (numSamples > 0) { + fpp.setNumSamples(numSamples); + } + +// fpp.addFilter(new FXAAFilter()); + fpp.addFilter(new ToneMapFilter(Vector3f.UNIT_XYZ.mult(4.0f))); +// fpp.addFilter(new SSAOFilter(0.5f, 3, 0.2f, 0.2f)); + viewPort.addProcessor(fpp); + + //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Sky_Cloudy.hdr", SkyFactory.EnvMapType.EquirectMap); + Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap); + //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap); + //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/road.hdr", SkyFactory.EnvMapType.EquirectMap); + rootNode.attachChild(sky); + + pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m"); + model.setMaterial(pbrMat); + + + final EnvironmentCamera envCam = new EnvironmentCamera(256, new Vector3f(0, 3f, 0)); + stateManager.attach(envCam); + +// EnvironmentManager envManager = new EnvironmentManager(); +// stateManager.attach(envManager); + + // envManager.setScene(rootNode); + + LightsDebugState debugState = new LightsDebugState(); + stateManager.attach(debugState); + + ChaseCamera chaser = new ChaseCamera(cam, modelNode, inputManager); + chaser.setDragToRotate(true); + chaser.setMinVerticalRotation(-FastMath.HALF_PI); + chaser.setMaxDistance(1000); + chaser.setSmoothMotion(true); + chaser.setRotationSensitivity(10); + chaser.setZoomSensitivity(5); + flyCam.setEnabled(false); + //flyCam.setMoveSpeed(100); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("debug") && isPressed) { + if (tex == null) { + return; + } + if (tex.getParent() == null) { + guiNode.attachChild(tex); + } else { + tex.removeFromParent(); + } + } + + if (name.equals("rup") && isPressed) { + roughness = FastMath.clamp(roughness + 0.1f, 0.0f, 1.0f); + pbrMat.setFloat("Roughness", roughness); + } + if (name.equals("rdown") && isPressed) { + roughness = FastMath.clamp(roughness - 0.1f, 0.0f, 1.0f); + pbrMat.setFloat("Roughness", roughness); + } + + + if (name.equals("up") && isPressed) { + model.move(0, tpf * 100f, 0); + } + + if (name.equals("down") && isPressed) { + model.move(0, -tpf * 100f, 0); + } + if (name.equals("left") && isPressed) { + model.move(0, 0, tpf * 100f); + } + if (name.equals("right") && isPressed) { + model.move(0, 0, -tpf * 100f); + } + if (name.equals("light") && isPressed) { + dl.setDirection(cam.getDirection().normalize()); + } + } + }, "toggle", "light", "up", "down", "left", "right", "debug", "rup", "rdown"); + + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addMapping("light", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT)); + inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addMapping("debug", new KeyTrigger(KeyInput.KEY_D)); + inputManager.addMapping("rup", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addMapping("rdown", new KeyTrigger(KeyInput.KEY_G)); + + + MaterialDebugAppState debug = new MaterialDebugAppState(); + debug.registerBinding("Common/MatDefs/Light/PBRLighting.frag", rootNode); + debug.registerBinding("Common/ShaderLib/PBR.glsllib", rootNode); + getStateManager().attach(debug); + + } + + @Override + public void simpleUpdate(float tpf) { + frame++; + + if (frame == 2) { + modelNode.removeFromParent(); + final LightProbe probe = LightProbeFactory.makeProbe(stateManager.getState(EnvironmentCamera.class), rootNode, new JobProgressAdapter() { + + @Override + public void done(LightProbe result) { + System.err.println("Done rendering env maps"); + tex = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(result.getPrefilteredEnvMap(), assetManager); + } + }); + probe.getArea().setRadius(100); + rootNode.addLight(probe); + //getStateManager().getState(EnvironmentManager.class).addEnvProbe(probe); + + } + if (frame > 10 && modelNode.getParent() == null) { + rootNode.attachChild(modelNode); + } + } + +} + diff --git a/jme3-examples/src/main/java/jme3test/light/pbr/package-info.java b/jme3-examples/src/main/java/jme3test/light/pbr/package-info.java new file mode 100644 index 0000000000..399267e70a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/light/pbr/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for physically based rendering (PBR) + */ +package jme3test.light.pbr; diff --git a/jme3-examples/src/main/java/jme3test/material/TestBumpModel.java b/jme3-examples/src/main/java/jme3test/material/TestBumpModel.java new file mode 100644 index 0000000000..f71e43ea63 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestBumpModel.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.plugins.ogre.OgreMeshKey; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TangentBinormalGenerator; + +public class TestBumpModel extends SimpleApplication { + + private float angle; + private PointLight pl; + private Spatial lightMdl; + + public static void main(String[] args){ + TestBumpModel app = new TestBumpModel(); + app.start(); + } + + @Override + public void simpleInitApp() { + Spatial signpost = assetManager.loadAsset(new OgreMeshKey("Models/Sign Post/Sign Post.mesh.xml")); + signpost.setMaterial(assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m")); + TangentBinormalGenerator.generate(signpost); + rootNode.attachChild(signpost); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + rootNode.attachChild(lightMdl); + + // fluorescent main light + pl = new PointLight(); + pl.setColor(new ColorRGBA(0.88f, 0.92f, 0.95f, 1.0f)); + rootNode.addLight(pl); + + // sunset light + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal()); + dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f)); + rootNode.addLight(dl); + + // skylight + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal()); + dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f)); + rootNode.addLight(dl); + + // white ambient light + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal()); + dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); + rootNode.addLight(dl); + } + + @Override + public void simpleUpdate(float tpf){ + angle += tpf * 0.25f; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 6f, 3f, FastMath.sin(angle) * 6f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java b/jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java new file mode 100644 index 0000000000..7f7c50fab0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestColoredTexture.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.renderer.queue.RenderQueue.Bucket; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; + +public class TestColoredTexture extends SimpleApplication { + + private float time = 0; + private ColorRGBA nextColor; + private ColorRGBA prevColor; + private Material mat; + + public static void main(String[] args){ + TestColoredTexture app = new TestColoredTexture(); + app.start(); + } + + @Override + public void simpleInitApp() { + Quad quadMesh = new Quad(512,512); + Geometry quad = new Geometry("Quad", quadMesh); + quad.setQueueBucket(Bucket.Gui); + + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png")); + quad.setMaterial(mat); + guiNode.attachChildAt(quad, 0); + + nextColor = ColorRGBA.randomColor(); + prevColor = ColorRGBA.Black; + } + + @Override + public void simpleUpdate(float tpf){ + time += tpf; + if (time > 1f){ + time -= 1f; + prevColor = nextColor; + nextColor = ColorRGBA.randomColor(); + } + ColorRGBA currentColor = new ColorRGBA(); + currentColor.interpolateLocal(prevColor, nextColor, time); + + mat.setColor("Color", currentColor); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java b/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java new file mode 100644 index 0000000000..0199d70cc2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java @@ -0,0 +1,46 @@ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.shape.Sphere; +import com.jme3.system.AppSettings; +import com.jme3.util.BufferUtils; + +/** + * Created by michael on 23.02.15. + */ +public class TestGeometryShader extends SimpleApplication { + @Override + public void simpleInitApp() { + Mesh mesh = new Mesh(); + mesh.setBuffer(VertexBuffer.Type.Index, 1, BufferUtils.createIntBuffer(new int[]{1})); + mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(new float[]{0, 0, 0})); + mesh.setMode(Mesh.Mode.Points); + mesh.setBound(new BoundingBox(new Vector3f(0, 0, 0), 10, 10, 10)); + mesh.updateCounts(); + Geometry geometry = new Geometry("Test", mesh); + geometry.updateGeometricState(); + geometry.setMaterial(new Material(assetManager, "Materials/Geom/SimpleGeom.j3md")); + //geometry.getMaterial().getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off); + //geometry.setMaterial(assetManager.loadMaterial("Materials/Geom/SimpleTess.j3md")); + rootNode.attachChild(geometry); + + Geometry geometry1 = new Geometry("T1", new Sphere(10, 10, 1)); + geometry1.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + rootNode.attachChild(geometry1); + + } + + public static void main(String[] args) { + TestGeometryShader app = new TestGeometryShader(); + AppSettings settings = new AppSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL33); + app.setSettings(settings); + app.start(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java b/jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java new file mode 100644 index 0000000000..2d599ef2f5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestMatParamOverride.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.MatParamOverride; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector4f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.shader.VarType; + +/** + * Test if {@link MatParamOverride}s are working correctly. + * + * @author Kirill Vainer + */ +public class TestMatParamOverride extends SimpleApplication { + + final private Box box = new Box(1, 1, 1); + final MatParamOverride overrideYellow + = new MatParamOverride(VarType.Vector4, "Color", + ColorRGBA.Yellow); + final MatParamOverride overrideWhite + = new MatParamOverride(VarType.Vector4, "Color", + Vector4f.UNIT_XYZW); + final MatParamOverride overrideGray + = new MatParamOverride(VarType.Vector4, "Color", + new Quaternion(0.5f, 0.5f, 0.5f, 1f)); + + public static void main(String[] args) { + TestMatParamOverride app = new TestMatParamOverride(); + app.start(); + } + + private void createBox(float location, ColorRGBA color) { + Geometry geom = new Geometry("Box", box); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", color); + geom.setMaterial(mat); + geom.move(location, 0, 0); + rootNode.attachChild(geom); + } + + @Override + public void simpleInitApp() { + inputManager.setCursorVisible(true); + + createBox(-3, ColorRGBA.Red); + createBox(0, ColorRGBA.Green); + createBox(3, ColorRGBA.Blue); + + System.out.println("Press G, W, Y, or space bar ..."); + inputManager.addMapping("overrideClear", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("overrideGray", new KeyTrigger(KeyInput.KEY_G)); + inputManager.addMapping("overrideWhite", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("overrideYellow", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + if (name.equals("overrideClear")) { + rootNode.clearMatParamOverrides(); + } else if (name.equals("overrideGray")) { + rootNode.clearMatParamOverrides(); + rootNode.addMatParamOverride(overrideGray); + } else if (name.equals("overrideWhite")) { + rootNode.clearMatParamOverrides(); + rootNode.addMatParamOverride(overrideWhite); + } else if (name.equals("overrideYellow")) { + rootNode.clearMatParamOverrides(); + rootNode.addMatParamOverride(overrideYellow); + } + System.out.println(rootNode.getLocalMatParamOverrides()); + } + } + }, "overrideClear", "overrideGray", "overrideWhite", "overrideYellow"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java b/jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java new file mode 100644 index 0000000000..a37855185c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestMaterialCompare.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.material; + +import com.jme3.asset.AssetManager; +import com.jme3.asset.TextureKey; +import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; +import com.jme3.system.JmeSystem; +import com.jme3.texture.Texture; + +public class TestMaterialCompare { + + public static void main(String[] args) { + AssetManager assetManager = JmeSystem.newAssetManager( + TestMaterialCompare.class.getResource("/com/jme3/asset/Desktop.cfg")); + + // Cloned materials + Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat1.setName("mat1"); + mat1.setColor("Color", ColorRGBA.Blue); + + Material mat2 = mat1.clone(); + mat2.setName("mat2"); + testEquality(mat1, mat2, true); + + // Cloned material with different render states + Material mat3 = mat1.clone(); + mat3.setName("mat3"); + mat3.getAdditionalRenderState().setBlendMode(BlendMode.ModulateX2); + testEquality(mat1, mat3, false); + + // Two separately loaded materials + Material mat4 = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + mat4.setName("mat4"); + Material mat5 = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + mat5.setName("mat5"); + testEquality(mat4, mat5, true); + + // Comparing same textures + TextureKey originalKey = (TextureKey) mat4.getTextureParam("DiffuseMap").getTextureValue().getKey(); + TextureKey tex1key = new TextureKey("Models/Sign Post/Sign Post.jpg", false); + tex1key.setGenerateMips(true); + + // Texture keys from the original and the loaded texture + // must be identical, otherwise the resultant textures not identical + // and thus materials are not identical! + if (!originalKey.equals(tex1key)){ + System.out.println("TEXTURE KEYS ARE NOT EQUAL"); + } + + Texture tex1 = assetManager.loadTexture(tex1key); + mat4.setTexture("DiffuseMap", tex1); + testEquality(mat4, mat5, true); + + // Change some stuff on the texture and compare, materials no longer equal + tex1.setWrap(Texture.WrapMode.MirroredRepeat); + testEquality(mat4, mat5, false); + + // Comparing different textures + Texture tex2 = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + mat4.setTexture("DiffuseMap", tex2); + testEquality(mat4, mat5, false); + + // Two materials created the same way + Material mat6 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat6.setName("mat6"); + mat6.setColor("Color", ColorRGBA.Blue); + testEquality(mat1, mat6, true); + + // Changing a material param + mat6.setColor("Color", ColorRGBA.Green); + testEquality(mat1, mat6, false); + } + + private static void testEquality(Material mat1, Material mat2, boolean expected) { + if (mat2.contentEquals(mat1)) { + System.out.print(mat1.getName() + " == " + mat2.getName()); + if (expected) { + System.out.println(" EQUAL OK"); + } else { + System.out.println(" EQUAL FAIL!"); + } + } else { + System.out.print(mat1.getName() + " != " + mat2.getName()); + if (!expected) { + System.out.println(" EQUAL OK"); + } else { + System.out.println(" EQUAL FAIL!"); + } + } + if (mat2.hashCode() == mat1.hashCode()){ + System.out.print(mat1.getName() + " == " + mat2.getName()); + if (expected) { + System.out.println(" HASH OK"); + } else { + System.out.println(" HASH FAIL!"); + } + } else { + System.out.print(mat1.getName() + " != " + mat2.getName()); + if (!expected) { + System.out.println(" HASH OK"); + } else { + System.out.println(" HASH FAIL!"); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java b/jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java new file mode 100644 index 0000000000..e75b33ba58 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TangentBinormalGenerator; + +public class TestNormalMapping extends SimpleApplication { + + private float angle; + private PointLight pl; + private Spatial lightMdl; + + public static void main(String[] args){ + TestNormalMapping app = new TestNormalMapping(); + app.start(); + } + + @Override + public void simpleInitApp() { + Sphere sphMesh = new Sphere(32, 32, 1); + sphMesh.setTextureMode(Sphere.TextureMode.Projected); + sphMesh.updateGeometry(32, 32, 1, false, false); + TangentBinormalGenerator.generate(sphMesh); + + Geometry sphere = new Geometry("Rock Ball", sphMesh); + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + sphere.setMaterial(mat); + rootNode.attachChild(sphere); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + rootNode.attachChild(lightMdl); + + pl = new PointLight(); + pl.setColor(ColorRGBA.White); + pl.setPosition(new Vector3f(0f, 0f, 4f)); + rootNode.addLight(pl); + +// DirectionalLight dl = new DirectionalLight(); +// dl.setDirection(new Vector3f(1,-1,1).normalizeLocal()); +// dl.setColor(new ColorRGBA(0.22f, 0.15f, 0.1f, 1.0f)); +// rootNode.addLight(dl); + } + + @Override + public void simpleUpdate(float tpf){ + angle += tpf * 0.25f; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 4f, 0.5f, FastMath.sin(angle) * 4f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestParallax.java b/jme3-examples/src/main/java/jme3test/material/TestParallax.java new file mode 100644 index 0000000000..80afeaf382 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestParallax.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.RectangleMesh; +import com.jme3.util.SkyFactory; +import com.jme3.util.TangentBinormalGenerator; + +public class TestParallax extends SimpleApplication { + + private final Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); + + public static void main(String[] args) { + TestParallax app = new TestParallax(); + app.start(); + } + + public void setupSkyBox() { + rootNode.attachChild(SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", SkyFactory.EnvMapType.CubeMap)); + } + + public void setupLighting() { + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(lightDir); + dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); + rootNode.addLight(dl); + } + private Material mat; + + public void setupFloor() { + mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); + + RectangleMesh rm = new RectangleMesh( + new Vector3f(-50, 22, 60), + new Vector3f(50, 22, 60), + new Vector3f(-50, 22, -40)); + rm.scaleTextureCoordinates(new Vector2f(10, 10)); + + Geometry floorGeom = new Geometry("floorGeom", rm); + TangentBinormalGenerator.generate(floorGeom); + floorGeom.setMaterial(mat); + + rootNode.attachChild(floorGeom); + } + + public void setupSignpost() { + Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); + Material matSp = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + TangentBinormalGenerator.generate(signpost); + signpost.setMaterial(matSp); + signpost.rotate(0, FastMath.HALF_PI, 0); + signpost.setLocalTranslation(12, 23.5f, 30); + signpost.setLocalScale(4); + signpost.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(signpost); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(-15.445636f, 30.162927f, 60.252777f)); + cam.setRotation(new Quaternion(0.05173137f, 0.92363626f, -0.13454558f, 0.35513034f)); + flyCam.setMoveSpeed(30); + + setupLighting(); + setupSkyBox(); + setupFloor(); + setupSignpost(); + + inputManager.addListener(new AnalogListener() { + + @Override + public void onAnalog(String name, float value, float tpf) { + if ("heightUP".equals(name)) { + parallaxHeight += 0.01; + mat.setFloat("ParallaxHeight", parallaxHeight); + } + if ("heightDown".equals(name)) { + parallaxHeight -= 0.01; + parallaxHeight = Math.max(parallaxHeight, 0); + mat.setFloat("ParallaxHeight", parallaxHeight); + } + + } + }, "heightUP", "heightDown"); + inputManager.addMapping("heightUP", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addMapping("heightDown", new KeyTrigger(KeyInput.KEY_K)); + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed && "toggleSteep".equals(name)) { + steep = !steep; + mat.setBoolean("SteepParallax", steep); + } + } + }, "toggleSteep"); + inputManager.addMapping("toggleSteep", new KeyTrigger(KeyInput.KEY_SPACE)); + } + private float parallaxHeight = 0.05f; + private boolean steep = false; + + @Override + public void simpleUpdate(float tpf) { +// time+=tpf; +// lightDir.set(FastMath.sin(time), -1, FastMath.cos(time)); +// bsr.setDirection(lightDir); +// dl.setDirection(lightDir); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java b/jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java new file mode 100644 index 0000000000..aca2282634 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.RectangleMesh; +import com.jme3.util.SkyFactory; +import com.jme3.util.TangentBinormalGenerator; + +public class TestParallaxPBR extends SimpleApplication { + + final private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); + + public static void main(String[] args) { + TestParallaxPBR app = new TestParallaxPBR(); + app.start(); + } + + public void setupSkyBox() { + rootNode.attachChild(SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", SkyFactory.EnvMapType.CubeMap)); + } + private DirectionalLight dl; + + public void setupLighting() { + + dl = new DirectionalLight(); + dl.setDirection(lightDir); + dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); + rootNode.addLight(dl); + } + private Material mat; + + public void setupFloor() { + mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWallPBR.j3m"); + //mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWallPBR2.j3m"); + + RectangleMesh rm = new RectangleMesh( + new Vector3f(-50, 22, 60), + new Vector3f(50, 22, 60), + new Vector3f(-50, 22, -40)); + rm.scaleTextureCoordinates(new Vector2f(10, 10)); + + Geometry floorGeom = new Geometry("floorGeom", rm); + TangentBinormalGenerator.generate(floorGeom); + //floorGeom.setLocalScale(100); + + floorGeom.setMaterial(mat); + rootNode.attachChild(floorGeom); + } + + public void setupSignpost() { + Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); + Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + TangentBinormalGenerator.generate(signpost); + signpost.setMaterial(mat); + signpost.rotate(0, FastMath.HALF_PI, 0); + signpost.setLocalTranslation(12, 23.5f, 30); + signpost.setLocalScale(4); + signpost.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(signpost); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(-15.445636f, 30.162927f, 60.252777f)); + cam.setRotation(new Quaternion(0.05173137f, 0.92363626f, -0.13454558f, 0.35513034f)); + flyCam.setMoveSpeed(30); + + + setupLighting(); + setupSkyBox(); + setupFloor(); + setupSignpost(); + + inputManager.addListener(new AnalogListener() { + + @Override + public void onAnalog(String name, float value, float tpf) { + if ("heightUP".equals(name)) { + parallaxHeight += 0.01; + mat.setFloat("ParallaxHeight", parallaxHeight); + } + if ("heightDown".equals(name)) { + parallaxHeight -= 0.01; + parallaxHeight = Math.max(parallaxHeight, 0); + mat.setFloat("ParallaxHeight", parallaxHeight); + } + + } + }, "heightUP", "heightDown"); + inputManager.addMapping("heightUP", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addMapping("heightDown", new KeyTrigger(KeyInput.KEY_K)); + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed && "toggleSteep".equals(name)) { + steep = !steep; + mat.setBoolean("SteepParallax", steep); + } + } + }, "toggleSteep"); + inputManager.addMapping("toggleSteep", new KeyTrigger(KeyInput.KEY_SPACE)); + } + private float parallaxHeight = 0.05f; + private boolean steep = false; + + @Override + public void simpleUpdate(float tpf) { +// time+=tpf; +// lightDir.set(FastMath.sin(time), -1, FastMath.cos(time)); +// bsr.setDirection(lightDir); +// dl.setDirection(lightDir); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java b/jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java new file mode 100644 index 0000000000..592663efeb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestShaderNodes.java @@ -0,0 +1,43 @@ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.material.Technique; +import com.jme3.material.TechniqueDef; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.shader.Shader; +import com.jme3.texture.Texture; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestShaderNodes extends SimpleApplication { + + public static void main(String[] args) { + TestShaderNodes app = new TestShaderNodes(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(20); + Logger.getLogger("com.jme3").setLevel(Level.WARNING); + Box boxShape1 = new Box(1f, 1f, 1f); + Geometry cube_tex = new Geometry("A Textured Box", boxShape1); + Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md"); + mat.selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager); + Technique t = mat.getActiveTechnique(); + + for (Shader.ShaderSource shaderSource : t.getDef().getShader(assetManager, renderer.getCaps(), t.getDynamicDefines()).getSources()) { + System.out.println(shaderSource.getSource()); + } + + mat.setColor("Color", ColorRGBA.Yellow); + mat.setTexture("ColorMap", tex); + cube_tex.setMaterial(mat); + rootNode.attachChild(cube_tex); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java b/jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java new file mode 100644 index 0000000000..4185e1caf7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Quad; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TangentBinormalGenerator; + +// phong cutoff for light to normal angle > 90? +public class TestSimpleBumps extends SimpleApplication { + + private float angle; + private PointLight pl; + private Spatial lightMdl; + + public static void main(String[] args){ + TestSimpleBumps app = new TestSimpleBumps(); + app.start(); + } + + @Override + public void simpleInitApp() { + Quad quadMesh = new Quad(1, 1); + + Geometry sphere = new Geometry("Rock Ball", quadMesh); + Material mat = assetManager.loadMaterial("Textures/BumpMapTest/SimpleBump.j3m"); + sphere.setMaterial(mat); + TangentBinormalGenerator.generate(sphere); + rootNode.attachChild(sphere); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + rootNode.attachChild(lightMdl); + + pl = new PointLight(); + pl.setColor(ColorRGBA.White); + pl.setPosition(new Vector3f(0f, 0f, 4f)); + rootNode.addLight(pl); + +// DirectionalLight dl = new DirectionalLight(); +// dl.setDirection(new Vector3f(1, -1, -1).normalizeLocal()); +// dl.setColor(new ColorRGBA(0.22f, 0.15f, 0.1f, 1.0f)); +// rootNode.addLight(dl); + } + + @Override + public void simpleUpdate(float tpf){ + angle += tpf * 0.25f; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 4f, 0.5f, FastMath.sin(angle) * 4f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java b/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java new file mode 100644 index 0000000000..a5af58bfc5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java @@ -0,0 +1,73 @@ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.shape.Quad; +import com.jme3.system.AppSettings; +import com.jme3.util.BufferUtils; + +import java.util.concurrent.Callable; + +/** + * Created by michael on 28.02.15. + */ +public class TestTessellationShader extends SimpleApplication { + private Material tessellationMaterial; + private int tessFactor=5; + @Override + public void simpleInitApp() { + tessellationMaterial = new Material(getAssetManager(), "Materials/Tess/SimpleTess.j3md"); + tessellationMaterial.setInt("TessellationFactor", tessFactor); + tessellationMaterial.getAdditionalRenderState().setWireframe(true); + Quad quad = new Quad(10, 10); + quad.clearBuffer(VertexBuffer.Type.Index); + quad.setBuffer(VertexBuffer.Type.Index, 4, BufferUtils.createIntBuffer(0, 1, 2, 3)); + quad.setMode(Mesh.Mode.Patch); + quad.setPatchVertexCount(4); + Geometry geometry = new Geometry("tessTest", quad); + geometry.setMaterial(tessellationMaterial); + rootNode.attachChild(geometry); + + getInputManager().addMapping("TessUp", new KeyTrigger(KeyInput.KEY_O)); + getInputManager().addMapping("TessDo", new KeyTrigger(KeyInput.KEY_L)); + getInputManager().addListener(new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + if(name.equals("TessUp")){ + tessFactor++; + enqueue(new Callable() { + @Override + public Boolean call() throws Exception { + tessellationMaterial.setInt("TessellationFactor",tessFactor); + return true; + } + }); + } + if(name.equals("TessDo")){ + tessFactor--; + enqueue(new Callable() { + @Override + public Boolean call() throws Exception { + tessellationMaterial.setInt("TessellationFactor",tessFactor); + return true; + } + }); + } + } + },"TessUp","TessDo"); + } + + public static void main(String[] args) { + TestTessellationShader app = new TestTessellationShader(); + AppSettings settings = new AppSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL40); + app.setSettings(settings); + app.start(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java b/jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java new file mode 100644 index 0000000000..826ef448d0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java @@ -0,0 +1,44 @@ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TangentBinormalGenerator; + +public class TestUnshadedModel extends SimpleApplication { + + public static void main(String[] args){ + TestUnshadedModel app = new TestUnshadedModel(); + app.start(); + } + + @Override + public void simpleInitApp() { + Sphere sphMesh = new Sphere(32, 32, 1); + sphMesh.setTextureMode(Sphere.TextureMode.Projected); + sphMesh.updateGeometry(32, 32, 1, false, false); + TangentBinormalGenerator.generate(sphMesh); + + Geometry sphere = new Geometry("Rock Ball", sphMesh); + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + mat.setColor("Ambient", ColorRGBA.DarkGray); + mat.setColor("Diffuse", ColorRGBA.White); + mat.setBoolean("UseMaterialColors", true); + sphere.setMaterial(mat); + rootNode.attachChild(sphere); + + PointLight pl = new PointLight(); + pl.setColor(ColorRGBA.White); + pl.setPosition(new Vector3f(4f, 0f, 0f)); + rootNode.addLight(pl); + + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White); + rootNode.addLight(al); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/package-info.java b/jme3-examples/src/main/java/jme3test/material/package-info.java new file mode 100644 index 0000000000..a90750386a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for materials + */ +package jme3test.material; diff --git a/jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java b/jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java new file mode 100644 index 0000000000..1bd9361bb7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/math/TestHalfFloat.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.math; + +import com.jme3.math.FastMath; +import java.util.Scanner; + +public class TestHalfFloat { + public static void main(String[] args){ + Scanner scan = new Scanner(System.in); + while (true){ + System.out.println("Enter float to convert or 'x' to exit: "); + String s = scan.nextLine(); + if (s.equals("x")) + break; + + float flt = Float.valueOf(s); + short half = FastMath.convertFloatToHalf(flt); + float flt2 = FastMath.convertHalfToFloat(half); + + System.out.println("Input float: "+flt); + System.out.println("Result float: "+flt2); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/math/package-info.java b/jme3-examples/src/main/java/jme3test/math/package-info.java new file mode 100644 index 0000000000..0dd99ffacb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/math/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for arithmetic + */ +package jme3test.math; diff --git a/jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java b/jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java new file mode 100644 index 0000000000..bbf03a8348 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/TestGltfLoading.java @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2009-2022 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. + */ +package jme3test.model; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.SkinningControl; +import com.jme3.app.*; +import com.jme3.asset.plugins.FileLocator; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.math.*; +import com.jme3.renderer.Limits; +import com.jme3.scene.*; +import com.jme3.scene.control.Control; +import com.jme3.scene.debug.custom.ArmatureDebugAppState; +import com.jme3.scene.plugins.gltf.GltfModelKey; +import jme3test.model.anim.EraseTimer; + +import java.util.*; + +public class TestGltfLoading extends SimpleApplication { + + final private Node autoRotate = new Node("autoRotate"); + final private List assets = new ArrayList<>(); + private Node probeNode; + private float time = 0; + private int assetIndex = 0; + private boolean useAutoRotate = false; + private final static String indentString = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; + final private int duration = 1; + private boolean playAnim = true; + + public static void main(String[] args) { + TestGltfLoading app = new TestGltfLoading(); + app.start(); + } + + /* + WARNING this test case can't work without the assets, and considering their size, they are not pushed into the repo + you can find them here : + https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0 + https://sketchfab.com/features/gltf + You have to copy them in Model/gltf folder in the jme3-testdata project. + */ + @Override + public void simpleInitApp() { + + ArmatureDebugAppState armatureDebugappState = new ArmatureDebugAppState(); + getStateManager().attach(armatureDebugappState); + setTimer(new EraseTimer()); + + String folder = System.getProperty("user.home"); + assetManager.registerLocator(folder, FileLocator.class); + + // cam.setLocation(new Vector3f(4.0339394f, 2.645184f, 6.4627485f)); + // cam.setRotation(new Quaternion(-0.013950467f, 0.98604023f, -0.119502485f, -0.11510504f)); + cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.1f, 100f); + renderer.setDefaultAnisotropicFilter(Math.min(renderer.getLimits().get(Limits.TextureAnisotropy), 8)); + setPauseOnLostFocus(false); + + flyCam.setMoveSpeed(5); + flyCam.setDragToRotate(true); + flyCam.setEnabled(false); + viewPort.setBackgroundColor(new ColorRGBA().setAsSrgb(0.2f, 0.2f, 0.2f, 1.0f)); + rootNode.attachChild(autoRotate); + probeNode = (Node) assetManager.loadModel("Scenes/defaultProbe.j3o"); + autoRotate.attachChild(probeNode); + +// DirectionalLight dl = new DirectionalLight(); +// dl.setDirection(new Vector3f(-1f, -1.0f, -1f).normalizeLocal()); +// dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); +// rootNode.addLight(dl); + +// DirectionalLight dl2 = new DirectionalLight(); +// dl2.setDirection(new Vector3f(1f, 1.0f, 1f).normalizeLocal()); +// dl2.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); +// rootNode.addLight(dl2); + +// PointLight pl = new PointLight(new Vector3f(5.0f, 5.0f, 5.0f), ColorRGBA.White, 30); +// rootNode.addLight(pl); +// PointLight pl1 = new PointLight(new Vector3f(-5.0f, -5.0f, -5.0f), ColorRGBA.White.mult(0.5f), 50); +// rootNode.addLight(pl1); + + //loadModel("Models/gltf/polly/project_polly.gltf", new Vector3f(0, 0, 0), 0.5f); + //loadModel("Models/gltf/zophrac/scene.gltf", new Vector3f(0, 0, 0), 0.01f); + // loadModel("Models/gltf/scifigirl/scene.gltf", new Vector3f(0, -1, 0), 0.1f); + //loadModel("Models/gltf/man/scene.gltf", new Vector3f(0, -1, 0), 0.1f); + //loadModel("Models/gltf/torus/scene.gltf", new Vector3f(0, -1, 0), 0.1f); + //loadModel("Models/gltf/morph/scene.gltf", new Vector3f(0, 0, 0), 0.2f); +// loadModel("Models/gltf/AnimatedMorphCube/glTF/AnimatedMorphCube.gltf", new Vector3f(0, 0, 0), 1f); +// loadModel("Models/gltf/SimpleMorph/glTF/SimpleMorph.gltf", new Vector3f(0, 0, 0), 0.1f); + //loadModel("Models/gltf/nier/scene.gltf", new Vector3f(0, -1.5f, 0), 0.01f); + //loadModel("Models/gltf/izzy/scene.gltf", new Vector3f(0, -1, 0), 0.01f); + //loadModel("Models/gltf/darth/scene.gltf", new Vector3f(0, -1, 0), 0.01f); + //loadModel("Models/gltf/mech/scene.gltf", new Vector3f(0, -1, 0), 0.01f); + //loadModel("Models/gltf/elephant/scene.gltf", new Vector3f(0, -1, 0), 0.01f); + //loadModel("Models/gltf/buffalo/scene.gltf", new Vector3f(0, -1, 0), 0.1f); + //loadModel("Models/gltf/war/scene.gltf", new Vector3f(0, -1, 0), 0.1f); + //loadModel("Models/gltf/ganjaarl/scene.gltf", new Vector3f(0, -1, 0), 0.01f); + //loadModel("Models/gltf/hero/scene.gltf", new Vector3f(0, -1, 0), 0.1f); + //loadModel("Models/gltf/mercy/scene.gltf", new Vector3f(0, -1, 0), 0.01f); + //loadModel("Models/gltf/crab/scene.gltf", Vector3f.ZERO, 1); + //loadModel("Models/gltf/manta/scene.gltf", Vector3f.ZERO, 0.2f); + //loadModel("Models/gltf/bone/scene.gltf", Vector3f.ZERO, 0.1f); +// loadModel("Models/gltf/box/box.gltf", Vector3f.ZERO, 1); + loadModel("Models/gltf/duck/Duck.gltf", new Vector3f(0, -1, 0), 1); +// loadModel("Models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf", Vector3f.ZERO, 1); +// loadModel("Models/gltf/hornet/scene.gltf", new Vector3f(0, -0.5f, 0), 0.4f); +//// loadModel("Models/gltf/adamHead/adamHead.gltf", Vector3f.ZERO, 0.6f); + //loadModel("Models/gltf/busterDrone/busterDrone.gltf", new Vector3f(0, 0f, 0), 0.8f); +// loadModel("Models/gltf/AnimatedCube/glTF/AnimatedCube.gltf", Vector3f.ZERO, 0.5f); +// loadModel("Models/gltf/BoxAnimated/glTF/BoxAnimated.gltf", new Vector3f(0, 0f, 0), 0.8f); +// loadModel("Models/gltf/RiggedSimple/glTF/RiggedSimple.gltf", new Vector3f(0, -0.3f, 0), 0.2f); +// loadModel("Models/gltf/RiggedFigure/glTF/RiggedFigure.gltf", new Vector3f(0, -1f, 0), 1f); +// loadModel("Models/gltf/CesiumMan/glTF/CesiumMan.gltf", new Vector3f(0, -1, 0), 1f); +// loadModel("Models/gltf/BrainStem/glTF/BrainStem.gltf", new Vector3f(0, -1, 0), 1f); + //loadModel("Models/gltf/Jaime/Jaime.gltf", new Vector3f(0, -1, 0), 1f); + // loadModel("Models/gltf/GiantWorm/GiantWorm.gltf", new Vector3f(0, -1, 0), 1f); + //loadModel("Models/gltf/RiggedFigure/WalkingLady.gltf", new Vector3f(0, -0.f, 0), 1f); + //loadModel("Models/gltf/Monster/Monster.gltf", Vector3f.ZERO, 0.03f); + +// loadModel("Models/gltf/Corset/glTF/Corset.gltf", new Vector3f(0, -1, 0), 20f); +// loadModel("Models/gltf/BoxInterleaved/glTF/BoxInterleaved.gltf", new Vector3f(0, 0, 0), 1f); + + + probeNode.attachChild(assets.get(0)); + + // setMorphTarget(morphIndex); + + ChaseCameraAppState chaseCam = new ChaseCameraAppState(); + chaseCam.setTarget(probeNode); + getStateManager().attach(chaseCam); + chaseCam.setInvertHorizontalAxis(true); + chaseCam.setInvertVerticalAxis(true); + chaseCam.setZoomSpeed(0.5f); + chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); + chaseCam.setRotationSpeed(3); + chaseCam.setDefaultDistance(3); + chaseCam.setDefaultVerticalRotation(0.3f); + + inputManager.addMapping("autorotate", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + useAutoRotate = !useAutoRotate; + } + } + }, "autorotate"); + + inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + playAnim = !playAnim; + if (playAnim) { + playFirstAnim(rootNode); + } else { + stopAnim(rootNode); + } + } + } + }, "toggleAnim"); + inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed && composer != null) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + } + } + }, "nextAnim"); + + dumpScene(rootNode, 0); + + // stateManager.attach(new DetailedProfilerState()); + } + + private T findControl(Spatial s, Class controlClass) { + T ctrl = s.getControl(controlClass); + if (ctrl != null) { + return ctrl; + } + if (s instanceof Node) { + Node n = (Node) s; + for (Spatial spatial : n.getChildren()) { + ctrl = findControl(spatial, controlClass); + if (ctrl != null) { + return ctrl; + } + } + } + return null; + } + + private void loadModel(String path, Vector3f offset, float scale) { + GltfModelKey k = new GltfModelKey(path); + //k.setKeepSkeletonPose(true); + Spatial s = assetManager.loadModel(k); + s.scale(scale); + s.move(offset); + assets.add(s); + if (playAnim) { + playFirstAnim(s); + } + + SkinningControl ctrl = findControl(s, SkinningControl.class); + + // ctrl.getSpatial().removeControl(ctrl); + if (ctrl == null) { + return; + } + //System.err.println(ctrl.getArmature().toString()); + //ctrl.setHardwareSkinningPreferred(false); + // getStateManager().getState(ArmatureDebugAppState.class).addArmatureFrom(ctrl); +// AnimControl aCtrl = findControl(s, AnimControl.class); +// //ctrl.getSpatial().removeControl(ctrl); +// if (aCtrl == null) { +// return; +// } +// if (aCtrl.getArmature() != null) { +// getStateManager().getState(SkeletonDebugAppState.class).addSkeleton(aCtrl.getArmature(), aCtrl.getSpatial(), true); +// } + + } + + final private Queue anims = new LinkedList<>(); + private AnimComposer composer; + + private void playFirstAnim(Spatial s) { + + AnimComposer control = s.getControl(AnimComposer.class); + if (control != null) { + anims.clear(); + for (String name : control.getAnimClipsNames()) { + anims.add(name); + } + if (anims.isEmpty()) { + return; + } + String anim = anims.poll(); + anims.add(anim); + control.setCurrentAction(anim); + composer = control; + } + if (s instanceof Node) { + Node n = (Node) s; + for (Spatial spatial : n.getChildren()) { + playFirstAnim(spatial); + } + } + } + + private void stopAnim(Spatial s) { + + AnimComposer control = s.getControl(AnimComposer.class); + if (control != null) { + control.reset(); + } + if (s instanceof Node) { + Node n = (Node) s; + for (Spatial spatial : n.getChildren()) { + stopAnim(spatial); + } + } + } + + @Override + public void simpleUpdate(float tpf) { + if (!useAutoRotate) { + return; + } + time += tpf; + // autoRotate.rotate(0, tpf * 0.5f, 0); + if (time > duration) { + // morphIndex++; + // setMorphTarget(morphIndex); + assets.get(assetIndex).removeFromParent(); + assetIndex = (assetIndex + 1) % assets.size(); +// if (assetIndex == 0) { +// duration = 10; +// } + probeNode.attachChild(assets.get(assetIndex)); + time = 0; + } + } + + private void dumpScene(Spatial s, int indent) { + System.err.println(indentString.substring(0, indent) + s.getName() + " (" + s.getClass().getSimpleName() + ") / " + + s.getLocalTransform().getTranslation().toString() + ", " + + s.getLocalTransform().getRotation().toString() + ", " + + s.getLocalTransform().getScale().toString()); + if (s instanceof Node) { + Node n = (Node) s; + for (Spatial spatial : n.getChildren()) { + dumpScene(spatial, indent + 1); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/TestHoverTank.java b/jme3-examples/src/main/java/jme3test/model/TestHoverTank.java new file mode 100644 index 0000000000..648f7390df --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/TestHoverTank.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.model; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.ChaseCamera; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.LodControl; +import jme3test.post.BloomUI; + +/** + * + * @author Nehon + */ +public class TestHoverTank extends SimpleApplication { + + public static void main(String[] args) { + TestHoverTank app = new TestHoverTank(); + app.start(); + } + + @Override + public void simpleInitApp() { + Node tank = (Node) assetManager.loadModel("Models/HoverTank/Tank2.mesh.xml"); + + flyCam.setEnabled(false); + ChaseCamera chaseCam = new ChaseCamera(cam, tank, inputManager); + chaseCam.setSmoothMotion(true); + chaseCam.setMaxDistance(100000); + chaseCam.setMinVerticalRotation(-FastMath.PI / 2); + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + Geometry tankGeom = (Geometry) tank.getChild(0); + LodControl control = new LodControl(); + tankGeom.addControl(control); + rootNode.attachChild(tank); + + Vector3f lightDir = new Vector3f(-0.8719428f, -0.46824604f, 0.14304268f); + DirectionalLight dl = new DirectionalLight(); + dl.setColor(new ColorRGBA(1.0f, 0.92f, 0.75f, 1f)); + dl.setDirection(lightDir); + + Vector3f lightDir2 = new Vector3f(0.70518064f, 0.5902297f, -0.39287305f); + DirectionalLight dl2 = new DirectionalLight(); + dl2.setColor(new ColorRGBA(0.7f, 0.85f, 1.0f, 1f)); + dl2.setDirection(lightDir2); + + rootNode.addLight(dl); + rootNode.addLight(dl2); + rootNode.attachChild(tank); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + BloomFilter bf = new BloomFilter(BloomFilter.GlowMode.Objects); + bf.setBloomIntensity(2.0f); + bf.setExposurePower(1.3f); + fpp.addFilter(bf); + BloomUI bui = new BloomUI(inputManager, bf); + viewPort.addProcessor(fpp); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java b/jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java new file mode 100644 index 0000000000..f97a71b3c0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/TestMonkeyHead.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.model; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; + +public class TestMonkeyHead extends SimpleApplication { + + private float angle; + private PointLight pl; + private Spatial lightMdl; + + public static void main(String[] args){ + TestMonkeyHead app = new TestMonkeyHead(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + Spatial bumpy = assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml"); + rootNode.attachChild(bumpy); + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + rootNode.attachChild(lightMdl); + + // fluorescent main light + pl = new PointLight(); + pl.setColor(new ColorRGBA(0.88f, 0.92f, 0.95f, 1.0f)); + rootNode.addLight(pl); + + // sunset light + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal()); + dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f)); + rootNode.addLight(dl); + + // skylight + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal()); + dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f)); + rootNode.addLight(dl); + + // white ambient light + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal()); + dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); + rootNode.addLight(dl); + } + + @Override + public void simpleUpdate(float tpf){ + angle += tpf * 0.25f; + angle %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle) * 6f, 3f, FastMath.sin(angle) * 6f)); + lightMdl.setLocalTranslation(pl.getPosition()); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java b/jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java new file mode 100644 index 0000000000..fb81e69382 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/TestObjGroupsLoading.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.ModelKey; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.font.Rectangle; +import com.jme3.light.AmbientLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Ray; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; + +public class TestObjGroupsLoading extends SimpleApplication { + + public static void main(String[] args) { + TestObjGroupsLoading app = new TestObjGroupsLoading(); + app.start(); + } + + private BitmapText pointerDisplay; + + @Override + public void simpleInitApp() { + + // load scene with following structure: + // Chair 1 (just mesh without name) and named groups: Chair 2, Pillow 2, Podium + Spatial scene = assetManager.loadModel(new ModelKey("OBJLoaderTest/TwoChairs.obj")); + // add light to make it visible + scene.addLight(new AmbientLight(ColorRGBA.White)); + // attach scene to the root + rootNode.attachChild(scene); + + // configure camera for best scene viewing + cam.setLocation(new Vector3f(-3, 4, 3)); + cam.lookAtDirection(new Vector3f(0, -0.5f, -1), Vector3f.UNIT_Y); + flyCam.setMoveSpeed(10); + + // create display to indicate pointed geometry name + pointerDisplay = new BitmapText(guiFont); + pointerDisplay.setBox(new Rectangle(0, settings.getHeight(), settings.getWidth(), settings.getHeight()/2)); + pointerDisplay.setAlignment(BitmapFont.Align.Center); + pointerDisplay.setVerticalAlignment(BitmapFont.VAlign.Center); + guiNode.attachChild(pointerDisplay); + + initCrossHairs(); + } + + @Override + public void simpleUpdate(final float tpf) { + + // ray to the center of the screen from the camera + Ray ray = new Ray(cam.getLocation(), cam.getDirection()); + + // find object at the center of the screen + + final CollisionResults results = new CollisionResults(); + rootNode.collideWith(ray, results); + + CollisionResult result = results.getClosestCollision(); + if (result == null) { + pointerDisplay.setText(""); + } else { + // display pointed geometry and it's parents names + StringBuilder sb = new StringBuilder(); + for (Spatial node = result.getGeometry(); node != null; node = node.getParent()) { + if (sb.length() > 0) { + sb.append(" < "); + } + sb.append(node.getName()); + } + pointerDisplay.setText(sb); + } + } + + private void initCrossHairs() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, + settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); + guiNode.attachChild(ch); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/TestObjLoading.java b/jme3-examples/src/main/java/jme3test/model/TestObjLoading.java new file mode 100644 index 0000000000..2788f12891 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/TestObjLoading.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.model; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; + +/** + * Tests OBJ format loading + */ +public class TestObjLoading extends SimpleApplication { + + public static void main(String[] args){ + TestObjLoading app = new TestObjLoading(); + app.start(); + } + + @Override + public void simpleInitApp() { + // create the geometry and attach it + Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + + // show normals as material + Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + teaGeom.setMaterial(mat); + + rootNode.attachChild(teaGeom); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java b/jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java new file mode 100644 index 0000000000..c3bc78f479 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/TestOgreLoading.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.light.PointLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; + +public class TestOgreLoading extends SimpleApplication { + + private float angle1; + private float angle2; + private PointLight pl; + private PointLight p2; + private Spatial lightMdl; + private Spatial lightMd2; + + public static void main(String[] args) { + TestOgreLoading app = new TestOgreLoading(); + app.start(); + } + + @Override + public void simpleInitApp() { +// PointLight pl = new PointLight(); +// pl.setPosition(new Vector3f(10, 10, -10)); +// rootNode.addLight(pl); + flyCam.setMoveSpeed(10f); + + // sunset light + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, 1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + + + lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + rootNode.attachChild(lightMdl); + + lightMd2 = new Geometry("Light", new Sphere(10, 10, 0.1f)); + lightMd2.setMaterial(assetManager.loadMaterial("Common/Materials/WhiteColor.j3m")); + rootNode.attachChild(lightMd2); + + + pl = new PointLight(); + pl.setColor(new ColorRGBA(1, 0.9f, 0.9f, 0)); + pl.setPosition(new Vector3f(0f, 0f, 4f)); + rootNode.addLight(pl); + + p2 = new PointLight(); + p2.setColor(new ColorRGBA(0.9f, 1, 0.9f, 0)); + p2.setPosition(new Vector3f(0f, 0f, 3f)); + rootNode.addLight(p2); + + + // create the geometry and attach it + Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml"); + float scale = 0.05f; + elephant.scale(scale, scale, scale); + rootNode.attachChild(elephant); + } + + @Override + public void simpleUpdate(float tpf) { + angle1 += tpf * 0.25f; + angle1 %= FastMath.TWO_PI; + + angle2 += tpf * 0.50f; + angle2 %= FastMath.TWO_PI; + + pl.setPosition(new Vector3f(FastMath.cos(angle1) * 4f, 0.5f, FastMath.sin(angle1) * 4f)); + p2.setPosition(new Vector3f(FastMath.cos(angle2) * 4f, 0.5f, FastMath.sin(angle2) * 4f)); + lightMdl.setLocalTranslation(pl.getPosition()); + lightMd2.setLocalTranslation(p2.getPosition()); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java b/jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java new file mode 100644 index 0000000000..6e7b1ee82d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/EraseTimer.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.system.Timer; + +/** + * @author Nehon + */ +public class EraseTimer extends Timer { + + + //private static final long TIMER_RESOLUTION = 1000L; + //private static final float INVERSE_TIMER_RESOLUTION = 1f/1000L; + private static final long TIMER_RESOLUTION = 1000000000L; + private static final float INVERSE_TIMER_RESOLUTION = 1f / 1000000000L; + + private long startTime; + private long previousTime; + private float tpf; + private float fps; + + public EraseTimer() { + //startTime = System.currentTimeMillis(); + startTime = System.nanoTime(); + } + + /** + * Returns the time in seconds. The timer starts + * at 0.0 seconds. + * + * @return the current time in seconds + */ + @Override + public float getTimeInSeconds() { + return getTime() * INVERSE_TIMER_RESOLUTION; + } + + @Override + public long getTime() { + //return System.currentTimeMillis() - startTime; + return System.nanoTime() - startTime; + } + + @Override + public long getResolution() { + return TIMER_RESOLUTION; + } + + @Override + public float getFrameRate() { + return fps; + } + + @Override + public float getTimePerFrame() { + return tpf; + } + + @Override + public void update() { + tpf = (getTime() - previousTime) * (1.0f / TIMER_RESOLUTION); + if (tpf >= 0.2) { + // The frame lasted more than 200ms, so we erase its time to 16ms. + tpf = 0.016666f; + } else { + fps = 1.0f / tpf; + } + previousTime = getTime(); + } + + @Override + public void reset() { + //startTime = System.currentTimeMillis(); + startTime = System.nanoTime(); + previousTime = getTime(); + } + + +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java new file mode 100644 index 0000000000..18b09edbf2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2017-2022 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.*; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.*; +import com.jme3.anim.util.AnimMigrationUtils; +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.*; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.debug.custom.ArmatureDebugAppState; + +import java.util.LinkedList; + +/** + * Created by Nehon on 18/12/2017. + */ +public class TestAnimMigration extends SimpleApplication { + + private ArmatureDebugAppState debugAppState; + private AnimComposer composer; + final private LinkedList anims = new LinkedList<>(); + private boolean playAnim = false; + private BlendAction action; + private float blendValue = 1f; + + public static void main(String... argv) { + TestAnimMigration app = new TestAnimMigration(); + app.start(); + } + + @Override + public void simpleInitApp() { + setTimer(new EraseTimer()); + cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.1f, 100f); + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); + rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); + + Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); + // Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml").scale(0.2f).move(0, 1, 0); + //Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); + //Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml").scale(0.02f); + + AnimMigrationUtils.migrate(model); + + rootNode.attachChild(model); + + + debugAppState = new ArmatureDebugAppState(); + stateManager.attach(debugAppState); + + setupModel(model); + + flyCam.setEnabled(false); + + Node target = new Node("CamTarget"); + //target.setLocalTransform(model.getLocalTransform()); + target.move(0, 1, 0); + ChaseCameraAppState chaseCam = new ChaseCameraAppState(); + chaseCam.setTarget(target); + getStateManager().attach(chaseCam); + chaseCam.setInvertHorizontalAxis(true); + chaseCam.setInvertVerticalAxis(true); + chaseCam.setZoomSpeed(0.5f); + chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); + chaseCam.setRotationSpeed(3); + chaseCam.setDefaultDistance(3); + chaseCam.setMinDistance(0.01f); + chaseCam.setZoomSpeed(0.01f); + chaseCam.setDefaultVerticalRotation(0.3f); + + initInputs(); + } + + public void initInputs() { + inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + playAnim = !playAnim; + if (playAnim) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } else { + composer.reset(); + } + } + } + }, "toggleAnim"); + inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed && composer != null) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } + } + }, "nextAnim"); + inputManager.addMapping("toggleArmature", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + debugAppState.setEnabled(!debugAppState.isEnabled()); + } + } + }, "toggleArmature"); + + inputManager.addMapping("mask", new KeyTrigger(KeyInput.KEY_M)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + ((BlendableAction)composer.setCurrentAction("Wave", "LeftArm", false)).setMaxTransitionWeight(0.9); + } + } + + }, "mask"); + + inputManager.addMapping("blendUp", new KeyTrigger(KeyInput.KEY_UP)); + inputManager.addMapping("blendDown", new KeyTrigger(KeyInput.KEY_DOWN)); + + inputManager.addListener(new AnalogListener() { + + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("blendUp")) { + blendValue += value; + blendValue = FastMath.clamp(blendValue, 1, 4); + action.getBlendSpace().setValue(blendValue); + //action.setSpeed(blendValue); + } + if (name.equals("blendDown")) { + blendValue -= value; + blendValue = FastMath.clamp(blendValue, 1, 4); + action.getBlendSpace().setValue(blendValue); + //action.setSpeed(blendValue); + } + //System.err.println(blendValue); + } + }, "blendUp", "blendDown"); + + inputManager.addMapping("maxTransitionWeightInc", new KeyTrigger(KeyInput.KEY_ADD)); + inputManager.addMapping("maxTransitionWeightDec", new KeyTrigger(KeyInput.KEY_SUBTRACT)); + + inputManager.addListener(new AnalogListener() { + + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("maxTransitionWeightInc")) { + Action action = composer.getCurrentAction(); + if (action instanceof BlendableAction) { + BlendableAction ba = (BlendableAction) action; + ba.setMaxTransitionWeight(Math.min(ba.getMaxTransitionWeight() + 0.01, 1.0)); + System.out.println("MaxTransitionWeight=" + ba.getMaxTransitionWeight()); + } + } + if (name.equals("maxTransitionWeightDec")) { + Action action = composer.getCurrentAction(); + if (action instanceof BlendableAction) { + BlendableAction ba = (BlendableAction) action; + ba.setMaxTransitionWeight(Math.max(ba.getMaxTransitionWeight() - 0.01, 0.0)); + System.out.println("MaxTransitionWeight=" + ba.getMaxTransitionWeight()); + } + } + //System.err.println(blendValue); + } + }, "maxTransitionWeightInc", "maxTransitionWeightDec"); + } + + private void setupModel(Spatial model) { + if (composer != null) { + return; + } + composer = model.getControl(AnimComposer.class); + if (composer != null) { + + SkinningControl sc = model.getControl(SkinningControl.class); + debugAppState.addArmatureFrom(sc); + + anims.clear(); + for (String name : composer.getAnimClipsNames()) { + anims.add(name); + } + composer.actionSequence("Sequence1", + composer.makeAction("Walk"), + composer.makeAction("Run"), + composer.makeAction("Jumping")).setSpeed(1); + + composer.actionSequence("Sequence2", + composer.makeAction("Walk"), + composer.makeAction("Run"), + composer.makeAction("Jumping")).setSpeed(-1); + + action = composer.actionBlended("Blend", new LinearBlendSpace(1, 4), + "Walk", "Run"); + + action.getBlendSpace().setValue(1); + + composer.action("Walk").setSpeed(-1); + + composer.addAction("WalkCycle", new BaseAction(Tweens.cycle(composer.makeAction("Walk")))); + + composer.makeLayer("LeftArm", ArmatureMask.createMask(sc.getArmature(), "shoulder.L")); + + anims.addFirst("WalkCycle"); + anims.addFirst("Blend"); + anims.addFirst("Sequence2"); + anims.addFirst("Sequence1"); + + if (anims.isEmpty()) { + return; + } + if (playAnim) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } + + } else { + if (model instanceof Node) { + Node n = (Node) model; + for (Spatial child : n.getChildren()) { + setupModel(child); + } + } + } + + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java new file mode 100644 index 0000000000..30306429da --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMorphSerialization.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2017-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.*; +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.FileLocator; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.math.*; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.debug.custom.ArmatureDebugAppState; +import com.jme3.system.JmeSystem; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by Nehon on 18/12/2017. + */ +public class TestAnimMorphSerialization extends SimpleApplication { + + private ArmatureDebugAppState debugAppState; + private AnimComposer composer; + final private Queue anims = new LinkedList<>(); + private boolean playAnim = true; + private File file; + + public static void main(String... argv) { + TestAnimMorphSerialization app = new TestAnimMorphSerialization(); + app.start(); + } + + @Override + public void simpleInitApp() { + setTimer(new EraseTimer()); + //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + //rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); + //rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); + Node probeNode = (Node) assetManager.loadModel("Scenes/defaultProbe.j3o"); + rootNode.attachChild(probeNode); + Spatial model = assetManager.loadModel("Models/gltf/zophrac/scene.gltf"); + + File storageFolder = JmeSystem.getStorageFolder(); + file = new File(storageFolder.getPath() + File.separator + "zophrac.j3o"); + BinaryExporter be = new BinaryExporter(); + try { + be.save(model, file); + } catch (IOException e) { + e.printStackTrace(); + } + + assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); + Spatial model2 = assetManager.loadModel("zophrac.j3o"); + model2.setLocalScale(0.1f); + probeNode.attachChild(model2); + + debugAppState = new ArmatureDebugAppState(); + stateManager.attach(debugAppState); + + setupModel(model2); + + flyCam.setEnabled(false); + + Node target = new Node("CamTarget"); + //target.setLocalTransform(model.getLocalTransform()); + target.move(0, 0, 0); + ChaseCameraAppState chaseCam = new ChaseCameraAppState(); + chaseCam.setTarget(target); + getStateManager().attach(chaseCam); + chaseCam.setInvertHorizontalAxis(true); + chaseCam.setInvertVerticalAxis(true); + chaseCam.setZoomSpeed(0.5f); + chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); + chaseCam.setRotationSpeed(3); + chaseCam.setDefaultDistance(3); + chaseCam.setMinDistance(0.01f); + chaseCam.setZoomSpeed(0.01f); + chaseCam.setDefaultVerticalRotation(0.3f); + + initInputs(); + } + + public void initInputs() { + inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + playAnim = !playAnim; + if (playAnim) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } else { + composer.reset(); + } + } + } + }, "toggleAnim"); + inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed && composer != null) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } + } + }, "nextAnim"); + } + + private void setupModel(Spatial model) { + if (composer != null) { + return; + } + composer = model.getControl(AnimComposer.class); + if (composer != null) { +// model.getControl(SkinningControl.class).setEnabled(false); +// model.getControl(MorphControl.class).setEnabled(false); +// composer.setEnabled(false); + + + SkinningControl sc = model.getControl(SkinningControl.class); + debugAppState.addArmatureFrom(sc); + + anims.clear(); + for (String name : composer.getAnimClipsNames()) { + anims.add(name); + } + if (anims.isEmpty()) { + return; + } + if (playAnim) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } + + } else { + if (model instanceof Node) { + Node n = (Node) model; + for (Spatial child : n.getChildren()) { + setupModel(child); + } + } + } + + } + + + @Override + public void destroy() { + super.destroy(); + file.delete(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java new file mode 100644 index 0000000000..512946bd01 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimSerialization.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2017-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.SkinningControl; +import com.jme3.anim.util.AnimMigrationUtils; +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.FileLocator; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.*; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.debug.custom.ArmatureDebugAppState; +import com.jme3.system.JmeSystem; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by Nehon on 18/12/2017. + */ +public class TestAnimSerialization extends SimpleApplication { + + private ArmatureDebugAppState debugAppState; + private AnimComposer composer; + final private Queue anims = new LinkedList<>(); + private boolean playAnim = true; + private File file; + + public static void main(String... argv) { + TestAnimSerialization app = new TestAnimSerialization(); + app.start(); + } + + @Override + public void simpleInitApp() { + setTimer(new EraseTimer()); + //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); + rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); + + Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); + + AnimMigrationUtils.migrate(model); + + File storageFolder = JmeSystem.getStorageFolder(); + file = new File(storageFolder.getPath() + File.separator + "newJaime.j3o"); + BinaryExporter be = new BinaryExporter(); + try { + be.save(model, file); + } catch (IOException e) { + e.printStackTrace(); + } + + assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); + model = assetManager.loadModel("newJaime.j3o"); + + rootNode.attachChild(model); + + debugAppState = new ArmatureDebugAppState(); + stateManager.attach(debugAppState); + + setupModel(model); + + flyCam.setEnabled(false); + + Node target = new Node("CamTarget"); + //target.setLocalTransform(model.getLocalTransform()); + target.move(0, 1, 0); + ChaseCameraAppState chaseCam = new ChaseCameraAppState(); + chaseCam.setTarget(target); + getStateManager().attach(chaseCam); + chaseCam.setInvertHorizontalAxis(true); + chaseCam.setInvertVerticalAxis(true); + chaseCam.setZoomSpeed(0.5f); + chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); + chaseCam.setRotationSpeed(3); + chaseCam.setDefaultDistance(3); + chaseCam.setMinDistance(0.01f); + chaseCam.setZoomSpeed(0.01f); + chaseCam.setDefaultVerticalRotation(0.3f); + + initInputs(); + } + + public void initInputs() { + inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN)); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + playAnim = !playAnim; + if (playAnim) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } else { + composer.reset(); + } + } + } + }, "toggleAnim"); + inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed && composer != null) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } + } + }, "nextAnim"); + } + + private void setupModel(Spatial model) { + if (composer != null) { + return; + } + composer = model.getControl(AnimComposer.class); + if (composer != null) { + + SkinningControl sc = model.getControl(SkinningControl.class); + + debugAppState.addArmatureFrom(sc); + anims.clear(); + for (String name : composer.getAnimClipsNames()) { + anims.add(name); + } + if (anims.isEmpty()) { + return; + } + if (playAnim) { + String anim = anims.poll(); + anims.add(anim); + composer.setCurrentAction(anim); + System.err.println(anim); + } + + } else { + if (model instanceof Node) { + Node n = (Node) model; + for (Spatial child : n.getChildren()) { + setupModel(child); + } + } + } + + } + + + @Override + public void destroy() { + super.destroy(); + file.delete(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java new file mode 100644 index 0000000000..e09500e248 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java @@ -0,0 +1,90 @@ +package jme3test.model.anim; + +import com.jme3.anim.AnimClip; +import com.jme3.anim.AnimComposer; +import com.jme3.anim.AnimFactory; +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; +import com.jme3.util.TangentBinormalGenerator; + +public class TestAnimationFactory extends SimpleApplication { + + public static void main(String[] args) { + TestAnimationFactory app = new TestAnimationFactory(); + app.start(); + } + + @Override + public void simpleInitApp() { + + AmbientLight al = new AmbientLight(); + rootNode.addLight(al); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(Vector3f.UNIT_XYZ.negate()); + rootNode.addLight(dl); + + // Create model + Box box = new Box(1, 1, 1); + Geometry geom = new Geometry("box", box); + geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); + Node model = new Node("model"); + model.attachChild(geom); + + Box child = new Box(0.5f, 0.5f, 0.5f); + Geometry childGeom = new Geometry("box", child); + childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); + Node childModel = new Node("child model"); + childModel.setLocalTranslation(2, 2, 2); + childModel.attachChild(childGeom); + model.attachChild(childModel); + TangentBinormalGenerator.generate(model); + + // Construct a complex animation using AnimFactory: + // 6 seconds in duration, named "anim", running at 25 frames per second + AnimFactory animationFactory = new AnimFactory(6f, "anim", 25f); + + // Create a translation keyFrame at time = 3 with a translation on the X axis of 5 WU. + animationFactory.addTimeTranslation(3, new Vector3f(5, 0, 0)); + //resetting the translation to the start position at time = 6 + animationFactory.addTimeTranslation(6, new Vector3f(0, 0, 0)); + + //Creating a scale keyFrame at time = 2 with the unit scale. + animationFactory.addTimeScale(2, new Vector3f(1, 1, 1)); + //Creating a scale keyFrame at time = 4 scaling to 1.5 + animationFactory.addTimeScale(4, new Vector3f(1.5f, 1.5f, 1.5f)); + //resetting the scale to the start value at time = 5 + animationFactory.addTimeScale(5, new Vector3f(1, 1, 1)); + + + //Creating a rotation keyFrame at time = 0.5 of quarter PI around the Z axis + animationFactory.addTimeRotation(0.5f,new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Z)); + //rotating back to initial rotation value at time = 1 + animationFactory.addTimeRotation(1,Quaternion.IDENTITY); + /* + * Perform a 360-degree rotation around the X axis between t=1 and t=2. + */ + for (int i = 1; i <= 3; ++i) { + float rotTime = i / 3f; + float xAngle = FastMath.TWO_PI * rotTime; + animationFactory.addTimeRotation(1f + rotTime, xAngle, 0f, 0f); + } + + AnimClip clip = animationFactory.buildAnimation(model); + AnimComposer control = new AnimComposer(); + control.addAnimClip(clip); + model.addControl(control); + + rootNode.attachChild(model); + + //run animation + control.setCurrentAction("anim"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java b/jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java new file mode 100644 index 0000000000..6c71144286 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestArmature.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2017-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.*; +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.scene.*; +import com.jme3.scene.debug.custom.ArmatureDebugAppState; +import com.jme3.scene.shape.Cylinder; + +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +/** + * Created by Nehon on 18/12/2017. + */ +public class TestArmature extends SimpleApplication { + + public static void main(String... argv) { + TestArmature app = new TestArmature(); + app.start(); + } + + @Override + public void simpleInitApp() { + setTimer(new EraseTimer()); + renderManager.setSinglePassLightBatchSize(2); + //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + //create armature + Joint root = new Joint("Root_Joint"); + Joint j1 = new Joint("Joint_1"); + Joint j2 = new Joint("Joint_2"); + Joint j3 = new Joint("Joint_3"); + root.addChild(j1); + j1.addChild(j2); + j2.addChild(j3); + root.setLocalTranslation(new Vector3f(0, 0, 0.5f)); + j1.setLocalTranslation(new Vector3f(0, 0.0f, -0.5f)); + j2.setLocalTranslation(new Vector3f(0, 0.0f, -0.3f)); + j3.setLocalTranslation(new Vector3f(0, 0, -0.2f)); + Joint[] joints = new Joint[]{root, j1, j2, j3}; + + final Armature armature = new Armature(joints); + //armature.setModelTransformClass(SeparateJointModelTransform.class); + armature.saveBindPose(); + + //create animations + AnimClip clip = new AnimClip("anim"); + float[] times = new float[]{0, 2, 4}; + Quaternion[] rotations = new Quaternion[]{ + new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X), + new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X), + new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X) + }; + Vector3f[] translations = new Vector3f[]{ + new Vector3f(0, 0.2f, 0), + new Vector3f(0, 1.0f, 0), + new Vector3f(0, 0.2f, 0), + }; + Vector3f[] scales = new Vector3f[]{ + new Vector3f(1, 1, 1), + new Vector3f(1, 1, 2), + new Vector3f(1, 1, 1), + }; + Vector3f[] scales2 = new Vector3f[]{ + new Vector3f(1, 1, 1), + new Vector3f(1, 1, 0.5f), + new Vector3f(1, 1, 1), + }; + + TransformTrack track1 = new TransformTrack(j1, times, null, rotations, scales); + TransformTrack track2 = new TransformTrack(j2, times, null, rotations, null); + + clip.setTracks(new TransformTrack[]{track1, track2}); + + //create the animComposer control + final AnimComposer composer = new AnimComposer(); + composer.addAnimClip(clip); + + //create the SkinningControl + SkinningControl ac = new SkinningControl(armature); + ac.setHardwareSkinningPreferred(false); + Node node = new Node("Test Armature"); + + rootNode.attachChild(node); + + //Create the mesh to deform. + Geometry cylinder = new Geometry("cylinder", createMesh()); + Material m = new Material(assetManager, "Common/MatDefs/Misc/fakeLighting.j3md"); + m.setColor("Color", ColorRGBA.randomColor()); + cylinder.setMaterial(m); + node.attachChild(cylinder); + node.addControl(composer); + node.addControl(ac); + + composer.setCurrentAction("anim"); + + ArmatureDebugAppState debugAppState = new ArmatureDebugAppState(); + debugAppState.addArmatureFrom(ac); + stateManager.attach(debugAppState); + + flyCam.setEnabled(false); + + ChaseCameraAppState chaseCam = new ChaseCameraAppState(); + chaseCam.setTarget(node); + getStateManager().attach(chaseCam); + chaseCam.setInvertHorizontalAxis(true); + chaseCam.setInvertVerticalAxis(true); + chaseCam.setZoomSpeed(0.5f); + chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); + chaseCam.setRotationSpeed(3); + chaseCam.setDefaultDistance(3); + chaseCam.setMinDistance(0.01f); + chaseCam.setZoomSpeed(0.01f); + chaseCam.setDefaultVerticalRotation(0.3f); + + + inputManager.addMapping("bind", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + composer.reset(); + armature.applyBindPose(); + + } else { + composer.setCurrentAction("anim"); + } + } + }, "bind"); + } + + private Mesh createMesh() { + Cylinder c = new Cylinder(30, 16, 0.1f, 1, true); + + ShortBuffer jointIndex = (ShortBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.UnsignedShort, 4, c.getVertexCount()); + jointIndex.rewind(); + c.setMaxNumWeights(1); + FloatBuffer jointWeight = (FloatBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.Float, 4, c.getVertexCount()); + jointWeight.rewind(); + VertexBuffer vb = c.getBuffer(VertexBuffer.Type.Position); + FloatBuffer fvb = (FloatBuffer) vb.getData(); + fvb.rewind(); + for (int i = 0; i < c.getVertexCount(); i++) { + fvb.get(); + fvb.get(); + float z = fvb.get(); + int index = 0; + if (z > 0) { + index = 0; + } else if (z > -0.2) { + index = 1; + } else { + index = 2; + } + jointIndex.put((short) index).put((short) 0).put((short) 0).put((short) 0); + jointWeight.put(1f).put(0f).put(0f).put(0f); + + } + c.setBuffer(VertexBuffer.Type.BoneIndex, 4, jointIndex); + c.setBuffer(VertexBuffer.Type.BoneWeight, 4, jointWeight); + + c.updateCounts(); + c.updateBound(); + + VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight); + VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex); + + indicesHW.setUsage(VertexBuffer.Usage.CpuOnly); + weightsHW.setUsage(VertexBuffer.Usage.CpuOnly); + c.setBuffer(weightsHW); + c.setBuffer(indicesHW); + c.generateBindPose(); + + c.prepareForAnim(false); + + return c; + } + + +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java new file mode 100644 index 0000000000..78d81f558c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestAttachmentsNode.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.SkinningControl; +import com.jme3.anim.tween.Tween; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; +import com.jme3.anim.util.AnimMigrationUtils; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; + +/** + * Simple application to test an attachments node on the Jaime model. + * + * Derived from {@link jme3test.model.anim.TestOgreAnim}. + */ +public class TestAttachmentsNode extends SimpleApplication + implements ActionListener { + + private Action punchesOnce; + private AnimComposer control; + + public static void main(String[] args) { + TestAttachmentsNode app = new TestAttachmentsNode(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10f); + cam.setLocation(new Vector3f(6.4f, 7.5f, 12.8f)); + cam.setRotation(new Quaternion(-0.060740203f, 0.93925786f, -0.2398315f, -0.2378785f)); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(ColorRGBA.White); + rootNode.addLight(dl); + /* + * Load the Jaime model and convert it + * from the old animation system to the new one. + */ + Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); + AnimMigrationUtils.migrate(model); + /* + * Play the "Idle" animation at half speed. + */ + control = model.getControl(AnimComposer.class); + control.setCurrentAction("Idle"); + control.setGlobalSpeed(0.5f); + /* + * Define a "PunchesOnce" action sequence to play the "Punches" + * animation for one cycle before returning to idle. + */ + Action punches = control.action("Punches"); + Tween doneTween + = Tweens.callMethod(control, "setCurrentAction", "Idle"); + punchesOnce = control.actionSequence("PunchesOnce", punches, doneTween); + + model.center(); + model.setLocalScale(5f); + + Box box = new Box(0.3f, 0.02f, 0.02f); + Geometry saber = new Geometry("saber", box); + saber.move(0.4f, 0.05f, 0.01f); + Material red = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + saber.setMaterial(red); + /* + * Create an attachments node for Jaime's right hand, + * and attach the saber to that Node. + */ + SkinningControl skeletonControl = model.getControl(SkinningControl.class); + Node n = skeletonControl.getAttachmentsNode("hand.R"); + n.attachChild(saber); + rootNode.attachChild(model); + + inputManager.addListener(this, "Attack"); + inputManager.addMapping("Attack", new KeyTrigger(KeyInput.KEY_SPACE)); + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (value && binding.equals("Attack") + && control.getCurrentAction() != punchesOnce) { + control.setCurrentAction("PunchesOnce"); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java b/jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java new file mode 100644 index 0000000000..5a5934142c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestBaseAnimSerialization.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2017-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.*; +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.FileLocator; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.scene.*; +import com.jme3.scene.debug.custom.ArmatureDebugAppState; +import com.jme3.scene.shape.Cylinder; +import com.jme3.system.JmeSystem; + +import java.io.File; +import java.io.IOException; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +/** + * Created by Nehon on 18/12/2017. + */ +public class TestBaseAnimSerialization extends SimpleApplication { + + private AnimComposer composer; + private Armature armature; + private File file; + + public static void main(String... argv) { + TestBaseAnimSerialization app = new TestBaseAnimSerialization(); + app.start(); + } + + @Override + public void simpleInitApp() { + setTimer(new EraseTimer()); + renderManager.setSinglePassLightBatchSize(2); + //cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + //create armature + Joint root = new Joint("Root_Joint"); + Joint j1 = new Joint("Joint_1"); + Joint j2 = new Joint("Joint_2"); + Joint j3 = new Joint("Joint_3"); + root.addChild(j1); + j1.addChild(j2); + j2.addChild(j3); + root.setLocalTranslation(new Vector3f(0, 0, 0.5f)); + j1.setLocalTranslation(new Vector3f(0, 0.0f, -0.5f)); + j2.setLocalTranslation(new Vector3f(0, 0.0f, -0.3f)); + j3.setLocalTranslation(new Vector3f(0, 0, -0.2f)); + Joint[] joints = new Joint[]{root, j1, j2, j3}; + + armature = new Armature(joints); + //armature.setModelTransformClass(SeparateJointModelTransform.class); + armature.saveBindPose(); + + //create animations + AnimClip clip = new AnimClip("anim"); + float[] times = new float[]{0, 2, 4}; + Quaternion[] rotations = new Quaternion[]{ + new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X), + new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X), + new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X) + }; + Vector3f[] translations = new Vector3f[]{ + new Vector3f(0, 0.2f, 0), + new Vector3f(0, 1.0f, 0), + new Vector3f(0, 0.2f, 0), + }; + Vector3f[] scales = new Vector3f[]{ + new Vector3f(1, 1, 1), + new Vector3f(1, 1, 2), + new Vector3f(1, 1, 1), + }; + Vector3f[] scales2 = new Vector3f[]{ + new Vector3f(1, 1, 1), + new Vector3f(1, 1, 0.5f), + new Vector3f(1, 1, 1), + }; + + TransformTrack track1 = new TransformTrack(j1, times, null, rotations, scales); + TransformTrack track2 = new TransformTrack(j2, times, null, rotations, null); + + clip.setTracks(new TransformTrack[]{track1, track2}); + + //create the animComposer control + composer = new AnimComposer(); + composer.addAnimClip(clip); + + //create the SkinningControl + SkinningControl ac = new SkinningControl(armature); + Node node = new Node("Test Armature"); + + //Create the mesh to deform. + Geometry cylinder = new Geometry("cylinder", createMesh()); + Material m = new Material(assetManager, "Common/MatDefs/Misc/fakeLighting.j3md"); + m.setColor("Color", ColorRGBA.randomColor()); + cylinder.setMaterial(m); + node.attachChild(cylinder); + node.addControl(composer); + node.addControl(ac); + + File storageFolder = JmeSystem.getStorageFolder(); + file = new File(storageFolder.getPath() + File.separator + "test.j3o"); + BinaryExporter be = new BinaryExporter(); + try { + be.save(node, file); + } catch (IOException e) { + e.printStackTrace(); + } + + assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); + Node newNode = (Node) assetManager.loadModel("test.j3o"); + + rootNode.attachChild(newNode); + + composer = newNode.getControl(AnimComposer.class); + ac = newNode.getControl(SkinningControl.class); + ac.setHardwareSkinningPreferred(false); + armature = ac.getArmature(); + composer.setCurrentAction("anim"); + + ArmatureDebugAppState debugAppState = new ArmatureDebugAppState(); + debugAppState.addArmatureFrom(ac); + stateManager.attach(debugAppState); + + flyCam.setEnabled(false); + + ChaseCameraAppState chaseCam = new ChaseCameraAppState(); + chaseCam.setTarget(node); + getStateManager().attach(chaseCam); + chaseCam.setInvertHorizontalAxis(true); + chaseCam.setInvertVerticalAxis(true); + chaseCam.setZoomSpeed(0.5f); + chaseCam.setMinVerticalRotation(-FastMath.HALF_PI); + chaseCam.setRotationSpeed(3); + chaseCam.setDefaultDistance(3); + chaseCam.setMinDistance(0.01f); + chaseCam.setZoomSpeed(0.01f); + chaseCam.setDefaultVerticalRotation(0.3f); + + + inputManager.addMapping("bind", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + composer.reset(); + armature.applyBindPose(); + + } else { + composer.setCurrentAction("anim"); + } + } + }, "bind"); + } + + private Mesh createMesh() { + Cylinder c = new Cylinder(30, 16, 0.1f, 1, true); + + ShortBuffer jointIndex = (ShortBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.UnsignedShort, 4, c.getVertexCount()); + jointIndex.rewind(); + c.setMaxNumWeights(1); + FloatBuffer jointWeight = (FloatBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.Float, 4, c.getVertexCount()); + jointWeight.rewind(); + VertexBuffer vb = c.getBuffer(VertexBuffer.Type.Position); + FloatBuffer fvb = (FloatBuffer) vb.getData(); + fvb.rewind(); + for (int i = 0; i < c.getVertexCount(); i++) { + fvb.get(); + fvb.get(); + float z = fvb.get(); + int index = 0; + if (z > 0) { + index = 0; + } else if (z > -0.2) { + index = 1; + } else { + index = 2; + } + jointIndex.put((short) index).put((short) 0).put((short) 0).put((short) 0); + jointWeight.put(1f).put(0f).put(0f).put(0f); + + } + c.setBuffer(VertexBuffer.Type.BoneIndex, 4, jointIndex); + c.setBuffer(VertexBuffer.Type.BoneWeight, 4, jointWeight); + + c.updateCounts(); + c.updateBound(); + + VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight); + VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex); + + indicesHW.setUsage(VertexBuffer.Usage.CpuOnly); + weightsHW.setUsage(VertexBuffer.Usage.CpuOnly); + c.setBuffer(weightsHW); + c.setBuffer(indicesHW); + c.generateBindPose(); + + c.prepareForAnim(false); + + return c; + } + + @Override + public void destroy() { + super.destroy(); + file.delete(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java new file mode 100644 index 0000000000..6c4b230f01 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.model.anim; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +import com.jme3.anim.Armature; +import com.jme3.anim.Joint; +import com.jme3.anim.SkinningControl; +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.Quaternion; +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.VertexBuffer.Format; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.scene.VertexBuffer.Usage; +import com.jme3.scene.shape.Box; + +public class TestCustomAnim extends SimpleApplication { + + private Joint bone; + private Armature armature; + final private Quaternion rotation = new Quaternion(); + + public static void main(String[] args) { + TestCustomAnim app = new TestCustomAnim(); + app.start(); + } + + @Override + public void simpleInitApp() { + + AmbientLight al = new AmbientLight(); + rootNode.addLight(al); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(Vector3f.UNIT_XYZ.negate()); + rootNode.addLight(dl); + + Box box = new Box(1, 1, 1); + + VertexBuffer weightsHW = new VertexBuffer(Type.HWBoneWeight); + VertexBuffer indicesHW = new VertexBuffer(Type.HWBoneIndex); + indicesHW.setUsage(Usage.CpuOnly); + weightsHW.setUsage(Usage.CpuOnly); + box.setBuffer(weightsHW); + box.setBuffer(indicesHW); + + // Setup bone weight buffer + FloatBuffer weights = FloatBuffer.allocate(box.getVertexCount() * 4); + VertexBuffer weightsBuf = new VertexBuffer(Type.BoneWeight); + weightsBuf.setupData(Usage.CpuOnly, 4, Format.Float, weights); + box.setBuffer(weightsBuf); + + // Setup bone index buffer + ByteBuffer indices = ByteBuffer.allocate(box.getVertexCount() * 4); + VertexBuffer indicesBuf = new VertexBuffer(Type.BoneIndex); + indicesBuf.setupData(Usage.CpuOnly, 4, Format.UnsignedByte, indices); + box.setBuffer(indicesBuf); + + // Create bind pose buffers + box.generateBindPose(); + + // Create skeleton + bone = new Joint("root"); + bone.setLocalTransform(new Transform(Vector3f.ZERO, Quaternion.IDENTITY, Vector3f.UNIT_XYZ)); + armature = new Armature(new Joint[] { bone }); + + // Assign all vertices to bone 0 with weight 1 + for (int i = 0; i < box.getVertexCount() * 4; i += 4) { + // assign vertex to bone index 0 + indices.array()[i + 0] = 0; + indices.array()[i + 1] = 0; + indices.array()[i + 2] = 0; + indices.array()[i + 3] = 0; + + // set weight to 1 only for first entry + weights.array()[i + 0] = 1; + weights.array()[i + 1] = 0; + weights.array()[i + 2] = 0; + weights.array()[i + 3] = 0; + } + + // Maximum number of weights per bone is 1 + box.setMaxNumWeights(1); + + // Create model + Geometry geom = new Geometry("box", box); + geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); + Node model = new Node("model"); + model.attachChild(geom); + + // Create skeleton control + SkinningControl skinningControl = new SkinningControl(armature); + model.addControl(skinningControl); + + rootNode.attachChild(model); + } + + @Override + public void simpleUpdate(float tpf) { + // Rotate around X axis + Quaternion rotate = new Quaternion(); + rotate.fromAngleAxis(tpf, Vector3f.UNIT_X); + + // Combine rotation with previous + rotation.multLocal(rotate); + + // Set new rotation into bone + bone.setLocalTransform(new Transform(Vector3f.ZERO, rotation, Vector3f.UNIT_XYZ)); + + // After changing skeleton transforms, must update world data + armature.update(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java b/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java new file mode 100644 index 0000000000..bf882bf1a1 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.SkinningControl; +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.*; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; + +import java.util.ArrayList; +import java.util.List; + +public class TestHWSkinning extends SimpleApplication implements ActionListener{ + + + // private AnimComposer composer; + final private String[] animNames = {"Dodge", "Walk", "pull", "push"}; + private final static int SIZE = 40; + private boolean hwSkinningEnable = true; + final private List skControls = new ArrayList<>(); + private BitmapText hwsText; + + public static void main(String[] args) { + TestHWSkinning app = new TestHWSkinning(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10f); + flyCam.setDragToRotate(true); + setPauseOnLostFocus(false); + cam.setLocation(new Vector3f(38.76639f, 14.744472f, 45.097454f)); + cam.setRotation(new Quaternion(-0.06086266f, 0.92303723f, -0.1639443f, -0.34266636f)); + + makeHudText(); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + + Spatial models[] = new Spatial[4]; + for (int i = 0; i < 4; i++) { + models[i] =loadModel(i); + } + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + Node model = (Node)models[(i + j) % 4]; + Spatial s = model.getChild(0).clone(); + model.attachChild(s); + float x = (i - SIZE / 2) / 0.1f; + float z = (j - SIZE / 2) / 0.1f; + s.setLocalTranslation(x, 0, z); + } + } + + inputManager.addListener(this, "toggleHWS"); + inputManager.addMapping("toggleHWS", new KeyTrigger(KeyInput.KEY_SPACE)); + + } + + private Spatial loadModel(int i) { + Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + model.setLocalScale(0.1f); + AnimComposer composer = model.getControl(AnimComposer.class); + + composer.setCurrentAction(animNames[i]); + SkinningControl skinningControl = model.getControl(SkinningControl.class); + skinningControl.setHardwareSkinningPreferred(hwSkinningEnable); + skControls.add(skinningControl); + rootNode.attachChild(model); + return model; + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(isPressed && name.equals("toggleHWS")){ + hwSkinningEnable = !hwSkinningEnable; + for (SkinningControl control : skControls) { + control.setHardwareSkinningPreferred(hwSkinningEnable); + hwsText.setText("HWS : "+ hwSkinningEnable); + } + } + } + + private void makeHudText() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + hwsText = new BitmapText(guiFont); + hwsText.setSize(guiFont.getCharSet().getRenderedSize()); + hwsText.setText("HWS : "+ hwSkinningEnable); + hwsText.setLocalTranslation(0, cam.getHeight(), 0); + guiNode.attachChild(hwsText); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java b/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java new file mode 100644 index 0000000000..d5c5cbd7e0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinningOld.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.animation.*; +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.*; +import com.jme3.scene.Spatial; + +import java.util.ArrayList; +import java.util.List; + +public class TestHWSkinningOld extends SimpleApplication implements ActionListener { + + final private String[] animNames = {"Dodge", "Walk", "pull", "push"}; + private final static int SIZE = 50; + private boolean hwSkinningEnable = true; + final private List skControls = new ArrayList<>(); + private BitmapText hwsText; + + public static void main(String[] args) { + TestHWSkinningOld app = new TestHWSkinningOld(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10f); + flyCam.setDragToRotate(true); + setPauseOnLostFocus(false); + cam.setLocation(new Vector3f(24.746134f, 13.081396f, 32.72753f)); + cam.setRotation(new Quaternion(-0.06867662f, 0.92435044f, -0.19981281f, -0.31770203f)); + makeHudText(); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + Spatial model = assetManager.loadModel("Models/Oto/OtoOldAnim.j3o"); + model.setLocalScale(0.1f); + model.setLocalTranslation(i - SIZE / 2, 0, j - SIZE / 2); + AnimControl control = model.getControl(AnimControl.class); + AnimChannel channel = control.createChannel(); + channel.setAnim(animNames[(i + j) % 4]); + SkeletonControl skeletonControl = model.getControl(SkeletonControl.class); + skeletonControl.setHardwareSkinningPreferred(hwSkinningEnable); + skControls.add(skeletonControl); + rootNode.attachChild(model); + } + } + + inputManager.addListener(this, "toggleHWS"); + inputManager.addMapping("toggleHWS", new KeyTrigger(KeyInput.KEY_SPACE)); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed && name.equals("toggleHWS")) { + hwSkinningEnable = !hwSkinningEnable; + for (SkeletonControl control : skControls) { + control.setHardwareSkinningPreferred(hwSkinningEnable); + hwsText.setText("HWS : " + hwSkinningEnable); + } + } + } + + private void makeHudText() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + hwsText = new BitmapText(guiFont); + hwsText.setSize(guiFont.getCharSet().getRenderedSize()); + hwsText.setText("HWS : " + hwSkinningEnable); + hwsText.setLocalTranslation(0, cam.getHeight(), 0); + guiNode.attachChild(hwsText); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java b/jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java new file mode 100644 index 0000000000..f0e8bd3a6b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestIssue1395.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.SkinningControl; +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; + +/** + * Test case for Issue 1395 (OGRE Importer should call saveInitialPose, to be + * consistent with GLTF) + * + * If the test succeeds, the humanoid Oto model will appear in a standing + * position. If the test fails, the model will appear rolled up into a tight + * bundle. + * + * @author sgold + */ +public class TestIssue1395 extends SimpleApplication { + + public static void main(String[] args) { + TestIssue1395 app = new TestIssue1395(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(new ColorRGBA(1f, 1f, 1f, 1f)); + + flyCam.setMoveSpeed(10f); + cam.setLocation(new Vector3f(6.4013605f, 7.488437f, 12.843031f)); + cam.setRotation(new Quaternion(-0.06f, 0.939258f, -0.2399f, -0.2379f)); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1f)); + rootNode.addLight(dl); + + Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + rootNode.attachChild(model); + model.center(); + + SkinningControl skinningControl + = model.getControl(SkinningControl.class); + skinningControl.getArmature().applyInitialPose(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java b/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java new file mode 100644 index 0000000000..7795753b9d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009-2015 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.AnimComposer; +import com.jme3.app.SimpleApplication; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; + +public class TestModelExportingCloning extends SimpleApplication { + + public static void main(String[] args) { + TestModelExportingCloning app = new TestModelExportingCloning(); + app.start(); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(10f, 3f, 40f)); + cam.lookAtDirection(Vector3f.UNIT_Z.negate(), Vector3f.UNIT_Y); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + + AnimComposer composer; + + Spatial originalModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + composer = originalModel.getControl(AnimComposer.class); + composer.setCurrentAction("Walk"); + composer.setGlobalSpeed(1.5f); + rootNode.attachChild(originalModel); + + Spatial clonedModel = originalModel.clone(); + clonedModel.move(10, 0, 0); + composer = clonedModel.getControl(AnimComposer.class); + composer.setCurrentAction("push"); + System.out.println("clonedModel: globalSpeed=" + composer.getGlobalSpeed()); + rootNode.attachChild(clonedModel); + + Spatial exportedModel = BinaryExporter.saveAndLoad(assetManager, originalModel); + exportedModel.move(20, 0, 0); + composer = exportedModel.getControl(AnimComposer.class); + composer.setCurrentAction("pull"); + System.out.println("exportedModel: globalSpeed=" + composer.getGlobalSpeed()); + rootNode.attachChild(exportedModel); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java b/jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java new file mode 100644 index 0000000000..f0b2161528 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java @@ -0,0 +1,149 @@ +package jme3test.model.anim; + +import com.jme3.anim.MorphControl; +import com.jme3.app.ChaseCameraAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.material.RenderState; +import com.jme3.scene.Geometry; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.mesh.MorphTarget; +import com.jme3.scene.shape.Box; +import com.jme3.util.BufferUtils; +import com.jme3.util.clone.Cloner; +import java.nio.FloatBuffer; + +public class TestMorph extends SimpleApplication { + + final private float[] weights = new float[2]; + + public static void main(String... args) { + TestMorph app = new TestMorph(); + app.start(); + } + + @Override + public void simpleInitApp() { + BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText text = new BitmapText(font); + text.setText("Press U-Y-I-J to vary weights. Drag LMB to orbit camera."); + text.setLocalTranslation(10f, cam.getHeight() - 10f, 0f); + guiNode.attachChild(text); + + final Box box = new Box(1, 1, 1); + /* + * Add a morph target that increases X coordinates of the "right" face. + */ + FloatBuffer buffer = BufferUtils.createVector3Buffer(box.getVertexCount()); + + float[] d = new float[box.getVertexCount() * 3]; + for (int i = 0; i < d.length; i++) { + d[i] = 0; + } + + d[12] = 3f; + d[15] = 3f; + d[18] = 3f; + d[21] = 3f; + + buffer.put(d); + buffer.rewind(); + + MorphTarget target = new MorphTarget(); + target.setBuffer(VertexBuffer.Type.Position, buffer); + box.addMorphTarget(target); + /* + * Add a morph target that increases Y coordinates of the "right" face. + */ + buffer = BufferUtils.createVector3Buffer(box.getVertexCount()); + + for (int i = 0; i < d.length; i++) { + d[i] = 0; + } + + d[13] = 3f; + d[16] = 3f; + d[19] = 3f; + d[22] = 3f; + + buffer.put(d); + buffer.rewind(); + + final MorphTarget target2 = new MorphTarget(); + target2.setBuffer(VertexBuffer.Type.Position, buffer); + box.addMorphTarget(target2); + + final Geometry g = new Geometry("box", box); + Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + g.setMaterial(m); + m.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off); + m.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + m.setInt("NumberOfMorphTargets", 2); + + rootNode.attachChild(g); + + g.setMorphState(weights); + g.addControl(new MorphControl()); + /* + * Attach a clone of the morphing box model, in order to test cloning. + */ + Geometry g2 = Cloner.deepClone(g); + g2.move(-4f, 0f, 0f); + rootNode.attachChild(g2); + /* + * Attach a saveAndLoad() copy of the morphing box model, + * in order to test serialization. + */ + Geometry g3 = BinaryExporter.saveAndLoad(assetManager, g); + g3.move(-4f, 4f, 0f); + rootNode.attachChild(g3); + + ChaseCameraAppState chase = new ChaseCameraAppState(); + chase.setTarget(rootNode); + getStateManager().attach(chase); + flyCam.setEnabled(false); + + inputManager.addMapping("morphright", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addMapping("morphleft", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("morphup", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("morphdown", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("change", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("morphleft")) { + weights[0] -= tpf; + } + if (name.equals("morphright")) { + weights[0] += tpf; + } + if (name.equals("morphup")) { + weights[1] += tpf; + } + if (name.equals("morphdown")) { + weights[1] -= tpf; + } + weights[0] = Math.max(0f, weights[0]); + weights[1] = Math.max(0f, weights[1]); + g.setMorphState(weights); + + } + }, "morphup", "morphdown", "morphleft", "morphright"); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("change") && isPressed) { + box.setBuffer(VertexBuffer.Type.MorphTarget0, 3, target2.getBuffer(VertexBuffer.Type.Position)); + } + } + }, "change"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java new file mode 100644 index 0000000000..fbd9524d80 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.model.anim; + +import com.jme3.anim.AnimClip; +import com.jme3.anim.AnimComposer; +import com.jme3.anim.SkinningControl; +import com.jme3.anim.tween.Tween; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; +import com.jme3.anim.tween.action.BaseAction; +import com.jme3.anim.tween.action.LinearBlendSpace; +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; + +public class TestOgreAnim extends SimpleApplication implements ActionListener { + + private AnimComposer animComposer; + private static Action currentAction; + + public static void main(String[] args) { + TestOgreAnim app = new TestOgreAnim(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10f); + cam.setLocation(new Vector3f(6.4013605f, 7.488437f, 12.843031f)); + cam.setRotation(new Quaternion(-0.060740203f, 0.93925786f, -0.2398315f, -0.2378785f)); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + + Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + model.center(); + + animComposer = model.getControl(AnimComposer.class); + animComposer.actionBlended("Attack", new LinearBlendSpace(0f, 0.5f), "Dodge"); + for (AnimClip animClip : animComposer.getAnimClips()) { + Action action = animComposer.action(animClip.getName()); + if(!"stand".equals(animClip.getName())) { + action = new BaseAction(Tweens.sequence(action, Tweens.callMethod(this, "backToStand", animComposer))); + } + animComposer.addAction(animClip.getName(), action); + } + currentAction = animComposer.setCurrentAction("stand"); // Walk, pull, Dodge, stand, push + + SkinningControl skinningControl = model.getControl(SkinningControl.class); + skinningControl.setHardwareSkinningPreferred(false); + + Box b = new Box(.25f, 3f, .25f); + Geometry item = new Geometry("Item", b); + item.move(0, 1.5f, 0); + item.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); + Node n = skinningControl.getAttachmentsNode("hand.right"); + n.attachChild(item); + + rootNode.attachChild(model); + + inputManager.addListener(this, "Attack"); + inputManager.addMapping("Attack", new KeyTrigger(KeyInput.KEY_SPACE)); + } + + public Tween backToStand(AnimComposer animComposer) { + currentAction = animComposer.setCurrentAction("stand"); + return currentAction; + } + + @Override + public void onAction(String binding, boolean value, float tpf) { + if (binding.equals("Attack") && value) { + if (currentAction != null && !currentAction.equals(animComposer.getAction("Dodge"))) { + currentAction = animComposer.setCurrentAction("Dodge"); + currentAction.setSpeed(0.1f); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java new file mode 100644 index 0000000000..aac2c1f970 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.model.anim; + +import com.jme3.anim.AnimComposer; +import com.jme3.anim.ArmatureMask; +import com.jme3.anim.Joint; +import com.jme3.anim.SkinningControl; +import com.jme3.anim.tween.action.Action; +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.debug.custom.ArmatureDebugger; + +public class TestOgreComplexAnim extends SimpleApplication { + + private SkinningControl skinningControl; + + private float angle = 0; + private float rate = 1; + + public static void main(String[] args) { + TestOgreComplexAnim app = new TestOgreComplexAnim(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10f); + cam.setLocation(new Vector3f(6.4013605f, 7.488437f, 12.843031f)); + cam.setRotation(new Quaternion(-0.060740203f, 0.93925786f, -0.2398315f, -0.2378785f)); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + + Node model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + + skinningControl = model.getControl(SkinningControl.class); + AnimComposer ac = model.getControl(AnimComposer.class); + + ArmatureMask feet = ArmatureMask.createMask(skinningControl.getArmature(), "hip.right", "hip.left"); + Action dodgeAction = ac.action("Dodge"); + dodgeAction.setMask(feet); + dodgeAction.setSpeed(2f); + Action walkAction = ac.action("Walk"); + walkAction.setMask(feet); + walkAction.setSpeed(0.25f); + + ArmatureMask rightHand = ArmatureMask.createMask(skinningControl.getArmature(), "uparm.right"); + Action pullAction = ac.action("pull"); + pullAction.setMask(rightHand); + pullAction.setSpeed(0.5f); + Action standAction = ac.action("stand"); + standAction.setMask(rightHand); + standAction.setSpeed(0.5f); + + ac.actionSequence("complexAction", + ac.actionSequence("feetAction", dodgeAction, walkAction), + ac.actionSequence("rightHandAction", pullAction, standAction)); + + ac.setCurrentAction("complexAction"); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.getAdditionalRenderState().setWireframe(true); + mat.setColor("Color", ColorRGBA.Green); + mat.setFloat("PointSize", 7f); // Bug ? do not change size of debug points ? + mat.getAdditionalRenderState().setDepthTest(false); + + ArmatureDebugger armatureDebug = new ArmatureDebugger("armature", skinningControl.getArmature(), + skinningControl.getArmature().getJointList()); + armatureDebug.setMaterial(mat); + model.attachChild(armatureDebug); + + rootNode.attachChild(model); + } + + @Override + public void simpleUpdate(float tpf) { + Joint j = skinningControl.getArmature().getJoint("spinehigh"); + Joint j2 = skinningControl.getArmature().getJoint("uparm.left"); + + angle += tpf * rate; + if (angle > FastMath.HALF_PI / 2f) { + angle = FastMath.HALF_PI / 2f; + rate = -1; + } else if (angle < -FastMath.HALF_PI / 2f) { + angle = -FastMath.HALF_PI / 2f; + rate = 1; + } + + Quaternion q = new Quaternion(); + q.fromAngles(0, angle, 0); + + j.setLocalRotation(j.getInitialTransform().getRotation().mult(q)); + j2.setLocalScale(j.getInitialTransform().getScale().mult(new Vector3f(1 + angle, 1 + angle, 1 + angle))); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java b/jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java new file mode 100644 index 0000000000..3761858166 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model.anim; + +import com.jme3.anim.AnimClip; +import com.jme3.anim.AnimComposer; +import com.jme3.anim.SkinningControl; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; +import com.jme3.anim.tween.action.BaseAction; +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.ssao.SSAOFilter; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Quad; +import com.jme3.shadow.DirectionalLightShadowFilter; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Nehon + */ +public class TestSkeletonControlRefresh extends SimpleApplication implements ActionListener{ + + private final static int SIZE = 10; + private boolean hwSkinningEnable = true; + final private List skinningControls = new ArrayList<>(); + private BitmapText hwsText; + + public static void main(String[] args) { + TestSkeletonControlRefresh app = new TestSkeletonControlRefresh(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.White); + flyCam.setMoveSpeed(10f); + cam.setLocation(new Vector3f(3.8664846f, 6.2704787f, 9.664585f)); + cam.setRotation(new Quaternion(-0.054774776f, 0.94064945f, -0.27974048f, -0.18418397f)); + makeHudText(); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey k = new TextureKey("Models/Oto/Oto.jpg", false); + m.setTexture("ColorMap", assetManager.loadTexture(k)); + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + //setting a different material + model.setMaterial(m.clone()); + model.setLocalScale(0.1f); + model.setLocalTranslation(i - SIZE / 2, 0, j - SIZE / 2); + + AnimComposer animComposer + = model.getControl(AnimComposer.class); + for (AnimClip animClip : animComposer.getAnimClips()) { + Action action = animComposer.action(animClip.getName()); + animComposer.addAction(animClip.getName(), new BaseAction( + Tweens.sequence(action, Tweens.callMethod(animComposer, "removeCurrentAction", AnimComposer.DEFAULT_LAYER)))); + } + animComposer.setCurrentAction(new ArrayList<>(animComposer.getAnimClips()).get((i + j) % 4).getName()); + + SkinningControl skinningControl = model.getControl(SkinningControl.class); + skinningControl.setHardwareSkinningPreferred(hwSkinningEnable); + skinningControls.add(skinningControl); + + rootNode.attachChild(model); + } + } + + rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + setupFloor(); + + inputManager.addListener(this, "toggleHWS"); + inputManager.addMapping("toggleHWS", new KeyTrigger(KeyInput.KEY_SPACE)); + +// DirectionalLightShadowRenderer pssm = new DirectionalLightShadowRenderer(assetManager, 1024, 2); +// pssm.setLight(dl); +// viewPort.addProcessor(pssm); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + + DirectionalLightShadowFilter sf = new DirectionalLightShadowFilter(assetManager, 1024, 2); + sf.setLight(dl); + fpp.addFilter(sf); + fpp.addFilter(new SSAOFilter()); + viewPort.addProcessor(fpp); + + + } + + public void setupFloor() { + Quad q = new Quad(20, 20); + q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10)); + Geometry geom = new Geometry("floor", q); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.White); + geom.setMaterial(mat); + + geom.rotate(-FastMath.HALF_PI, 0, 0); + geom.center(); + geom.move(0, -0.3f, 0); + geom.setShadowMode(RenderQueue.ShadowMode.Receive); + rootNode.attachChild(geom); + } + + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(isPressed && name.equals("toggleHWS")){ + hwSkinningEnable = !hwSkinningEnable; + for (SkinningControl sc : skinningControls) { + sc.setHardwareSkinningPreferred(hwSkinningEnable); + } + hwsText.setText("HWS : "+ hwSkinningEnable); + } + } + + private void makeHudText() { + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + hwsText = new BitmapText(guiFont); + hwsText.setSize(guiFont.getCharSet().getRenderedSize()); + hwsText.setText("HWS : "+ hwSkinningEnable); + hwsText.setLocalTranslation(0, cam.getHeight(), 0); + guiNode.attachChild(hwsText); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java b/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java new file mode 100644 index 0000000000..6ca1611d19 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java @@ -0,0 +1,85 @@ +package jme3test.model.anim; + +import com.jme3.anim.AnimClip; +import com.jme3.anim.AnimComposer; +import com.jme3.anim.AnimTrack; +import com.jme3.anim.TransformTrack; +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; + +public class TestSpatialAnim extends SimpleApplication { + + public static void main(String[] args) { + TestSpatialAnim app = new TestSpatialAnim(); + app.start(); + } + + @Override + public void simpleInitApp() { + + AmbientLight al = new AmbientLight(); + rootNode.addLight(al); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(Vector3f.UNIT_XYZ.negate()); + rootNode.addLight(dl); + + // Create model + Box box = new Box(1, 1, 1); + Geometry geom = new Geometry("box", box); + geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); + Node model = new Node("model"); + model.attachChild(geom); + + Box child = new Box(0.5f, 0.5f, 0.5f); + Geometry childGeom = new Geometry("box", child); + childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m")); + Node childModel = new Node("childmodel"); + childModel.setLocalTranslation(2, 2, 2); + childModel.attachChild(childGeom); + model.attachChild(childModel); + + //animation parameters + float animTime = 5; + int fps = 25; + float totalXLength = 10; + + //calculating frames + int totalFrames = (int) (fps * animTime); + float dT = animTime / totalFrames, t = 0; + float dX = totalXLength / totalFrames, x = 0; + float[] times = new float[totalFrames]; + Vector3f[] translations = new Vector3f[totalFrames]; + Quaternion[] rotations = new Quaternion[totalFrames]; + Vector3f[] scales = new Vector3f[totalFrames]; + for (int i = 0; i < totalFrames; ++i) { + times[i] = t; + t += dT; + translations[i] = new Vector3f(x, 0, 0); + x += dX; + rotations[i] = Quaternion.IDENTITY; + scales[i] = Vector3f.UNIT_XYZ; + } + TransformTrack transformTrack = new TransformTrack(geom, times, translations, rotations, scales); + TransformTrack transformTrackChild = new TransformTrack(childGeom, times, translations, rotations, scales); + // creating the animation + AnimClip animClip = new AnimClip("anim"); + animClip.setTracks(new AnimTrack[] { transformTrack, transformTrackChild }); + + // create spatial animation control + AnimComposer animComposer = new AnimComposer(); + animComposer.addAnimClip(animClip); + + model.addControl(animComposer); + rootNode.attachChild(model); + + // run animation + model.getControl(AnimComposer.class).setCurrentAction("anim"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/anim/package-info.java b/jme3-examples/src/main/java/jme3test/model/anim/package-info.java new file mode 100644 index 0000000000..dc7e590f17 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for animated 3-D models + */ +package jme3test.model.anim; diff --git a/jme3-examples/src/main/java/jme3test/model/package-info.java b/jme3-examples/src/main/java/jme3test/model/package-info.java new file mode 100644 index 0000000000..964c56fd87 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for 3-D models + */ +package jme3test.model; diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java b/jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java new file mode 100644 index 0000000000..17c44a1430 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/TestBillboard.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.model.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.BillboardControl; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Quad; + +/** + * + * @author Kirill Vainer + */ +public class TestBillboard extends SimpleApplication { + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10); + + Quad q = new Quad(2, 2); + Geometry g = new Geometry("Quad", q); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + g.setMaterial(mat); + + Quad q2 = new Quad(1, 1); + Geometry g3 = new Geometry("Quad2", q2); + Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.setColor("Color", ColorRGBA.Yellow); + g3.setMaterial(mat2); + g3.setLocalTranslation(.5f, .5f, .01f); + + Box b = new Box(.25f, .5f, .25f); + Geometry g2 = new Geometry("Box", b); + g2.setLocalTranslation(0, 0, 3); + g2.setMaterial(mat); + + Node bb = new Node("billboard"); + + BillboardControl control=new BillboardControl(); + + bb.addControl(control); + bb.attachChild(g); + bb.attachChild(g3); + + + n=new Node("parent"); + n.attachChild(g2); + n.attachChild(bb); + rootNode.attachChild(n); + + n2=new Node("parentParent"); + n2.setLocalTranslation(Vector3f.UNIT_X.mult(5)); + n2.attachChild(n); + + rootNode.attachChild(n2); + + +// rootNode.attachChild(bb); +// rootNode.attachChild(g2); + } + private Node n; + private Node n2; + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + n.rotate(0, tpf, 0); + n.move(0.1f*tpf, 0, 0); + n2.rotate(0, 0, -tpf); + } + + + + public static void main(String[] args) { + TestBillboard app = new TestBillboard(); + app.start(); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestBox.java b/jme3-examples/src/main/java/jme3test/model/shape/TestBox.java new file mode 100644 index 0000000000..0e5e86aeff --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/TestBox.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.model.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +public class TestBox extends SimpleApplication { + + public static void main(String[] args){ + TestBox app = new TestBox(); + app.start(); + } + + @Override + public void simpleInitApp() { + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + geom.setMaterial(mat); + rootNode.attachChild(geom); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java b/jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java new file mode 100644 index 0000000000..5f205def3b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.model.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.util.BufferUtils; + +/** + * How to create custom meshes by specifying vertices + * We render the mesh in three different ways, once with a solid blue color, + * once with vertex colors, and once with a wireframe material. + * @author KayTrance + */ +public class TestCustomMesh extends SimpleApplication { + + public static void main(String[] args){ + TestCustomMesh app = new TestCustomMesh(); + app.start(); + } + + @Override + public void simpleInitApp() { + + Mesh m = new Mesh(); + + // Vertex positions in space + Vector3f [] vertices = new Vector3f[4]; + vertices[0] = new Vector3f(0,0,0); + vertices[1] = new Vector3f(3,0,0); + vertices[2] = new Vector3f(0,3,0); + vertices[3] = new Vector3f(3,3,0); + + // Texture coordinates + Vector2f [] texCoord = new Vector2f[4]; + texCoord[0] = new Vector2f(0,0); + texCoord[1] = new Vector2f(1,0); + texCoord[2] = new Vector2f(0,1); + texCoord[3] = new Vector2f(1,1); + + // Indexes. We define the order in which mesh should be constructed + short[] indexes = {2, 0, 1, 1, 3, 2}; + + // Setting buffers + m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices)); + m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord)); + m.setBuffer(Type.Index, 1, BufferUtils.createShortBuffer(indexes)); + m.updateBound(); + + // ************************************************************************* + // First mesh uses one solid color + // ************************************************************************* + + // Creating a geometry, and apply a single color material to it + Geometry geom = new Geometry("OurMesh", m); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + geom.setMaterial(mat); + + // Attaching our geometry to the root node. + rootNode.attachChild(geom); + + // ************************************************************************* + // Second mesh uses vertex colors to color each vertex + // ************************************************************************* + Mesh cMesh = m.clone(); + Geometry coloredMesh = new Geometry ("ColoredMesh", cMesh); + Material matVC = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matVC.setBoolean("VertexColor", true); + + //We have 4 vertices and 4 color values for each of them. + //If you have more vertices, you need 'new float[yourVertexCount * 4]' here! + float[] colorArray = new float[4*4]; + int colorIndex = 0; + + //Set custom RGBA value for each Vertex. Values range from 0.0f to 1.0f + for(int i = 0; i < 4; i++){ + // Red value (is increased by .2 on each next vertex here) + colorArray[colorIndex++]= 0.1f+(.2f*i); + // Green value (is reduced by .2 on each next vertex) + colorArray[colorIndex++]= 0.9f-(0.2f*i); + // Blue value (remains the same in our case) + colorArray[colorIndex++]= 0.5f; + // Alpha value (no transparency set here) + colorArray[colorIndex++]= 1.0f; + } + // Set the color buffer + cMesh.setBuffer(Type.Color, 4, colorArray); + coloredMesh.setMaterial(matVC); + // move mesh a bit so that it doesn't intersect with the first one + coloredMesh.setLocalTranslation(4, 0, 0); + rootNode.attachChild(coloredMesh); + +// /** Alternatively, you can show the mesh vertices as points +// * instead of coloring the faces. */ +// cMesh.setMode(Mesh.Mode.Points); +// cMesh.setPointSize(10f); +// cMesh.updateBound(); +// cMesh.setStatic(); +// Geometry points = new Geometry("Points", m); +// points.setMaterial(mat); +// rootNode.attachChild(points); + + // ************************************************************************* + // Third mesh will use a wireframe shader to show wireframe + // ************************************************************************* + Mesh wfMesh = m.clone(); + Geometry wfGeom = new Geometry("wireframeGeometry", wfMesh); + Material matWireframe = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matWireframe.setColor("Color", ColorRGBA.Green); + matWireframe.getAdditionalRenderState().setWireframe(true); + wfGeom.setMaterial(matWireframe); + wfGeom.setLocalTranslation(4, 4, 0); + rootNode.attachChild(wfGeom); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java b/jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java new file mode 100644 index 0000000000..bec3847faa --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/TestCylinder.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.model.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Cylinder; +import com.jme3.texture.Texture; + +public class TestCylinder extends SimpleApplication { + + public static void main(String[] args){ + TestCylinder app = new TestCylinder(); + app.start(); + } + + @Override + public void simpleInitApp() { + Cylinder t = new Cylinder(20, 50, 1, 2, true); + Geometry geom = new Geometry("Cylinder", t); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + TextureKey key = new TextureKey("Interface/Logo/Monkey.jpg", true); + key.setGenerateMips(true); + Texture tex = assetManager.loadTexture(key); + tex.setMinFilter(Texture.MinFilter.Trilinear); + mat.setTexture("ColorMap", tex); + + geom.setMaterial(mat); + + rootNode.attachChild(geom); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java b/jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java new file mode 100644 index 0000000000..25bde0a797 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/TestDebugShapes.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.model.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.debug.Arrow; +import com.jme3.scene.debug.Grid; +import com.jme3.scene.debug.WireBox; +import com.jme3.scene.debug.WireSphere; + +public class TestDebugShapes extends SimpleApplication { + + public static void main(String[] args){ + TestDebugShapes app = new TestDebugShapes(); + app.start(); + } + + private Geometry putShape(Mesh shape, ColorRGBA color) { + Geometry g = new Geometry("shape", shape); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.getAdditionalRenderState().setWireframe(true); + mat.setColor("Color", color); + g.setMaterial(mat); + rootNode.attachChild(g); + return g; + } + + private void putArrow(Vector3f pos, Vector3f dir, ColorRGBA color){ + Arrow arrow = new Arrow(dir); + putShape(arrow, color).setLocalTranslation(pos); + } + + private void putBox(Vector3f pos, float size, ColorRGBA color) { + putShape(new WireBox(size, size, size), color).setLocalTranslation(pos); + } + + private void putGrid(Vector3f pos, ColorRGBA color) { + putShape(new Grid(6, 6, 0.2f), color).center().move(pos); + } + + private void putSphere(Vector3f pos, ColorRGBA color) { + putShape(new WireSphere(1), color).setLocalTranslation(pos); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(2,1.5f,2)); + cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + + putArrow(Vector3f.ZERO, Vector3f.UNIT_X, ColorRGBA.Red); + putArrow(Vector3f.ZERO, Vector3f.UNIT_Y, ColorRGBA.Green); + putArrow(Vector3f.ZERO, Vector3f.UNIT_Z, ColorRGBA.Blue); + + putBox(new Vector3f(2, 0, 0), 0.5f, ColorRGBA.Yellow); + putGrid(new Vector3f(3.5f, 0, 0), ColorRGBA.White); + putSphere(new Vector3f(4.5f, 0, 0), ColorRGBA.Magenta); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java b/jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java new file mode 100644 index 0000000000..69f5b8f4f6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/TestExpandingTorus.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.model.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Torus; + +public class TestExpandingTorus extends SimpleApplication { + + private float outerRadius = 1.5f; + private float rate = 1; + private Torus torus; + + public static void main(String[] args) { + TestExpandingTorus app = new TestExpandingTorus(); + app.start(); + } + + @Override + public void simpleInitApp() { + torus = new Torus(30, 10, .5f, 1f); + Geometry geom = new Geometry("Torus", torus); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + geom.setMaterial(mat); + rootNode.attachChild(geom); + } + + @Override + public void simpleUpdate(float tpf){ + if (outerRadius > 2.5f){ + outerRadius = 2.5f; + rate = -rate; + }else if (outerRadius < 1f){ + outerRadius = 1f; + rate = -rate; + } + outerRadius += rate * tpf; + torus.updateGeometry(30, 10, .5f, outerRadius); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java b/jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java new file mode 100644 index 0000000000..0bdf0e7ac5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/TestSphere.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.model.shape; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Sphere; + +public class TestSphere extends SimpleApplication { + + public static void main(String[] args){ + TestSphere app = new TestSphere(); + app.start(); + } + + @Override + public void simpleInitApp() { + Sphere sphMesh = new Sphere(14, 14, 1); + Material solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + + for (int y = -5; y < 5; y++){ + for (int x = -5; x < 5; x++){ + Geometry sphere = new Geometry("sphere", sphMesh); + sphere.setMaterial(solidColor); + sphere.setLocalTranslation(x * 2, 0, y * 2); + rootNode.attachChild(sphere); + } + } + cam.setLocation(new Vector3f(0, 5, 0)); + cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/model/shape/package-info.java b/jme3-examples/src/main/java/jme3test/model/shape/package-info.java new file mode 100644 index 0000000000..60502bdb70 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/shape/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for meshes + */ +package jme3test.model.shape; diff --git a/jme3-examples/src/main/java/jme3test/network/MovingAverage.java b/jme3-examples/src/main/java/jme3test/network/MovingAverage.java new file mode 100644 index 0000000000..28addcb3d8 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/MovingAverage.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.network; + +class MovingAverage { + + final private long[] samples; + private long sum; + private int count, index; + + public MovingAverage(int numSamples){ + samples = new long[numSamples]; + } + + public void add(long sample){ + sum = sum - samples[index] + sample; + samples[index++] = sample; + if (index > count){ + count = index; + } + if (index >= samples.length){ + index = 0; + } + } + + public long getAverage(){ + if (count == 0) + return 0; + else + return (long) (sum / (float) count); + } + +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/network/TestChatClient.java b/jme3-examples/src/main/java/jme3test/network/TestChatClient.java new file mode 100644 index 0000000000..7312122e67 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestChatClient.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2011-2021 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. + */ +package jme3test.network; + +import com.jme3.network.Client; +import com.jme3.network.ClientStateListener; +import com.jme3.network.ErrorListener; +import com.jme3.network.Message; +import com.jme3.network.MessageListener; +import com.jme3.network.Network; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.*; +import jme3test.network.TestChatServer.ChatMessage; + +/** + * A simple test chat server. When SM implements a set + * of standard chat classes this can become a lot simpler. + * + * @version $Revision$ + * @author Paul Speed + */ +public class TestChatClient extends JFrame { + + private final Client client; + private final JEditorPane chatLog; + private final StringBuilder chatMessages = new StringBuilder(); + private final JTextField nameField; + private final JTextField messageField; + + public TestChatClient(String host) throws IOException { + super("jME3 Test Chat Client - to:" + host); + + // Build out the UI + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + setSize(800, 600); + + chatLog = new JEditorPane(); + chatLog.setEditable(false); + chatLog.setContentType("text/html"); + chatLog.setText(""); + + getContentPane().add(new JScrollPane(chatLog), "Center"); + + // A crude form + JPanel p = new JPanel(); + p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); + p.add(new JLabel("Name:")); + nameField = new JTextField(System.getProperty("user.name", "yourname")); + Dimension d = nameField.getPreferredSize(); + nameField.setMaximumSize(new Dimension(120, d.height + 6)); + p.add(nameField); + p.add(new JLabel(" Message:")); + messageField = new JTextField(); + p.add(messageField); + p.add(new JButton(new SendAction(true))); + p.add(new JButton(new SendAction(false))); + + getContentPane().add(p, "South"); + + client = Network.connectToServer(TestChatServer.NAME, TestChatServer.VERSION, + host, TestChatServer.PORT, TestChatServer.UDP_PORT); + client.addMessageListener(new ChatHandler(), ChatMessage.class); + client.addClientStateListener(new ChatClientStateListener()); + client.addErrorListener(new ChatErrorListener()); + client.start(); + + System.out.println("Started client:" + client); + } + + @Override + public void dispose() { + System.out.println("Chat window closing."); + super.dispose(); + if( client.isConnected() ) { + client.close(); + } + } + + public static String getString(Component owner, String title, String message, String initialValue) { + return (String) JOptionPane.showInputDialog(owner, message, title, JOptionPane.PLAIN_MESSAGE, + null, null, initialValue); + } + + public static void main(String... args) throws Exception { + + // Increase the logging level for networking... + System.out.println("Setting logging to max"); + Logger networkLog = Logger.getLogger("com.jme3.network"); + networkLog.setLevel(Level.FINEST); + + // And we have to tell JUL's handler also + // turn up logging in a very convoluted way + Logger rootLog = Logger.getLogger(""); + if( rootLog.getHandlers().length > 0 ) { + rootLog.getHandlers()[0].setLevel(Level.FINEST); + } + + // Note: in JME 3.1 this is generally unnecessary as the server will + // send a message with all server-registered classes. + // TestChatServer.initializeClasses(); + // Leaving the call commented out to be illustrative regarding the + // common old pattern. + + // Grab a host string from the user + String s = getString(null, "Host Info", "Enter chat host:", "localhost"); + if (s == null) { + System.out.println("User cancelled."); + return; + } + + // Register a shutdown hook to get a message on the console when the + // app actually finishes + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + System.out.println("Chat client is terminating."); + } + }); + + + TestChatClient test = new TestChatClient(s); + test.setVisible(true); + } + + private class ChatHandler implements MessageListener { + + @Override + public void messageReceived(Client source, Message m) { + ChatMessage chat = (ChatMessage) m; + + System.out.println("Received:" + chat); + + // One of the least efficient ways to add text to a + // JEditorPane + chatMessages.append("" + (m.isReliable() ? "TCP" : "UDP") + ""); + chatMessages.append(" -- " + chat.getName() + " : "); + chatMessages.append(chat.getMessage()); + chatMessages.append("
"); + String s = "" + chatMessages + ""; + chatLog.setText(s); + + // Set selection to the end so that the scroll panel will scroll + // down. + chatLog.select(s.length(), s.length()); + } + } + + private class ChatClientStateListener implements ClientStateListener { + + @Override + public void clientConnected(Client c) { + System.out.println("clientConnected(" + c + ")"); + } + + @Override + public void clientDisconnected(Client c, DisconnectInfo info) { + System.out.println("clientDisconnected(" + c + "):" + info); + if( info != null ) { + // The connection was closed by the server + JOptionPane.showMessageDialog(rootPane, + info.reason, + "Connection Closed", + JOptionPane.INFORMATION_MESSAGE); + dispose(); + } + } + } + + private class ChatErrorListener implements ErrorListener { + + @Override + public void handleError( Client source, Throwable t ) { + System.out.println("handleError(" + source + ", " + t + ")"); + JOptionPane.showMessageDialog(rootPane, + String.valueOf(t), + "Connection Error", + JOptionPane.ERROR_MESSAGE); + } + + } + + private class SendAction extends AbstractAction { + + private final boolean reliable; + + public SendAction(boolean reliable) { + super(reliable ? "TCP" : "UDP"); + this.reliable = reliable; + } + + @Override + public void actionPerformed(ActionEvent evt) { + String name = nameField.getText(); + String message = messageField.getText(); + + ChatMessage chat = new ChatMessage(name, message); + chat.setReliable(reliable); + System.out.println("Sending:" + chat); + client.send(chat); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java b/jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java new file mode 100644 index 0000000000..ee08067ae0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestChatClientAndServer.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015 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. + */ +package jme3test.network; + + +/** + * Combines the server instance and a client instance into the + * same JVM to show an example of, and to test, a pattern like + * self-hosted multiplayer games. + * + * @author Paul Speed + */ +public class TestChatClientAndServer { + + public static void main( String... args ) throws Exception { + + System.out.println("Starting chat server..."); + TestChatServer chatServer = new TestChatServer(); + chatServer.start(); + + System.out.println("Waiting for connections on port:" + TestChatServer.PORT); + + // Now launch a client + + TestChatClient test = new TestChatClient("localhost"); + test.setVisible(true); + + // Register a shutdown hook to get a message on the console when the + // app actually finishes + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + System.out.println("Client and server test is terminating."); + } + }); + + // Keep running basically forever or until the server + // shuts down + while( chatServer.isRunning() ) { + synchronized (chatServer) { + chatServer.wait(); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestChatServer.java b/jme3-examples/src/main/java/jme3test/network/TestChatServer.java new file mode 100644 index 0000000000..31aca2ffe3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestChatServer.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2011-2021 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. + */ +package jme3test.network; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.network.*; +import com.jme3.network.serializing.Serializable; +import com.jme3.network.serializing.Serializer; +import java.io.IOException; + +/** + * A simple test chat server. When SM implements a set + * of standard chat classes this can become a lot simpler. + * + * @version $Revision$ + * @author Paul Speed + */ +public class TestChatServer { + // Normally these and the initialized method would + // be in shared constants or something. + + public static final String NAME = "Test Chat Server"; + public static final int VERSION = 1; + public static final int PORT = 5110; + public static final int UDP_PORT = 5110; + + private Server server; + private boolean isRunning; + + public TestChatServer() throws IOException { + + // Use this to test the client/server name version check + this.server = Network.createServer(NAME, VERSION, PORT, UDP_PORT); + + // Initialize our own messages only after the server has been created. + // It registers some additional messages with the serializer by default + // that need to go before custom messages. + initializeClasses(); + + ChatHandler handler = new ChatHandler(); + server.addMessageListener(handler, ChatMessage.class); + + server.addConnectionListener(new ChatConnectionListener()); + } + + public boolean isRunning() { + return isRunning; + } + + public synchronized void start() { + if( isRunning ) { + return; + } + server.start(); + isRunning = true; + } + + public synchronized void close() { + if( !isRunning ) { + return; + } + + // Gracefully let any connections know that the server is + // going down. Without this, their connections will simply + // error out. + for( HostedConnection conn : server.getConnections() ) { + conn.close("Server is shutting down."); + } + try { + Thread.sleep(1000); // wait a couple beats to let the messages go out + } catch( InterruptedException e ) { + e.printStackTrace(); + } + + server.close(); + isRunning = false; + notifyAll(); + } + + protected void runCommand( HostedConnection conn, String user, String command ) { + if( "/shutdown".equals(command) ) { + server.broadcast(new ChatMessage("server", "Server is shutting down.")); + close(); + } else if( "/help".equals(command) ) { + StringBuilder sb = new StringBuilder(); + sb.append("Chat commands:\n"); + sb.append("/help - prints this message.\n"); + sb.append("/shutdown - shuts down the server."); + server.broadcast(new ChatMessage("server", sb.toString())); + } + } + + public static void initializeClasses() { + // Doing it here means that the client code only needs to + // call our initialize. + Serializer.registerClass(ChatMessage.class); + } + + public static void main(String... args) throws Exception { + + // Increase the logging level for networking... + System.out.println("Setting logging to max"); + Logger networkLog = Logger.getLogger("com.jme3.network"); + networkLog.setLevel(Level.FINEST); + + // And we have to tell JUL's handler also + // turn up logging in a very convoluted way + Logger rootLog = Logger.getLogger(""); + if( rootLog.getHandlers().length > 0 ) { + rootLog.getHandlers()[0].setLevel(Level.FINEST); + } + + TestChatServer chatServer = new TestChatServer(); + chatServer.start(); + + System.out.println("Waiting for connections on port:" + PORT); + + // Keep running basically forever + while( chatServer.isRunning ) { + synchronized (chatServer) { + chatServer.wait(); + } + } + } + + private class ChatHandler implements MessageListener { + + public ChatHandler() { + } + + @Override + public void messageReceived(HostedConnection source, Message m) { + if (m instanceof ChatMessage) { + // Keep track of the name just in case we + // want to know it for some other reason later, and it's + // a good example of session data. + ChatMessage cm = (ChatMessage)m; + source.setAttribute("name", cm.getName()); + + // Check for a / command + if( cm.message.startsWith("/") ) { + runCommand(source, cm.name, cm.message); + return; + } + + System.out.println("Broadcasting:" + m + " reliable:" + m.isReliable()); + + // Just rebroadcast... the reliable flag will stay the + // same so if it came in on UDP it will go out on that too + source.getServer().broadcast(cm); + } else { + System.err.println("Received odd message:" + m); + } + } + } + + private class ChatConnectionListener implements ConnectionListener { + + @Override + public void connectionAdded( Server server, HostedConnection conn ) { + System.out.println("connectionAdded(" + conn + ")"); + } + + @Override + public void connectionRemoved(Server server, HostedConnection conn) { + System.out.println("connectionRemoved(" + conn + ")"); + } + + } + + @Serializable + public static class ChatMessage extends AbstractMessage { + + private String name; + private String message; + + public ChatMessage() { + } + + public ChatMessage(String name, String message) { + setName(name); + setMessage(message); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setMessage(String s) { + this.message = s; + } + + public String getMessage() { + return message; + } + + @Override + public String toString() { + return name + ":" + message; + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestLatency.java b/jme3-examples/src/main/java/jme3test/network/TestLatency.java new file mode 100644 index 0000000000..e449380ead --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestLatency.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.network; + +import com.jme3.network.*; +import com.jme3.network.serializing.Serializable; +import com.jme3.network.serializing.Serializer; +import java.io.IOException; + +public class TestLatency { + + private static long startTime; + private static Client client; + private static MovingAverage average = new MovingAverage(100); + + static { + startTime = System.currentTimeMillis(); + } + + private static long getTime(){ + return System.currentTimeMillis() - startTime; + } + + @Serializable + public static class TimestampMessage extends AbstractMessage { + + private long timeSent = 0; + private long timeReceived = 0; + + public TimestampMessage(){ + setReliable(false); + } + + public TimestampMessage(long timeSent, long timeReceived){ + setReliable(false); + this.timeSent = timeSent; + this.timeReceived = timeReceived; + } + + } + + public static void main(String[] args) throws IOException, InterruptedException{ + Serializer.registerClass(TimestampMessage.class); + + Server server = Network.createServer(5110); + server.start(); + + client = Network.connectToServer("localhost", 5110); + client.start(); + + client.addMessageListener(new MessageListener(){ + @Override + public void messageReceived(Client source, Message m) { + TimestampMessage timeMsg = (TimestampMessage) m; + + long curTime = getTime(); + //System.out.println("Time sent: " + timeMsg.timeSent); + //System.out.println("Time received by server: " + timeMsg.timeReceived); + //System.out.println("Time received by client: " + curTime); + + long latency = (curTime - timeMsg.timeSent); + System.out.println("Latency: " + (latency) + " ms"); + //long timeOffset = ((timeMsg.timeSent + curTime) / 2) - timeMsg.timeReceived; + //System.out.println("Approximate timeOffset: "+ (timeOffset) + " ms"); + + average.add(latency); + System.out.println("Average latency: " + average.getAverage()); + + long latencyOffset = latency - average.getAverage(); + System.out.println("Latency offset: " + latencyOffset); + + client.send(new TimestampMessage(getTime(), 0)); + } + }, TimestampMessage.class); + + server.addMessageListener(new MessageListener(){ + @Override + public void messageReceived(HostedConnection source, Message m) { + TimestampMessage timeMsg = (TimestampMessage) m; + TimestampMessage outMsg = new TimestampMessage(timeMsg.timeSent, getTime()); + source.send(outMsg); + } + }, TimestampMessage.class); + + Thread.sleep(1); + + client.send(new TimestampMessage(getTime(), 0)); + + Object obj = new Object(); + synchronized(obj){ + obj.wait(); + } + } + +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestMessages.java b/jme3-examples/src/main/java/jme3test/network/TestMessages.java new file mode 100644 index 0000000000..b67476ae1d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestMessages.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.network; + +import com.jme3.network.*; +import com.jme3.network.serializing.Serializable; +import com.jme3.network.serializing.Serializer; +import java.io.IOException; + +public class TestMessages { + + @Serializable + public static class PingMessage extends AbstractMessage { + } + + @Serializable + public static class PongMessage extends AbstractMessage { + } + + private static class ServerPingResponder implements MessageListener { + @Override + public void messageReceived(HostedConnection source, com.jme3.network.Message message) { + if (message instanceof PingMessage){ + System.out.println("Server: Received ping message!"); + source.send(new PongMessage()); + } + } + } + + private static class ClientPingResponder implements MessageListener { + @Override + public void messageReceived(Client source, com.jme3.network.Message message) { + if (message instanceof PongMessage){ + System.out.println("Client: Received pong message!"); + } + } + } + + public static void main(String[] args) throws IOException, InterruptedException{ + Serializer.registerClass(PingMessage.class); + Serializer.registerClass(PongMessage.class); + + Server server = Network.createServer(5110); + server.start(); + + Client client = Network.connectToServer("localhost", 5110); + client.start(); + + server.addMessageListener(new ServerPingResponder(), PingMessage.class); + client.addMessageListener(new ClientPingResponder(), PongMessage.class); + + System.out.println("Client: Sending ping message.."); + client.send(new PingMessage()); + + Object obj = new Object(); + synchronized (obj){ + obj.wait(); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java b/jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java new file mode 100644 index 0000000000..13bf63c8e2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestNetworkStress.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.network; + +import com.jme3.network.*; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestNetworkStress implements ConnectionListener { + + @Override + public void connectionAdded(Server server, HostedConnection conn) { + System.out.println("Client Connected: "+conn.getId()); + //conn.close("goodbye"); + } + + @Override + public void connectionRemoved(Server server, HostedConnection conn) { + } + + public static void main(String[] args) throws IOException, InterruptedException{ + Logger.getLogger("").getHandlers()[0].setLevel(Level.OFF); + + Server server = Network.createServer(5110); + server.start(); + server.addConnectionListener(new TestNetworkStress()); + + for (int i = 0; i < 1000; i++){ + Client client = Network.connectToServer("localhost", 5110); + client.start(); + + Thread.sleep(10); + + client.close(); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java b/jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java new file mode 100644 index 0000000000..208af7b682 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestRemoteCall.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.network; + +import com.jme3.app.SimpleApplication; +import com.jme3.export.Savable; +import com.jme3.network.Client; +import com.jme3.network.Network; +import com.jme3.network.Server; +import com.jme3.network.rmi.ObjectStore; +import com.jme3.network.serializing.Serializer; +import com.jme3.network.serializing.serializers.SavableSerializer; +import com.jme3.scene.Spatial; +import java.io.IOException; +import java.util.concurrent.Callable; + +public class TestRemoteCall { + + private static SimpleApplication serverApp; + + /** + * Interface implemented by the server, exposing + * RMI calls that clients can use. + */ + public static interface ServerAccess { + /** + * Attaches the model with the given name to the server's scene. + * + * @param model The model name + * + * @return True if the model was attached. + * + * @throws RuntimeException If some error occurs. + */ + public boolean attachChild(String model); + } + + public static class ServerAccessImpl implements ServerAccess { + @Override + public boolean attachChild(String model) { + if (model == null) + throw new RuntimeException("Cannot be null. .. etc"); + + final String finalModel = model; + serverApp.enqueue(new Callable() { + @Override + public Void call() throws Exception { + Spatial spatial = serverApp.getAssetManager().loadModel(finalModel); + serverApp.getRootNode().attachChild(spatial); + return null; + } + }); + return true; + } + } + + public static void createServer(){ + serverApp = new SimpleApplication() { + @Override + public void simpleInitApp() { + } + }; + serverApp.start(); + + try { + Server server = Network.createServer(5110); + server.start(); + + ObjectStore store = new ObjectStore(server); + store.exposeObject("access", new ServerAccessImpl()); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + public static void main(String[] args) throws IOException, InterruptedException{ + Serializer.registerClass(Savable.class, new SavableSerializer()); + + createServer(); + + Client client = Network.connectToServer("localhost", 5110); + client.start(); + + ObjectStore store = new ObjectStore(client); + ServerAccess access = store.getExposedObject("access", ServerAccess.class, true); + boolean result = access.attachChild("Models/Oto/Oto.mesh.xml"); + System.out.println(result); + } +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestSerialization.java b/jme3-examples/src/main/java/jme3test/network/TestSerialization.java new file mode 100644 index 0000000000..0d1ba0a585 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestSerialization.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.network; + +import com.jme3.network.*; +import com.jme3.network.serializing.Serializable; +import com.jme3.network.serializing.Serializer; +import java.io.IOException; +import java.util.*; + +public class TestSerialization implements MessageListener { + + @Serializable + public static class SomeObject { + + private int val; + + public SomeObject(){ + } + + public SomeObject(int val){ + this.val = val; + } + + public int getVal(){ + return val; + } + + @Override + public String toString(){ + return "SomeObject[val="+val+"]"; + } + } + + public enum Status { + High, + Middle, + Low; + } + + @Serializable + public static class TestSerializationMessage extends AbstractMessage { + + private boolean z; + private byte b; + private char c; + private short s; + private int i; + private float f; + private long l; + private double d; + + private int[] ia; + private List ls; + private Map mp; + + private Status status1; + private Status status2; + + private Date date; + + public TestSerializationMessage(){ + super(true); + } + + public TestSerializationMessage(boolean initIt){ + super(true); + if (initIt){ + z = true; + b = -88; + c = 'Y'; + s = 9999; + i = 123; + f = -75.4e8f; + l = 9438345072805034L; + d = -854834.914703e88; + ia = new int[]{ 456, 678, 999 }; + + ls = new ArrayList(); + ls.add("hello"); + ls.add(new SomeObject(-22)); + + mp = new HashMap(); + mp.put("abc", new SomeObject(555)); + + status1 = Status.High; + status2 = Status.Middle; + + date = new Date(System.currentTimeMillis()); + } + } + } + + @Override + public void messageReceived(HostedConnection source, Message m) { + TestSerializationMessage cm = (TestSerializationMessage) m; + System.out.println(cm.z); + System.out.println(cm.b); + System.out.println(cm.c); + System.out.println(cm.s); + System.out.println(cm.i); + System.out.println(cm.f); + System.out.println(cm.l); + System.out.println(cm.d); + System.out.println(Arrays.toString(cm.ia)); + System.out.println(cm.ls); + System.out.println(cm.mp); + System.out.println(cm.status1); + System.out.println(cm.status2); + System.out.println(cm.date); + } + + public static void main(String[] args) throws IOException, InterruptedException{ + Serializer.registerClass(SomeObject.class); + Serializer.registerClass(TestSerializationMessage.class); + + Server server = Network.createServer( 5110 ); + server.start(); + + Client client = Network.connectToServer( "localhost", 5110 ); + client.start(); + + server.addMessageListener(new TestSerialization(), TestSerializationMessage.class); + client.send(new TestSerializationMessage(true)); + + Thread.sleep(10000); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/network/TestThroughput.java b/jme3-examples/src/main/java/jme3test/network/TestThroughput.java new file mode 100644 index 0000000000..b27b17ef14 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/TestThroughput.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011-2021 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. + */ +package jme3test.network; + +import com.jme3.network.*; +import com.jme3.network.serializing.Serializable; +import com.jme3.network.serializing.Serializer; +import java.io.IOException; + +public class TestThroughput implements MessageListener { //extends MessageAdapter { + + private static long lastTime = -1; + private static long counter = 0; + private static long total = 0; + // Change this flag to test UDP instead of TCP + final private static boolean testReliable = false; + final private boolean isOnServer; + + public TestThroughput(boolean isOnServer) { + this.isOnServer = isOnServer; + } + + @Serializable + public static class TestMessage extends AbstractMessage { + + public TestMessage() { + setReliable(testReliable); + } + } + + @Override + public void messageReceived(MessageConnection source, Message msg) { + + if (!isOnServer) { + // It's local to the client, so we got it back. + counter++; + total++; + long time = System.currentTimeMillis(); +//System.out.println( "total:" + total + " counter:" + counter + " lastTime:" + lastTime + " time:" + time ); + if (lastTime < 0) { + lastTime = time; + } else if (time - lastTime > 1000) { + long delta = time - lastTime; + double scale = delta / 1000.0; + double pps = counter / scale; + System.out.println("messages per second:" + pps + " total messages:" + total); + counter = 0; + lastTime = time; + } + } else { + if (source == null) { + System.out.println("Received a message from a not fully connected source, msg:" + msg); + } else { +//System.out.println( "sending:" + msg + " back to client:" + source ); + // The 'reliable' flag is transient and the server doesn't + // (yet) reset this value for us. + msg.setReliable(testReliable); + source.send(msg); + } + } + } + + public static void main(String[] args) throws IOException, InterruptedException { + + Serializer.registerClass(TestMessage.class); + + // Use this to test the client/server name version check + //Server server = Network.createServer( "bad name", 42, 5110, 5110 ); + Server server = Network.createServer(5110, 5110); + server.start(); + + Client client = Network.connectToServer("localhost", 5110); + client.start(); + + client.addMessageListener(new TestThroughput(false), TestMessage.class); + server.addMessageListener(new TestThroughput(true), TestMessage.class); + + Thread.sleep(1); + + TestMessage test = new TestMessage(); +// for( int i = 0; i < 10; i++ ) { + while (true) { +//System.out.println( "sending." ); + client.send(test); + } + + //Thread.sleep(5000); + } +} diff --git a/jme3-examples/src/main/java/jme3test/network/package-info.java b/jme3-examples/src/main/java/jme3test/network/package-info.java new file mode 100644 index 0000000000..087eb1bb41 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/network/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for network communication + */ +package jme3test.network; diff --git a/jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java b/jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java new file mode 100644 index 0000000000..3fba0f46a0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/niftygui/StartScreenController.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.niftygui; + +import com.jme3.app.Application; +import de.lessvoid.nifty.Nifty; +import de.lessvoid.nifty.screen.Screen; +import de.lessvoid.nifty.screen.ScreenController; + +/** + * A ScreenController for the "start" screen defined in + * "Interfaces/Nifty/HelloJme.xml", which is used in the TestAppStates and + * TestNiftyGui applications. + */ +public class StartScreenController implements ScreenController { + + final private Application application; + + /** + * Instantiate a ScreenController for the specified Application. + * + * @param app the Application + */ + public StartScreenController(Application app) { + this.application = app; + } + + /** + * Nifty invokes this method when the screen gets enabled for the first + * time. + * + * @param nifty (not null) + * @param screen (not null) + */ + @Override + public void bind(Nifty nifty, Screen screen) { + System.out.println("bind(" + screen.getScreenId() + ")"); + } + + /** + * Nifty invokes this method each time the screen starts up. + */ + @Override + public void onStartScreen() { + System.out.println("onStartScreen"); + } + + /** + * Nifty invokes this method each time the screen shuts down. + */ + @Override + public void onEndScreen() { + System.out.println("onEndScreen"); + } + + /** + * Stop the Application. Nifty invokes this method (via reflection) after + * the user clicks on the flashing orange panel. + */ + public void quit() { + application.stop(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java b/jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java new file mode 100644 index 0000000000..b40311f62c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/niftygui/TestIssue1013.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.niftygui; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.niftygui.NiftyJmeDisplay; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import de.lessvoid.nifty.Nifty; +import de.lessvoid.nifty.builder.LayerBuilder; +import de.lessvoid.nifty.builder.PanelBuilder; +import de.lessvoid.nifty.builder.ScreenBuilder; +import de.lessvoid.nifty.controls.button.builder.ButtonBuilder; +import de.lessvoid.nifty.screen.Screen; +import de.lessvoid.nifty.screen.ScreenController; + +public class TestIssue1013 extends SimpleApplication implements ScreenController { + + public static void main(String[] args) { + new TestIssue1013().start(); + } + + private NiftyJmeDisplay niftyDisplay; + + @Override + public void simpleInitApp() { + + // this box here always renders + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("/com/jme3/app/Monkey.png")); + geom.setMaterial(mat); + rootNode.attachChild(geom); + + niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort); + + Nifty nifty = niftyDisplay.getNifty(); + nifty.loadStyleFile("nifty-default-styles.xml"); + nifty.loadControlFile("nifty-default-controls.xml"); + + ScreenController ctrl = this; + + new ScreenBuilder("start") { + { + controller(ctrl); + layer(new LayerBuilder() { + { + childLayoutVertical(); + panel(new PanelBuilder() { + { + childLayoutCenter(); + width("100%"); + height("50%"); + backgroundColor("#ff0000"); + } + }); + control(new ButtonBuilder("RestartButton", "Restart Context") { + { + alignCenter(); + valignCenter(); + height("32px"); + width("480px"); + interactOnClick("restartContext()"); + } + }); + } + }); + } + }.build(nifty); + + guiViewPort.addProcessor(niftyDisplay); + nifty.gotoScreen("start"); + + flyCam.setDragToRotate(true); + } + + @Override + public void bind(Nifty nifty, Screen screen) { + } + + @Override + public void onStartScreen() { + } + + @Override + public void onEndScreen() { + } + + public void restartContext() { + // even without changing settings, stuff breaks! + restart(); + // ...and re-adding the processor doesn't help at all + guiViewPort.addProcessor(niftyDisplay); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java b/jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java new file mode 100644 index 0000000000..d63d988768 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/niftygui/TestIssue99.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2022 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. + */ +package jme3test.niftygui; + +import com.jme3.app.SimpleApplication; +import com.jme3.niftygui.NiftyJmeDisplay; +import com.jme3.texture.image.ColorSpace; +import de.lessvoid.nifty.Nifty; +import de.lessvoid.nifty.screen.Screen; +import de.lessvoid.nifty.screen.ScreenController; + +/** + * Test case for JME issue #99: blendMode="multiply" in Nifty renders + * incorrectly. + *

+ * If successful, two text labels will be legible. If unsuccessful, only the top + * one will be legible. + * + * @author Stephen Gold sgold@sonic.net + */ +public class TestIssue99 + extends SimpleApplication + implements ScreenController { + + public static void main(String[] args) { + TestIssue99 app = new TestIssue99(); + app.start(); + } + + @Override + public void simpleInitApp() { + /* + * GUI requires a cursor; prevent flyCam from hiding it. + */ + flyCam.setDragToRotate(true); + /* + * Start NiftyGUI without the batched renderer. + */ + ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() + ? ColorSpace.sRGB : ColorSpace.Linear; + NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay( + assetManager, inputManager, audioRenderer, guiViewPort, colorSpace); + guiViewPort.addProcessor(niftyDisplay); + /* + * Load GUI controls, styles, and layout from XML assets. + */ + Nifty nifty = niftyDisplay.getNifty(); + nifty.loadControlFile("nifty-default-controls.xml"); + nifty.loadStyleFile("nifty-default-styles.xml"); + nifty.fromXml("Interface/Nifty/test-issue-99.xml", + "test-issue-99", this); + } + + /** + * A callback from Nifty, invoked when the screen gets enabled for the first + * time. + * + * @param nifty (not null) + * @param screen (not null) + */ + @Override + public void bind(Nifty nifty, Screen screen) { + } + + /** + * A callback from Nifty, invoked each time the screen shuts down. + */ + @Override + public void onEndScreen() { + } + + /** + * A callback from Nifty, invoked each time the screen starts up. + */ + @Override + public void onStartScreen() { + } +} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java new file mode 100644 index 0000000000..f498c3b87d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyExamples.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2009-2022 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. + */ + +package jme3test.niftygui; + +import com.jme3.app.SimpleApplication; +import com.jme3.niftygui.NiftyJmeDisplay; +import com.jme3.texture.image.ColorSpace; +import de.lessvoid.nifty.Nifty; + +public class TestNiftyExamples extends SimpleApplication { + + public static void main(String[] args){ + TestNiftyExamples app = new TestNiftyExamples(); + app.setPauseOnLostFocus(false); + app.start(); + } + + @Override + public void simpleInitApp() { + ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() + ? ColorSpace.sRGB : ColorSpace.Linear; + NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, + inputManager, + audioRenderer, + guiViewPort, + colorSpace); + Nifty nifty = niftyDisplay.getNifty(); + nifty.fromXml("all/intro.xml", "start"); + + // attach the nifty display to the gui view port as a processor + guiViewPort.addProcessor(niftyDisplay); + + // disable the fly cam + flyCam.setEnabled(false); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java new file mode 100644 index 0000000000..873d90548a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.niftygui; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.niftygui.NiftyJmeDisplay; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import de.lessvoid.nifty.Nifty; + +public class TestNiftyGui extends SimpleApplication { + + private Nifty nifty; + + public static void main(String[] args){ + TestNiftyGui app = new TestNiftyGui(); + app.setPauseOnLostFocus(false); + app.start(); + } + + @Override + public void simpleInitApp() { + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + geom.setMaterial(mat); + rootNode.attachChild(geom); + + NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay( + assetManager, + inputManager, + audioRenderer, + guiViewPort); + nifty = niftyDisplay.getNifty(); + StartScreenController startScreen = new StartScreenController(this); + nifty.fromXml("Interface/Nifty/HelloJme.xml", "start", startScreen); + + // attach the nifty display to the gui view port as a processor + guiViewPort.addProcessor(niftyDisplay); + + // disable the fly cam +// flyCam.setEnabled(false); +// flyCam.setDragToRotate(true); + inputManager.setCursorVisible(true); + } +} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java new file mode 100644 index 0000000000..da428f5d5e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyToMesh.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009-2022 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. + */ + +package jme3test.niftygui; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.niftygui.NiftyJmeDisplay; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture.MagFilter; +import com.jme3.texture.Texture.MinFilter; +import com.jme3.texture.Texture2D; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; +import com.jme3.texture.image.ColorSpace; +import de.lessvoid.nifty.Nifty; + +public class TestNiftyToMesh extends SimpleApplication{ + + public static void main(String[] args){ + TestNiftyToMesh app = new TestNiftyToMesh(); + app.start(); + } + + @Override + public void simpleInitApp() { + ViewPort niftyView = renderManager.createPreView("NiftyView", new Camera(1024, 768)); + niftyView.setClearFlags(true, true, true); + + ColorSpace colorSpace = renderer.isMainFrameBufferSrgb() + ? ColorSpace.sRGB : ColorSpace.Linear; + NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, + inputManager, + audioRenderer, + niftyView, + colorSpace); + Nifty nifty = niftyDisplay.getNifty(); + nifty.fromXml("all/intro.xml", "start"); + niftyView.addProcessor(niftyDisplay); + + Texture2D depthTex = new Texture2D(1024, 768, Format.Depth); + FrameBuffer fb = new FrameBuffer(1024, 768, 1); + fb.setDepthTarget(FrameBufferTarget.newTarget(depthTex)); + + Texture2D tex = new Texture2D(1024, 768, Format.RGBA8); + tex.setMinFilter(MinFilter.Trilinear); + tex.setMagFilter(MagFilter.Bilinear); + + fb.addColorTarget(FrameBufferTarget.newTarget(tex)); + niftyView.setClearFlags(true, true, true); + niftyView.setOutputFrameBuffer(fb); + + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", tex); + geom.setMaterial(mat); + rootNode.attachChild(geom); + } +} diff --git a/jme3-examples/src/main/java/jme3test/niftygui/package-info.java b/jme3-examples/src/main/java/jme3test/niftygui/package-info.java new file mode 100644 index 0000000000..485741acf3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/niftygui/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for Nifty GUI + */ +package jme3test.niftygui; diff --git a/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java b/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java new file mode 100644 index 0000000000..737547fca9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.opencl; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.math.ColorRGBA; +import com.jme3.opencl.*; +import com.jme3.system.AppSettings; +import com.jme3.util.BufferUtils; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.Arrays; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Simple test checking if the basic functions of the OpenCL wrapper work + * @author shaman + */ +public class HelloOpenCL extends SimpleApplication { + private static final Logger LOG = Logger.getLogger(HelloOpenCL.class.getName()); + + public static void main(String[] args){ + HelloOpenCL app = new HelloOpenCL(); + AppSettings settings = new AppSettings(true); + settings.setOpenCLSupport(true); + settings.setVSync(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL2); + app.setSettings(settings); + app.start(); // start the game + } + + @Override + public void simpleInitApp() { + BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); + Context clContext = context.getOpenCLContext(); + if (clContext == null) { + BitmapText txt = new BitmapText(fnt); + txt.setText("No OpenCL Context created!\nSee output log for details."); + txt.setLocalTranslation(5, settings.getHeight() - 5, 0); + guiNode.attachChild(txt); + return; + } + CommandQueue clQueue = clContext.createQueue(); + + StringBuilder str = new StringBuilder(); + str.append("OpenCL Context created:\n Platform: ") + .append(clContext.getDevices().get(0).getPlatform().getName()) + .append("\n Devices: ").append(clContext.getDevices()); + str.append("\nTests:"); + str.append("\n Buffers: ").append(testBuffer(clContext, clQueue)); + str.append("\n Kernel: ").append(testKernel(clContext, clQueue)); + str.append("\n Images: ").append(testImages(clContext, clQueue)); + + clQueue.release(); + + BitmapText txt1 = new BitmapText(fnt); + txt1.setText(str.toString()); + txt1.setLocalTranslation(5, settings.getHeight() - 5, 0); + guiNode.attachChild(txt1); + + flyCam.setEnabled(false); + inputManager.setCursorVisible(true); + } + + private static void assertEquals(byte expected, byte actual, String message) { + if (expected != actual) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + private static void assertEquals(long expected, long actual, String message) { + if (expected != actual) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + private static void assertEquals(double expected, double actual, String message) { + if (Math.abs(expected - actual) >= 0.00001) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + private static void assertEquals(Object expected, Object actual, String message) { + if (!Objects.equals(expected, actual)) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + + private boolean testBuffer(Context clContext, CommandQueue clQueue) { + try { + //create two buffers + ByteBuffer h1 = BufferUtils.createByteBuffer(256); + Buffer b1 = clContext.createBuffer(256); + ByteBuffer h2 = BufferUtils.createByteBuffer(256); + Buffer b2 = clContext.createBuffer(256); + + //fill buffer + h2.rewind(); + for (int i=0; i<256; ++i) { + h2.put((byte)i); + } + h2.rewind(); + b2.write(clQueue, h2); + + //copy b2 to b1 + b2.copyTo(clQueue, b1); + + //read buffer + h1.rewind(); + b1.read(clQueue, h1); + h1.rewind(); + for (int i=0; i<256; ++i) { + byte b = h1.get(); + assertEquals((byte) i, b, "Wrong byte read"); + } + + //read buffer with offset + int low = 26; + int high = 184; + h1.position(5); + Event event = b1.readAsync(clQueue, h1, high-low, low); + event.waitForFinished(); + h1.position(5); + for (int i=0; i deviceListBox; + + private static String selectedPlatform; + private static String selectedDevice; + private Context clContext; + private static List availablePlatforms; + private Buffer testBuffer; + private boolean bufferCreated; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + new TestContextSwitching().start(); + } + + public TestContextSwitching() { + AppSettings settings = new AppSettings(true); + settings.setOpenCLSupport(true); + settings.setVSync(true); + settings.setWidth(800); + settings.setHeight(600); + settings.setOpenCLPlatformChooser(CustomPlatformChooser.class); + settings.setRenderer(AppSettings.LWJGL_OPENGL2); + + setSettings(settings); + setShowSettings(false); + } + + @Override + public void simpleInitApp() { + + clContext = null; + + NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay( + assetManager, + inputManager, + audioRenderer, + guiViewPort); + Nifty nifty = niftyDisplay.getNifty(); + nifty.fromXml("jme3test/opencl/ContextSwitchingScreen.xml", "Screen", this); + guiViewPort.addProcessor(niftyDisplay); + inputManager.setCursorVisible(true); + flyCam.setEnabled(false); + } + + @Override + public void simpleUpdate(float tpf) { + if (applyButton != null) { + updateInfos(); + } + } + + @Override + @SuppressWarnings("unchecked") + public void bind(Nifty nifty, Screen screen) { + applyButton = screen.findNiftyControl("ApplyButton", Button.class); + ListBox platformListBox + = screen.findNiftyControl("PlatformListBox", ListBox.class); + deviceListBox = screen.findNiftyControl("DeviceListBox", ListBox.class); + infoLabel = screen.findNiftyControl("InfoLabel", Label.class); + + updateInfos(); + + platformListBox.clear(); + for (Platform p : availablePlatforms) { + platformListBox.addItem(p.getName()); + } + platformListBox.selectItem(selectedPlatform); + changePlatform(selectedPlatform); + } + + private void updateInfos() { + + if (testBuffer == null && clContext != null && !bufferCreated) { + try { + testBuffer = clContext.createBuffer(1024).register(); + LOG.info("Test buffer created"); + } catch (OpenCLException ex) { + LOG.log(Level.SEVERE, "Unable to create buffer", ex); + } + bufferCreated = true; + } + + Context c = context.getOpenCLContext(); + if (c == clContext) { + return; + } + clContext = c; + LOG.info("context changed"); + testBuffer = null; + bufferCreated = false; + StringBuilder text = new StringBuilder(); + text.append("Current context:\n"); + text.append(" Platform: ").append(clContext.getDevices().get(0).getPlatform().getName()).append("\n"); + text.append(" Device: ").append(clContext.getDevices().get(0).getName()).append("\n"); + text.append(" Profile: ").append(clContext.getDevices().get(0).getProfile()).append("\n"); + text.append(" Memory: ").append(clContext.getDevices().get(0).getGlobalMemorySize()).append(" B\n"); + text.append(" Compute Units: ").append(clContext.getDevices().get(0).getComputeUnits()).append("\n"); + infoLabel.setText(text.toString()); + } + + @NiftyEventSubscriber(id="ApplyButton") + public void onButton(String id, ButtonClickedEvent event) { + LOG.log(Level.INFO, "Change context: platform={0}, device={1}", new Object[]{selectedPlatform, selectedDevice}); + restart(); + } + + private void changePlatform(String platform) { + selectedPlatform = platform; + Platform p = null; + for (Platform p2 : availablePlatforms) { + if (p2.getName().equals(selectedPlatform)) { + p = p2; + break; + } + } + deviceListBox.clear(); + if (p == null) { + return; + } + for (Device d : p.getDevices()) { + deviceListBox.addItem(d.getName()); + } + deviceListBox.selectItem(selectedDevice); + } + + @NiftyEventSubscriber(id="PlatformListBox") + public void onPlatformChanged(String id, ListBoxSelectionChangedEvent event) { + String p = event.getSelection().isEmpty() ? null : event.getSelection().get(0); + LOG.log(Level.INFO, "Selected platform changed to {0}", p); + selectedPlatform = p; + changePlatform(p); + } + + @NiftyEventSubscriber(id="DeviceListBox") + public void onDeviceChanged(String id, ListBoxSelectionChangedEvent event) { + String d = event.getSelection().isEmpty() ? null : event.getSelection().get(0); + LOG.log(Level.INFO, "Selected device changed to {0}", d); + selectedDevice = d; + } + + @Override + public void onStartScreen() { + + } + + @Override + public void onEndScreen() { + + } + + public static class CustomPlatformChooser implements PlatformChooser { + + public CustomPlatformChooser() {} + + @Override + public List chooseDevices(List platforms) { + availablePlatforms = platforms; + + Platform platform = null; + for (Platform p : platforms) { + if (p.getName().equals(selectedPlatform)) { + platform = p; + break; + } + } + if (platform == null) { + platform = platforms.get(0); + } + selectedPlatform = platform.getName(); + + Device device = null; + for (Device d : platform.getDevices()) { + if (d.getName().equals(selectedDevice)) { + device = d; + break; + } + } + if (device == null) { + for (Device d : platform.getDevices()) { + if (d.getDeviceType() == Device.DeviceType.GPU) { + device = d; + break; + } + } + } + if (device == null) { + device = platform.getDevices().get(0); + } + selectedDevice = device.getName(); + + return Collections.singletonList(device); + } + + } +} + diff --git a/jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java b/jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java new file mode 100644 index 0000000000..3b3ec8fe7f --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/opencl/TestMultipleApplications.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.opencl; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.opencl.*; +import com.jme3.system.AppSettings; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class creates multiple instances of {@link TestVertexBufferSharing}. + * This is used to test if multiple opencl instances can run in parallel. + * @author Sebastian Weiss + */ +public class TestMultipleApplications extends SimpleApplication { + private static final Logger LOG = Logger.getLogger(TestMultipleApplications.class.getName()); + + private static final Object sync = new Object(); + private static List availableDevices; + private static int currentDeviceIndex; + + private CommandQueue clQueue; + private Kernel kernel; + private Buffer buffer; + private boolean failed; + private BitmapText statusText; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + final AppSettings settings = new AppSettings(true); + settings.setOpenCLSupport(true); + settings.setVSync(true); + settings.setOpenCLPlatformChooser(CustomPlatformChooser.class); + settings.setRenderer(AppSettings.LWJGL_OPENGL2); + for (int i=0; i<2; ++i) { + new Thread() { + @Override + public void run() { + if (currentDeviceIndex == -1) { + return; + } + TestMultipleApplications app = new TestMultipleApplications(); + app.setSettings(settings); + app.setShowSettings(false); + app.start(); + } + }.start(); + } + } + + public static class CustomPlatformChooser implements PlatformChooser { + + public CustomPlatformChooser() {} + + @Override + public List chooseDevices(List platforms) { + synchronized(sync) { + if (currentDeviceIndex == -1) { + return Collections.emptyList(); + } + + Platform platform = platforms.get(0); + availableDevices = platform.getDevices(); + + Device device = platform.getDevices().get(currentDeviceIndex); + currentDeviceIndex ++; + if (currentDeviceIndex >= availableDevices.size()) { + currentDeviceIndex = -1; + } + + return Collections.singletonList(device); + } + } + + } + + @Override + public void simpleInitApp() { + Context clContext = context.getOpenCLContext(); + if (clContext == null) { + LOG.severe("No OpenCL context found"); + stop(); + return; + } + Device device = clContext.getDevices().get(0); + clQueue = clContext.createQueue(device); + clQueue.register(); + + String source = "" + + "__kernel void Fill(__global float* vb, float v)\n" + + "{\n" + + " int idx = get_global_id(0);\n" + + " vb[idx] = v;\n" + + "}\n"; + Program program = clContext.createProgramFromSourceCode(source); + program.build(); + program.register(); + kernel = program.createKernel("Fill"); + kernel.register(); + + buffer = clContext.createBuffer(4); + buffer.register(); + + flyCam.setEnabled(false); + inputManager.setCursorVisible(true); + + BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText infoText = new BitmapText(fnt); + //infoText.setBox(new Rectangle(0, 0, settings.getWidth(), settings.getHeight())); + infoText.setText("Device: "+clContext.getDevices()); + infoText.setLocalTranslation(0, settings.getHeight(), 0); + guiNode.attachChild(infoText); + statusText = new BitmapText(fnt); + //statusText.setBox(new Rectangle(0, 0, settings.getWidth(), settings.getHeight())); + statusText.setText("Running"); + statusText.setLocalTranslation(0, settings.getHeight() - infoText.getHeight() - 2, 0); + guiNode.attachChild(statusText); + } + + @Override + public void simpleUpdate(float tpf) { + //call kernel to test if it is still working + if (!failed) { + try { + kernel.Run1NoEvent(clQueue, new Kernel.WorkSize(1), buffer, 1.0f); + } catch (OpenCLException ex) { + LOG.log(Level.SEVERE, "Kernel call not working anymore", ex); + failed = true; + statusText.setText("Failed"); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java b/jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java new file mode 100644 index 0000000000..2a712314cb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/opencl/TestOpenCLLibraries.java @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.opencl; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.math.FastMath; +import com.jme3.math.Matrix3f; +import com.jme3.math.Matrix4f; +import com.jme3.opencl.*; +import com.jme3.system.AppSettings; +import com.jme3.util.BufferUtils; +import java.nio.*; +import java.util.Objects; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Test class for the build in libraries + * @author shaman + */ +public class TestOpenCLLibraries extends SimpleApplication { + private static final Logger LOG = Logger.getLogger(TestOpenCLLibraries.class.getName()); + + public static void main(String[] args){ + TestOpenCLLibraries app = new TestOpenCLLibraries(); + AppSettings settings = new AppSettings(true); + settings.setOpenCLSupport(true); + settings.setVSync(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL2); + app.setSettings(settings); + app.start(); // start the game + } + + @Override + public void simpleInitApp() { + BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); + Context clContext = context.getOpenCLContext(); + if (clContext == null) { + BitmapText txt = new BitmapText(fnt); + txt.setText("No OpenCL Context created!\nSee output log for details."); + txt.setLocalTranslation(5, settings.getHeight() - 5, 0); + guiNode.attachChild(txt); + return; + } + CommandQueue clQueue = clContext.createQueue(clContext.getDevices().get(0)); + + StringBuilder str = new StringBuilder(); + str.append("OpenCL Context created:\n Platform: ") + .append(clContext.getDevices().get(0).getPlatform().getName()) + .append("\n Devices: ").append(clContext.getDevices()); + str.append("\nTests:"); + str.append("\n Random numbers: ").append(testRandom(clContext, clQueue)); + str.append("\n Matrix3f: ").append(testMatrix3f(clContext, clQueue)); + str.append("\n Matrix4f: ").append(testMatrix4f(clContext, clQueue)); + + clQueue.release(); + + BitmapText txt1 = new BitmapText(fnt); + txt1.setText(str.toString()); + txt1.setLocalTranslation(5, settings.getHeight() - 5, 0); + guiNode.attachChild(txt1); + + flyCam.setEnabled(false); + inputManager.setCursorVisible(true); + } + + private static void assertEquals(byte expected, byte actual, String message) { + if (expected != actual) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + private static void assertEquals(long expected, long actual, String message) { + if (expected != actual) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + private static void assertEquals(double expected, double actual, String message) { + if (Math.abs(expected - actual) >= 0.00001) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + private static void assertEquals(Object expected, Object actual, String message) { + if (!Objects.equals(expected, actual)) { + System.err.println(message+": expected="+expected+", actual="+actual); + throw new AssertionError(); + } + } + + private boolean testRandom(Context clContext, CommandQueue clQueue) { + try { + //test for doubles + boolean supportsDoubles = clContext.getDevices().get(0).hasDouble(); + + //create code + String code = "" + + "#import \"Common/OpenCL/Random.clh\"\n" + + "__kernel void TestBool(__global ulong* seeds, __global uchar* results) {\n" + + " results[get_global_id(0)] = randBool(seeds + get_global_id(0)) ? 1 : 0;\n" + + "}\n" + + "__kernel void TestInt(__global ulong* seeds, __global int* results) {\n" + + " results[get_global_id(0)] = randInt(seeds + get_global_id(0));\n" + + "}\n" + + "__kernel void TestIntN(__global ulong* seeds, int n, __global int* results) {\n" + + " results[get_global_id(0)] = randIntN(n, seeds + get_global_id(0));\n" + + "}\n" + + "__kernel void TestLong(__global ulong* seeds, __global long* results) {\n" + + " results[get_global_id(0)] = randLong(seeds + get_global_id(0));\n" + + "}\n" + + "__kernel void TestFloat(__global ulong* seeds, __global float* results) {\n" + + " results[get_global_id(0)] = randFloat(seeds + get_global_id(0));\n" + + "}\n" + + "#ifdef RANDOM_DOUBLES\n" + + "__kernel void TestDouble(__global ulong* seeds, __global double* results) {\n" + + " results[get_global_id(0)] = randDouble(seeds + get_global_id(0));\n" + + "}\n" + + "#endif\n"; + if (supportsDoubles) { + code = "#define RANDOM_DOUBLES\n" + code; + } + Program program = clContext.createProgramFromSourceCodeWithDependencies(code, assetManager); + program.build(); + + int count = 256; + Kernel.WorkSize ws = new Kernel.WorkSize(count); + + //create seeds + Random initRandom = new Random(); + long[] seeds = new long[count]; + Random[] randoms = new Random[count]; + for (int i=0; i 0 ) { + fpp.setNumSamples(numSamples); + } + + BloomFilter bloom=new BloomFilter(); + bloom.setDownSamplingFactor(2); + bloom.setBlurScale(1.37f); + bloom.setExposurePower(3.30f); + bloom.setExposureCutOff(0.2f); + bloom.setBloomIntensity(2.45f); + BloomUI ui=new BloomUI(inputManager, bloom); + + + viewPort.addProcessor(fpp); + fpp.addFilter(bloom); + initInputs(); + + } + + private void initInputs() { + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + + ActionListener acl = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggle") && keyPressed) { + if(active){ + active=false; + viewPort.removeProcessor(fpp); + }else{ + active=true; + viewPort.addProcessor(fpp); + } + } + } + }; + + inputManager.addListener(acl, "toggle"); + + } + + + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java b/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java new file mode 100644 index 0000000000..9e5a9aaed3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.post.filters.BloomFilter.GlowMode; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; + +public class TestBloomAlphaThreshold extends SimpleApplication +{ + private boolean active = true; + private FilterPostProcessor fpp; + + public static void main(String[] args) + { + TestBloomAlphaThreshold app = new TestBloomAlphaThreshold(); + app.start(); + } + + @Override + public void simpleInitApp() + { + // put the camera in a bad position + cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -10)); + cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f)); + // cam.setFrustumFar(1000); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + + mat.setFloat("Shininess", 15f); + mat.setBoolean("UseMaterialColors", true); + mat.setColor("Ambient", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Diffuse", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Specular", ColorRGBA.Yellow.mult(0.8f)); + mat.setColor("GlowColor", ColorRGBA.Green); + + Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + matSoil.setFloat("Shininess", 15f); + matSoil.setBoolean("UseMaterialColors", true); + matSoil.setColor("Ambient", ColorRGBA.Gray); + matSoil.setColor("Diffuse", ColorRGBA.Black); + matSoil.setColor("Specular", ColorRGBA.Gray); + + Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); + teapot.setLocalTranslation(0, 0, 10); + + teapot.setMaterial(mat); + teapot.setShadowMode(ShadowMode.CastAndReceive); + teapot.setLocalScale(10.0f); + rootNode.attachChild(teapot); + + Vector3f boxMin1 = new Vector3f(-800f, -23f, -150f); + Vector3f boxMax1 = new Vector3f(800f, 3f, 1250f); + Box boxMesh1 = new Box(boxMin1, boxMax1); + Geometry soil = new Geometry("soil", boxMesh1); + soil.setMaterial(matSoil); + soil.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(soil); + + Material matBox = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matBox.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png")); + matBox.setFloat("AlphaDiscardThreshold", 0.5f); + + Vector3f boxMin2 = new Vector3f(-5.5f, 8f, -4f); + Vector3f boxMax2 = new Vector3f(-1.5f, 12f, 0f); + Box boxMesh2 = new Box(boxMin2, boxMax2); + Geometry box = new Geometry("box", boxMesh2); + box.setMaterial(matBox); + box.setQueueBucket(RenderQueue.Bucket.Translucent); + // box.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(box); + + DirectionalLight light = new DirectionalLight(); + light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + light.setColor(ColorRGBA.White.mult(1.5f)); + rootNode.addLight(light); + + // load sky + Spatial sky = SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/FullskiesBlueClear03.dds", + EnvMapType.CubeMap); + sky.setCullHint(Spatial.CullHint.Never); + rootNode.attachChild(sky); + + fpp = new FilterPostProcessor(assetManager); + int numSamples = getContext().getSettings().getSamples(); + if (numSamples > 0) + { + fpp.setNumSamples(numSamples); + } + + BloomFilter bloom = new BloomFilter(GlowMode.Objects); + bloom.setDownSamplingFactor(2); + bloom.setBlurScale(1.37f); + bloom.setExposurePower(3.30f); + bloom.setExposureCutOff(0.2f); + bloom.setBloomIntensity(2.45f); + BloomUI ui = new BloomUI(inputManager, bloom); + + viewPort.addProcessor(fpp); + fpp.addFilter(bloom); + initInputs(); + + } + + private void initInputs() + { + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + + ActionListener acl = new ActionListener() + { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) + { + if (name.equals("toggle") && keyPressed) + { + if (active) + { + active = false; + viewPort.removeProcessor(fpp); + } + else + { + active = true; + viewPort.addProcessor(fpp); + } + } + } + }; + + inputManager.addListener(acl, "toggle"); + + } + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java b/jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java new file mode 100644 index 0000000000..ff6ab497f3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestCartoonEdge.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.CartoonEdgeFilter; +import com.jme3.renderer.Caps; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.Spatial.CullHint; +import com.jme3.texture.Texture; + +public class TestCartoonEdge extends SimpleApplication { + + private FilterPostProcessor fpp; + + public static void main(String[] args){ + TestCartoonEdge app = new TestCartoonEdge(); + app.start(); + } + + public void setupFilters(){ + if (renderer.getCaps().contains(Caps.GLSL100)){ + fpp=new FilterPostProcessor(assetManager); + //fpp.setNumSamples(4); + int numSamples = getContext().getSettings().getSamples(); + if( numSamples > 0 ) { + fpp.setNumSamples(numSamples); + } + CartoonEdgeFilter toon=new CartoonEdgeFilter(); + toon.setEdgeColor(ColorRGBA.Yellow); + fpp.addFilter(toon); + viewPort.addProcessor(fpp); + } + } + + public void makeToonish(Spatial spatial){ + if (spatial instanceof Node){ + Node n = (Node) spatial; + for (Spatial child : n.getChildren()) + makeToonish(child); + }else if (spatial instanceof Geometry){ + Geometry g = (Geometry) spatial; + Material m = g.getMaterial(); + if (m.getMaterialDef().getMaterialParam("UseMaterialColors") != null) { + Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png"); +// t.setMinFilter(Texture.MinFilter.NearestNoMipMaps); +// t.setMagFilter(Texture.MagFilter.Nearest); + m.setTexture("ColorRamp", t); + m.setBoolean("UseMaterialColors", true); + m.setColor("Specular", ColorRGBA.Black); + m.setColor("Diffuse", ColorRGBA.White); + m.setBoolean("VertexLighting", true); + } + } + } + + public void setupLighting(){ + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, 1).normalizeLocal()); + dl.setColor(new ColorRGBA(2,2,2,1)); + + rootNode.addLight(dl); + } + + public void setupModel(){ + Spatial model = assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml"); + makeToonish(model); + model.rotate(0, FastMath.PI, 0); +// signpost.setLocalTranslation(12, 3.5f, 30); +// model.scale(0.10f); +// signpost.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(model); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.Gray); + + cam.setLocation(new Vector3f(-5.6310086f, 5.0892987f, -13.000479f)); + cam.setRotation(new Quaternion(0.1779095f, 0.20036356f, -0.03702727f, 0.96272093f)); + cam.update(); + + cam.setFrustumFar(300); + flyCam.setMoveSpeed(30); + + rootNode.setCullHint(CullHint.Never); + + setupLighting(); + setupModel(); + setupFilters(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java b/jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java new file mode 100644 index 0000000000..52c125cb3e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestContrastAdjustment.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.ContrastAdjustmentFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Sphere; +import com.jme3.texture.Texture; + +/** + * A {@link ContrastAdjustmentFilter} with user-controlled exponents, scales, and input range. + * + * @author pavl_g. + */ +public class TestContrastAdjustment extends SimpleApplication { + + /** + * Display filter status. + */ + private BitmapText statusText; + /** + * The filter being tested. + */ + private ContrastAdjustmentFilter contrastAdjustmentFilter; + + public static void main(String[] args) { + new TestContrastAdjustment().start(); + } + + @Override + public void simpleInitApp() { + /* + * Attach an unshaded globe to the scene. + */ + final Sphere globe = new Sphere(40, 40, 3.5f); + final Geometry earth = new Geometry("Earth", globe); + earth.rotate(-FastMath.HALF_PI, 0f, 0f); + final Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + final Texture texture = assetManager.loadTexture("Textures/Sky/Earth/Earth.jpg"); + material.setTexture("ColorMap", texture); + earth.setMaterial(material); + rootNode.attachChild(earth); + + final FilterPostProcessor postProcessor = new FilterPostProcessor(assetManager); + int numSamples = settings.getSamples(); + if (numSamples > 0) { + postProcessor.setNumSamples(numSamples); + } + viewPort.addProcessor(postProcessor); + /* + * Add the filter to be tested. + */ + contrastAdjustmentFilter = new ContrastAdjustmentFilter(); + //adjusting some parameters + contrastAdjustmentFilter.setExponents(1.8f, 1.8f, 2.1f) + .setInputRange(0, 0.367f) + .setScales(0.25f, 0.25f, 1f); + postProcessor.addFilter(contrastAdjustmentFilter); + + setUpUserInterface(); + } + + /** + * Update the status text. + * + * @param tpf unused + */ + @Override + public void simpleUpdate(float tpf) { + String status = contrastAdjustmentFilter.toString(); + statusText.setText(status); + } + + private void setUpUserInterface() { + /* + * Attach a BitmapText to display the status of the ContrastAdjustmentFilter. + */ + statusText = new BitmapText(guiFont); + guiNode.attachChild(statusText); + statusText.setLocalTranslation(0f, cam.getHeight(), 0f); + /* + * Create listeners for user keypresses. + */ + ActionListener action = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("reset") && keyPressed) { + contrastAdjustmentFilter.setExponents(1f, 1f, 1f) + .setInputRange(0f, 1f) + .setScales(1f, 1f, 1f); + } + } + }; + AnalogListener analog = new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + float increment = name.endsWith("+") ? 0.3f * tpf : -0.3f * tpf; + + if (name.startsWith("lower")) { + float newValue = contrastAdjustmentFilter.getLowerLimit() + increment; + contrastAdjustmentFilter.setLowerLimit(newValue); + + } else if (name.startsWith("upper")) { + float newValue = contrastAdjustmentFilter.getUpperLimit() + increment; + contrastAdjustmentFilter.setUpperLimit(newValue); + + } else if (name.startsWith("re")) { + float newValue = contrastAdjustmentFilter.getRedExponent() + increment; + contrastAdjustmentFilter.setRedExponent(newValue); + + } else if (name.startsWith("ge")) { + float newValue = contrastAdjustmentFilter.getGreenExponent() + increment; + contrastAdjustmentFilter.setGreenExponent(newValue); + + } else if (name.startsWith("be")) { + float newValue = contrastAdjustmentFilter.getBlueExponent() + increment; + contrastAdjustmentFilter.setBlueExponent(newValue); + + } else if (name.startsWith("rs")) { + float newValue = contrastAdjustmentFilter.getRedScale() + increment; + contrastAdjustmentFilter.setRedScale(newValue); + + } else if (name.startsWith("gs")) { + float newValue = contrastAdjustmentFilter.getGreenScale() + increment; + contrastAdjustmentFilter.setGreenScale(newValue); + + } else if (name.startsWith("bs")) { + float newValue = contrastAdjustmentFilter.getBlueScale() + increment; + contrastAdjustmentFilter.setBlueScale(newValue); + } + } + }; + /* + * Add mappings and listeners for user keypresses. + */ + System.out.println("Press Enter to reset the filter to defaults."); + inputManager.addMapping("reset", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addListener(action, "reset"); + + System.out.println("lower limit: press R to increase, F to decrease"); + inputManager.addMapping("lower+", new KeyTrigger(KeyInput.KEY_R)); + inputManager.addMapping("lower-", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addListener(analog, "lower+", "lower-"); + + System.out.println("upper limit: press T to increase, G to decrease"); + inputManager.addMapping("upper+", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addMapping("upper-", new KeyTrigger(KeyInput.KEY_G)); + inputManager.addListener(analog, "upper+", "upper-"); + + System.out.println("red exponent: press Y to increase, H to decrease"); + inputManager.addMapping("re+", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("re-", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addListener(analog, "re+", "re-"); + + System.out.println("green exponent: press U to increase, J to decrease"); + inputManager.addMapping("ge+", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("ge-", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addListener(analog, "ge+", "ge-"); + + System.out.println("blue exponent: press I to increase, K to decrease"); + inputManager.addMapping("be+", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addMapping("be-", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addListener(analog, "be+", "be-"); + + System.out.println("red scale: press O to increase, L to decrease"); + inputManager.addMapping("rs+", new KeyTrigger(KeyInput.KEY_O)); + inputManager.addMapping("rs-", new KeyTrigger(KeyInput.KEY_L)); + inputManager.addListener(analog, "rs+", "rs-"); + + System.out.println("green scale: press P to increase, ; to decrease"); + inputManager.addMapping("gs+", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addMapping("gs-", new KeyTrigger(KeyInput.KEY_SEMICOLON)); + inputManager.addListener(analog, "gs+", "gs-"); + + System.out.println("blue scale: press [ to increase, ' to decrease"); + inputManager.addMapping("bs+", new KeyTrigger(KeyInput.KEY_LBRACKET)); + inputManager.addMapping("bs-", new KeyTrigger(KeyInput.KEY_APOSTROPHE)); + inputManager.addListener(analog, "bs+", "bs-"); + + System.out.println(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java b/jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java new file mode 100644 index 0000000000..6883ddcabf --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestCrossHatch.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.CrossHatchFilter; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; + +public class TestCrossHatch extends SimpleApplication { + + private boolean active=true; + private FilterPostProcessor fpp; + + public static void main(String[] args){ + TestCrossHatch app = new TestCrossHatch(); + app.start(); + } + + @Override + public void simpleInitApp() { + // put the camera in a bad position + cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f)); + cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f)); + //cam.setFrustumFar(1000); + + + Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); + mat.setFloat("Shininess", 15f); + mat.setBoolean("UseMaterialColors", true); + mat.setColor("Ambient", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Diffuse", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Specular", ColorRGBA.Yellow.mult(0.8f)); + + + + + Material matSoil = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); + matSoil.setFloat("Shininess", 15f); + matSoil.setBoolean("UseMaterialColors", true); + matSoil.setColor("Ambient", ColorRGBA.Gray); + matSoil.setColor("Diffuse", ColorRGBA.Black); + matSoil.setColor("Specular", ColorRGBA.Gray); + + + Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); + teapot.setLocalTranslation(0,0,10); + + teapot.setMaterial(mat); + teapot.setShadowMode(ShadowMode.CastAndReceive); + teapot.setLocalScale(10.0f); + rootNode.attachChild(teapot); + + + + Geometry soil = new Geometry("soil", new Box(800, 10, 700)); + soil.setLocalTranslation(0, -13, 550); + soil.setMaterial(matSoil); + soil.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(soil); + + DirectionalLight light=new DirectionalLight(); + light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + light.setColor(ColorRGBA.White.mult(1.5f)); + rootNode.addLight(light); + + // load sky + Spatial sky = SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/FullskiesBlueClear03.dds", + EnvMapType.CubeMap); + sky.setCullHint(Spatial.CullHint.Never); + rootNode.attachChild(sky); + + fpp=new FilterPostProcessor(assetManager); + + int numSamples = getContext().getSettings().getSamples(); + if( numSamples > 0 ) { + fpp.setNumSamples(numSamples); + } + + CrossHatchFilter chf=new CrossHatchFilter(); + + + + viewPort.addProcessor(fpp); + fpp.addFilter(chf); + initInputs(); + + } + + private void initInputs() { + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + + ActionListener acl = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggle") && keyPressed) { + if(active){ + active=false; + viewPort.removeProcessor(fpp); + }else{ + active=true; + viewPort.addProcessor(fpp); + } + } + } + }; + + inputManager.addListener(acl, "toggle"); + + } + + + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java b/jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java new file mode 100644 index 0000000000..3690fe9aa7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestDepthOfField.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.DepthOfFieldFilter; +import com.jme3.renderer.Camera; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; +import java.util.ArrayList; +import java.util.List; + +/** + * test + * @author Nehon + */ +public class TestDepthOfField extends SimpleApplication { + + final private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f); + private TerrainQuad terrain; + private DepthOfFieldFilter dofFilter; + + public static void main(String[] args) { + TestDepthOfField app = new TestDepthOfField(); + app.start(); + } + + @Override + public void simpleInitApp() { + + + Node mainScene = new Node("Main Scene"); + rootNode.attachChild(mainScene); + + createTerrain(mainScene); + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(lightDir); + sun.setColor(ColorRGBA.White.clone().multLocal(1.7f)); + mainScene.addLight(sun); + + DirectionalLight l = new DirectionalLight(); + l.setDirection(Vector3f.UNIT_Y.mult(-1)); + l.setColor(ColorRGBA.White.clone().multLocal(0.3f)); + mainScene.addLight(l); + + flyCam.setMoveSpeed(50); + cam.setFrustumFar(3000); + cam.setLocation(new Vector3f(-700, 100, 300)); + cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0})); + + + Spatial sky = SkyFactory.createSky(assetManager, + "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); + sky.setLocalScale(350); + mainScene.attachChild(sky); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + // fpp.setNumSamples(4); + int numSamples = getContext().getSettings().getSamples(); + if( numSamples > 0 ) { + fpp.setNumSamples(numSamples); + } + + dofFilter = new DepthOfFieldFilter(); + dofFilter.setFocusDistance(0); + dofFilter.setFocusRange(50); + dofFilter.setBlurScale(1.4f); + fpp.addFilter(dofFilter); + viewPort.addProcessor(fpp); + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + if (name.equals("toggle")) { + dofFilter.setEnabled(!dofFilter.isEnabled()); + } + + + } + } + }, "toggle"); + inputManager.addListener(new AnalogListener() { + + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("blurScaleUp")) { + dofFilter.setBlurScale(dofFilter.getBlurScale() + 0.01f); + System.out.println("blurScale : " + dofFilter.getBlurScale()); + } + if (name.equals("blurScaleDown")) { + dofFilter.setBlurScale(dofFilter.getBlurScale() - 0.01f); + System.out.println("blurScale : " + dofFilter.getBlurScale()); + } + if (name.equals("focusRangeUp")) { + dofFilter.setFocusRange(dofFilter.getFocusRange() + 1f); + System.out.println("focusRange : " + dofFilter.getFocusRange()); + } + if (name.equals("focusRangeDown")) { + dofFilter.setFocusRange(dofFilter.getFocusRange() - 1f); + System.out.println("focusRange : " + dofFilter.getFocusRange()); + } + if (name.equals("focusDistanceUp")) { + dofFilter.setFocusDistance(dofFilter.getFocusDistance() + 1f); + System.out.println("focusDistance : " + dofFilter.getFocusDistance()); + } + if (name.equals("focusDistanceDown")) { + dofFilter.setFocusDistance(dofFilter.getFocusDistance() - 1f); + System.out.println("focusDistance : " + dofFilter.getFocusDistance()); + } + + } + }, "blurScaleUp", "blurScaleDown", "focusRangeUp", "focusRangeDown", "focusDistanceUp", "focusDistanceDown"); + + + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("blurScaleUp", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("blurScaleDown", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("focusRangeUp", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addMapping("focusRangeDown", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("focusDistanceUp", new KeyTrigger(KeyInput.KEY_O)); + inputManager.addMapping("focusDistanceDown", new KeyTrigger(KeyInput.KEY_L)); + + } + + private void createTerrain(Node rootNode) { + Material matRock = new Material(assetManager, + "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matRock.setBoolean("useTriPlanarMapping", false); + matRock.setBoolean("WardIso", true); + matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap", grass); + matRock.setFloat("DiffuseMap_0_scale", 64); + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_1", dirt); + matRock.setFloat("DiffuseMap_1_scale", 16); + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_2", rock); + matRock.setFloat("DiffuseMap_2_scale", 128); + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(WrapMode.Repeat); + matRock.setTexture("NormalMap", normalMap0); + matRock.setTexture("NormalMap_1", normalMap1); + matRock.setTexture("NormalMap_2", normalMap2); + + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); + heightmap.load(); + } catch (Exception e) { + e.printStackTrace(); + } + terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + List cameras = new ArrayList<>(); + cameras.add(getCamera()); + terrain.setMaterial(matRock); + terrain.setLocalScale(new Vector3f(5, 5, 5)); + terrain.setLocalTranslation(new Vector3f(0, -30, 0)); + terrain.setLocked(false); // unlock it so we can edit the height + + terrain.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(terrain); + + } + + @Override + public void simpleUpdate(float tpf) { + Vector3f origin = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); + Vector3f direction = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); + direction.subtractLocal(origin).normalizeLocal(); + Ray ray = new Ray(origin, direction); + CollisionResults results = new CollisionResults(); + int numCollisions = terrain.collideWith(ray, results); + if (numCollisions > 0) { + CollisionResult hit = results.getClosestCollision(); + fpsText.setText(""+hit.getDistance()); + dofFilter.setFocusDistance(hit.getDistance()/10.0f); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java b/jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java new file mode 100644 index 0000000000..72a4c875f5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestFBOPassthrough.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.Renderer; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture2D; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; +import com.jme3.ui.Picture; + +/** + * Demonstrates FrameBuffer usage. + * The scene is first rendered to an FB with a texture attached, + * the texture is then rendered onto the screen in ortho mode. + * + * @author Kirill + */ +public class TestFBOPassthrough extends SimpleApplication { + + final private Node fbNode = new Node("Framebuffer Node"); + private FrameBuffer fb; + + public static void main(String[] args){ + TestFBOPassthrough app = new TestFBOPassthrough(); + app.start(); + } + + @Override + public void simpleInitApp() { + int w = settings.getWidth(); + int h = settings.getHeight(); + + //setup framebuffer + fb = new FrameBuffer(w, h, 1); + + Texture2D fbTex = new Texture2D(w, h, Format.RGBA8); + fb.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); + fb.addColorTarget(FrameBufferTarget.newTarget(fbTex)); + + // setup framebuffer's scene + Sphere sphMesh = new Sphere(20, 20, 1); + Material solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + + Geometry sphere = new Geometry("sphere", sphMesh); + sphere.setMaterial(solidColor); + fbNode.attachChild(sphere); + + //setup main scene + Picture p = new Picture("Picture"); + p.setPosition(0, 0); + p.setWidth(w); + p.setHeight(h); + p.setTexture(assetManager, fbTex, false); + + rootNode.attachChild(p); + } + + @Override + public void simpleUpdate(float tpf){ + fbNode.updateLogicalState(tpf); + fbNode.updateGeometricState(); + } + + @Override + public void simpleRender(RenderManager rm){ + Renderer r = rm.getRenderer(); + + //do FBO rendering + r.setFrameBuffer(fb); + + rm.setCamera(cam, false); // FBO uses current camera + r.clearBuffers(true, true, true); + rm.renderScene(fbNode, viewPort); + rm.flushQueue(viewPort); + + //go back to default rendering and let + //SimpleApplication render the default scene + r.setFrameBuffer(null); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestFog.java b/jme3-examples/src/main/java/jme3test/post/TestFog.java new file mode 100644 index 0000000000..b7a913d79f --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestFog.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.FogFilter; +import com.jme3.renderer.Camera; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Node; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.util.SkyFactory; +import java.util.ArrayList; +import java.util.List; + +public class TestFog extends SimpleApplication { + + private FilterPostProcessor fpp; + private boolean enabled=true; + private FogFilter fog; + + public static void main(String[] args) { + TestFog app = new TestFog(); + app.start(); + } + + @Override + public void simpleInitApp() { + this.flyCam.setMoveSpeed(50); + Node mainScene=new Node(); + cam.setLocation(new Vector3f(-34.74095f, 95.21318f, -287.4945f)); + cam.setRotation(new Quaternion(0.023536969f, 0.9361278f, -0.016098259f, -0.35050195f)); + + // load sky + mainScene.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + createTerrain(mainScene); + + + + DirectionalLight sun = new DirectionalLight(); + Vector3f lightDir=new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); + sun.setDirection(lightDir); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + mainScene.addLight(sun); + + rootNode.attachChild(mainScene); + + fpp=new FilterPostProcessor(assetManager); + //fpp.setNumSamples(4); + int numSamples = getContext().getSettings().getSamples(); + if( numSamples > 0 ) { + fpp.setNumSamples(numSamples); + } + fog=new FogFilter(); + fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f)); + fog.setFogDistance(155); + fog.setFogDensity(1.0f); + fpp.addFilter(fog); + viewPort.addProcessor(fpp); + initInputs(); + } + + private void initInputs() { + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("DensityUp", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("DensityDown", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("DistanceUp", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("DistanceDown", new KeyTrigger(KeyInput.KEY_J)); + + + ActionListener acl = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggle") && keyPressed) { + if(enabled){ + enabled=false; + viewPort.removeProcessor(fpp); + }else{ + enabled=true; + viewPort.addProcessor(fpp); + } + } + + } + }; + + AnalogListener anl=new AnalogListener() { + + @Override + public void onAnalog(String name, float isPressed, float tpf) { + if(name.equals("DensityUp")){ + fog.setFogDensity(fog.getFogDensity()+0.001f); + System.out.println("Fog density : "+fog.getFogDensity()); + } + if(name.equals("DensityDown")){ + fog.setFogDensity(fog.getFogDensity()-0.010f); + System.out.println("Fog density : "+fog.getFogDensity()); + } + if(name.equals("DistanceUp")){ + fog.setFogDistance(fog.getFogDistance()+0.5f); + System.out.println("Fog Distance : "+fog.getFogDistance()); + } + if(name.equals("DistanceDown")){ + fog.setFogDistance(fog.getFogDistance()-0.5f); + System.out.println("Fog Distance : "+fog.getFogDistance()); + } + + } + }; + + inputManager.addListener(acl, "toggle"); + inputManager.addListener(anl, "DensityUp","DensityDown","DistanceUp","DistanceDown"); + + } + + private void createTerrain(Node rootNode) { + Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matRock.setBoolean("useTriPlanarMapping", false); + matRock.setBoolean("WardIso", true); + matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(Texture.WrapMode.Repeat); + matRock.setTexture("DiffuseMap", grass); + matRock.setFloat("DiffuseMap_0_scale", 64); + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(Texture.WrapMode.Repeat); + matRock.setTexture("DiffuseMap_1", dirt); + matRock.setFloat("DiffuseMap_1_scale", 16); + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(Texture.WrapMode.Repeat); + matRock.setTexture("DiffuseMap_2", rock); + matRock.setFloat("DiffuseMap_2_scale", 128); + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(Texture.WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(Texture.WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(Texture.WrapMode.Repeat); + matRock.setTexture("NormalMap", normalMap0); + matRock.setTexture("NormalMap_1", normalMap1); + matRock.setTexture("NormalMap_2", normalMap2); + + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); + heightmap.load(); + } catch (Exception e) { + e.printStackTrace(); + } + TerrainQuad terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + List cameras = new ArrayList<>(); + cameras.add(getCamera()); + terrain.setMaterial(matRock); + terrain.setLocalScale(new Vector3f(5, 5, 5)); + terrain.setLocalTranslation(new Vector3f(0, -30, 0)); + terrain.setLocked(false); // unlock it so we can edit the height + + terrain.setShadowMode(RenderQueue.ShadowMode.Receive); + rootNode.attachChild(terrain); + + } +} + diff --git a/jme3-examples/src/main/java/jme3test/post/TestIssue1798.java b/jme3-examples/src/main/java/jme3test/post/TestIssue1798.java new file mode 100644 index 0000000000..79605f29a8 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestIssue1798.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2009-2022 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.CartoonEdgeFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.system.AppSettings; +import com.jme3.texture.Texture; + +/** + * Test case for JME issue #1798: filtered scenes are squeezed by resizable + * windows. + *

+ * If successful, a cartoon monkey head will be shown, and resizing the window + * (using the system's window manager) will not change its shape. + *

+ * If unsuccessful, then making the window taller will make the head taller, and + * making the window wider will make the head wider. + *

+ * Based on the TestCartoonEdge application. + */ +public class TestIssue1798 extends SimpleApplication { + // ************************************************************************* + // fields + + private FilterPostProcessor fpp; + // ************************************************************************* + // new methods exposed + + public static void main(String[] args) { + AppSettings s = new AppSettings(true); + s.setResizable(true); + TestIssue1798 app = new TestIssue1798(); + app.setSettings(s); + app.start(); + } + // ************************************************************************* + // SimpleApplication methods + + /** + * Initialize this application. + */ + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.Gray); + flyCam.setDragToRotate(true); + setupLighting(); + setupModel(); + setupFilters(); + } + // ************************************************************************* + // private methods + + private void makeToonish(Spatial spatial) { + if (spatial instanceof Node) { + Node n = (Node) spatial; + for (Spatial child : n.getChildren()) { + makeToonish(child); + } + } else if (spatial instanceof Geometry) { + Geometry g = (Geometry) spatial; + Material m = g.getMaterial(); + if (m.getMaterialDef().getMaterialParam("UseMaterialColors") != null) { + Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png"); + m.setTexture("ColorRamp", t); + m.setBoolean("UseMaterialColors", true); + m.setColor("Specular", ColorRGBA.Black); + m.setColor("Diffuse", ColorRGBA.White); + m.setBoolean("VertexLighting", true); + } + } + } + + private void setupFilters() { + fpp = new FilterPostProcessor(assetManager); + int numSamples = getContext().getSettings().getSamples(); + if (numSamples > 0) { + fpp.setNumSamples(numSamples); + } + CartoonEdgeFilter toon = new CartoonEdgeFilter(); + toon.setEdgeColor(ColorRGBA.Yellow); + fpp.addFilter(toon); + viewPort.addProcessor(fpp); + } + + private void setupLighting() { + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, 1).normalizeLocal()); + dl.setColor(new ColorRGBA(2, 2, 2, 1)); + rootNode.addLight(dl); + } + + private void setupModel() { + Spatial model = assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml"); + makeToonish(model); + rootNode.attachChild(model); + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestLightScattering.java b/jme3-examples/src/main/java/jme3test/post/TestLightScattering.java new file mode 100644 index 0000000000..c2940cab6b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestLightScattering.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.LightScatteringFilter; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.util.SkyFactory; +import com.jme3.util.TangentBinormalGenerator; + +public class TestLightScattering extends SimpleApplication { + + public static void main(String[] args) { + TestLightScattering app = new TestLightScattering(); + + app.start(); + } + + @Override + public void simpleInitApp() { + // put the camera in a bad position + cam.setLocation(new Vector3f(55.35316f, -0.27061665f, 27.092093f)); + cam.setRotation(new Quaternion(0.010414706f, 0.9874893f, 0.13880467f, -0.07409228f)); +// cam.setDirection(new Vector3f(0,-0.5f,1.0f)); +// cam.setLocation(new Vector3f(0, 300, -500)); + //cam.setFrustumFar(1000); + flyCam.setMoveSpeed(10); + Material mat = assetManager.loadMaterial("Textures/Terrain/Rocky/Rocky.j3m"); + Spatial scene = assetManager.loadModel("Models/Terrain/Terrain.mesh.xml"); + TangentBinormalGenerator.generate(((Geometry)((Node)scene).getChild(0)).getMesh()); + scene.setMaterial(mat); + scene.setShadowMode(ShadowMode.CastAndReceive); + scene.setLocalScale(400); + scene.setLocalTranslation(0, -10, -120); + + rootNode.attachChild(scene); + + // load sky + rootNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/FullskiesBlueClear03.dds", + SkyFactory.EnvMapType.CubeMap)); + + DirectionalLight sun = new DirectionalLight(); + Vector3f lightDir = new Vector3f(-0.12f, -0.3729129f, 0.74847335f); + sun.setDirection(lightDir); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + scene.addLight(sun); + + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + int numSamples = getContext().getSettings().getSamples(); + if (numSamples > 0) { + fpp.setNumSamples(numSamples); + } + Vector3f lightPos = lightDir.multLocal(-3000); + LightScatteringFilter filter = new LightScatteringFilter(lightPos); + LightScatteringUI ui = new LightScatteringUI(inputManager, filter); + fpp.addFilter(filter); + viewPort.addProcessor(fpp); + } + + @Override + public void simpleUpdate(float tpf) { + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java b/jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java new file mode 100644 index 0000000000..a5422ac539 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.post.SceneProcessor; +import com.jme3.profile.AppProfiler; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture2D; +import com.jme3.ui.Picture; + +/** + * Demonstrates rendering to multiple texture targets of a single FrameBuffer. + * + *

The GUI viewport is tiled into 4 pictures, + * each displaying a different render of 5 colorful cubes in the main scene. + */ +public class TestMultiRenderTarget extends SimpleApplication implements SceneProcessor { + private FrameBuffer fb; + /** + * Displays the merged RGB (normal color) output

    + *
  • from "ExtractRGB.frag" location 3,
  • + *
  • in the lower-left quadrant of the window.
+ */ + private Picture display1; + /** + * Displays the red-channel output in color
    + *
  • from "ExtractRGB.frag" location 0,
  • + *
  • in the upper-left quadrant of the window.
+ */ + private Picture display2; + /** + * Displays the green-channel output in monochrome
    + *
  • from ExtractRGB.frag location 1,
  • + *
  • in the upper-right quadrant of the window.
+ */ + private Picture display3; + /** + * Displays the blue-channel output in monochrome
    + *
  • from ExtractRGB.frag location 2,
  • + *
  • in the lower-right quadrant of the window.
+ */ + private Picture display4; + + private boolean initialized = false; + + /** + * The main entry point for the TestMultiRenderTarget application. + * + * @param args unused + */ + public static void main(String[] args) { + TestMultiRenderTarget app = new TestMultiRenderTarget(); + app.start(); + } + + /** + * Add 5 colorful cubes to the main scene. + */ + protected void buildScene() { + Geometry cube1 = buildCube(ColorRGBA.Red); + cube1.setLocalTranslation(-1f, 0f, 0f); + Geometry cube2 = buildCube(ColorRGBA.Green); + cube2.setLocalTranslation(0f, 0f, 0f); + Geometry cube3 = buildCube(ColorRGBA.Blue); + cube3.setLocalTranslation(1f, 0f, 0f); + + Geometry cube4 = buildCube(ColorRGBA.randomColor()); + cube4.setLocalTranslation(-0.5f, 1f, 0f); + Geometry cube5 = buildCube(ColorRGBA.randomColor()); + cube5.setLocalTranslation(0.5f, 1f, 0f); + + rootNode.attachChild(cube1); + rootNode.attachChild(cube2); + rootNode.attachChild(cube3); + rootNode.attachChild(cube4); + rootNode.attachChild(cube5); + } + + /** + * Create a cube with the specified color, + * using a custom unshaded material that outputs 4 textures:
    + *
  • red channel only to location 0,
  • + *
  • green channel only to location 1,
  • + *
  • blue channel only to location 2,
  • + *
  • merged RGB to location 3.
+ * + * @param color the desired albedo color (alias created) + * @return a new Geometry with no parent + */ + private Geometry buildCube(ColorRGBA color) { + Geometry cube = new Geometry("Box", new Box(0.5f, 0.5f, 0.5f)); + Material mat = new Material(assetManager, "TestMRT/MatDefs/ExtractRGB.j3md"); + mat.setColor("Albedo", color); + cube.setMaterial(mat); + return cube; + } + + @Override + public void simpleInitApp() { + viewPort.addProcessor(this); + buildScene(); + + display1 = new Picture("Picture"); + display1.move(0, 0, -1); // make it appear behind stats view + display2 = (Picture) display1.clone(); + display3 = (Picture) display1.clone(); + display4 = (Picture) display1.clone(); + } + + @Override + public void destroy() { + viewPort.removeProcessor(this); + super.destroy(); + } + + // Scene Processor from now on + @Override + public void initialize(RenderManager rm, ViewPort vp) { + reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight()); + viewPort.setOutputFrameBuffer(fb); + guiViewPort.setClearFlags(true, true, true); + + guiNode.attachChild(display1); + guiNode.attachChild(display2); + guiNode.attachChild(display3); + guiNode.attachChild(display4); + guiNode.updateGeometricState(); + } + + @Override + public void reshape(ViewPort vp, int w, int h) { + // You can use multiple channel formats as well. That's why red is using RGBA8 as an example. + Texture2D redTexture = new Texture2D(w, h, Format.RGBA8); // color texture + Texture2D greenTexture = new Texture2D(w, h, Format.Luminance8); // monochrome texture + Texture2D blueTexture = new Texture2D(w, h, Format.Luminance8); // monochrome texture + Texture2D rgbTexture = new Texture2D(w, h, Format.RGBA8); // color texture + + fb = new FrameBuffer(w, h, 1); + fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(redTexture)); // location 0 + fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(greenTexture)); // location 1 + fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(blueTexture)); // location 2 + fb.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(rgbTexture)); // location 3 + fb.setMultiTarget(true); + + display1.setTexture(assetManager, rgbTexture, false); + display2.setTexture(assetManager, redTexture, false); + display3.setTexture(assetManager, greenTexture, false); + display4.setTexture(assetManager, blueTexture, false); + + display1.setPosition(0, 0); // lower-left quadrant + display1.setWidth(w / 2f); + display1.setHeight(h / 2f); + + display2.setPosition(0, h / 2f); // upper-left quadrant + display2.setWidth(w / 2f); + display2.setHeight(h / 2f); + + display3.setPosition(w / 2f, h / 2f); // upper-right quadrant + display3.setWidth(w / 2f); + display3.setHeight(h / 2f); + + display4.setPosition(w / 2f, 0f); // lower-right quadrant + display4.setWidth(w / 2f); + display4.setHeight(h / 2f); + + guiNode.updateGeometricState(); + initialized = true; + } + + @Override + public boolean isInitialized() { + return initialized; + } + + @Override + public void preFrame(float tpf) { + } + + @Override + public void postQueue(RenderQueue rq) { + } + + @Override + public void postFrame(FrameBuffer out) { + } + + @Override + public void cleanup() { + initialized = false; + } + + @Override + public void setProfiler(AppProfiler profiler) { + // not implemented + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java b/jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java new file mode 100644 index 0000000000..fe0484ece5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestMultiViewsFilters.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.*; +import com.jme3.post.ssao.SSAOFilter; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.util.SkyFactory; + +public class TestMultiViewsFilters extends SimpleApplication { + + public static void main(String[] args) { + TestMultiViewsFilters app = new TestMultiViewsFilters(); + app.start(); + } + private boolean filterEnabled = true; + + @Override + public void simpleInitApp() { + // create the geometry and attach it + Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + teaGeom.scale(3); + teaGeom.getMaterial().setColor("GlowColor", ColorRGBA.Green); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White); + dl.setDirection(Vector3f.UNIT_XYZ.negate()); + + rootNode.addLight(dl); + rootNode.attachChild(teaGeom); + + // Setup first view + cam.setViewPort(.5f, 1f, 0f, 0.5f); + cam.setLocation(new Vector3f(3.3212643f, 4.484704f, 4.2812433f)); + cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f)); + + // Setup second view + Camera cam2 = cam.clone(); + cam2.setViewPort(0f, 0.5f, 0f, 0.5f); + cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f)); + cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f)); + + final ViewPort view2 = renderManager.createMainView("Bottom Left", cam2); + view2.setClearFlags(true, true, true); + view2.attachScene(rootNode); + + // Setup third view + Camera cam3 = cam.clone(); + cam3.setName("cam3"); + cam3.setViewPort(0f, .5f, .5f, 1f); + cam3.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f)); + cam3.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f)); + + final ViewPort view3 = renderManager.createMainView("Top Left", cam3); + view3.setClearFlags(true, true, true); + view3.attachScene(rootNode); + + + // Setup fourth view + Camera cam4 = cam.clone(); + cam4.setName("cam4"); + cam4.setViewPort(.5f, 1f, .5f, 1f); + + cam4.setLocation(new Vector3f(4.775564f, 1.4548365f, 0.11491505f)); + cam4.setRotation(new Quaternion(0.02356979f, -0.74957186f, 0.026729556f, 0.66096294f)); + + final ViewPort view4 = renderManager.createMainView("Top Right", cam4); + view4.setClearFlags(true, true, true); + view4.attachScene(rootNode); + +// Camera cam5 = new Camera(200, 200); +// cam5.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f); +// cam5.setName("cam5"); +// cam5.setViewPort(5.23f, 6.33f, 0.56f, 1.66f); +// this.setViewPortAreas(5.23f, 6.33f, 0.56f, 1.66f); +// this.setViewPortCamSize(200, 200); +// 1046,1266,112,332 + Camera cam5 = cam.clone(); + cam5.setName("cam5"); + cam5.setViewPort(1046f/settings.getWidth(), 1266f/settings.getWidth(), 112f/settings.getHeight(), 332f/settings.getHeight()); + cam5.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f)); + cam5.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f)); + + final ViewPort view5 = renderManager.createMainView("center", cam5); + view5.setClearFlags(true, true, true); + view5.attachScene(rootNode); + + + + rootNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + + final FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + final FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager); + final FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager); + final FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager); + final FilterPostProcessor fpp5 = new FilterPostProcessor(assetManager); + + + // fpp.addFilter(new WaterFilter(rootNode, Vector3f.UNIT_Y.mult(-1))); + fpp3.addFilter(new CartoonEdgeFilter()); + + fpp2.addFilter(new CrossHatchFilter()); + final FogFilter ff = new FogFilter(ColorRGBA.Yellow, 0.7f, 2); + fpp.addFilter(ff); + + final RadialBlurFilter rbf = new RadialBlurFilter(1, 10); + // rbf.setEnabled(false); + fpp.addFilter(rbf); + + + SSAOFilter f = new SSAOFilter(1.8899765f, 20.490374f, 0.4699998f, 0.1f); + fpp4.addFilter(f); + SSAOUI ui = new SSAOUI(inputManager, f); + + fpp5.addFilter(new BloomFilter(BloomFilter.GlowMode.Objects)); + + viewPort.addProcessor(fpp); + view2.addProcessor(fpp2); + view3.addProcessor(fpp3); + view4.addProcessor(fpp4); + view5.addProcessor(fpp5); + + + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals("press") && isPressed) { + if (filterEnabled) { + viewPort.removeProcessor(fpp); + view2.removeProcessor(fpp2); + view3.removeProcessor(fpp3); + view4.removeProcessor(fpp4); + view5.removeProcessor(fpp5); + } else { + viewPort.addProcessor(fpp); + view2.addProcessor(fpp2); + view3.addProcessor(fpp3); + view4.addProcessor(fpp4); + view5.addProcessor(fpp5); + } + filterEnabled = !filterEnabled; + } + if (name.equals("filter") && isPressed) { + ff.setEnabled(!ff.isEnabled()); + rbf.setEnabled(!rbf.isEnabled()); + } + } + }, "press", "filter"); + + inputManager.addMapping("press", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("filter", new KeyTrigger(KeyInput.KEY_F)); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java b/jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java new file mode 100644 index 0000000000..0d150bfe1a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestMultiplesFilters.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.asset.plugins.ZipLocator; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.post.filters.ColorOverlayFilter; +import com.jme3.post.ssao.SSAOFilter; +import com.jme3.scene.Spatial; +import com.jme3.util.SkyFactory; +import com.jme3.water.WaterFilter; +import java.io.File; + +public class TestMultiplesFilters extends SimpleApplication { + + private static boolean useHttp = false; + + public static void main(String[] args) { + TestMultiplesFilters app = new TestMultiplesFilters(); + app.start(); + } + private SSAOFilter ssaoFilter; + + @Override + public void simpleInitApp() { + File file = new File("wildhouse.zip"); + if (!file.exists()) { + useHttp = true; + } + + this.flyCam.setMoveSpeed(10); + cam.setLocation(new Vector3f(6.0344796f, 1.5054002f, 55.572033f)); + cam.setRotation(new Quaternion(0.0016069f, 0.9810479f, -0.008143323f, 0.19358753f)); + + // load sky + rootNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + + // create the geometry and attach it + // load the level from zip or http zip + if (useHttp) { + assetManager.registerLocator( + "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", + HttpZipLocator.class); + } else { + assetManager.registerLocator("wildhouse.zip", ZipLocator.class); + } + Spatial scene = assetManager.loadModel("main.scene"); + + + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f)); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + scene.addLight(sun); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + // fpp.setNumSamples(4); + ssaoFilter = new SSAOFilter(0.92f, 2.2f, 0.46f, 0.2f); + final WaterFilter water=new WaterFilter(rootNode,new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f)); + water.setWaterHeight(-20); + SSAOUI ui=new SSAOUI(inputManager,ssaoFilter); + final BloomFilter bloom = new BloomFilter(); + final ColorOverlayFilter overlay = new ColorOverlayFilter(ColorRGBA.LightGray); + + + fpp.addFilter(ssaoFilter); + + fpp.addFilter(water); + + fpp.addFilter(bloom); + + fpp.addFilter(overlay); + + viewPort.addProcessor(fpp); + + rootNode.attachChild(scene); + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if ("toggleSSAO".equals(name) && isPressed) { + if (ssaoFilter.isEnabled()) { + ssaoFilter.setEnabled(false); + } else { + ssaoFilter.setEnabled(true); + } + } + if ("toggleWater".equals(name) && isPressed) { + if (water.isEnabled()) { + water.setEnabled(false); + } else { + water.setEnabled(true); + } + } + if ("toggleBloom".equals(name) && isPressed) { + if (bloom.isEnabled()) { + bloom.setEnabled(false); + } else { + bloom.setEnabled(true); + } + } + if ("toggleOverlay".equals(name) && isPressed) { + if (overlay.isEnabled()) { + overlay.setEnabled(false); + } else { + overlay.setEnabled(true); + } + } + } + }, "toggleSSAO", "toggleBloom", "toggleWater","toggleOverlay"); + inputManager.addMapping("toggleSSAO", new KeyTrigger(KeyInput.KEY_1)); + inputManager.addMapping("toggleWater", new KeyTrigger(KeyInput.KEY_2)); + inputManager.addMapping("toggleBloom", new KeyTrigger(KeyInput.KEY_3)); + inputManager.addMapping("toggleOverlay", new KeyTrigger(KeyInput.KEY_4)); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestPostFilters.java b/jme3-examples/src/main/java/jme3test/post/TestPostFilters.java new file mode 100644 index 0000000000..b7f6658ce7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestPostFilters.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.*; +import com.jme3.renderer.Caps; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.texture.Texture; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; +import com.jme3.util.TangentBinormalGenerator; + +public class TestPostFilters extends SimpleApplication implements ActionListener { + + private FilterPostProcessor fpp; + final private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); + private FadeFilter fade; + + public static void main(String[] args) { + TestPostFilters app = new TestPostFilters(); +// AppSettings settings = new AppSettings(true); +// settings.setRenderer(AppSettings.LWJGL_OPENGL2); +// app.setSettings(settings); + app.start(); + } + + public void setupFilters() { + if (renderer.getCaps().contains(Caps.GLSL100)) { + fpp = new FilterPostProcessor(assetManager); + // fpp.setNumSamples(4); + // fpp.setNumSamples(4); + //fpp.addFilter(new ColorOverlayFilter(ColorRGBA.LightGray)); + fpp.addFilter(new RadialBlurFilter()); + fade = new FadeFilter(1.0f); + fpp.addFilter(fade); + + + viewPort.addProcessor(fpp); + } + } + + public void setupSkyBox() { + Texture envMap; + if (renderer.getCaps().contains(Caps.FloatTexture)) { + envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.hdr"); + } else { + envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.jpg"); + } + Spatial sky = SkyFactory.createSky(assetManager, envMap, + new Vector3f(-1f, -1f, -1f), EnvMapType.SphereMap); + rootNode.attachChild(sky); + } + + public void setupLighting() { + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(lightDir); + + dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1)); + + rootNode.addLight(dl); + + dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1, 0, -1).normalizeLocal()); + + dl.setColor(new ColorRGBA(.4f, .4f, .4f, 1)); + + // rootNode.addLight(dl); + } + + public void setupFloor() { + Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); + Box floor = new Box(50, 1f, 50); + TangentBinormalGenerator.generate(floor); + floor.scaleTextureCoordinates(new Vector2f(5, 5)); + Geometry floorGeom = new Geometry("Floor", floor); + floorGeom.setMaterial(mat); + floorGeom.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(floorGeom); + } + + public void setupSignpost() { + Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); + Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + signpost.setMaterial(mat); + signpost.rotate(0, FastMath.HALF_PI, 0); + signpost.setLocalTranslation(12, 3.5f, 30); + signpost.setLocalScale(4); + signpost.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(signpost); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(-32.295086f, 54.80136f, 79.59805f)); + cam.setRotation(new Quaternion(0.074364014f, 0.92519957f, -0.24794696f, 0.27748522f)); + + setupLighting(); + setupSkyBox(); + + + setupFloor(); + + setupSignpost(); + + setupFilters(); + + initInput(); + + } + + protected void initInput() { + flyCam.setMoveSpeed(50); + //init input + inputManager.addMapping("fadein", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addListener(this, "fadein"); + inputManager.addMapping("fadeout", new KeyTrigger(KeyInput.KEY_O)); + inputManager.addListener(this, "fadeout"); + + } + + @Override + public void onAction(String name, boolean value, float tpf) { + if (name.equals("fadein") && value) { + fade.fadeIn(); + System.out.println("fade in"); + + } + if (name.equals("fadeout") && value) { + fade.fadeOut(); + System.out.println("fade out"); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java b/jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java new file mode 100644 index 0000000000..8661ee550e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestPostFiltersCompositing.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.ColorOverlayFilter; +import com.jme3.post.filters.ComposeFilter; +import com.jme3.scene.Spatial; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image; +import com.jme3.texture.Texture2D; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; +import com.jme3.texture.Image.Format; +import com.jme3.util.SkyFactory; + +/** + * This test showcases the possibility to compose the post filtered outputs of several viewports. + * The usual use case is when you want to apply some post process to the main viewport and then other post process to the gui viewport + * @author Nehon + */ +public class TestPostFiltersCompositing extends SimpleApplication { + + public static void main(String[] args) { + TestPostFiltersCompositing app = new TestPostFiltersCompositing(); +// AppSettings settings = new AppSettings(true); +// settings.putBoolean("GraphicsDebug", false); +// app.setSettings(settings); + app.start(); + + } + + @Override + public void simpleInitApp() { + this.flyCam.setMoveSpeed(10); + cam.setLocation(new Vector3f(0.028406568f, 2.015769f, 7.386517f)); + cam.setRotation(new Quaternion(-1.0729783E-5f, 0.9999721f, -0.0073241726f, -0.0014647911f)); + + + makeScene(); + + //Creating the main view port post processor + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(new ColorOverlayFilter(ColorRGBA.Blue)); + viewPort.addProcessor(fpp); + + //creating a frame buffer for the main viewport + FrameBuffer mainVPFrameBuffer = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); + Texture2D mainVPTexture = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); + mainVPFrameBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); + mainVPFrameBuffer.addColorTarget(FrameBufferTarget.newTarget(mainVPTexture)); + + viewPort.setOutputFrameBuffer(mainVPFrameBuffer); + + // Create the post processor for the GUI viewport. + final FilterPostProcessor guiFpp = new FilterPostProcessor(assetManager); + guiFpp.setFrameBufferFormat(Image.Format.RGBA8); + guiFpp.addFilter(new ColorOverlayFilter(ColorRGBA.Red)); + // This will compose the main viewport texture with the GUI-viewport back buffer. + // Note that you can switch the order of the filters so that GUI-viewport filters are applied or not to the main viewport texture + guiFpp.addFilter(new ComposeFilter(mainVPTexture)); + + guiViewPort.addProcessor(guiFpp); + + // Compositing is done by mixing texture depending on the alpha channel, so + // it's important that the GUI-viewport clear-color alpha value is set to 0. + guiViewPort.setBackgroundColor(ColorRGBA.BlackNoAlpha); + guiViewPort.setClearColor(true); + + + } + + private void makeScene() { + // load sky + rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap)); + //assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/wildhouse.zip", HttpZipLocator.class); + Spatial scene = assetManager.loadModel("Models/Test/CornellBox.j3o"); + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f)); + scene.addLight(sun); + rootNode.attachChild(scene); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestPosterization.java b/jme3-examples/src/main/java/jme3test/post/TestPosterization.java new file mode 100644 index 0000000000..aebb415a07 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestPosterization.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.PosterizationFilter; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.util.SkyFactory; + +public class TestPosterization extends SimpleApplication { + + private PosterizationFilter pf; + + public static void main(String[] args){ + TestPosterization app = new TestPosterization(); + app.start(); + } + + @Override + public void simpleInitApp() { + // put the camera in a bad position + cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f)); + cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f)); + + Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); + mat.setFloat("Shininess", 15f); + mat.setBoolean("UseMaterialColors", true); + mat.setColor("Ambient", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Diffuse", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Specular", ColorRGBA.Yellow.mult(0.8f)); + + Material matSoil = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); + matSoil.setFloat("Shininess", 15f); + matSoil.setBoolean("UseMaterialColors", true); + matSoil.setColor("Ambient", ColorRGBA.Gray); + matSoil.setColor("Diffuse", ColorRGBA.Black); + matSoil.setColor("Specular", ColorRGBA.Gray); + + Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); + teapot.setLocalTranslation(0,0,10); + + teapot.setMaterial(mat); + teapot.setShadowMode(ShadowMode.CastAndReceive); + teapot.setLocalScale(10.0f); + rootNode.attachChild(teapot); + + Geometry soil = new Geometry("soil", new Box(800, 10, 700)); + soil.setLocalTranslation(0, -13, 550); + soil.setMaterial(matSoil); + soil.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(soil); + + DirectionalLight light=new DirectionalLight(); + light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + light.setColor(ColorRGBA.White.mult(1.5f)); + rootNode.addLight(light); + + // load sky + Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/FullskiesBlueClear03.dds", SkyFactory.EnvMapType.CubeMap); + sky.setCullHint(Spatial.CullHint.Never); + rootNode.attachChild(sky); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + int numSamples = getContext().getSettings().getSamples(); + if (numSamples > 0) { + fpp.setNumSamples(numSamples); + } + pf = new PosterizationFilter(); + fpp.addFilter(pf); + + viewPort.addProcessor(fpp); + initInputs(); + + } + + private void initInputs() { + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + + ActionListener acl = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggle") && keyPressed) { + pf.setEnabled(!pf.isEnabled()); + } + } + }; + + inputManager.addListener(acl, "toggle"); + + } + + + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java b/jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java new file mode 100644 index 0000000000..da00ccecd5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestRenderToCubemap.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.TextureCubeMap; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; + +/** + * Renders a rotating box to a cubemap texture, then applies the cubemap + * texture as a sky. + */ +public class TestRenderToCubemap extends SimpleApplication { + + private Geometry offBox; + private float angle = 0; + + public static void main(String[] args){ + TestRenderToCubemap app = new TestRenderToCubemap(); + app.start(); + } + + public Texture setupOffscreenView(){ + Camera offCamera = new Camera(512, 512); + + ViewPort offView + = renderManager.createPreView("Offscreen View", offCamera); + offView.setClearFlags(true, true, true); + offView.setBackgroundColor(ColorRGBA.DarkGray); + + // create offscreen framebuffer + FrameBuffer offBuffer = new FrameBuffer(512, 512, 1); + + //setup framebuffer's cam + offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f); + offCamera.setLocation(new Vector3f(0f, 0f, -5f)); + offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); + + //setup framebuffer's texture + TextureCubeMap offTex = new TextureCubeMap(512, 512, Format.RGBA8); + offTex.setMinFilter(Texture.MinFilter.Trilinear); + offTex.setMagFilter(Texture.MagFilter.Bilinear); + + //setup framebuffer to use texture + offBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); + offBuffer.setMultiTarget(true); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.NegativeX)); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.PositiveX)); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.NegativeY)); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.PositiveY)); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.NegativeZ)); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex, TextureCubeMap.Face.PositiveZ)); + + //set viewport to render to offscreen framebuffer + offView.setOutputFrameBuffer(offBuffer); + + // setup framebuffer's scene + Box boxMesh = new Box( 1,1,1); + Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); + offBox = new Geometry("box", boxMesh); + offBox.setMaterial(material); + + // attach the scene to the viewport to be rendered + offView.attachScene(offBox); + + return offTex; + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(3, 3, 3)); + cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + + Texture offTex = setupOffscreenView(); + Spatial sky = SkyFactory.createSky(assetManager, offTex, + EnvMapType.CubeMap); + rootNode.attachChild(sky); + } + + @Override + public void simpleUpdate(float tpf){ + Quaternion q = new Quaternion(); + + angle += tpf; + angle %= FastMath.TWO_PI; + q.fromAngles(angle, 0, angle); + + offBox.setLocalRotation(q); + offBox.updateLogicalState(tpf); + offBox.updateGeometricState(); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java b/jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java new file mode 100644 index 0000000000..1cfa50b9a2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.SceneProcessor; +import com.jme3.profile.AppProfiler; +import com.jme3.renderer.Camera; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeContext.Type; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; +import com.jme3.texture.Image.Format; +import com.jme3.util.BufferUtils; +import com.jme3.util.Screenshots; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.nio.ByteBuffer; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/** + * This test renders a scene to an offscreen framebuffer, then copies + * the contents to a Swing JFrame. Note that some parts are done inefficiently, + * this is done to make the code more readable. + */ +public class TestRenderToMemory extends SimpleApplication implements SceneProcessor { + + private Geometry offBox; + private float angle = 0; + + private FrameBuffer offBuffer; + private ImageDisplay display; + + private static final int width = 800, height = 600; + + private final ByteBuffer cpuBuf = BufferUtils.createByteBuffer(width * height * 4); + private final BufferedImage image = new BufferedImage(width, height, + BufferedImage.TYPE_INT_BGR); + + private class ImageDisplay extends JPanel { + + private long t; + private long total; + private int frames; + private int fps; + + @Override + public void paintComponent(Graphics gfx) { + super.paintComponent(gfx); + Graphics2D g2d = (Graphics2D) gfx; + + if (t == 0) + t = timer.getTime(); + +// g2d.setBackground(Color.BLACK); +// g2d.clearRect(0,0,width,height); + + synchronized (image){ + g2d.drawImage(image, null, 0, 0); + } + + long t2 = timer.getTime(); + long dt = t2 - t; + total += dt; + frames ++; + t = t2; + + if (total > timer.getResolution()) { + fps = frames; + total = 0; + frames = 0; + } + + g2d.setColor(Color.white); + g2d.drawString("FPS: "+fps, 0, getHeight() - 100); + } + } + + public static void main(String[] args){ + TestRenderToMemory app = new TestRenderToMemory(); + app.setPauseOnLostFocus(false); + AppSettings settings = new AppSettings(true); + settings.setResolution(1, 1); + app.setSettings(settings); + app.start(Type.OffscreenSurface); + } + + public void createDisplayFrame(){ + SwingUtilities.invokeLater(new Runnable(){ + @Override + public void run(){ + JFrame frame = new JFrame("Render Display"); + display = new ImageDisplay(); + display.setPreferredSize(new Dimension(width, height)); + frame.getContentPane().add(display); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.addWindowListener(new WindowAdapter(){ + @Override + public void windowClosed(WindowEvent e){ + stop(); + } + }); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setResizable(false); + frame.setVisible(true); + } + }); + } + + public void updateImageContents(){ + cpuBuf.clear(); + renderer.readFrameBuffer(offBuffer, cpuBuf); + + synchronized (image) { + Screenshots.convertScreenShot2(cpuBuf.asIntBuffer(), image); + } + + if (display != null) + display.repaint(); + } + + public void setupOffscreenView(){ + Camera offCamera = new Camera(width, height); + + // create a pre-view. a view that is rendered before the main view + ViewPort offView + = renderManager.createPreView("Offscreen View", offCamera); + offView.setBackgroundColor(ColorRGBA.DarkGray); + offView.setClearFlags(true, true, true); + + // this will let us know when the scene has been rendered to the + // frame buffer + offView.addProcessor(this); + + // create offscreen framebuffer + offBuffer = new FrameBuffer(width, height, 1); + + //setup framebuffer's cam + offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f); + offCamera.setLocation(new Vector3f(0f, 0f, -5f)); + offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); + + //setup framebuffer's texture +// offTex = new Texture2D(width, height, Format.RGBA8); + + //setup framebuffer to use renderbuffer + // this is faster for gpu -> cpu copies + offBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(Format.RGBA8)); + + //set viewport to render to offscreen framebuffer + offView.setOutputFrameBuffer(offBuffer); + + // setup framebuffer's scene + Box boxMesh = new Box(1, 1, 1); + Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); + offBox = new Geometry("box", boxMesh); + offBox.setMaterial(material); + + // attach the scene to the viewport to be rendered + offView.attachScene(offBox); + } + + @Override + public void simpleInitApp() { + setupOffscreenView(); + createDisplayFrame(); + } + + @Override + public void simpleUpdate(float tpf){ + Quaternion q = new Quaternion(); + angle += tpf; + angle %= FastMath.TWO_PI; + q.fromAngles(angle, 0, angle); + + offBox.setLocalRotation(q); + offBox.updateLogicalState(tpf); + offBox.updateGeometricState(); + } + + @Override + public void initialize(RenderManager rm, ViewPort vp) { + } + + @Override + public void reshape(ViewPort vp, int w, int h) { + } + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public void preFrame(float tpf) { + } + + @Override + public void postQueue(RenderQueue rq) { + } + + /** + * Update the CPU image's contents after the scene has + * been rendered to the framebuffer. + */ + @Override + public void postFrame(FrameBuffer out) { + updateImageContents(); + } + + @Override + public void cleanup() { + } + + @Override + public void setProfiler(AppProfiler profiler) { + // not implemented + } + + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java b/jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java new file mode 100644 index 0000000000..88de57274d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestRenderToTexture.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; + +/** + * This test renders a scene to a texture, then displays the texture on a cube. + */ +public class TestRenderToTexture extends SimpleApplication implements ActionListener { + + private static final String TOGGLE_UPDATE = "Toggle Update"; + private Geometry offBox; + private float angle = 0; + private ViewPort offView; + + public static void main(String[] args){ + TestRenderToTexture app = new TestRenderToTexture(); + app.start(); + } + + public Texture setupOffscreenView(){ + Camera offCamera = new Camera(512, 512); + + offView = renderManager.createPreView("Offscreen View", offCamera); + offView.setClearFlags(true, true, true); + offView.setBackgroundColor(ColorRGBA.DarkGray); + + // create offscreen framebuffer + FrameBuffer offBuffer = new FrameBuffer(512, 512, 1); + + //setup framebuffer's cam + offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f); + offCamera.setLocation(new Vector3f(0f, 0f, -5f)); + offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y); + + //setup framebuffer's texture + Texture2D offTex = new Texture2D(512, 512, Format.RGBA8); + offTex.setMinFilter(Texture.MinFilter.Trilinear); + offTex.setMagFilter(Texture.MagFilter.Bilinear); + + //setup framebuffer to use texture + offBuffer.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth)); + offBuffer.addColorTarget(FrameBufferTarget.newTarget(offTex)); + + //set viewport to render to offscreen framebuffer + offView.setOutputFrameBuffer(offBuffer); + + // setup framebuffer's scene + Box boxMesh = new Box(1, 1, 1); + Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m"); + offBox = new Geometry("box", boxMesh); + offBox.setMaterial(material); + + // attach the scene to the viewport to be rendered + offView.attachScene(offBox); + + return offTex; + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(3, 3, 3)); + cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + + //setup main scene + Geometry quad = new Geometry("box", new Box(1, 1, 1)); + + Texture offTex = setupOffscreenView(); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", offTex); + quad.setMaterial(mat); + rootNode.attachChild(quad); + inputManager.addMapping(TOGGLE_UPDATE, new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(this, TOGGLE_UPDATE); + } + + @Override + public void simpleUpdate(float tpf){ + Quaternion q = new Quaternion(); + + if (offView.isEnabled()) { + angle += tpf; + angle %= FastMath.TWO_PI; + q.fromAngles(angle, 0, angle); + + offBox.setLocalRotation(q); + offBox.updateLogicalState(tpf); + offBox.updateGeometricState(); + } + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (name.equals(TOGGLE_UPDATE) && isPressed) { + offView.setEnabled(!offView.isEnabled()); + } + } + + +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestSSAO.java b/jme3-examples/src/main/java/jme3test/post/TestSSAO.java new file mode 100644 index 0000000000..9275feb23d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestSSAO.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.ssao.SSAOFilter; +import com.jme3.scene.Geometry; +import com.jme3.texture.Texture; + +public class TestSSAO extends SimpleApplication { + + public static void main(String[] args) { + TestSSAO app = new TestSSAO(); + app.start(); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(68.45442f, 8.235511f, 7.9676695f)); + cam.setRotation(new Quaternion(0.046916496f, -0.69500375f, 0.045538206f, 0.7160271f)); + + + flyCam.setMoveSpeed(50); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + Texture diff = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"); + diff.setWrap(Texture.WrapMode.Repeat); + Texture norm = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall_normal.jpg"); + norm.setWrap(Texture.WrapMode.Repeat); + mat.setTexture("DiffuseMap", diff); + mat.setTexture("NormalMap", norm); + mat.setFloat("Shininess", 2.0f); + + + AmbientLight al = new AmbientLight(); + al.setColor(new ColorRGBA(1.8f, 1.8f, 1.8f, 1.0f)); + + rootNode.addLight(al); + + Geometry model + = (Geometry) assetManager.loadModel("Models/Sponza/Sponza.j3o"); + model.getMesh().scaleTextureCoordinates(new Vector2f(2, 2)); + + model.setMaterial(mat); + + rootNode.attachChild(model); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + SSAOFilter ssaoFilter = new SSAOFilter(2.9299974f,32.920483f,5.8100376f,0.091000035f); + ssaoFilter.setApproximateNormals(true); + fpp.addFilter(ssaoFilter); + SSAOUI ui = new SSAOUI(inputManager, ssaoFilter); + + viewPort.addProcessor(fpp); + } + + @Override + public void simpleUpdate(float tpf) { + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestSSAO2.java b/jme3-examples/src/main/java/jme3test/post/TestSSAO2.java new file mode 100644 index 0000000000..34fe62e27c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestSSAO2.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.*; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.app.DetailedProfilerState; +import com.jme3.post.ssao.SSAOFilter; +import com.jme3.scene.*; +import com.jme3.scene.shape.Box; + +public class TestSSAO2 extends SimpleApplication { + + public static void main(String[] args) { + TestSSAO2 app = new TestSSAO2(); + app.start(); + } + + @Override + public void simpleInitApp() { + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1,-1,-1).normalizeLocal()); + rootNode.addLight(dl); + + flyCam.setDragToRotate(true); + setPauseOnLostFocus(false); + + getStateManager().attach(new DetailedProfilerState()); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + mat.setFloat("Shininess", 16f); + //mat.setBoolean("VertexLighting", true); + + + Geometry floor = new Geometry("floor", new Box(1000,0.1f,1000)); + floor.setMaterial(mat); + rootNode.attachChild(floor); + + Node teapotNode = (Node) assetManager.loadModel("Models/Teapot/Teapot.mesh.xml"); + Geometry teapot = (Geometry) teapotNode.getChild(0); + teapot.setMaterial(mat); +// Sphere sph = new Sphere(16, 16, 4); +// Geometry teapot = new Geometry("teapot", sph); + + + + // A special Material to visualize mesh normals: + //Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + for (int f = 10; f > 3; f--) { + for (int y = -f; y < f; y++) { + for (int x = -f; x < f; x++) { + Geometry clonePot = teapot.clone(); + + //clonePot.setMaterial(mat); + clonePot.setLocalTranslation(x * .5f, 10 - f, y * .5f); + clonePot.setLocalScale(.15f); + + rootNode.attachChild(clonePot); + } + } + } + + cam.setLocation(new Vector3f(10.247649f, 8.275992f, 10.405156f)); + cam.setRotation(new Quaternion(-0.083419204f, 0.90370524f, -0.20599906f, -0.36595422f)); + + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + SSAOFilter ssaoFilter = new SSAOFilter(2.9299974f,25f,5.8100376f,0.091000035f); + int numSamples = context.getSettings().getSamples(); + if (numSamples > 0) { + fpp.setNumSamples(numSamples); + } + + //ssaoFilter.setApproximateNormals(true); + fpp.addFilter(ssaoFilter); + SSAOUI ui = new SSAOUI(inputManager, ssaoFilter); + + viewPort.addProcessor(fpp); + } + + @Override + public void simpleUpdate(float tpf) { + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java b/jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java new file mode 100644 index 0000000000..b886829650 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestToneMapFilter.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.ToneMapFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; + +public class TestToneMapFilter extends SimpleApplication { + + private boolean enabled = true; + private FilterPostProcessor fpp; + private ToneMapFilter toneMapFilter; + private float whitePointLog = 1f; + + public static void main(String[] args){ + TestToneMapFilter app = new TestToneMapFilter(); + AppSettings settings = new AppSettings(true); + + // Must turn on gamma correction, as otherwise it looks too dark. + settings.setGammaCorrection(true); + + app.setSettings(settings); + app.start(); + } + + public Geometry createHDRBox(){ + Box boxMesh = new Box(1, 1, 1); + Geometry box = new Geometry("Box", boxMesh); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Textures/HdrTest/Memorial.hdr")); + box.setMaterial(mat); + return box; + } + + @Override + public void simpleInitApp() { + System.out.println("== Tone Mapping Sample =="); + System.out.println(" SPACE:\tToggle tone-mapping OFF or ON"); + System.out.println(" Y:\tIncrease white-point"); + System.out.println(" H:\tDecrease white-point"); + + fpp = new FilterPostProcessor(assetManager); + toneMapFilter = new ToneMapFilter(); + fpp.addFilter(toneMapFilter); + viewPort.addProcessor(fpp); + + rootNode.attachChild(createHDRBox()); + + cam.setLocation(new Vector3f(0f,0f,3f)); + + initInputs(); + } + + private void initInputs() { + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addMapping("WhitePointUp", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("WhitePointDown", new KeyTrigger(KeyInput.KEY_H)); + + ActionListener acl = new ActionListener() { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggle") && keyPressed) { + if (enabled) { + enabled = false; + viewPort.removeProcessor(fpp); + System.out.println("Tone Mapping OFF"); + } else { + enabled = true; + viewPort.addProcessor(fpp); + System.out.println("Tone Mapping ON"); + } + } + } + }; + + AnalogListener anl = new AnalogListener() { + + @Override + public void onAnalog(String name, float isPressed, float tpf) { + if (name.equals("WhitePointUp")) { + whitePointLog += tpf * 1.0; + if (whitePointLog > 4f) { + whitePointLog = 4f; + } + float wp = FastMath.exp(whitePointLog); + toneMapFilter.setWhitePoint(new Vector3f(wp, wp, wp)); + System.out.println("White point: " + wp); + } + + if (name.equals("WhitePointDown")) { + whitePointLog -= tpf * 1.0; + if (whitePointLog < -4f) { + whitePointLog = -4f; + } + float wp = FastMath.exp(whitePointLog); + toneMapFilter.setWhitePoint(new Vector3f(wp, wp, wp)); + System.out.println("White point: " + wp); + } + } + }; + + inputManager.addListener(acl, "toggle"); + inputManager.addListener(anl, "WhitePointUp", "WhitePointDown"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java b/jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java new file mode 100644 index 0000000000..2e2c9874f7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestTransparentCartoonEdge.java @@ -0,0 +1,98 @@ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.CartoonEdgeFilter; +import com.jme3.renderer.queue.RenderQueue.Bucket; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.RectangleMesh; +import com.jme3.texture.Texture; + +public class TestTransparentCartoonEdge extends SimpleApplication { + + public static void main(String[] args){ + TestTransparentCartoonEdge app = new TestTransparentCartoonEdge(); + app.start(); + } + + @Override + public void simpleInitApp() { + renderManager.setAlphaToCoverage(true); + cam.setLocation(new Vector3f(0.14914267f, 0.58147097f, 4.7686534f)); + cam.setRotation(new Quaternion(-0.0044764364f, 0.9767943f, 0.21314798f, 0.020512417f)); + +// cam.setLocation(new Vector3f(2.0606942f, 3.20342f, 6.7860126f)); +// cam.setRotation(new Quaternion(-0.017481906f, 0.98241085f, -0.12393151f, -0.13857932f)); + + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + RectangleMesh rm = new RectangleMesh( + new Vector3f(-10, 0, 10), + new Vector3f(10, 0, 10), + new Vector3f(-10, 0, -10)); + rm.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(5)); + Geometry geom = new Geometry("floor", rm); + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + geom.setMaterial(mat); + geom.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(geom); + + // create the geometry and attach it + Spatial teaGeom = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); + teaGeom.setQueueBucket(Bucket.Transparent); + teaGeom.setShadowMode(ShadowMode.Cast); + makeToonish(teaGeom); + + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(2)); + rootNode.addLight(al); + + DirectionalLight dl1 = new DirectionalLight(); + dl1.setDirection(new Vector3f(1, -1, 1).normalizeLocal()); + dl1.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); + rootNode.addLight(dl1); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); + rootNode.addLight(dl); + + rootNode.attachChild(teaGeom); + + FilterPostProcessor fpp=new FilterPostProcessor(assetManager); + CartoonEdgeFilter toon=new CartoonEdgeFilter(); + toon.setEdgeWidth(0.5f); + toon.setEdgeIntensity(1.0f); + toon.setNormalThreshold(0.8f); + fpp.addFilter(toon); + viewPort.addProcessor(fpp); + } + + public void makeToonish(Spatial spatial){ + if (spatial instanceof Node){ + Node n = (Node) spatial; + for (Spatial child : n.getChildren()) + makeToonish(child); + }else if (spatial instanceof Geometry){ + Geometry g = (Geometry) spatial; + Material m = g.getMaterial(); + if (m.getMaterialDef().getName().equals("Phong Lighting")){ + Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png"); +// t.setMinFilter(Texture.MinFilter.NearestNoMipMaps); +// t.setMagFilter(Texture.MagFilter.Nearest); + m.setTexture("ColorRamp", t); + m.setBoolean("UseMaterialColors", true); + m.setColor("Specular", ColorRGBA.Black); + m.setColor("Diffuse", ColorRGBA.White); + m.setBoolean("VertexLighting", true); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java b/jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java new file mode 100644 index 0000000000..6694454a9b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java @@ -0,0 +1,78 @@ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.ssao.SSAOFilter; +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.scene.shape.RectangleMesh; +import com.jme3.util.TangentBinormalGenerator; + +public class TestTransparentSSAO extends SimpleApplication { + + public static void main(String[] args) { + TestTransparentSSAO app = new TestTransparentSSAO(); + app.start(); + } + + @Override + public void simpleInitApp() { + renderManager.setAlphaToCoverage(true); + cam.setLocation(new Vector3f(0.14914267f, 0.58147097f, 4.7686534f)); + cam.setRotation(new Quaternion(-0.0044764364f, 0.9767943f, 0.21314798f, 0.020512417f)); + +// cam.setLocation(new Vector3f(2.0606942f, 3.20342f, 6.7860126f)); +// cam.setRotation(new Quaternion(-0.017481906f, 0.98241085f, -0.12393151f, -0.13857932f)); + + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + + RectangleMesh rm = new RectangleMesh( + new Vector3f(-10, 0, 10), + new Vector3f(10, 0, 10), + new Vector3f(-10, 0, -10)); + rm.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(5)); + Geometry geom = new Geometry("floor", rm); + Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m"); + geom.setMaterial(mat); + + geom.setShadowMode(ShadowMode.Receive); + TangentBinormalGenerator.generate(geom); + rootNode.attachChild(geom); + + // create the geometry and attach it + Spatial teaGeom = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); + teaGeom.setQueueBucket(Bucket.Transparent); + teaGeom.setShadowMode(ShadowMode.Cast); + + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(2)); + rootNode.addLight(al); + + DirectionalLight dl1 = new DirectionalLight(); + dl1.setDirection(new Vector3f(1, -1, 1).normalizeLocal()); + dl1.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); + rootNode.addLight(dl1); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f)); + rootNode.addLight(dl); + + rootNode.attachChild(teaGeom); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + + SSAOFilter ssao = new SSAOFilter();//0.49997783f, 42.598858f, 35.999966f, 0.39299846f + fpp.addFilter(ssao); + + SSAOUI ui = new SSAOUI(inputManager, ssao); + + viewPort.addProcessor(fpp); + } +} diff --git a/jme3-examples/src/main/java/jme3test/post/package-info.java b/jme3-examples/src/main/java/jme3test/post/package-info.java new file mode 100644 index 0000000000..8b0450420a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for post-processing, including filters + */ +package jme3test.post; diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java b/jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java new file mode 100644 index 0000000000..d5e02ae7a9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestAlphaToCoverage.java @@ -0,0 +1,54 @@ +package jme3test.renderer; +import com.jme3.app.SimpleApplication; + +import com.jme3.renderer.lwjgl.LwjglGL; +import com.jme3.renderer.opengl.GL; +import com.jme3.renderer.opengl.GLExt; +import com.jme3.renderer.opengl.GLFbo; +import com.jme3.renderer.opengl.GLRenderer; +import com.jme3.renderer.lwjgl.LwjglGLExt; +import com.jme3.renderer.lwjgl.LwjglGLFboEXT; +import com.jme3.renderer.Caps; + +import java.util.EnumSet; + +/** + * Simple application to test the getter and setters of AlphaToCoverage and + * DefaultAnisotropicFilter from the GLRenderer class. + * + * Since the app doesn't display anything relevant a stop() has been added + * This starts and closes the app on a successful run + */ +public class TestAlphaToCoverage extends SimpleApplication { + + public static void main(String[] args) { + new TestAlphaToCoverage().start(); + } + + final private GL gl = new LwjglGL(); + final private GLExt glext = new LwjglGLExt(); + final private GLFbo glfbo = new LwjglGLFboEXT(); + final private GLRenderer glRenderer= new GLRenderer(gl,glext,glfbo); + + final private EnumSet caps = glRenderer.getCaps(); + + + + @Override + public void simpleInitApp() { + glRenderer.setAlphaToCoverage(false); + assert !glRenderer.getAlphaToCoverage(); + + caps.add(Caps.Multisample); + glRenderer.setAlphaToCoverage(true); + assert glRenderer.getAlphaToCoverage(); + glRenderer.setAlphaToCoverage(false); + assert !glRenderer.getAlphaToCoverage(); + + glRenderer.setDefaultAnisotropicFilter(1); + assert glRenderer.getDefaultAnisotropicFilter() == 1; + + stop(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java b/jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java new file mode 100644 index 0000000000..50a2377bef --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestAspectFov.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; +import com.jme3.util.TempVars; + +/** + * Tests the setting of the FOV and aspect ratios. + * + * @author Markil 3 + */ +public class TestAspectFov extends SimpleApplication implements AnalogListener { + private static final String FOV_IN = "fovIn"; + private static final String FOV_OUT = "fovOut"; + private BitmapText header, fov; + + public static void main(String[] args) { + new TestAspectFov().start(); + } + + @Override + public void simpleInitApp() { + header = new BitmapText(this.guiFont); + header.setText("Adjust FOV with R/F or with mouse scroll"); + guiNode.attachChild(header); + fov = new BitmapText(this.guiFont); + guiNode.attachChild(fov); + + viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); + flyCam.setMoveSpeed(100); + + // We add light so we see the scene + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(1.3f)); + rootNode.addLight(al); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White); + dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal()); + rootNode.addLight(dl); + + assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/town.zip", + HttpZipLocator.class); + Spatial sceneModel = assetManager.loadModel("main.scene"); + sceneModel.setLocalScale(2f); + + rootNode.attachChild(sceneModel); + + inputManager.addMapping(FOV_IN, new KeyTrigger(KeyInput.KEY_R)); + inputManager.addMapping(FOV_OUT, new KeyTrigger(KeyInput.KEY_F)); + inputManager.addListener(this, FOV_IN, FOV_OUT); + } + + @Override + public void update() { + /* + * Updates the labels + */ + TempVars vars = TempVars.get(); + super.update(); + header.setLocalTranslation(0, cam.getHeight(), 0); + vars.vect1.set(header.getLocalTranslation()); + vars.vect1.subtractLocal(0, header.getLineHeight(), 0); + fov.setLocalTranslation(vars.vect1); + fov.setText("FOV: " + cam.getFov()); + vars.vect1.subtractLocal(0, fov.getLineHeight(), 0); + vars.release(); + } + + @Override + public void onAnalog(String name, float value, float tpf) { + final float CHANGE_VALUE = tpf * 10; + float newFov = cam.getFov(); + switch (name) { + case FOV_IN: + newFov -= CHANGE_VALUE; + break; + case FOV_OUT: + newFov += CHANGE_VALUE; + break; + } + if (newFov > 0 && newFov != cam.getFov()) { + cam.setFov(newFov); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java b/jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java new file mode 100644 index 0000000000..bdb526710e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestAspectRatio.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009-2018 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +/** + * Simple application to test a viewport/camera with a different aspect ratio + * than the display -- issue #357. The cube should render as a blue square, not + * a rectangle. + * + * Based closely on the test case submitted by slyh on September 28, 2015. + */ +public class TestAspectRatio extends SimpleApplication { + + public static void main(String[] args) { + new TestAspectRatio().start(); + } + + @Override + public void simpleInitApp() { + Geometry cube = new Geometry("blue cube", new Box(1, 1, 1)); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + cube.setMaterial(mat); + + rootNode.attachChild(cube); + + // Trying to update the viewport: + cam.setViewPortBottom(0.5f); + cam.resize(640, 480 / 2, false); + cam.setFrustumPerspective(40, 640f / (480 / 2), 0.05f, 500f); + cam.update(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java b/jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java new file mode 100644 index 0000000000..c8c004a9c3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestBackgroundImage.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2021 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. + */ +package jme3test.renderer; + +import com.jme3.anim.util.AnimMigrationUtils; +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.material.Materials; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Texture; +import java.util.List; + +/** + * Demonstrates how to render a non-moving background image using a pre + * ViewPort. + * + * @author Stephen Gold sgold@sonic.net + */ +public class TestBackgroundImage extends SimpleApplication { + + private static ViewPort backgroundViewport; + + public static void main(String[] args) { + new TestBackgroundImage().start(); + } + + @Override + public void simpleInitApp() { + /* + * SimpleApplication creates 2 viewports: + * 1. the default viewport (rendered first, after clearing all buffers) + * 2. the GUI viewport (rendered last, without clearing any buffers) + * + * Create a 3rd ViewPort, named "background viewport", + * to be rendered BEFORE the default viewport. + */ + Camera backgroundCamera = guiViewPort.getCamera().clone(); + backgroundViewport = renderManager.createPreView( + "background viewport", backgroundCamera); + /* + * Don't clear the color buffer before drawing the main viewport. + * Clearing the color buffer would hide the background. + */ + boolean clearColorBuffer = false; + viewPort.setClearFlags(clearColorBuffer, true, true); + /* + * Create a quad to display the JMonkeyEngine logo, + * assign it to the Gui bucket, + * and attach it to the background viewport. + */ + Texture quadTexture + = assetManager.loadTexture("Interface/Logo/Monkey.png"); + Material quadMaterial = new Material(assetManager, Materials.UNSHADED); + quadMaterial.setTexture("ColorMap", quadTexture); + + float quadHeight = backgroundCamera.getHeight(); + float quadWidth = backgroundCamera.getWidth(); + Mesh quadMesh = new Quad(quadWidth, quadHeight); + + Spatial quadGeometry = new Geometry("quad geometry", quadMesh); + quadGeometry.setMaterial(quadMaterial); + quadGeometry.setQueueBucket(RenderQueue.Bucket.Gui); + backgroundViewport.attachScene(quadGeometry); + /* + * Add Jaime model and lighting to the default scene. + */ + loadModel(); + setupLights(); + /* + * Speed up camera motion for convenience. + */ + flyCam.setMoveSpeed(8f); + } + + @Override + public void simpleUpdate(float timePerFrame) { + /* + * Since SimpleApplication is unaware of the background viewport, + * the application must explicitly update its scenes. + */ + List scenes = backgroundViewport.getScenes(); + for (Spatial scene : scenes) { + scene.updateLogicalState(timePerFrame); + scene.updateGeometricState(); + } + } + + private void loadModel() { + Node jaime = (Node) assetManager.loadModel("Models/Jaime/Jaime.j3o"); + AnimMigrationUtils.migrate(jaime); + jaime.scale(3f); + rootNode.attachChild(jaime); + } + + private void setupLights() { + AmbientLight ambient = new AmbientLight(); + ambient.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f)); + rootNode.addLight(ambient); + + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(0f, -1f, -1f).normalizeLocal()); + sun.setColor(ColorRGBA.White.mult(1.5f)); + rootNode.addLight(sun); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java b/jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java new file mode 100644 index 0000000000..f979017b3c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestBlendEquations.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.material.RenderState; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Quad; + +/** + * This test demonstrates the usage of customized blend equations and factors on a material.
+ * Customized blend equations and factors always requires {@link com.jme3.material.RenderState.BlendMode#Custom}. + * + * @author the_Minka + */ +public class TestBlendEquations extends SimpleApplication { + + private Geometry leftQuad; + private Geometry rightQuad; + + private float timer; + + public static void main(String[] args) { + TestBlendEquations app = new TestBlendEquations(); + app.start(); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(0f, 0.5f, 3f)); + viewPort.setBackgroundColor(ColorRGBA.LightGray); + + // Add a light source to the scene. + DirectionalLight directionalLight = new DirectionalLight(); + directionalLight.setColor(ColorRGBA.Magenta); + directionalLight.setDirection(Vector3f.UNIT_XYZ.negate()); + rootNode.addLight(directionalLight); + + + // Create and add a teapot to the scene graph. + Spatial teapotModel = assetManager.loadModel("Models/Teapot/Teapot.obj"); + rootNode.attachChild(teapotModel); + + // Create the two moving quads with custom blend modes. + createLeftQuad(); + createRightQuad(); + } + + /** + * Adds a "transparent" quad to the scene, that shows an inverse blue value sight of the scene behind. + */ + private void createLeftQuad() { + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + + // This color creates a blue value image. The effect will have a strength of 80% (set by the alpha value). + material.setColor("Color", new ColorRGBA(0f, 0f, 1f, 0.8f)); + + // Result.RGB = Source.A * Source.RGB - Source.A * Destination.RGB + // Result.A = Destination.A + material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Custom); + material.getAdditionalRenderState().setBlendEquation(RenderState.BlendEquation.Subtract); + material.getAdditionalRenderState().setBlendEquationAlpha(RenderState.BlendEquationAlpha.Add); + material.getAdditionalRenderState().setCustomBlendFactors( + RenderState.BlendFunc.Src_Alpha, RenderState.BlendFunc.Src_Alpha, + RenderState.BlendFunc.Zero, RenderState.BlendFunc.One); + + leftQuad = new Geometry("LeftQuad", new Quad(1f, 1f)); + leftQuad.setMaterial(material); + leftQuad.setQueueBucket(RenderQueue.Bucket.Transparent); + rootNode.attachChild(leftQuad); + } + + /** + * Adds a "transparent" quad to the scene, that limits the color values of the scene behind the object.
+ * This effect can be good seen on bright areas of the scene (e.g. areas with specular lighting effects). + */ + private void createRightQuad() { + Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + material.setColor("Color", new ColorRGBA(0.4f, 0.4f, 0.4f, 1f)); + + // Min( Source , Destination) + material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Custom); + material.getAdditionalRenderState().setBlendEquation(RenderState.BlendEquation.Min); + material.getAdditionalRenderState().setBlendEquationAlpha(RenderState.BlendEquationAlpha.Min); + + // In OpenGL no blend factors are used, when using the blend equations Min or Max! + //material.getAdditionalRenderState().setCustomBlendFactors( + // RenderState.BlendFunc.One, RenderState.BlendFunc.One, + // RenderState.BlendFunc.One, RenderState.BlendFunc.One); + + rightQuad = new Geometry("RightQuad", new Quad(1f, 1f)); + rightQuad.setMaterial(material); + rightQuad.setQueueBucket(RenderQueue.Bucket.Transparent); + rootNode.attachChild(rightQuad); + } + + @Override + public void simpleUpdate(float tpf) { + timer += tpf; + + float xOffset = FastMath.sin(timer * 0.5f) * 2f; + leftQuad.setLocalTranslation(xOffset - 2f, 0f, 0.5f); + rightQuad.setLocalTranslation(xOffset + 1f, 0f, 0.5f); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java b/jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java new file mode 100644 index 0000000000..2244191459 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestContextRestart.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.control.AbstractControl; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; + +/** + * Tests whether gamma correction works after a context restart. This test + * generates a series of boxes, each one with a slightly different shade from + * the other. If the boxes look the same before and after the restart, that + * means that gamma correction is working properly. + *

+ * Note that for testing, it may be helpful to bypass the test chooser and run + * this class directly, since it can be easier to define your own settings + * beforehand. Of course, it should still work if all you need to test is the + * gamma correction, as long as you enable it in the settings dialog. + *

+ * + * @author Markil 3 + */ +public class TestContextRestart extends SimpleApplication +{ + public static final String INPUT_RESTART_CONTEXT = "SIMPLEAPP_Restart"; + + public static void main(String[] args) + { + TestContextRestart app = new TestContextRestart(); + AppSettings settings = new AppSettings(true); + settings.setGammaCorrection(true); +// settings.setRenderer(AppSettings.LWJGL_OPENGL32); + app.setSettings(settings); + app.start(); + } + + @Override + public void simpleInitApp() + { + for (int i = 0, l = 256; i < l; i += 8) + { + Geometry box = new Geometry("Box" + i, new Box(10, 200, 10)); + Material mat = new Material(this.assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", new ColorRGBA((float) i / 255F, 0, 0, 1)); + box.setMaterial(mat); + box.setLocalTranslation(-2.5F * (l / 2 - i), 0, -700); + box.addControl(new AbstractControl() + { + @Override + protected void controlUpdate(float tpf) + { + float[] angles = this.getSpatial() + .getLocalRotation() + .toAngles(new float[3]); + angles[0] = angles[0] + (FastMath.PI / 500F); + this.getSpatial() + .setLocalRotation(new Quaternion().fromAngles(angles)); + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp) + { + + } + }); + this.rootNode.attachChild(box); + } + + this.viewPort.setBackgroundColor(ColorRGBA.Yellow); + + this.flyCam.setEnabled(false); + this.inputManager.setCursorVisible(true); + + inputManager.addMapping(INPUT_RESTART_CONTEXT, new KeyTrigger( + KeyInput.KEY_TAB)); + this.inputManager.addListener(new ActionListener() + { + @Override + public void onAction(String name, boolean isPressed, float tpf) + { + if (name.equals(INPUT_RESTART_CONTEXT)) + { + restart(); + } + } + }, INPUT_RESTART_CONTEXT); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java b/jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java new file mode 100644 index 0000000000..20f0a55e89 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestDepthFuncChange.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.material.RenderState; +import com.jme3.math.ColorRGBA; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +public class TestDepthFuncChange extends SimpleApplication { + + public static void main(String[] args) { + TestDepthFuncChange app = new TestDepthFuncChange(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + flyCam.setMoveSpeed(20); + + + //top of the screen + //default depth func (less or equal) rendering. + //2 cubes, a blue and a red. the red cube is offset by 0.2 WU to the right + //the red cube is put in the transparent bucket to be sure it's rendered after the blue one (but there is no transparency involved). + //You should see a small part of the blue cube on the left and the whole red cube + Box boxShape1 = new Box(1f, 1f, 1f); + Geometry cube1 = new Geometry("box", boxShape1); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + + cube1.setMaterial(mat); + rootNode.attachChild(cube1); + cube1.move(0, 1.5f, 0); + + Geometry cube2 = cube1.clone(true); + cube2.move(0.2f, 0 , 0); + cube2.setQueueBucket(RenderQueue.Bucket.Transparent); + cube2.getMaterial().setColor("Color", ColorRGBA.Red); + rootNode.attachChild(cube2); + + //Bottom of the screen + //here the 2 cubes are cloned and the depthFunc for the red cube's material is set to Less + //You should see the whole blue cube and a small part of the red cube on the right + Geometry cube3 = cube1.clone(); + Geometry cube4 = cube2.clone(true); + cube4.getMaterial().getAdditionalRenderState().setDepthFunc(RenderState.TestFunction.Less); + cube3.move(0,-3,0); + cube4.move(0,-3,0); + rootNode.attachChild(cube3); + rootNode.attachChild(cube4); + + //Note that if you move the camera z fighting will occur but that's expected. + + + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java b/jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java new file mode 100644 index 0000000000..0f333ac661 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestDepthStencil.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.material.RenderState; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.Renderer; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.AbstractControl; +import com.jme3.scene.shape.Sphere; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture2D; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; +import com.jme3.ui.Picture; + +public class TestDepthStencil extends SimpleApplication { + + private boolean enableStencil = false; + + final private Node fbNode = new Node("Framebuffer Node"); + private FrameBuffer fb; + + public static void main(String[] args){ + TestDepthStencil app = new TestDepthStencil(); + app.start(); + } + + @Override + public void simpleInitApp() { + int w = settings.getWidth(); + int h = settings.getHeight(); + + //setup framebuffer + fb = new FrameBuffer(w, h, 1); + + Texture2D fbTex = new Texture2D(w, h, Format.RGB8); + fb.setDepthTarget(FrameBufferTarget.newTarget(Format.Depth24Stencil8)); + fb.addColorTarget(FrameBufferTarget.newTarget(fbTex)); + + // setup framebuffer's scene + Sphere sphMesh = new Sphere(20, 20, 1); + Material solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + + final Geometry sphere = new Geometry("sphere", sphMesh); + sphere.setMaterial(solidColor); + fbNode.attachChild(sphere); + + sphere.addControl(new AbstractControl() { + @Override + protected void controlUpdate(float tpf) { + Material mat = sphere.getMaterial(); + mat.getAdditionalRenderState().setStencil(enableStencil, + RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, + RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, RenderState.StencilOperation.Keep, + RenderState.TestFunction.Never, RenderState.TestFunction.Never + //TestFunction.Always, TestFunction.Always + ); + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp) { + } + }); + + //setup main scene + Picture p = new Picture("Picture"); + p.setPosition(0, 0); + p.setWidth(w); + p.setHeight(h); + p.setTexture(assetManager, fbTex, false); + + rootNode.attachChild(p); + + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + ActionListener acl = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("toggle") && keyPressed) { + if (enableStencil) { + enableStencil = false; + System.out.println("Stencil Disabled (model should be visible)"); + } else { + enableStencil = true; + System.out.println("Stencil Enabled (model should be hidden)"); + } + } + } + }; + inputManager.addListener(acl, "toggle"); + + System.out.println("Press space to toggle stencil"); + } + + @Override + public void simpleUpdate(float tpf){ + fbNode.updateLogicalState(tpf); + fbNode.updateGeometricState(); + } + + @Override + public void simpleRender(RenderManager rm){ + Renderer r = rm.getRenderer(); + + //do FBO rendering + r.setFrameBuffer(fb); + + rm.setCamera(cam, false); // FBO uses current camera + r.clearBuffers(true, true, true); + rm.renderScene(fbNode, viewPort); + rm.flushQueue(viewPort); + + //go back to default rendering and let + //SimpleApplication render the default scene + r.setFrameBuffer(null); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java b/jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java new file mode 100644 index 0000000000..dbb2eaad8d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestInconsistentCompareDetection.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.texture.Texture; + +/** + * Changes a material's texture from another thread while it is rendered. + * This should trigger the sorting function's inconsistent compare detection. + * + * @author Kirill Vainer + */ +public class TestInconsistentCompareDetection extends SimpleApplication { + + private static Texture t1, t2; + + public static void main(String[] args){ + TestInconsistentCompareDetection app = new TestInconsistentCompareDetection(); + app.start(); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(-11.674385f, 7.892636f, 33.133106f)); + cam.setRotation(new Quaternion(0.06426433f, 0.90940624f, -0.15329266f, 0.38125014f)); + + Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + m.setColor("Color", ColorRGBA.White); + + t1 = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"); + t2 = assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"); + + Box b = new Box(1, 1, 1); + + for (int x = 0; x < 12; x++) { + for (int y = 0; y < 12; y++) { + Geometry g = new Geometry("g_" + x + "_" + y, b); + Node monkey = new Node("n_" + x + "_" + y); + monkey.attachChild(g); + monkey.move(x * 2, 0, y * 2); + + Material newMat = m.clone(); + g.setMaterial(newMat); + + if (FastMath.rand.nextBoolean()) { + newMat.setTexture("ColorMap", t1); + } else { + newMat.setTexture("ColorMap", t2); + } + + rootNode.attachChild(monkey); + } + } + + Thread evilThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + } + + // begin randomly changing textures after 1 sec. + while (true) { + for (Spatial child : rootNode.getChildren()) { + Geometry g = (Geometry) (((Node)child).getChild(0)); + Material m = g.getMaterial(); + Texture curTex = m.getTextureParam("ColorMap").getTextureValue(); + if (curTex == t1) { + m.setTexture("ColorMap", t2); + } else { + m.setTexture("ColorMap", t1); + } + } + } + } + }); + evilThread.setDaemon(true); + evilThread.start(); + } +} + diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java new file mode 100644 index 0000000000..037dd980a6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestIssue2011.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.system.AppSettings; + +/** + * Test for JMonkeyEngine issue #2011: context profiles are not defined for + * OpenGL v3.0/v3.1 + *

+ * If the issue is resolved, then pressing the "0" or "1" key shouldn't crash + * the app; it should close the app display and create a new display, mostly + * black with statistics displayed in the lower left. + *

+ * If the issue is not resolved, then pressing the "0" or "1" key should crash + * the app with multiple exceptions. + *

+ * Since the issue was specific to LWJGL v3, this test should be built with the + * jme3-lwjgl3 library, not jme3-lwjgl. + * + * @author Stephen Gold + */ +public class TestIssue2011 extends SimpleApplication { + /** + * Main entry point for the TestIssue2011 application. + * + * @param args array of command-line arguments (not null) + */ + public static void main(String[] args) { + TestIssue2011 app = new TestIssue2011(); + app.start(); + } + + /** + * Initialize this application. + */ + @Override + public void simpleInitApp() { + inputManager.addMapping("3.0", new KeyTrigger(KeyInput.KEY_0), + new KeyTrigger(KeyInput.KEY_NUMPAD0)); + inputManager.addMapping("3.1", new KeyTrigger(KeyInput.KEY_1), + new KeyTrigger(KeyInput.KEY_NUMPAD1)); + inputManager.addMapping("3.2", new KeyTrigger(KeyInput.KEY_2), + new KeyTrigger(KeyInput.KEY_NUMPAD2)); + + ActionListener listener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("3.0") && keyPressed) { + setApi(AppSettings.LWJGL_OPENGL30); + } else if (name.equals("3.1") && keyPressed) { + setApi(AppSettings.LWJGL_OPENGL31); + } else if (name.equals("3.2") && keyPressed) { + setApi(AppSettings.LWJGL_OPENGL32); + } + } + }; + + inputManager.addListener(listener, "3.0", "3.1", "3.2"); + } + + /** + * Restart the app, specifying which OpenGL version to use. + * + * @param desiredApi the string to be passed to setRenderer() + */ + private void setApi(String desiredApi) { + System.out.println("desiredApi = " + desiredApi); + settings.setRenderer(desiredApi); + setSettings(settings); + + restart(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java new file mode 100644 index 0000000000..ce276e81d9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestIssue37.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021 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. + */ +package jme3test.renderer; + +import com.jme3.app.Application; +import com.jme3.app.SimpleApplication; +import com.jme3.material.MatParamOverride; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.shape.Box; +import com.jme3.shader.VarType; +import com.jme3.texture.Texture; + +/** + * Test a Material with increasing numbers of texture parameters, to see what + * happens when the renderer's dynamic limit is exceeded. + * + * If successful, this test throws an IllegalStateException with a helpful + * diagnostic message. + */ +public class TestIssue37 extends SimpleApplication { + + /** + * Edit this field to change how parameters are assigned (which determines + * where the exception is caught): true to use mat param overrides, false to + * use ordinary mat params. + */ + final private boolean useOverrides = true; + + private int numTextures; + private Material manyTexturesMaterial; + private Texture testTexture; + + public static void main(String[] args) { + Application application = new TestIssue37(); + application.start(); + } + + @Override + public void simpleInitApp() { + /* + * Attach a test geometry to the scene. + */ + Mesh cubeMesh = new Box(1f, 1f, 1f); + Geometry cubeGeometry = new Geometry("Box", cubeMesh); + rootNode.attachChild(cubeGeometry); + /* + * Apply a test material (with no textures assigned) to the geometry. + */ + manyTexturesMaterial = new Material(assetManager, + "jme3test/materials/TestIssue37.j3md"); + manyTexturesMaterial.setName("manyTexturesMaterial"); + cubeGeometry.setMaterial(manyTexturesMaterial); + numTextures = 0; + /* + * Load the test texture. + */ + String texturePath = "Interface/Logo/Monkey.jpg"; + testTexture = assetManager.loadTexture(texturePath); + } + + /** + * During each update, define another texture parameter until the dynamic + * limit is reached. + * + * @param tpf ignored + */ + @Override + public void simpleUpdate(float tpf) { + String parameterName = "ColorMap" + numTextures; + if (useOverrides) { + MatParamOverride override = new MatParamOverride(VarType.Texture2D, + parameterName, testTexture); + rootNode.addMatParamOverride(override); + } else { + manyTexturesMaterial.setTexture(parameterName, testTexture); + } + ++numTextures; + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java new file mode 100644 index 0000000000..d350566d03 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestIssue798.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; + +/** + * Test for JMonkeyEngine issue #798: OpenGLException on restart with changed + * display settings. + *

+ * If the issue is resolved, then pressing the "P", "T", or "Y" key shouldn't + * crash the app; it should close the app display and create a new display, + * mostly black with statistics displayed in the lower left. + *

+ * If the issue is not resolved, the expected failure mode depends on whether + * assertions are enabled. If they're enabled, the app will crash with an + * OpenGLException. If assertions aren't enabled, the new window will be + * entirely black, with no statistics visible. + *

+ * Since the issue was specific to LWJGL v2, this test should be built with the + * jme3-lwjgl library, not jme3-lwjgl3. + * + * @author Stephen Gold + */ +public class TestIssue798 extends SimpleApplication { + /** + * Main entry point for the TestIssue798 application. + * + * @param args array of command-line arguments (not null) + */ + public static void main(String[] args) { + TestIssue798 app = new TestIssue798(); + app.start(); + } + + /** + * Initialize this application. + */ + @Override + public void simpleInitApp() { + inputManager.addMapping("windowedMode", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addMapping("moreSamples", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addMapping("toggleDepth", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addMapping("toggleBpp", new KeyTrigger(KeyInput.KEY_Y)); + + ActionListener listener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("moreSamples") && keyPressed) { + moreSamples(); + } else if (name.equals("toggleBpp") && keyPressed) { + toggleBpp(); + } else if (name.equals("toggleDepth") && keyPressed) { + toggleDepth(); + } else if (name.equals("windowedMode") && keyPressed) { + windowedMode(); + } + } + }; + + inputManager.addListener(listener, + "moreSamples", "toggleBpp", "toggleDepth", "windowedMode"); + } + + /** + * Restart the app, requesting 2 more MSAA samples per pixel. + */ + private void moreSamples() { + int numSamples = settings.getSamples(); + numSamples += 2; + System.out.println("numSamples = " + numSamples); + settings.setSamples(numSamples); + setSettings(settings); + + restart(); + } + + /** + * Restart the app, requesting a different number of bits per pixel in the + * RGB buffer. + */ + private void toggleBpp() { + int bpp = settings.getBitsPerPixel(); + bpp = (bpp == 24) ? 16 : 24; + System.out.println("BPP = " + bpp); + settings.setBitsPerPixel(bpp); + setSettings(settings); + + restart(); + } + + /** + * Restart the app, requesting a different number of bits per pixel in the + * depth buffer. + */ + private void toggleDepth() { + int depthBits = settings.getDepthBits(); + depthBits = (depthBits == 24) ? 16 : 24; + System.out.println("depthBits = " + depthBits); + settings.setDepthBits(depthBits); + setSettings(settings); + + restart(); + } + + /** + * If the app is in fullscreen mode, restart it in 640x480 windowed mode. + */ + private void windowedMode() { + boolean isFullscreen = settings.isFullscreen(); + if (!isFullscreen) { + System.out.println("Request ignored: already in windowed mode!"); + return; + } + + System.out.println("fullscreen = " + false); + settings.setFullscreen(false); + settings.setWidth(640); + settings.setHeight(480); + setSettings(settings); + + restart(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java b/jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java new file mode 100644 index 0000000000..0f1893c43b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestIssue801.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.system.AppSettings; + +public class TestIssue801 extends SimpleApplication { + + public static void main(String[] args) { + AppSettings initialSettings = new AppSettings(true); + initialSettings.setBitsPerPixel(24); + + TestIssue801 app = new TestIssue801(); + app.setSettings(initialSettings); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(new ColorRGBA(0.3f, 0.3f, 0.3f, 1f)); + + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + geom.setMaterial(mat); + + rootNode.attachChild(geom); + inputManager.addMapping("changeBpp", new KeyTrigger(KeyInput.KEY_P)); + ActionListener listener = new ActionListener() { + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("changeBpp") && keyPressed) { + goWindowed(); + } + } + }; + inputManager.addListener(listener, "changeBpp"); + } + + void goWindowed() { + AppSettings newSettings = new AppSettings(false); + newSettings.copyFrom(settings); + newSettings.setBitsPerPixel(16); + + setSettings(newSettings); + restart(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java b/jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java new file mode 100644 index 0000000000..e73132d314 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.material.Material; +import com.jme3.material.Materials; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.shape.Line; +import com.jme3.system.AppSettings; + +/** + * Display the renderer's maximum line width. + * + * @author Stephen Gold sgold@sonic.net + */ +public class TestLineWidth extends SimpleApplication { + + public static void main(String... args) { + TestLineWidth app = new TestLineWidth(); + AppSettings set = new AppSettings(true); + set.setRenderer(AppSettings.LWJGL_OPENGL2); + app.setSettings(set); + app.start(); + } + + @Override + public void simpleInitApp() { + /* + * Generate a message to report (1) which renderer is selected + * and (2) the maximum line width. + */ + String rendererName = settings.getRenderer(); + float maxWidth = renderer.getMaxLineWidth(); + String message = String.format( + "using %s renderer%nmaximum line width = %.1f pixel%s", + rendererName, maxWidth, (maxWidth == 1f) ? "" : "s"); + /* + * Display the message, centered near the top of the display. + */ + BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText text = new BitmapText(font); + text.setSize(font.getCharSet().getRenderedSize()); + text.setText(message); + float leftX = (cam.getWidth() - text.getLineWidth()) / 2; + float topY = cam.getHeight(); + text.setLocalTranslation(leftX, topY, 0f); + guiNode.attachChild(text); + /* + * Display a vertical green line on the left side of the display. + */ + float lineWidth = Math.min(maxWidth, leftX); + drawVerticalLine(lineWidth, leftX / 2, ColorRGBA.Green); + } + + private void drawVerticalLine(float lineWidth, float x, ColorRGBA color) { + Material material = new Material(assetManager, Materials.UNSHADED); + material.setColor("Color", color.clone()); + material.getAdditionalRenderState().setLineWidth(lineWidth); + + float viewportHeight = cam.getHeight(); + Vector3f startLocation = new Vector3f(x, 0.1f * viewportHeight, 0f); + Vector3f endLocation = new Vector3f(x, 0.9f * viewportHeight, 0f); + Mesh wireMesh = new Line(startLocation, endLocation); + Geometry wire = new Geometry("wire", wireMesh); + wire.setMaterial(material); + guiNode.attachChild(wire); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java b/jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java new file mode 100644 index 0000000000..ae8e51dca5 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; + +public class TestMultiViews extends SimpleApplication { + + public static void main(String[] args) { + TestMultiViews app = new TestMultiViews(); + app.start(); + } + + @Override + public void simpleInitApp() { + // create the geometry and attach it + Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + teaGeom.scale(3); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White); + dl.setDirection(Vector3f.UNIT_XYZ.negate()); + + rootNode.addLight(dl); + rootNode.attachChild(teaGeom); + + // Setup first view + viewPort.setBackgroundColor(ColorRGBA.Blue); + cam.setViewPort(.5f, 1f, 0f, 0.5f); + cam.setLocation(new Vector3f(3.3212643f, 4.484704f, 4.2812433f)); + cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f)); + + // Setup second view + Camera cam2 = cam.clone(); + cam2.setViewPort(0f, 0.5f, 0f, 0.5f); + cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f)); + cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f)); + + ViewPort view2 = renderManager.createMainView("Bottom Left", cam2); + view2.setClearFlags(true, true, true); + view2.attachScene(rootNode); + + // Setup third view + Camera cam3 = cam.clone(); + cam3.setViewPort(0f, .5f, .5f, 1f); + cam3.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f)); + cam3.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f)); + + ViewPort view3 = renderManager.createMainView("Top Left", cam3); + view3.setClearFlags(true, true, true); + view3.attachScene(rootNode); + + // Setup fourth view + Camera cam4 = cam.clone(); + cam4.setViewPort(.5f, 1f, .5f, 1f); + cam4.setLocation(new Vector3f(4.775564f, 1.4548365f, 0.11491505f)); + cam4.setRotation(new Quaternion(0.02356979f, -0.74957186f, 0.026729556f, 0.66096294f)); + + ViewPort view4 = renderManager.createMainView("Top Right", cam4); + view4.setClearFlags(true, true, true); + view4.attachScene(rootNode); + + //test multiview for gui + guiViewPort.getCamera().setViewPort(.5f, 1f, .5f, 1f); + + // Setup second gui view + Camera guiCam2 = guiViewPort.getCamera().clone(); + guiCam2.setViewPort(0f, 0.5f, 0f, 0.5f); + ViewPort guiViewPort2 = renderManager.createPostView("Gui 2", guiCam2); + guiViewPort2.setClearFlags(false, false, false); + guiViewPort2.attachScene(guiViewPort.getScenes().get(0)); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java b/jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java new file mode 100644 index 0000000000..990da80158 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestParallelProjection.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; + +public class TestParallelProjection extends SimpleApplication implements AnalogListener { + + private float frustumSize = 1; + + public static void main(String[] args){ + TestParallelProjection app = new TestParallelProjection(); + app.start(); + } + + @Override + public void simpleInitApp() { + Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); + + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White); + dl.setDirection(Vector3f.UNIT_XYZ.negate()); + + rootNode.addLight(dl); + rootNode.attachChild(teaGeom); + + // Setup first view + cam.setParallelProjection(true); + float aspect = (float) cam.getWidth() / cam.getHeight(); + cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); + + inputManager.addListener(this, "Size+", "Size-"); + inputManager.addMapping("Size+", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Size-", new KeyTrigger(KeyInput.KEY_S)); + } + + @Override + public void onAnalog(String name, float value, float tpf) { + // Instead of moving closer/farther to object, we zoom in/out. + if (name.equals("Size-")) + frustumSize += 0.3f * tpf; + else + frustumSize -= 0.3f * tpf; + + float aspect = (float) cam.getWidth() / cam.getHeight(); + cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java b/jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java new file mode 100644 index 0000000000..51f2f37071 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/TestSplitScreen.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.renderer; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; + +/** + * Simple application to test split-screen rendering. Clicking with LMB toggles + * between a single camera/viewport (cam) and split screen (leftCam plus + * rightCam). See issue #357. + */ +public class TestSplitScreen extends SimpleApplication implements ActionListener { + + private boolean splitScreen = false; + final private Box mesh = new Box(1f, 1f, 1f); + final private Node leftScene = new Node("left scene"); + private ViewPort leftView, rightView; + + @Override + public void simpleInitApp() { + flyCam.setEnabled(false); + + Geometry blueBox = new Geometry("blue box", mesh); + Material blueMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + blueMat.setColor("Color", ColorRGBA.Blue); + blueBox.setMaterial(blueMat); + rootNode.attachChild(blueBox); + + Camera rightCam = cam.clone(); + rightCam.setViewPort(0.5f, 1f, 0f, 1f); + + rightView = renderManager.createMainView("right", rightCam); + rightView.setClearFlags(true, true, true); + rightView.setEnabled(false); + rightView.attachScene(rootNode); + + Geometry redBox = new Geometry("red box", mesh); + Material redMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + redMat.setColor("Color", ColorRGBA.Red); + redBox.setMaterial(redMat); + leftScene.attachChild(redBox); + + Camera leftCam = cam.clone(); + leftCam.setViewPort(0f, 0.5f, 0f, 1f); + + leftView = renderManager.createMainView("left", leftCam); + leftView.setClearFlags(true, true, true); + leftView.setEnabled(false); + leftView.attachScene(leftScene); + + inputManager.addMapping("lmb", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(this, "lmb"); + } + + @Override + public void onAction(String name, boolean keyPressed, float tpf) { + if (name.equals("lmb") && !keyPressed) { + splitScreen = !splitScreen; + viewPort.setEnabled(!splitScreen); + leftView.setEnabled(splitScreen); + rightView.setEnabled(splitScreen); + } + } + + @Override + public void simpleUpdate(float tpf) { + leftScene.updateLogicalState(tpf); + leftScene.updateGeometricState(); + } + + public static void main(String[] args) { + TestSplitScreen app = new TestSplitScreen(); + app.start(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/renderer/package-info.java b/jme3-examples/src/main/java/jme3test/renderer/package-info.java new file mode 100644 index 0000000000..aa907287a7 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/renderer/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for rendering, including cameras + */ +package jme3test.renderer; diff --git a/jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java b/jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java new file mode 100644 index 0000000000..6bd6298235 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/TestLineWidthRenderState.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009-2012 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. + */ + +package jme3test.scene; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; + +public class TestLineWidthRenderState extends SimpleApplication { + + private Material mat; + + public static void main(String[] args){ + TestLineWidthRenderState app = new TestLineWidthRenderState(); + app.start(); + } + + + + @Override + public void simpleInitApp() { + setDisplayFps(false); + setDisplayStatView(false); + cam.setLocation(new Vector3f(5.5826545f, 3.6192513f, 8.016988f)); + cam.setRotation(new Quaternion(-0.04787097f, 0.9463123f, -0.16569641f, -0.27339742f)); + + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + mat.getAdditionalRenderState().setWireframe(true); + mat.getAdditionalRenderState().setLineWidth(2); + geom.setMaterial(mat); + rootNode.attachChild(geom); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(name.equals("up") && isPressed){ + mat.getAdditionalRenderState().setLineWidth(mat.getAdditionalRenderState().getLineWidth() + 1); + } + if(name.equals("down") && isPressed){ + mat.getAdditionalRenderState().setLineWidth(Math.max(mat.getAdditionalRenderState().getLineWidth() - 1, 1)); + } + } + }, "up", "down"); + inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_J)); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java b/jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java new file mode 100644 index 0000000000..6c8d4d87c1 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/TestRefreshFlagBug.java @@ -0,0 +1,45 @@ +package jme3test.scene; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Box; + +public class TestRefreshFlagBug extends SimpleApplication { + + private float time = 0; + private boolean attached = false; + private Node inBetweenNode; + + public static void main(String[] args) { + TestRefreshFlagBug app = new TestRefreshFlagBug(); + app.start(); + } + + @Override + public void simpleUpdate(float tpf) { + time += tpf; + if (time > 5 && !attached) { + attached = true; + + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + geom.setMaterial(mat); + + inBetweenNode.attachChild(geom); + + // the refresh flags become corrupted here ... + inBetweenNode.getWorldBound(); + } + } + + @Override + public void simpleInitApp() { + inBetweenNode = new Node("In Between Node"); + rootNode.attachChild(inBetweenNode); + + flyCam.setDragToRotate(true); + } +} diff --git a/jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java b/jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java new file mode 100644 index 0000000000..0e007de394 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/TestSceneLoading.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.scene; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.asset.plugins.ZipLocator; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.SkyFactory; +import java.io.File; + +public class TestSceneLoading extends SimpleApplication { + + final private Sphere sphereMesh = new Sphere(32, 32, 10, false, true); + final private Geometry sphere = new Geometry("Sky", sphereMesh); + private static boolean useHttp = false; + + public static void main(String[] args) { + + TestSceneLoading app = new TestSceneLoading(); + app.start(); + } + + @Override + public void simpleUpdate(float tpf){ + sphere.setLocalTranslation(cam.getLocation()); + } + + @Override + public void simpleInitApp() { + File file = new File("wildhouse.zip"); + if (!file.exists()) { + useHttp = true; + } + + this.flyCam.setMoveSpeed(10); + + // load sky + rootNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + + // create the geometry and attach it + // load the level from zip or http zip + if (useHttp) { + assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", HttpZipLocator.class); + } else { + assetManager.registerLocator("wildhouse.zip", ZipLocator.class); + } + Spatial scene = assetManager.loadModel("main.scene"); + + AmbientLight al = new AmbientLight(); + scene.addLight(al); + + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(0.69077975f, -0.6277887f, -0.35875428f).normalizeLocal()); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + scene.addLight(sun); + + rootNode.attachChild(scene); + } +} diff --git a/jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java b/jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java new file mode 100644 index 0000000000..81ff47e092 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/TestSceneStress.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.scene; + +import com.jme3.app.BasicProfilerState; +import com.jme3.app.DebugKeysAppState; +import com.jme3.app.FlyCamAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.app.StatsAppState; +import com.jme3.app.state.ScreenshotAppState; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.control.AbstractControl; +import com.jme3.scene.shape.Box; +import java.util.Random; + + +/** + * Tests a deep scene with an unrecommended amount of objects. + * + * @author Paul Speed + */ +public class TestSceneStress extends SimpleApplication { + + final private static Box BOX = new Box(2f, 0.5f, 0.5f); + + private Material mat; + final private Random random = new Random(0); + + private int totalNodes = 0; + private int totalGeometry = 0; + private int totalControls = 0; + + public static void main( String... args ) { + + TestSceneStress test = new TestSceneStress(); + test.start(); + } + + public TestSceneStress() { + super(new StatsAppState(), new DebugKeysAppState(), new BasicProfilerState(false), + new FlyCamAppState(), + new ScreenshotAppState("", System.currentTimeMillis())); + } + + @Override + public void simpleInitApp() { + + stateManager.getState(FlyCamAppState.class).getCamera().setMoveSpeed(10); + + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Blue); + + // Create a deep, mostly static scene + Spatial oct = createOctSplit("root", 500, 5); + + rootNode.attachChild(oct); + + // Position to see most of it + cam.setLocation(new Vector3f(400.8009f, 370.16455f, -408.17984f)); + cam.setRotation(new Quaternion(0.24906662f, -0.3756747f, 0.105560325f, 0.88639235f)); + + System.out.println("Total nodes:" + totalNodes + " Total Geometry:" + totalGeometry + " Total controls:" + totalControls ); + } + + protected Spatial createOctSplit( String name, int size, int depth ) { + + if( depth == 0 ) { + // Done splitting + Geometry geom = new Geometry(name, BOX); + totalGeometry++; + geom.setMaterial(mat); + + if( random.nextFloat() < 0.01 ) { + RotatorControl control = new RotatorControl(random.nextFloat(), random.nextFloat(), random.nextFloat()); + geom.addControl(control); + totalControls++; + } + + return geom; + } + + Node root = new Node(name); + totalNodes++; + + int half = size / 2; + float quarter = half * 0.5f; + + for( int i = 0; i < 2; i++ ) { + float x = i * half - quarter; + for( int j = 0; j < 2; j++ ) { + float y = j * half - quarter; + for( int k = 0; k < 2; k++ ) { + float z = k * half - quarter; + + Spatial child = createOctSplit(name + "(" + i + ", " + j + ", " + k + ")", + half, depth - 1); + child.setLocalTranslation(x, y, z); + root.attachChild(child); + } + } + } + + return root; + } + + private class RotatorControl extends AbstractControl { + final private float[] rotate; + + public RotatorControl( float... rotate ) { + this.rotate = rotate; + } + + @Override + protected void controlUpdate( float tpf ) { + if( spatial != null ) { + spatial.rotate(rotate[0] * tpf, rotate[1] * tpf, rotate[2] * tpf); + } + } + + @Override + protected void controlRender( RenderManager rm, ViewPort vp ) { + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/scene/TestUserData.java b/jme3-examples/src/main/java/jme3test/scene/TestUserData.java new file mode 100644 index 0000000000..b482f1906e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/TestUserData.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.scene; + +import com.jme3.app.SimpleApplication; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; + +public class TestUserData extends SimpleApplication { + + public static void main(String[] args) { + TestUserData app = new TestUserData(); + app.start(); + } + + @Override + public void simpleInitApp() { + Node scene = (Node) assetManager.loadModel("Scenes/DotScene/DotScene.scene"); + System.out.println("Scene: " + scene); + + Spatial testNode = scene.getChild("TestNode"); + System.out.println("TestNode: "+ testNode); + + for (String key : testNode.getUserDataKeys()){ + System.out.println("Property " + key + " = " + testNode.getUserData(key)); + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java new file mode 100644 index 0000000000..8a3da3abdd --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.scene.instancing; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Spatial; +import com.jme3.scene.Node; +import com.jme3.scene.instancing.InstancedGeometry; +import com.jme3.scene.instancing.InstancedNode; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.system.AppSettings; + +public class TestInstanceNode extends SimpleApplication { + + private Mesh mesh1; + private Mesh mesh2; + private final Material[] materials = new Material[6]; + private Node instancedNode; + private float time = 0; + final private boolean INSTANCING = true; + + public static void main(String[] args){ + TestInstanceNode app = new TestInstanceNode(); + AppSettings settings = new AppSettings(true); + settings.setVSync(false); + app.setSettings(settings); + app.start(); + } + + private Geometry createInstance(float x, float z) { + Mesh mesh; + if (FastMath.nextRandomInt(0, 1) == 1) mesh = mesh2; + else mesh = mesh1; + Geometry geometry = new Geometry("randomGeom", mesh); + geometry.setMaterial(materials[FastMath.nextRandomInt(0, materials.length - 1)]); + geometry.setLocalTranslation(x, 0, z); + return geometry; + } + + @Override + public void simpleInitApp() { + mesh1 = new Sphere(13, 13, 0.4f, true, false); + mesh2 = new Box(0.4f, 0.4f, 0.4f); + + materials[0] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + materials[0].setBoolean("UseInstancing", INSTANCING); + materials[0].setColor("Color", ColorRGBA.Red); + + materials[1] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + materials[1].setBoolean("UseInstancing", INSTANCING); + materials[1].setColor("Color", ColorRGBA.Green); + + materials[2] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + materials[2].setBoolean("UseInstancing", INSTANCING); + materials[2].setColor("Color", ColorRGBA.Blue); + + materials[3] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + materials[3].setBoolean("UseInstancing", INSTANCING); + materials[3].setColor("Color", ColorRGBA.Cyan); + + materials[4] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + materials[4].setBoolean("UseInstancing", INSTANCING); + materials[4].setColor("Color", ColorRGBA.Magenta); + + materials[5] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + materials[5].setBoolean("UseInstancing", INSTANCING); + materials[5].setColor("Color", ColorRGBA.Yellow); + + instancedNode = new InstancedNode("instanced_node"); + + rootNode.attachChild(instancedNode); + + int extent = 30; + + for (int y = -extent; y < extent; y++) { + for (int x = -extent; x < extent; x++) { + Geometry instance = createInstance(x, y); + + float height = (smoothstep(0, 1, FastMath.nextRandomFloat()) * 2.5f) - 1.25f; + instance.setUserData("height", height); + instance.setUserData("dir", 1f); + + instancedNode.attachChild(instance); + } + } + + if (INSTANCING) { + ((InstancedNode)instancedNode).instance(); + } + + //instancedNode = (InstancedNode) instancedNode.clone(); + //instancedNode.move(0, 5, 0); + //rootNode.attachChild(instancedNode); + + cam.setLocation(new Vector3f(38.373516f, 6.689055f, 38.482082f)); + cam.setRotation(new Quaternion(-0.04004206f, 0.918326f, -0.096310444f, -0.38183528f)); + flyCam.setMoveSpeed(15); + flyCam.setEnabled(false); + } + + private float smoothstep(float edge0, float edge1, float x) { + // Scale, bias and saturate x to 0..1 range + x = FastMath.clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); + // Evaluate polynomial + return x * x * (3 - 2 * x); + } + + + @Override + public void simpleUpdate(float tpf) { + time += tpf; + + if (time > 1f) { + time = 0f; + + for (Spatial instance : instancedNode.getChildren()) { + if (!(instance instanceof InstancedGeometry)) { + Geometry geom = (Geometry) instance; + geom.setMaterial(materials[FastMath.nextRandomInt(0, materials.length - 1)]); + + Mesh mesh; + if (FastMath.nextRandomInt(0, 1) == 1) mesh = mesh2; + else mesh = mesh1; + geom.setMesh(mesh); + } + } + } + + for (Spatial child : instancedNode.getChildren()) { + if (!(child instanceof InstancedGeometry)) { + float val = ((Float)child.getUserData("height")).floatValue(); + float dir = ((Float)child.getUserData("dir")).floatValue(); + + val += (dir + ((FastMath.nextRandomFloat() * 0.5f) - 0.25f)) * tpf; + + if (val > 1f) { + val = 1f; + dir = -dir; + } else if (val < 0f) { + val = 0f; + dir = -dir; + } + + Vector3f translation = child.getLocalTranslation(); + translation.y = (smoothstep(0, 1, val) * 2.5f) - 1.25f; + + child.setUserData("height", val); + child.setUserData("dir", dir); + + child.setLocalTranslation(translation); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java new file mode 100644 index 0000000000..087ce1b7c3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNodeWithLight.java @@ -0,0 +1,62 @@ +package jme3test.scene.instancing; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.instancing.InstancedNode; +import com.jme3.scene.shape.Box; + +public class TestInstanceNodeWithLight extends SimpleApplication { + // Try to test with different offset + private static float offset = 12; + + public static void main(String[] args) { + TestInstanceNodeWithLight app = new TestInstanceNodeWithLight(); + app.start(); + } + + private Geometry box; + private PointLight pointLight; + + @Override + public void simpleInitApp() { + InstancedNode instancedNode = new InstancedNode("testInstancedNode"); + rootNode.attachChild(instancedNode); + + box = new Geometry("Box", new Box(0.5f, 0.5f, 0.5f)); + Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + material.setBoolean("UseInstancing", true); + material.setColor("Diffuse", ColorRGBA.Red); + material.setBoolean("UseMaterialColors", true); + box.setMaterial(material); + + instancedNode.attachChild(box); + instancedNode.instance(); + + pointLight = new PointLight(); + pointLight.setColor(ColorRGBA.White); + pointLight.setRadius(10f); + rootNode.addLight(pointLight); + + box.setLocalTranslation(new Vector3f(offset, 0, 0)); + pointLight.setPosition(new Vector3f(offset - 3f, 0, 0)); + + cam.setLocation(new Vector3f(offset - 5f, 0, 0)); + cam.lookAtDirection(Vector3f.UNIT_X, Vector3f.UNIT_Y); + } + + @Override + public void simpleUpdate(float tpf) { + offset += tpf; + + System.err.println(offset); + box.setLocalTranslation(new Vector3f(offset, 0, 0)); + pointLight.setPosition(new Vector3f(offset - 3f, 0, 0)); + + cam.setLocation(new Vector3f(offset - 5f, 0, 0)); + cam.lookAtDirection(Vector3f.UNIT_X, Vector3f.UNIT_Y); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java new file mode 100644 index 0000000000..054f4e6efd --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithPicking.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.scene.instancing; + +import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; +import com.jme3.font.BitmapText; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Ray; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.instancing.InstancedNode; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.system.AppSettings; + + +/** + * A test case for using instancing with ray casting. + * + * Based on distance from camera, swap in/out more/less detailed geometry to/from an InstancedNode. + * + * @author duncanj + */ +public class TestInstancedNodeAttachDetachWithPicking extends SimpleApplication { + public static void main(String[] args) { + TestInstancedNodeAttachDetachWithPicking app = new TestInstancedNodeAttachDetachWithPicking(); + AppSettings settings = new AppSettings(true); + settings.setVSync(false); + app.setSettings(settings); + app.start(); + } + + private InstancedNode instancedNode; + + final private Vector3f[] locations = new Vector3f[10]; + final private Geometry[] spheres = new Geometry[10]; + final private Geometry[] boxes = new Geometry[10]; + + @Override + public void simpleInitApp() { + addPointLight(); + addAmbientLight(); + + Material material = createInstancedLightingMaterial(); + + instancedNode = new InstancedNode("theParentInstancedNode"); + rootNode.attachChild(instancedNode); + Sphere sphereMesh = new Sphere(16, 16, 1f); + Box boxMesh = new Box(0.7f, 0.7f, 0.7f); + // create 10 spheres & boxes, positioned along Z-axis successively further from the camera + for (int i = 0; i < 10; i++) { + Vector3f location = new Vector3f(0, -3, -(i*5)); + locations[i] = location; + + Geometry sphere = new Geometry("sphere", sphereMesh); + sphere.setMaterial(material); + sphere.setLocalTranslation(location); + instancedNode.attachChild(sphere); // initially just add the spheres to the InstancedNode + spheres[i] = sphere; + + Geometry box = new Geometry("box", boxMesh); + box.setMaterial(material); + box.setLocalTranslation(location); + boxes[i] = box; + } + instancedNode.instance(); + + flyCam.setMoveSpeed(30); + + + addCrossHairs(); + + // when you left-click, print the distance to the object to system.out + inputManager.addMapping("leftClick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if( isPressed ) { + CollisionResult result = pickFromCamera(); + if( result != null ) { + System.out.println("Picked = " + result.getGeometry() + ", Distance = "+result.getDistance()); + } + } + } + }, "leftClick"); + } + + @Override + public void simpleUpdate(float tpf) { + // Each frame, determine the distance to each sphere/box from the camera. + // If the object is > 25 units away, switch in the Box. If it's nearer, switch in the Sphere. + // Normally we wouldn't do this every frame, only when player has moved a sufficient distance, etc. + + + boolean modified = false; + for (int i = 0; i < 10; i++) { + Vector3f location = locations[i]; + float distance = location.distance(cam.getLocation()); + + if(distance > 25.0f && boxes[i].getParent() == null) { + modified = true; + instancedNode.attachChild(boxes[i]); + instancedNode.detachChild(spheres[i]); + } else if(distance <= 25.0f && spheres[i].getParent() == null) { + modified = true; + instancedNode.attachChild(spheres[i]); + instancedNode.detachChild(boxes[i]); + } + } + + if(modified) { + instancedNode.instance(); + } + } + + private Material createInstancedLightingMaterial() { + Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + material.setBoolean("UseMaterialColors", true); + material.setBoolean("UseInstancing", true); + material.setColor("Ambient", ColorRGBA.Red); + material.setColor("Diffuse", ColorRGBA.Red); + material.setColor("Specular", ColorRGBA.Red); + material.setFloat("Shininess", 1.0f); + return material; + } + + private void addAmbientLight() { + AmbientLight ambientLight = new AmbientLight(new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f)); + rootNode.addLight(ambientLight); + } + + private void addPointLight() { + PointLight pointLight = new PointLight(); + pointLight.setColor(ColorRGBA.White); + pointLight.setRadius(100f); + pointLight.setPosition(new Vector3f(10f, 10f, 0)); + rootNode.addLight(pointLight); + } + + private void addCrossHairs() { + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize()+4); + ch.setText("+"); // crosshairs + ch.setColor(ColorRGBA.White); + ch.setLocalTranslation( // center + settings.getWidth() / 2 - ch.getLineWidth() / 2, + settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); + guiNode.attachChild(ch); + } + + private CollisionResult pickFromCamera() { + CollisionResults results = new CollisionResults(); + Ray ray = new Ray(cam.getLocation(), cam.getDirection()); + instancedNode.collideWith(ray, results); + return results.getClosestCollision(); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java new file mode 100644 index 0000000000..6d5b76da83 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancedNodeAttachDetachWithShadowFilter.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.scene.instancing; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.instancing.InstancedNode; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.shadow.DirectionalLightShadowFilter; +import com.jme3.shadow.EdgeFilteringMode; +import com.jme3.system.AppSettings; + +/** + * A test case for using instancing with shadow filter. + * + * Based on distance from camera, swap in/out more/less detailed geometry to/from an InstancedNode. + * + * @author duncanj + */ +public class TestInstancedNodeAttachDetachWithShadowFilter extends SimpleApplication { + public static void main(String[] args) { + TestInstancedNodeAttachDetachWithShadowFilter app = new TestInstancedNodeAttachDetachWithShadowFilter(); + AppSettings settings = new AppSettings(true); + settings.setVSync(false); + app.setSettings(settings); + app.start(); + } + + private FilterPostProcessor filterPostProcessor; + private InstancedNode instancedNode; + + final private Vector3f[] locations = new Vector3f[10]; + final private Geometry[] spheres = new Geometry[10]; + final private Geometry[] boxes = new Geometry[10]; + + @Override + public void simpleInitApp() { + filterPostProcessor = new FilterPostProcessor(assetManager); + getViewPort().addProcessor(filterPostProcessor); + + addDirectionalLight(); + addAmbientLight(); + + Material instancingMaterial = createLightingMaterial(true, ColorRGBA.LightGray); + + instancedNode = new InstancedNode("theParentInstancedNode"); + instancedNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + rootNode.attachChild(instancedNode); + + // create 10 spheres & boxes, along the z-axis, successively further from the camera + Mesh sphereMesh = new Sphere(32, 32, 1f); + Mesh boxMesh = new Box(0.7f, 0.7f, 0.7f); + for (int z = 0; z < 10; z++) { + Vector3f location = new Vector3f(0, -3, -(z * 4)); + locations[z] = location; + + Geometry sphere = new Geometry("sphere", sphereMesh); + sphere.setMaterial(instancingMaterial); + sphere.setLocalTranslation(location); + instancedNode.attachChild(sphere); // initially just add the spheres to the InstancedNode + spheres[z] = sphere; + + Geometry box = new Geometry("box", boxMesh); + box.setMaterial(instancingMaterial); + box.setLocalTranslation(location); + boxes[z] = box; + } + + instancedNode.instance(); + + + Geometry floor = new Geometry("floor", new Box(20, 0.1f, 40)); + floor.setMaterial(createLightingMaterial(false, ColorRGBA.Yellow)); + floor.setLocalTranslation(5, -5, 0); + floor.setShadowMode(RenderQueue.ShadowMode.Receive); + rootNode.attachChild(floor); + + flyCam.setMoveSpeed(30); + } + + @Override + public void simpleUpdate(float tpf) { + // Each frame, determine the distance to each sphere/box from the camera. + // If the object is > 25 units away, switch in the Box. If it's nearer, switch in the Sphere. + // Normally we wouldn't do this every frame, only when player has moved a sufficient distance, etc. + + boolean modified = false; + for (int i = 0; i < 10; i++) { + Vector3f location = locations[i]; + float distance = location.distance(cam.getLocation()); + + if(distance > 25.0f && boxes[i].getParent() == null) { + modified = true; + instancedNode.attachChild(boxes[i]); + instancedNode.detachChild(spheres[i]); + } else if(distance <= 25.0f && spheres[i].getParent() == null) { + modified = true; + instancedNode.attachChild(spheres[i]); + instancedNode.detachChild(boxes[i]); + } + } + + if(modified) { + instancedNode.instance(); + } + } + + private Material createLightingMaterial(boolean useInstancing, ColorRGBA color) { + Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + material.setBoolean("UseMaterialColors", true); + material.setBoolean("UseInstancing", useInstancing); + material.setColor("Ambient", color); + material.setColor("Diffuse", color); + material.setColor("Specular", color); + material.setFloat("Shininess", 1.0f); + return material; + } + + private void addAmbientLight() { + AmbientLight ambientLight = new AmbientLight(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f)); + rootNode.addLight(ambientLight); + } + + private void addDirectionalLight() { + DirectionalLight light = new DirectionalLight(); + + light.setColor(ColorRGBA.White); + light.setDirection(new Vector3f(-1, -1, -1)); + + DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, 1024, 1); + dlsf.setLight(light); + dlsf.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON); + filterPostProcessor.addFilter(dlsf); + + rootNode.addLight(light); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java new file mode 100644 index 0000000000..f0fe8f6b7e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009-2023 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. + */ + +package jme3test.scene.instancing; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.scene.Geometry; +import com.jme3.scene.instancing.InstancedNode; +import com.jme3.scene.shape.Box; +import com.jme3.water.WaterFilter; + +/** + * A test case for using instancing with shadow filter. This is a test case + * for issue 2007 (Instanced objects are culled when using the WaterFilter). + * + * If test succeeds, all the boxes in the camera frustum will be rendered. If + * test fails, some of the boxes that are in the camera frustum will be culled. + * + * @author Ali-RS + */ +public class TestInstancingWithWaterFilter extends SimpleApplication { + public static void main(String[] args) { + TestInstancingWithWaterFilter test = new TestInstancingWithWaterFilter(); + test.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10); + + DirectionalLight light = new DirectionalLight(); + light.setDirection(new Vector3f(-1, -1, -1)); + rootNode.addLight(light); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + mat.setBoolean("UseInstancing", true); + + Box mesh = new Box(0.5f, 0.5f, 0.5f); + + InstancedNode instanceNode = new InstancedNode("TestInstancedNode"); + //instanceNode.setCullHint(Spatial.CullHint.Never); + rootNode.attachChild(instanceNode); + + for (int i = 0; i < 200; i++) { + Geometry obj = new Geometry("TestBox" + i, mesh); + obj.setMaterial(mat); + obj.setLocalTranslation(i, i, 0); + instanceNode.attachChild(obj); + } + instanceNode.instance(); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + WaterFilter waterFilter = new WaterFilter(rootNode, light.getDirection()); + fpp.addFilter(waterFilter); + viewPort.addProcessor(fpp); + } +} diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java b/jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java new file mode 100644 index 0000000000..ddce65ca9a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/instancing/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for instancing + */ +package jme3test.scene.instancing; diff --git a/jme3-examples/src/main/java/jme3test/scene/package-info.java b/jme3-examples/src/main/java/jme3test/scene/package-info.java new file mode 100644 index 0000000000..9e19c9956a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for various scene-graph features + */ +package jme3test.scene; diff --git a/jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java b/jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java new file mode 100644 index 0000000000..717ed6d8f6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestBatchLod.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.stress; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.LodControl; +import jme3tools.optimize.GeometryBatchFactory; + +public class TestBatchLod extends SimpleApplication { + + public static void main(String[] args) { + TestBatchLod app = new TestBatchLod(); + app.start(); + } + + @Override + 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); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + mat.setFloat("Shininess", 16f); + mat.setBoolean("VertexLighting", true); + teapot.setMaterial(mat); + + // A special Material to visualize mesh normals: + //Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + flyCam.setMoveSpeed(5); + for (int y = -5; y < 5; y++) { + for (int x = -5; x < 5; x++) { + Geometry clonePot = teapot.clone(); + + //clonePot.setMaterial(mat); + clonePot.setLocalTranslation(x * .5f, 0, y * .5f); + clonePot.setLocalScale(.15f); + clonePot.setMaterial(mat); + rootNode.attachChild(clonePot); + } + } + GeometryBatchFactory.optimize(rootNode, true); + LodControl control = new LodControl(); + rootNode.getChild(0).addControl(control); + cam.setLocation(new Vector3f(-1.0748308f, 1.35778f, -1.5380064f)); + cam.setRotation(new Quaternion(0.18343268f, 0.34531063f, -0.069015436f, 0.9177962f)); + + } +} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java b/jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java new file mode 100644 index 0000000000..24861464ad --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestLeakingGL.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.stress; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial.CullHint; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.NativeObjectManager; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Generates 400 new meshes every frame then leaks them. + * Notice how memory usage stays constant and OpenGL objects + * are properly destroyed. + */ +public class TestLeakingGL extends SimpleApplication { + + private Material solidColor; + private Sphere original; + + public static void main(String[] args){ + TestLeakingGL app = new TestLeakingGL(); + app.start(); + } + + @Override + public void simpleInitApp() { + original = new Sphere(4, 4, 1); + original.setStatic(); + //original.setInterleaved(); + + // this will make sure all spheres are rendered always + rootNode.setCullHint(CullHint.Never); + solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); + cam.setLocation(new Vector3f(0, 5, 0)); + cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + + Logger.getLogger(Node.class.getName()).setLevel(Level.WARNING); + Logger.getLogger(NativeObjectManager.class.getName()).setLevel(Level.WARNING); + } + + @Override + public void simpleUpdate(float tpf){ + rootNode.detachAllChildren(); + for (int y = -15; y < 15; y++){ + for (int x = -15; x < 15; x++){ + Mesh sphMesh = original.deepClone(); + Geometry sphere = new Geometry("sphere", sphMesh); + + sphere.setMaterial(solidColor); + sphere.setLocalTranslation(x * 1.5f, 0, y * 1.5f); + rootNode.attachChild(sphere); + } + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java b/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java new file mode 100644 index 0000000000..f182460251 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.stress; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ScheduledThreadPoolExecutor; + +import com.jme3.anim.SkinningControl; +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.font.BitmapText; +import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.VertexBuffer; + +import jme3tools.optimize.LodGenerator; + +public class TestLodGeneration extends SimpleApplication { + + public static void main(String[] args) { + TestLodGeneration app = new TestLodGeneration(); + app.start(); + } + + private boolean wireFrame = false; + private float reductionValue = 0.0f; + private int lodLevel = 0; + private BitmapText hudText; + final private List listGeoms = new ArrayList<>(); + final private ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(5); + + @Override + public void simpleInitApp() { + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + rootNode.addLight(dl); + + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(0.6f)); + rootNode.addLight(al); + + // model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); + Node model = (Node) assetManager.loadModel("Models/Jaime/Jaime.j3o"); + BoundingBox b = ((BoundingBox) model.getWorldBound()); + model.setLocalScale(1.2f / (b.getYExtent() * 2)); + // model.setLocalTranslation(0,-(b.getCenter().y - b.getYExtent())* model.getLocalScale().y, 0); + for (Spatial spatial : model.getChildren()) { + if (spatial instanceof Geometry) { + listGeoms.add((Geometry) spatial); + } + } + + ChaseCamera chaseCam = new ChaseCamera(cam, inputManager); + model.addControl(chaseCam); + chaseCam.setLookAtOffset(b.getCenter()); + chaseCam.setDefaultDistance(5); + chaseCam.setMinVerticalRotation(-FastMath.HALF_PI + 0.01f); + chaseCam.setZoomSensitivity(0.5f); + + SkinningControl skControl = model.getControl(SkinningControl.class); + if (skControl != null) { + skControl.setEnabled(false); + } + + reductionValue = 0.80f; + lodLevel = 1; + for (final Geometry geom : listGeoms) { + LodGenerator lodGenerator = new LodGenerator(geom); + lodGenerator.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL, reductionValue); + geom.setLodLevel(lodLevel); + } + + rootNode.attachChild(model); + flyCam.setEnabled(false); + + guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + hudText = new BitmapText(guiFont); + hudText.setSize(guiFont.getCharSet().getRenderedSize()); + hudText.setText(computeNbTri() + " tris"); + hudText.setLocalTranslation(cam.getWidth() / 2, hudText.getLineHeight(), 0); + guiNode.attachChild(hudText); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + if (name.equals("plus")) { + reductionValue += 0.05f; + updateLod(); + } + if (name.equals("minus")) { + reductionValue -= 0.05f; + updateLod(); + } + if (name.equals("wireFrame")) { + wireFrame = !wireFrame; + for (Geometry geom : listGeoms) { + Material mat = geom.getMaterial(); + mat.getAdditionalRenderState().setWireframe(wireFrame); + } + } + } + } + }, "plus", "minus", "wireFrame"); + + inputManager.addMapping("plus", new KeyTrigger(KeyInput.KEY_ADD)); + inputManager.addMapping("minus", new KeyTrigger(KeyInput.KEY_SUBTRACT)); + inputManager.addMapping("wireFrame", new KeyTrigger(KeyInput.KEY_SPACE)); + } + + @Override + public void simpleUpdate(float tpf) { + } + + @Override + public void destroy() { + super.destroy(); + exec.shutdown(); + } + + private void updateLod() { + reductionValue = FastMath.clamp(reductionValue, 0.0f, 1.0f); + makeLod(LodGenerator.TriangleReductionMethod.PROPORTIONAL, reductionValue, 1); + } + + private int computeNbTri() { + int nbTri = 0; + for (Geometry geom : listGeoms) { + Mesh mesh = geom.getMesh(); + if (mesh.getNumLodLevels() > 0) { + nbTri += mesh.getLodLevel(lodLevel).getNumElements(); + } else { + nbTri += mesh.getTriangleCount(); + } + } + return nbTri; + } + + private void makeLod(final LodGenerator.TriangleReductionMethod method, final float value, final int ll) { + exec.execute(new Runnable() { + @Override + public void run() { + for (final Geometry geom : listGeoms) { + LodGenerator lodGenerator = new LodGenerator(geom); + final VertexBuffer[] lods = lodGenerator.computeLods(method, value); + + enqueue(new Callable() { + @Override + public Void call() throws Exception { + geom.getMesh().setLodLevels(lods); + lodLevel = 0; + if (geom.getMesh().getNumLodLevels() > ll) { + lodLevel = ll; + } + geom.setLodLevel(lodLevel); + hudText.setText(computeNbTri() + " tris"); + return null; + } + }); + } + } + }); + } +} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestLodStress.java b/jme3-examples/src/main/java/jme3test/stress/TestLodStress.java new file mode 100644 index 0000000000..a02616680f --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestLodStress.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.stress; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.control.LodControl; + +public class TestLodStress extends SimpleApplication { + + public static void main(String[] args){ + TestLodStress app = new TestLodStress(); + app.setShowSettings(false); + app.setPauseOnLostFocus(false); + app.start(); + } + + @Override + public void simpleInitApp() { + 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); + +// 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); + teapot.setMaterial(mat); + + // A special Material to visualize mesh normals: + //Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); + + for (int y = -10; y < 10; y++){ + for (int x = -10; x < 10; x++){ + Geometry clonePot = teapot.clone(); + + //clonePot.setMaterial(mat); + clonePot.setLocalTranslation(x * .5f, 0, y * .5f); + clonePot.setLocalScale(.15f); + + LodControl control = new LodControl(); + clonePot.addControl(control); + rootNode.attachChild(clonePot); + } + } + + cam.setLocation(new Vector3f(8.378951f, 5.4324f, 8.795956f)); + cam.setRotation(new Quaternion(-0.083419204f, 0.90370524f, -0.20599906f, -0.36595422f)); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java b/jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java new file mode 100644 index 0000000000..a8c463b459 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestParallelTangentGeneration.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.stress; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.TangentBinormalGenerator; + +public class TestParallelTangentGeneration { + + final private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + public static void main(String[] args) { + + for (int i = 0; i < 10; i++) { + { + Node root = new Node("Root"); + for (int count = 0; count < 10; count++) { + for (int samples = 4; samples < 50; samples++) { + Geometry g = new Geometry(); + g.setMesh(new Sphere(samples, samples, 1.0f)); + root.attachChild(g); + } + } + + long start = System.currentTimeMillis(); + TangentBinormalGenerator.generate(root); + System.out.println("Serial " + (System.currentTimeMillis() - start)); + } + + { + Node root = new Node("Root"); + for (int count = 0; count < 10; count++) { + for (int samples = 4; samples < 50; samples++) { + Geometry g = new Geometry(); + g.setMesh(new Sphere(samples, samples, 1.0f)); + root.attachChild(g); + } + } + + long start = System.currentTimeMillis(); + TangentBinormalGenerator.generateParallel(root, executor); + System.out.println("Parallel " + (System.currentTimeMillis() - start)); + } + + } + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java b/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java new file mode 100644 index 0000000000..34ab16f550 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java @@ -0,0 +1,109 @@ +package jme3test.stress; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.profile.*; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Texture; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestShaderNodesStress extends SimpleApplication { + + public static void main(String[] args) { + TestShaderNodesStress app = new TestShaderNodesStress(); + app.start(); + } + + @Override + public void simpleInitApp() { + + Quad q = new Quad(1, 1); + Geometry g = new Geometry("quad", q); + g.setLocalTranslation(-500, -500, 0); + g.setLocalScale(1000); + + rootNode.attachChild(g); + cam.setLocation(new Vector3f(0.0f, 0.0f, 0.40647888f)); + cam.setRotation(new Quaternion(0.0f, 1.0f, 0.0f, 0.0f)); + + Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md"); + //Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + + mat.setColor("Color", ColorRGBA.Yellow); + mat.setTexture("ColorMap", tex); + g.setMaterial(mat); + //place the geoms in the transparent bucket so that they are rendered back to front for maximum overdraw + g.setQueueBucket(RenderQueue.Bucket.Transparent); + + for (int i = 0; i < 1000; i++) { + Geometry cl = g.clone(false); + cl.move(0, 0, -(i + 1)); + rootNode.attachChild(cl); + } + + flyCam.setMoveSpeed(20); + Logger.getLogger("com.jme3").setLevel(Level.WARNING); + + this.setAppProfiler(new Profiler()); + + } + + private class Profiler implements AppProfiler { + + private long startTime; + private long updateTime; + private long renderTime; + private long sum; + private int nbFrames; + + @Override + public void appStep(AppStep step) { + + switch (step) { + case BeginFrame: + startTime = System.nanoTime(); + break; + case RenderFrame: + updateTime = System.nanoTime(); + // System.err.println("Update time : " + (updateTime - startTime)); + break; + case EndFrame: + nbFrames++; + if (nbFrames >= 150) { + renderTime = System.nanoTime(); + sum += renderTime - updateTime; + System.err.println("render time : " + (renderTime - updateTime)); + System.err.println("Average render time : " + (sum / (float)(nbFrames-150))); + } + break; + + } + + } + + @Override + public void appSubStep(String... additionalInfo) { + + } + + @Override + public void vpStep(VpStep step, ViewPort vp, RenderQueue.Bucket bucket) { + + } + + @Override + public void spStep(SpStep step, String... additionalInfo) { + + } + + } +} diff --git a/jme3-examples/src/main/java/jme3test/stress/package-info.java b/jme3-examples/src/main/java/jme3test/stress/package-info.java new file mode 100644 index 0000000000..ab72f67ad2 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * non-automated stress tests + */ +package jme3test.stress; diff --git a/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java b/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java new file mode 100644 index 0000000000..8375db317a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainAdvancedTest.java @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.terrain; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.light.LightProbe; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.shader.VarType; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Image; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.texture.TextureArray; +import java.util.ArrayList; +import java.util.List; + +/** + * This test uses 'AdvancedPBRTerrain.j3md' to create a terrain Material with + * more textures than 'PBRTerrain.j3md' can handle. + * + * Upon running the app, the user should see a mountainous, terrain-based + * landscape with some grassy areas, some snowy areas, and some tiled roads and + * gravel paths weaving between the valleys. Snow should be slightly + * shiny/reflective, and marble texture should be even shinier. If you would + * like to know what each texture is supposed to look like, you can find the + * textures used for this test case located in jme3-testdata. (Screenshots + * showing how this test-case should look will also be available soon so you can + * compare your results, and I will replace this comment with a link to their + * location as soon as they are posted.) + * + * Press 'p' to toggle tri-planar mode. Enabling tri-planar mode should prevent + * stretching of textures in steep areas of the terrain. + * + * Press 'n' to toggle between night and day. Pressing 'n' will cause the light + * to gradually fade darker/brighter until the min/max lighting levels are + * reached. At night the scene should be noticeably darker, and the marble and + * tiled-road texture should be noticeably glowing from the emissiveColors and + * the emissiveIntensity map that is packed into the alpha channel of the + * MetallicRoughness maps. + * + * The MetallicRoughness map stores: + *

    + *
  • AmbientOcclusion in the Red channel
  • + *
  • Roughness in the Green channel
  • + *
  • Metallic in the Blue channel
  • + *
  • EmissiveIntensity in the Alpha channel
  • + *
+ * + * The shaders are still subject to the GLSL max limit of 16 textures, however + * each TextureArray counts as a single texture, and each TextureArray can store + * multiple images. For more information on texture arrays see: + * https://www.khronos.org/opengl/wiki/Array_Texture + * + * Uses assets from CC0Textures.com, licensed under CC0 1.0 Universal. For more + * information on the textures this test case uses, view the license.txt file + * located in the jme3-testdata directory where these textures are located: + * jme3-testdata/src/main/resources/Textures/Terrain/PBR + * + *

+ * Notes: (as of 12 April 2021) + *

    + *
  1. + * The results look better with anti-aliasing, especially from a distance. This + * may be due to the way that the terrain is generated from a heightmap, as + * these same textures do not have this issue in my other project. + *
  2. + *
  3. + * The number of images per texture array may still be limited by + * GL_MAX_ARRAY_TEXTURE_LAYERS, however this value should be high enough that + * users will likely run into issues with extremely low FPS from too many + * texture-reads long before you surpass the limit of texture-layers per + * textureArray. If this ever becomes an issue, a secondary set of + * Albedo/Normal/MetallicRoughness texture arrays could be added to the shader + * to store any textures that surpass the limit of the primary textureArrays. + *
  4. + *
+ * + * @author yaRnMcDonuts + */ +public class PBRTerrainAdvancedTest extends SimpleApplication { + + private TerrainQuad terrain; + private Material matTerrain; + private boolean triPlanar = false; + + private final int terrainSize = 512; + private final int patchSize = 256; + private final float dirtScale = 24; + private final float darkRockScale = 24; + private final float snowScale = 64; + private final float tileRoadScale = 64; + private final float grassScale = 24; + private final float marbleScale = 64; + private final float gravelScale = 64; + + private final ColorRGBA tilesEmissiveColor = new ColorRGBA(0.12f, 0.02f, 0.23f, 0.85f); //dim magenta emission + private final ColorRGBA marbleEmissiveColor = new ColorRGBA(0.0f, 0.0f, 1.0f, 1.0f); //fully saturated blue emission + + private AmbientLight ambientLight; + private DirectionalLight directionalLight; + private boolean isNight = false; + + private final float dayLightIntensity = 1.0f; + private final float nightLightIntensity = 0.03f; + + private BitmapText keybindingsText; + + private final float camMoveSpeed = 50f; + + public static void main(String[] args) { + PBRTerrainAdvancedTest app = new PBRTerrainAdvancedTest(); + app.start(); + } + + private final ActionListener actionListener = new ActionListener() { + @Override + public void onAction(String name, boolean pressed, float tpf) { + if (name.equals("triPlanar") && !pressed) { + triPlanar = !triPlanar; + if (triPlanar) { + matTerrain.setBoolean("useTriPlanarMapping", true); + // Tri-planar textures don't use the mesh's texture coordinates but real world coordinates, + // so we need to convert these texture coordinate scales into real world scales so it looks + // the same when we switch to/from tri-planar mode. + matTerrain.setFloat("AlbedoMap_0_scale", (dirtScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_1_scale", (darkRockScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_2_scale", (snowScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_3_scale", (tileRoadScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_4_scale", (grassScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_5_scale", (marbleScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_6_scale", (gravelScale / terrainSize)); + } else { + matTerrain.setBoolean("useTriPlanarMapping", false); + + matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); + matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); + matTerrain.setFloat("AlbedoMap_2_scale", snowScale); + matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); + matTerrain.setFloat("AlbedoMap_4_scale", grassScale); + matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); + matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); + } + } + if (name.equals("toggleNight") && !pressed) { + isNight = !isNight; + // Ambient and directional light are faded smoothly in update loop below. + } + } + }; + + @Override + public void simpleInitApp() { + setupKeys(); + setUpTerrain(); + setUpTerrainMaterial(); // <- This method contains the important info about using 'AdvancedPBRTerrain.j3md' + setUpLights(); + setUpCamera(); + } + + private void setUpTerrainMaterial() { + // advanced PBR terrain matdef + matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md"); + + matTerrain.setBoolean("useTriPlanarMapping", false); + + // ALPHA map (for splat textures) + matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); + matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); + // this material also supports 'AlphaMap_2', so you can get up to 12 texture slots + + // load textures for texture arrays + // These MUST all have the same dimensions and format in order to be put into a texture array. + //ALBEDO MAPS + Texture dirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); + Texture darkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Color.png"); + Texture snow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Color.png"); + Texture tileRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Color.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); + Texture marble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Color.png"); + Texture gravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Color.png"); + + // NORMAL MAPS + Texture normalMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_1K_Normal.png"); + Texture normalMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Normal.png"); + Texture normalMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Normal.png"); + Texture normalMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Normal.png"); + Texture normalMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Normal.png"); + Texture normalMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Normal.png"); + Texture normalMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Normal.png"); + + //PACKED METALLIC/ROUGHNESS / AMBIENT OCCLUSION / EMISSIVE INTENSITY MAPS + Texture metallicRoughnessAoEiMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_PackedMetallicRoughnessMap.png"); + Texture metallicRoughnessAoEiMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_PackedMetallicRoughnessMap.png"); + Texture metallicRoughnessAoEiMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_PackedMetallicRoughnessMap.png"); + Texture metallicRoughnessAoEiMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel_015_PackedMetallicRoughnessMap.png"); + Texture metallicRoughnessAoEiMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_PackedMetallicRoughnessMap.png"); + Texture metallicRoughnessAoEiMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_PackedMetallicRoughnessMap.png"); + Texture metallicRoughnessAoEiMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_PackedMetallicRoughnessMap.png"); + + // put all images into lists to create texture arrays. + // + // The index of each image in its list will be + // sent to the material to tell the shader to choose that texture from + // the textureArray when setting up a texture slot's mat params. + // + List albedoImages = new ArrayList<>(); + List normalMapImages = new ArrayList<>(); + List metallicRoughnessAoEiMapImages = new ArrayList<>(); + + albedoImages.add(dirt.getImage()); //0 + albedoImages.add(darkRock.getImage()); //1 + albedoImages.add(snow.getImage()); //2 + albedoImages.add(tileRoad.getImage()); //3 + albedoImages.add(grass.getImage()); //4 + albedoImages.add(marble.getImage()); //5 + albedoImages.add(gravel.getImage()); //6 + + normalMapImages.add(normalMapDirt.getImage()); //0 + normalMapImages.add(normalMapDarkRock.getImage()); //1 + normalMapImages.add(normalMapSnow.getImage()); //2 + normalMapImages.add(normalMapRoad.getImage()); //3 + normalMapImages.add(normalMapGrass.getImage()); //4 + normalMapImages.add(normalMapMarble.getImage()); //5 + normalMapImages.add(normalMapGravel.getImage()); //6 + + metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDirt.getImage()); //0 + metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDarkRock.getImage()); //1 + metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapSnow.getImage()); //2 + metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapRoad.getImage()); //3 + metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGrass.getImage()); //4 + metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapMarble.getImage()); //5 + metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGravel.getImage()); //6 + + //initiate texture arrays + TextureArray albedoTextureArray = new TextureArray(albedoImages); + TextureArray normalParallaxTextureArray = new TextureArray(normalMapImages); // parallax is not used currently + TextureArray metallicRoughnessAoEiTextureArray = new TextureArray(metallicRoughnessAoEiMapImages); + + //apply wrapMode to the whole texture array, rather than each individual texture in the array + albedoTextureArray.setWrap(WrapMode.Repeat); + normalParallaxTextureArray.setWrap(WrapMode.Repeat); + metallicRoughnessAoEiTextureArray.setWrap(WrapMode.Repeat); + + //assign texture array to materials + matTerrain.setParam("AlbedoTextureArray", VarType.TextureArray, albedoTextureArray); + matTerrain.setParam("NormalParallaxTextureArray", VarType.TextureArray, normalParallaxTextureArray); + matTerrain.setParam("MetallicRoughnessAoEiTextureArray", VarType.TextureArray, metallicRoughnessAoEiTextureArray); + + //set up texture slots: + matTerrain.setInt("AlbedoMap_0", 0); // dirt is index 0 in the albedo image list + matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); + matTerrain.setFloat("Roughness_0", 1); + matTerrain.setFloat("Metallic_0", 0.02f); + + matTerrain.setInt("AlbedoMap_1", 1); // darkRock is index 1 in the albedo image list + matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); + matTerrain.setFloat("Roughness_1", 1); + matTerrain.setFloat("Metallic_1", 0.04f); + + matTerrain.setInt("AlbedoMap_2", 2); + matTerrain.setFloat("AlbedoMap_2_scale", snowScale); + matTerrain.setFloat("Roughness_2", 0.72f); + matTerrain.setFloat("Metallic_2", 0.12f); + + matTerrain.setInt("AlbedoMap_3", 3); + matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); + matTerrain.setFloat("Roughness_3", 1); + matTerrain.setFloat("Metallic_3", 0.04f); + + matTerrain.setInt("AlbedoMap_4", 4); + matTerrain.setFloat("AlbedoMap_4_scale", grassScale); + matTerrain.setFloat("Roughness_4", 1); + matTerrain.setFloat("Metallic_4", 0); + + matTerrain.setInt("AlbedoMap_5", 5); + matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); + matTerrain.setFloat("Roughness_5", 1); + matTerrain.setFloat("Metallic_5", 0.2f); + + matTerrain.setInt("AlbedoMap_6", 6); + matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); + matTerrain.setFloat("Roughness_6", 1); + matTerrain.setFloat("Metallic_6", 0.01f); + + // NORMAL MAPS + // int being passed to shader corresponds to the index of the texture's + // image in the List of images used to create its texture array + matTerrain.setInt("NormalMap_0", 0); + matTerrain.setInt("NormalMap_1", 1); + matTerrain.setInt("NormalMap_2", 2); + matTerrain.setInt("NormalMap_3", 3); + matTerrain.setInt("NormalMap_4", 4); + matTerrain.setInt("NormalMap_5", 5); + matTerrain.setInt("NormalMap_6", 6); + + //METALLIC/ROUGHNESS/AO/EI MAPS + matTerrain.setInt("MetallicRoughnessMap_0", 0); + matTerrain.setInt("MetallicRoughnessMap_1", 1); + matTerrain.setInt("MetallicRoughnessMap_2", 2); + matTerrain.setInt("MetallicRoughnessMap_3", 3); + matTerrain.setInt("MetallicRoughnessMap_4", 4); + matTerrain.setInt("MetallicRoughnessMap_5", 5); + matTerrain.setInt("MetallicRoughnessMap_6", 6); + + //EMISSIVE + matTerrain.setColor("EmissiveColor_5", marbleEmissiveColor); + matTerrain.setColor("EmissiveColor_3", tilesEmissiveColor); + //these two texture slots (marble & tiledRoad, indexed in each texture array at 5 and 3 respectively) both + // have packed MRAoEi maps with an emissiveTexture packed into the alpha channel + +// matTerrain.setColor("EmissiveColor_1", new ColorRGBA(0.08f, 0.01f, 0.1f, 0.4f)); +//this texture slot does not have a unique emissiveIntensityMap packed into its MRAoEi map, + // so setting an emissiveColor will apply equal intensity to every pixel + + terrain.setMaterial(matTerrain); + } + + private void setupKeys() { + flyCam.setMoveSpeed(50); + inputManager.addMapping("triPlanar", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addMapping("toggleNight", new KeyTrigger(KeyInput.KEY_N)); + + inputManager.addListener(actionListener, "triPlanar"); + inputManager.addListener(actionListener, "toggleNight"); + + keybindingsText = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt")); + keybindingsText.setText("Press 'N' to toggle day/night fade (takes a moment) \nPress 'P' to toggle tri-planar mode"); + + getGuiNode().attachChild(keybindingsText); + keybindingsText.move(new Vector3f(200, 120, 0)); + } + + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + + //smoothly transition from day to night + float currentLightIntensity = ambientLight.getColor().getRed(); + float incrementPerFrame = tpf * 0.3f; + + if (isNight) { + if (ambientLight.getColor().getRed() > nightLightIntensity) { + currentLightIntensity -= incrementPerFrame; + if (currentLightIntensity < nightLightIntensity) { + currentLightIntensity = nightLightIntensity; + } + + ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + } + } else { + if (ambientLight.getColor().getRed() < dayLightIntensity) { + currentLightIntensity += incrementPerFrame; + if (currentLightIntensity > dayLightIntensity) { + currentLightIntensity = dayLightIntensity; + } + + ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + } + } + } + + private void setUpTerrain() { + // HEIGHTMAP image (for the terrain heightmap) + TextureKey hmKey = new TextureKey("Textures/Terrain/splat/mountains512.png", false); + Texture heightMapImage = assetManager.loadTexture(hmKey); + + // CREATE HEIGHTMAP + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.3f); + heightmap.load(); + heightmap.smooth(0.9f, 1); + + } catch (Exception e) { + e.printStackTrace(); + } + + terrain = new TerrainQuad("terrain", patchSize + 1, terrainSize + 1, heightmap.getHeightMap()); +//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations + TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); + control.setLodCalculator(new DistanceLodCalculator(patchSize + 1, 2.7f)); // patch size, and a multiplier + terrain.addControl(control); + terrain.setMaterial(matTerrain); + terrain.setLocalTranslation(0, -100, 0); + terrain.setLocalScale(1f, 1f, 1f); + rootNode.attachChild(terrain); + } + + private void setUpLights() { + LightProbe probe = (LightProbe) assetManager.loadAsset("Scenes/LightProbes/quarry_Probe.j3o"); + + probe.setAreaType(LightProbe.AreaType.Spherical); + probe.getArea().setRadius(2000); + probe.getArea().setCenter(new Vector3f(0, 0, 0)); + rootNode.addLight(probe); + + directionalLight = new DirectionalLight(); + directionalLight.setDirection((new Vector3f(-0.3f, -0.5f, -0.3f)).normalize()); + directionalLight.setColor(ColorRGBA.White); + rootNode.addLight(directionalLight); + + ambientLight = new AmbientLight(); + directionalLight.setColor(ColorRGBA.White); + rootNode.addLight(ambientLight); + } + + private void setUpCamera() { + cam.setLocation(new Vector3f(0, 10, -10)); + cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y); + + getFlyByCamera().setMoveSpeed(camMoveSpeed); + } +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java b/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java new file mode 100644 index 0000000000..db17e0da26 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/PBRTerrainTest.java @@ -0,0 +1,365 @@ +package jme3test.terrain; + +/* + * Copyright (c) 2009-2021 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. + */ +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.light.LightProbe; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; + +/** + * This test uses 'PBRTerrain.j3md' to create a terrain Material for PBR. + * + * Upon running the app, the user should see a mountainous, terrain-based + * landscape with some grassy areas, some snowy areas, and some tiled roads and + * gravel paths weaving between the valleys. Snow should be slightly + * shiny/reflective, and marble texture should be even shinier. If you would + * like to know what each texture is supposed to look like, you can find the + * textures used for this test case located in jme3-testdata. (Screenshots + * showing how this test-case should look will also be available soon so you can + * compare your results, and I will replace this comment with a link to their + * location as soon as they are posted.) + * + * Press 'p' to toggle tri-planar mode. Enabling tri-planar mode should prevent + * stretching of textures in steep areas of the terrain. + * + * Press 'n' to toggle between night and day. Pressing 'n' will cause the light + * to gradually fade darker/brighter until the min/max lighting levels are + * reached. At night the scene should be noticeably darker. + * + * Uses assets from CC0Textures.com, licensed under CC0 1.0 Universal. For more + * information on the textures this test case uses, view the license.txt file + * located in the jme3-testdata directory where these textures are located: + * jme3-testdata/src/main/resources/Textures/Terrain/PBR + * + *

+ * Notes: (as of 12 April 2021) + *

    + *
  1. + * This shader is subject to the GLSL max limit of 16 textures, and users should + * consider using "AdvancedPBRTerrain.j3md" instead if they need additional + * texture slots. + *
  2. + *
+ * + * @author yaRnMcDonuts + */ +public class PBRTerrainTest extends SimpleApplication { + + private TerrainQuad terrain; + private Material matTerrain; + private boolean triPlanar = false; + + private final int terrainSize = 512; + private final int patchSize = 256; + private final float dirtScale = 24; + private final float darkRockScale = 24; + private final float snowScale = 64; + private final float tileRoadScale = 64; + private final float grassScale = 24; + private final float marbleScale = 64; + private final float gravelScale = 64; + + private AmbientLight ambientLight; + private DirectionalLight directionalLight; + private boolean isNight = false; + + private final float dayLightIntensity = 1.0f; + private final float nightLightIntensity = 0.03f; + + private BitmapText keybindingsText; + + private final float camMoveSpeed = 50f; + + public static void main(String[] args) { + PBRTerrainTest app = new PBRTerrainTest(); + app.start(); + } + + private final ActionListener actionListener = new ActionListener() { + @Override + public void onAction(String name, boolean pressed, float tpf) { + if (name.equals("triPlanar") && !pressed) { + triPlanar = !triPlanar; + if (triPlanar) { + matTerrain.setBoolean("useTriPlanarMapping", true); + // Tri-planar textures don't use the mesh's texture coordinates but real world coordinates, + // so we need to convert these texture coordinate scales into real world scales so it looks + // the same when we switch to/from tri-planar mode. + matTerrain.setFloat("AlbedoMap_0_scale", (dirtScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_1_scale", (darkRockScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_2_scale", (snowScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_3_scale", (tileRoadScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_4_scale", (grassScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_5_scale", (marbleScale / terrainSize)); + matTerrain.setFloat("AlbedoMap_6_scale", (gravelScale / terrainSize)); + } else { + matTerrain.setBoolean("useTriPlanarMapping", false); + + matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); + matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); + matTerrain.setFloat("AlbedoMap_2_scale", snowScale); + matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); + matTerrain.setFloat("AlbedoMap_4_scale", grassScale); + matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); + matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); + } + } + if (name.equals("toggleNight") && !pressed) { + isNight = !isNight; + // Ambient and directional light are faded smoothly in update loop below. + } + } + }; + + @Override + public void simpleInitApp() { + setupKeys(); + setUpTerrain(); + setUpTerrainMaterial(); + setUpLights(); + setUpCamera(); + } + + private void setUpTerrainMaterial() { + // PBR terrain matdef + matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/PBRTerrain.j3md"); + + matTerrain.setBoolean("useTriPlanarMapping", false); + + // ALPHA map (for splat textures) + matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); + matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); + // this material also supports 'AlphaMap_2', so you can get up to 12 diffuse textures + + // DIRT texture, Diffuse textures 0 to 3 use the first AlphaMap + Texture dirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); + dirt.setWrap(WrapMode.Repeat); + matTerrain.setTexture("AlbedoMap_0", dirt); + matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); + matTerrain.setFloat("Roughness_0", 1); + matTerrain.setFloat("Metallic_0", 0); + //matTerrain.setInt("AfflictionMode_0", 0); + + // DARK ROCK texture + Texture darkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Color.png"); + darkRock.setWrap(WrapMode.Repeat); + matTerrain.setTexture("AlbedoMap_1", darkRock); + matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); + matTerrain.setFloat("Roughness_1", 0.92f); + matTerrain.setFloat("Metallic_1", 0.02f); + //matTerrain.setInt("AfflictionMode_1", 0); + + // SNOW texture + Texture snow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Color.png"); + snow.setWrap(WrapMode.Repeat); + matTerrain.setTexture("AlbedoMap_2", snow); + matTerrain.setFloat("AlbedoMap_2_scale", snowScale); + matTerrain.setFloat("Roughness_2", 0.55f); + matTerrain.setFloat("Metallic_2", 0.12f); + + Texture tiles = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Color.png"); + tiles.setWrap(WrapMode.Repeat); + matTerrain.setTexture("AlbedoMap_3", tiles); + matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); + matTerrain.setFloat("Roughness_3", 0.87f); + matTerrain.setFloat("Metallic_3", 0.08f); + + // GRASS texture + Texture grass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); + grass.setWrap(WrapMode.Repeat); + matTerrain.setTexture("AlbedoMap_4", grass); + matTerrain.setFloat("AlbedoMap_4_scale", grassScale); + matTerrain.setFloat("Roughness_4", 1); + matTerrain.setFloat("Metallic_4", 0); + + // MARBLE texture + Texture marble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Color.png"); + marble.setWrap(WrapMode.Repeat); + matTerrain.setTexture("AlbedoMap_5", marble); + matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); + matTerrain.setFloat("Roughness_5", 0.06f); + matTerrain.setFloat("Metallic_5", 0.8f); + + // Gravel texture + Texture gravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Color.png"); + gravel.setWrap(WrapMode.Repeat); + matTerrain.setTexture("AlbedoMap_6", gravel); + matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); + matTerrain.setFloat("Roughness_6", 0.9f); + matTerrain.setFloat("Metallic_6", 0.07f); + // NORMAL MAPS + Texture normalMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_1K_Normal.png"); + normalMapDirt.setWrap(WrapMode.Repeat); + + Texture normalMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Normal.png"); + normalMapDarkRock.setWrap(WrapMode.Repeat); + + Texture normalMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Normal.png"); + normalMapSnow.setWrap(WrapMode.Repeat); + + Texture normalMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Normal.png"); + normalMapGravel.setWrap(WrapMode.Repeat); + + Texture normalMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Normal.png"); + normalMapGrass.setWrap(WrapMode.Repeat); + +// Texture normalMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Normal.png"); +// normalMapMarble.setWrap(WrapMode.Repeat); + + Texture normalMapTiles = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Normal.png"); + normalMapTiles.setWrap(WrapMode.Repeat); + + matTerrain.setTexture("NormalMap_0", normalMapDirt); + matTerrain.setTexture("NormalMap_1", normalMapDarkRock); + matTerrain.setTexture("NormalMap_2", normalMapSnow); + matTerrain.setTexture("NormalMap_3", normalMapTiles); + matTerrain.setTexture("NormalMap_4", normalMapGrass); +// matTerrain.setTexture("NormalMap_5", normalMapMarble); // Adding this texture would exceed the 16 texture limit. + matTerrain.setTexture("NormalMap_6", normalMapGravel); + + terrain.setMaterial(matTerrain); + } + + private void setupKeys() { + flyCam.setMoveSpeed(50); + inputManager.addMapping("triPlanar", new KeyTrigger(KeyInput.KEY_P)); + inputManager.addMapping("toggleNight", new KeyTrigger(KeyInput.KEY_N)); + + inputManager.addListener(actionListener, "triPlanar"); + inputManager.addListener(actionListener, "toggleNight"); + + keybindingsText = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt")); + keybindingsText.setText("Press 'N' to toggle day/night fade (takes a moment) \nPress 'P' to toggle tri-planar mode"); + + getGuiNode().attachChild(keybindingsText); + keybindingsText.move(new Vector3f(200, 120, 0)); + } + + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + + //smoothly transition from day to night + float currentLightIntensity = ambientLight.getColor().getRed(); + float incrementPerFrame = tpf * 0.3f; + + if (isNight) { + if (ambientLight.getColor().getRed() > nightLightIntensity) { + currentLightIntensity -= incrementPerFrame; + if (currentLightIntensity < nightLightIntensity) { + currentLightIntensity = nightLightIntensity; + } + + ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + } + } else { + if (ambientLight.getColor().getRed() < dayLightIntensity) { + currentLightIntensity += incrementPerFrame; + if (currentLightIntensity > dayLightIntensity) { + currentLightIntensity = dayLightIntensity; + } + + ambientLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + directionalLight.getColor().set(currentLightIntensity, currentLightIntensity, currentLightIntensity, 1.0f); + } + } + } + + private void setUpTerrain() { + // HEIGHTMAP image (for the terrain heightmap) + TextureKey hmKey = new TextureKey("Textures/Terrain/splat/mountains512.png", false); + Texture heightMapImage = assetManager.loadTexture(hmKey); + + // CREATE HEIGHTMAP + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.3f); + heightmap.load(); + heightmap.smooth(0.9f, 1); + + } catch (Exception e) { + e.printStackTrace(); + } + + terrain = new TerrainQuad("terrain", patchSize + 1, terrainSize + 1, heightmap.getHeightMap()); +//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations + TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); + control.setLodCalculator(new DistanceLodCalculator(patchSize + 1, 2.7f)); // patch size, and a multiplier + terrain.addControl(control); + terrain.setMaterial(matTerrain); + terrain.setLocalTranslation(0, -100, 0); + terrain.setLocalScale(1f, 1f, 1f); + rootNode.attachChild(terrain); + } + + private void setUpLights() { + LightProbe probe = (LightProbe) assetManager.loadAsset("Scenes/LightProbes/quarry_Probe.j3o"); + + probe.setAreaType(LightProbe.AreaType.Spherical); + probe.getArea().setRadius(2000); + probe.getArea().setCenter(new Vector3f(0, 0, 0)); + rootNode.addLight(probe); + + directionalLight = new DirectionalLight(); + directionalLight.setDirection((new Vector3f(-0.3f, -0.5f, -0.3f)).normalize()); + directionalLight.setColor(ColorRGBA.White); + rootNode.addLight(directionalLight); + + ambientLight = new AmbientLight(); + directionalLight.setColor(ColorRGBA.White); + rootNode.addLight(ambientLight); + } + + private void setUpCamera() { + cam.setLocation(new Vector3f(0, 10, -10)); + cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y); + + getFlyByCamera().setMoveSpeed(camMoveSpeed); + } +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java new file mode 100644 index 0000000000..76d10a8220 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/TerrainFractalGridTest.java @@ -0,0 +1,141 @@ +package jme3test.terrain; + +import com.jme3.app.SimpleApplication; +import com.jme3.app.state.ScreenshotAppState; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.terrain.geomipmap.TerrainGrid; +import com.jme3.terrain.geomipmap.TerrainGridLodControl; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.grid.FractalTileLoader; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.noise.ShaderUtils; +import com.jme3.terrain.noise.basis.FilteredBasis; +import com.jme3.terrain.noise.filter.IterativeFilter; +import com.jme3.terrain.noise.filter.OptimizedErode; +import com.jme3.terrain.noise.filter.PerturbFilter; +import com.jme3.terrain.noise.filter.SmoothFilter; +import com.jme3.terrain.noise.fractal.FractalSum; +import com.jme3.terrain.noise.modulator.NoiseModulator; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; + +public class TerrainFractalGridTest extends SimpleApplication { + + final private float grassScale = 64; + final private float dirtScale = 16; + final private float rockScale = 128; + + public static void main(final String[] args) { + TerrainFractalGridTest app = new TerrainFractalGridTest(); + app.start(); + } + + @Override + public void simpleInitApp() { + this.flyCam.setMoveSpeed(100f); + ScreenshotAppState state = new ScreenshotAppState(); + this.stateManager.attach(state); + + // TERRAIN TEXTURE material + Material mat_terrain = new Material(this.assetManager, + "Common/MatDefs/Terrain/HeightBasedTerrain.j3md"); + + // Parameters to material: + // regionXColorMap: X = 1..4 the texture that should be applied to state X + // regionX: a Vector3f containing the following information: + // regionX.x: the start height of the region + // regionX.y: the end height of the region + // regionX.z: the texture scale for the region + // it might not be the most elegant way for storing these 3 values, but it packs the data nicely :) + // slopeColorMap: the texture to be used for cliffs, and steep mountain sites + // slopeTileFactor: the texture scale for slopes + // terrainSize: the total size of the terrain (used for scaling the texture) + // GRASS texture + Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("region1ColorMap", grass); + mat_terrain.setVector3("region1", new Vector3f(15, 200, this.grassScale)); + + // DIRT texture + Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("region2ColorMap", dirt); + mat_terrain.setVector3("region2", new Vector3f(0, 20, this.dirtScale)); + + // ROCK texture + Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg"); + rock.setWrap(WrapMode.Repeat); + mat_terrain.setTexture("region3ColorMap", rock); + mat_terrain.setVector3("region3", new Vector3f(198, 260, this.rockScale)); + + mat_terrain.setTexture("region4ColorMap", rock); + mat_terrain.setVector3("region4", new Vector3f(198, 260, this.rockScale)); + + mat_terrain.setTexture("slopeColorMap", rock); + mat_terrain.setFloat("slopeTileFactor", 32); + + mat_terrain.setFloat("terrainSize", 513); + + FractalSum base = new FractalSum(); + base.setRoughness(0.7f); + base.setFrequency(1.0f); + base.setAmplitude(1.0f); + base.setLacunarity(2.12f); + base.setOctaves(8); + base.setScale(0.02125f); + base.addModulator(new NoiseModulator() { + + @Override + public float value(float... in) { + return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1); + } + }); + + FilteredBasis ground = new FilteredBasis(base); + + PerturbFilter perturb = new PerturbFilter(); + perturb.setMagnitude(0.119f); + + OptimizedErode therm = new OptimizedErode(); + therm.setRadius(5); + therm.setTalus(0.011f); + + SmoothFilter smooth = new SmoothFilter(); + smooth.setRadius(1); + smooth.setEffect(0.7f); + + IterativeFilter iterate = new IterativeFilter(); + iterate.addPreFilter(perturb); + iterate.addPostFilter(smooth); + iterate.setFilter(therm); + iterate.setIterations(1); + + ground.addPreFilter(iterate); + + TerrainGrid terrain + = new TerrainGrid("terrain", 33, 129, new FractalTileLoader(ground, 256f)); + terrain.setMaterial(mat_terrain); + terrain.setLocalTranslation(0, 0, 0); + terrain.setLocalScale(2f, 1f, 2f); + this.rootNode.attachChild(terrain); + + TerrainLodControl control + = new TerrainGridLodControl(terrain, this.getCamera()); + control.setLodCalculator(new DistanceLodCalculator(33, 2.7f)); // patch size, and a multiplier + terrain.addControl(control); + + this.getCamera().setLocation(new Vector3f(0, 300, 0)); + cam.setRotation(new Quaternion(0.51176f, -0.14f, 0.085f, 0.84336f)); + + this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); + + + } + + @Override + public void simpleUpdate(final float tpf) { + } +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java new file mode 100644 index 0000000000..a5f01976bd --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/TerrainGridAlphaMapTest.java @@ -0,0 +1,359 @@ +package jme3test.terrain; + +import com.jme3.app.SimpleApplication; +import com.jme3.app.state.ScreenshotAppState; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.asset.plugins.ZipLocator; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; +import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; +import com.jme3.bullet.control.CharacterControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.debug.Arrow; +import com.jme3.terrain.geomipmap.TerrainGrid; +import com.jme3.terrain.geomipmap.TerrainGridListener; +import com.jme3.terrain.geomipmap.TerrainGridLodControl; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.grid.FractalTileLoader; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.noise.ShaderUtils; +import com.jme3.terrain.noise.basis.FilteredBasis; +import com.jme3.terrain.noise.filter.IterativeFilter; +import com.jme3.terrain.noise.filter.OptimizedErode; +import com.jme3.terrain.noise.filter.PerturbFilter; +import com.jme3.terrain.noise.filter.SmoothFilter; +import com.jme3.terrain.noise.fractal.FractalSum; +import com.jme3.terrain.noise.modulator.NoiseModulator; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import java.io.File; + +public class TerrainGridAlphaMapTest extends SimpleApplication { + + private TerrainGrid terrain; + final private float grassScale = 64; + final private float dirtScale = 16; + final private float rockScale = 128; + private boolean usePhysics = false; + + public static void main(final String[] args) { + TerrainGridAlphaMapTest app = new TerrainGridAlphaMapTest(); + app.start(); + } + private CharacterControl player3; + + @Override + public void simpleInitApp() { + DirectionalLight sun = new DirectionalLight(); + sun.setColor(ColorRGBA.White); + sun.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + rootNode.addLight(sun); + + AmbientLight al = new AmbientLight(); + al.setColor(ColorRGBA.White.mult(1.3f)); + rootNode.addLight(al); + + File file = new File("TerrainGridTestData.zip"); + if (!file.exists()) { + assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/TerrainGridTestData.zip", HttpZipLocator.class); + } else { + assetManager.registerLocator("TerrainGridTestData.zip", ZipLocator.class); + } + + this.flyCam.setMoveSpeed(100f); + ScreenshotAppState state = new ScreenshotAppState(); + this.stateManager.attach(state); + + // TERRAIN TEXTURE material + Material material = new Material(assetManager, + "Common/MatDefs/Terrain/TerrainLighting.j3md"); + material.setBoolean("useTriPlanarMapping", false); + //material.setBoolean("isTerrainGrid", true); + material.setFloat("Shininess", 0.0f); + + // GRASS texture + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + material.setTexture("DiffuseMap", grass); + material.setFloat("DiffuseMap_0_scale", grassScale); + + // DIRT texture + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + material.setTexture("DiffuseMap_1", dirt); + material.setFloat("DiffuseMap_1_scale", dirtScale); + + // ROCK texture + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + material.setTexture("DiffuseMap_2", rock); + material.setFloat("DiffuseMap_2_scale", rockScale); + + // WIREFRAME material + Material matWire = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + matWire.getAdditionalRenderState().setWireframe(true); + matWire.setColor("Color", ColorRGBA.Green); + + FractalSum base = new FractalSum(); + base.setRoughness(0.7f); + base.setFrequency(1.0f); + base.setAmplitude(1.0f); + base.setLacunarity(2.12f); + base.setOctaves(8); + base.setScale(0.02125f); + base.addModulator(new NoiseModulator() { + + @Override + public float value(float... in) { + return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1); + } + }); + + FilteredBasis ground = new FilteredBasis(base); + + PerturbFilter perturb = new PerturbFilter(); + perturb.setMagnitude(0.119f); + + OptimizedErode therm = new OptimizedErode(); + therm.setRadius(5); + therm.setTalus(0.011f); + + SmoothFilter smooth = new SmoothFilter(); + smooth.setRadius(1); + smooth.setEffect(0.7f); + + IterativeFilter iterate = new IterativeFilter(); + iterate.addPreFilter(perturb); + iterate.addPostFilter(smooth); + iterate.setFilter(therm); + iterate.setIterations(1); + + ground.addPreFilter(iterate); + + this.terrain = new TerrainGrid("terrain", 33, 257, new FractalTileLoader(ground, 256)); + this.terrain.setMaterial(material); + + this.terrain.setLocalTranslation(0, 0, 0); + this.terrain.setLocalScale(2f, 1f, 2f); + this.rootNode.attachChild(this.terrain); + + TerrainLodControl control = new TerrainGridLodControl(this.terrain, this.getCamera()); + control.setLodCalculator( new DistanceLodCalculator(33, 2.7f) ); // patch size, and a multiplier + this.terrain.addControl(control); + + final BulletAppState bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + + + this.getCamera().setLocation(new Vector3f(0, 256, 0)); + cam.setRotation(new Quaternion(-0.1f, 0.89826f, -0.2695f, -0.3325f)); + + this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); + + if (usePhysics) { + CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1); + player3 = new CharacterControl(capsuleShape, 0.5f); + player3.setJumpSpeed(20); + player3.setFallSpeed(10); + player3.setGravity(10); + + player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z)); + + bulletAppState.getPhysicsSpace().add(player3); + + } + terrain.addListener(new TerrainGridListener() { + + @Override + public void gridMoved(Vector3f newCenter) { + } + + @Override + public void tileAttached(Vector3f cell, TerrainQuad quad) { + Texture alpha = null; + try { + alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_" + (int)cell.x+ "_" + (int)cell.z + ".png"); + } catch (Exception e) { + alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_default.png"); + } + quad.getMaterial().setTexture("AlphaMap", alpha); + if (usePhysics) { + quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0)); + bulletAppState.getPhysicsSpace().add(quad); + } + updateMarkerElevations(); + } + + @Override + public void tileDetached(Vector3f cell, TerrainQuad quad) { + if (usePhysics) { + if (quad.getControl(RigidBodyControl.class) != null) { + bulletAppState.getPhysicsSpace().remove(quad); + quad.removeControl(RigidBodyControl.class); + } + } + updateMarkerElevations(); + } + }); + + this.initKeys(); + + markers = new Node(); + rootNode.attachChild(markers); + createMarkerPoints(1); + } + + private Node markers; + + + private void createMarkerPoints(float count) { + Node center = createAxisMarker(10); + markers.attachChild(center); + + float xS = (count-1)*terrain.getTerrainSize() - (terrain.getTerrainSize()/2); + float zS = (count-1)*terrain.getTerrainSize() - (terrain.getTerrainSize()/2); + float xSi = xS; + float zSi = zS; + for (int x=0; x collisionMarkers; + private Geometry selectedCollisionObject; + + public static void main(String[] args) { + TerrainTestCollision app = new TerrainTestCollision(); + app.start(); + } + + @Override + public void initialize() { + super.initialize(); + loadHintText(); + initCrossHairs(); + } + + @Override + public void simpleInitApp() { + collisionMarkers = new ArrayList<>(); + BulletAppState bulletAppState = new BulletAppState(); + bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); + stateManager.attach(bulletAppState); + setupKeys(); + matRock = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md"); + matRock.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matRock.setTexture("Tex1", grass); + matRock.setFloat("Tex1Scale", 64f); + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matRock.setTexture("Tex2", dirt); + matRock.setFloat("Tex2Scale", 32f); + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matRock.setTexture("Tex3", rock); + matRock.setFloat("Tex3Scale", 128f); + matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matWire.getAdditionalRenderState().setWireframe(true); + matWire.setColor("Color", ColorRGBA.Green); + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); + heightmap.load(); + + } catch (Exception e) { + } + + terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); + control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier + terrain.addControl(control); + terrain.setMaterial(matRock); + terrain.setLocalScale(new Vector3f(2, 2, 2)); + terrain.setLocked(false); // unlock it so we can edit the height + rootNode.attachChild(terrain); + + // if set to false, only the first collision is returned and collision is slightly faster. + terrain.setSupportMultipleCollisions(true); + + /* + * Create PhysicsRigidBodyControl for collision + */ + terrain.addControl(new RigidBodyControl(0)); + bulletAppState.getPhysicsSpace().addAll(terrain); + + + // Add 5 physics spheres to the world, with random sizes and positions + // let them drop from the sky + for (int i = 0; i < 5; i++) { + float r = (float) (8 * Math.random()); + Geometry sphere = new Geometry("cannonball", new Sphere(10, 10, r)); + sphere.setMaterial(matWire); + float x = (float) (20 * Math.random()) - 40; // random position + float y = (float) (20 * Math.random()) - 40; // random position + float z = (float) (20 * Math.random()) - 40; // random position + sphere.setLocalTranslation(new Vector3f(x, 100 + y, z)); + sphere.addControl(new RigidBodyControl(new SphereCollisionShape(r), 2)); + rootNode.attachChild(sphere); + bulletAppState.getPhysicsSpace().add(sphere); + } + + Geometry collisionBox = new Geometry("collisionBox", new Box(2, 2, 2)); + collisionBox.setModelBound(new BoundingBox()); + collisionBox.setLocalTranslation(new Vector3f(20, 95, 30)); + collisionBox.setMaterial(matWire); + rootNode.attachChild(collisionBox); + selectedCollisionObject = collisionBox; + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(1, -0.5f, -0.1f).normalizeLocal()); + dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f)); + rootNode.addLight(dl); + + cam.setLocation(new Vector3f(43f, 121f, 10f)); + cam.setRotation(new Quaternion(0.15824f, -0.79309f, 0.23223f, 0.5404f)); + } + + public void loadHintText() { + BitmapText hintText = new BitmapText(guiFont); + hintText.setSize(guiFont.getCharSet().getRenderedSize()); + hintText.setLocalTranslation(0, getCamera().getHeight(), 0); + hintText.setText("Press T to toggle wireframe"); + guiNode.attachChild(hintText); + } + + protected void initCrossHairs() { + //guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, + settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); + guiNode.attachChild(ch); + } + + private void setupKeys() { + flyCam.setMoveSpeed(50); + inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addListener(actionListener, "wireframe"); + inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addMapping("Forwards", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("Backs", new KeyTrigger(KeyInput.KEY_I)); + inputManager.addListener(actionListener, "Lefts"); + inputManager.addListener(actionListener, "Rights"); + inputManager.addListener(actionListener, "Ups"); + inputManager.addListener(actionListener, "Downs"); + inputManager.addListener(actionListener, "Forwards"); + inputManager.addListener(actionListener, "Backs"); + inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(actionListener, "shoot"); + inputManager.addMapping("cameraDown", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + inputManager.addListener(actionListener, "cameraDown"); + } + + @Override + public void update() { + super.update(); + } + + private void createCollisionMarkers(int num) { + for (int i = 0; i < num; i++) { + Sphere s = new Sphere(6, 6, 1); + Geometry collisionMarker = new Geometry("collisionMarker"); + collisionMarker.setMesh(s); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", i == 0 ? ColorRGBA.Orange : ColorRGBA.Blue); + collisionMarker.setMaterial(mat); + rootNode.attachChild(collisionMarker); + collisionMarkers.add(collisionMarker); + } + } + + final private ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String binding, boolean keyPressed, float tpf) { + if (binding.equals("wireframe") && !keyPressed) { + wireframe = !wireframe; + if (wireframe) { + terrain.setMaterial(matWire); + } else { + terrain.setMaterial(matRock); + } + } else if (binding.equals("shoot") && !keyPressed) { + Vector3f origin = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); + Vector3f direction = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); + direction.subtractLocal(origin).normalizeLocal(); + + Ray ray = new Ray(origin, direction); + CollisionResults results = new CollisionResults(); + + if (terrain.collideWith(ray, results) > 0) { + CollisionResult hit = results.getClosestCollision(); // sorts the collection before printing + printCollisions(results); + + // Remove old markers. + for (Geometry g: collisionMarkers) { + g.removeFromParent(); + } + collisionMarkers.clear(); + + createCollisionMarkers(results.size()); + + // Position Closest Collision + Vector2f loc = new Vector2f(hit.getContactPoint().x, hit.getContactPoint().z); + float height = terrain.getHeight(loc); + System.out.println("Closest Collision: " + hit.getContactPoint() + ", height: " + height + ", distance: " + hit.getDistance()); + collisionMarkers.get(0).setLocalTranslation(new Vector3f(hit.getContactPoint().x, height, hit.getContactPoint().z)); + + // Position Rest: When getClosestCollision has been called, the results are sorted, and thus 0 is closest. + for (int i = 1; i < results.size(); i++) { + collisionMarkers.get(i).setLocalTranslation(results.getCollision(i).getContactPoint()); + } + } + } else if (binding.equals("cameraDown") && !keyPressed) { + getCamera().lookAtDirection(new Vector3f(0, -1, 0), Vector3f.UNIT_Y); + } else if (binding.equals("Lefts") && !keyPressed) { + Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); + selectedCollisionObject.move(-0.5f, 0, 0); + testCollision(oldLoc); + } else if (binding.equals("Rights") && !keyPressed) { + Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); + selectedCollisionObject.move(0.5f, 0, 0); + testCollision(oldLoc); + } else if (binding.equals("Forwards") && !keyPressed) { + Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); + selectedCollisionObject.move(0, 0, 0.5f); + testCollision(oldLoc); + } else if (binding.equals("Backs") && !keyPressed) { + Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); + selectedCollisionObject.move(0, 0, -0.5f); + testCollision(oldLoc); + } else if (binding.equals("Ups") && !keyPressed) { + Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); + selectedCollisionObject.move(0, 0.5f, 0); + testCollision(oldLoc); + } else if (binding.equals("Downs") && !keyPressed) { + Vector3f oldLoc = selectedCollisionObject.getLocalTranslation().clone(); + selectedCollisionObject.move(0, -0.5f, 0); + testCollision(oldLoc); + } + + } + }; + + private void testCollision(Vector3f oldLoc) { + if (terrain.collideWith(selectedCollisionObject.getWorldBound(), new CollisionResults()) > 0) { + selectedCollisionObject.setLocalTranslation(oldLoc); + } + } + + private void printCollisions(CollisionResults cr) { + System.out.println("================ Collision Results ================"); + for (int i = 0; i < cr.size(); i++) { + CollisionResult res = cr.getCollision(i); + System.out.println("Result " + i); + System.out.println("\t\t" + res.toString()); + } + System.out.println("================ END Collision Results ================"); + } +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java new file mode 100644 index 0000000000..4a34906fd0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestModifyHeight.java @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.terrain; + +import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResult; +import com.jme3.collision.CollisionResults; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Ray; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.debug.Arrow; +import com.jme3.scene.shape.Sphere; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Brent Owens + */ +public class TerrainTestModifyHeight extends SimpleApplication { + + private TerrainQuad terrain; + private Material matTerrain; + private Material matWire; + private boolean wireframe = false; + private BitmapText hintText; + final private float grassScale = 64; + final private float dirtScale = 16; + final private float rockScale = 128; + + private boolean raiseTerrain = false; + private boolean lowerTerrain = false; + + private Geometry marker; + private Geometry markerNormal; + + public static void main(String[] args) { + TerrainTestModifyHeight app = new TerrainTestModifyHeight(); + app.start(); + } + + @Override + public void simpleUpdate(float tpf){ + Vector3f intersection = getWorldIntersection(); + updateHintText(intersection); + + if (raiseTerrain){ + + if (intersection != null) { + adjustHeight(intersection, 64, tpf * 60); + } + }else if (lowerTerrain){ + if (intersection != null) { + adjustHeight(intersection, 64, -tpf * 60); + } + } + + if (terrain != null && intersection != null) { + float h = terrain.getHeight(new Vector2f(intersection.x, intersection.z)); + Vector3f tl = terrain.getWorldTranslation(); + marker.setLocalTranslation(tl.add(new Vector3f(intersection.x, h, intersection.z)) ); + markerNormal.setLocalTranslation(tl.add(new Vector3f(intersection.x, h, intersection.z)) ); + + Vector3f normal = terrain.getNormal(new Vector2f(intersection.x, intersection.z)); + ((Arrow)markerNormal.getMesh()).setArrowExtent(normal); + } + } + + @Override + public void simpleInitApp() { + loadHintText(); + initCrossHairs(); + setupKeys(); + + createMarker(); + + // WIREFRAME material + matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matWire.getAdditionalRenderState().setWireframe(true); + matWire.setColor("Color", ColorRGBA.Green); + + createTerrain(); + //createTerrainGrid(); + + DirectionalLight light = new DirectionalLight(); + light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); + rootNode.addLight(light); + + AmbientLight ambLight = new AmbientLight(); + ambLight.setColor(new ColorRGBA(1f, 1f, 0.8f, 0.2f)); + rootNode.addLight(ambLight); + + cam.setLocation(new Vector3f(0, 256, 0)); + cam.setRotation(new Quaternion(0.25966f, 0.690398f, -0.2952f, 0.60727f)); + } + + public void loadHintText() { + hintText = new BitmapText(guiFont); + hintText.setLocalTranslation(0, getCamera().getHeight(), 0); + hintText.setText("Hit 1 to raise terrain, hit 2 to lower terrain"); + guiNode.attachChild(hintText); + } + + public void updateHintText(Vector3f target) { + int x = (int) getCamera().getLocation().x; + int y = (int) getCamera().getLocation().y; + int z = (int) getCamera().getLocation().z; + String targetText = ""; + if (target!= null) + targetText = " intersect: "+target.toString(); + hintText.setText("Press left mouse button to raise terrain, press right mouse button to lower terrain. " + x + "," + y + "," + z+targetText); + } + + protected void initCrossHairs() { + BitmapText ch = new BitmapText(guiFont); + ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); + ch.setText("+"); // crosshairs + ch.setLocalTranslation( // center + settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, + settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); + guiNode.attachChild(ch); + } + + private void setupKeys() { + flyCam.setMoveSpeed(100); + inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addListener(actionListener, "wireframe"); + inputManager.addMapping("Raise", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + inputManager.addListener(actionListener, "Raise"); + inputManager.addMapping("Lower", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + inputManager.addListener(actionListener, "Lower"); + } + final private ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean pressed, float tpf) { + if (name.equals("wireframe") && !pressed) { + wireframe = !wireframe; + if (wireframe) { + terrain.setMaterial(matWire); + } else { + terrain.setMaterial(matTerrain); + } + } else if (name.equals("Raise")) { + raiseTerrain = pressed; + } else if (name.equals("Lower")) { + lowerTerrain = pressed; + } + } + }; + + private void adjustHeight(Vector3f loc, float radius, float height) { + + // offset it by radius because in the loop we iterate through 2 radii + int radiusStepsX = (int) (radius / terrain.getLocalScale().x); + int radiusStepsZ = (int) (radius / terrain.getLocalScale().z); + + float xStepAmount = terrain.getLocalScale().x; + float zStepAmount = terrain.getLocalScale().z; + long start = System.currentTimeMillis(); + List locs = new ArrayList<>(); + List heights = new ArrayList<>(); + + for (int z = -radiusStepsZ; z < radiusStepsZ; z++) { + for (int x = -radiusStepsX; x < radiusStepsX; x++) { + + float locX = loc.x + (x * xStepAmount); + float locZ = loc.z + (z * zStepAmount); + + if (isInRadius(locX - loc.x, locZ - loc.z, radius)) { + // see if it is in the radius of the tool + float h = calculateHeight(radius, height, locX - loc.x, locZ - loc.z); + locs.add(new Vector2f(locX, locZ)); + heights.add(h); + } + } + } + + terrain.adjustHeight(locs, heights); + //System.out.println("Modified "+locs.size()+" points, took: " + (System.currentTimeMillis() - start)+" ms"); + terrain.updateModelBound(); + } + + private boolean isInRadius(float x, float y, float radius) { + Vector2f point = new Vector2f(x, y); + // return true if the distance is less than equal to the radius + return point.length() <= radius; + } + + private float calculateHeight(float radius, float heightFactor, float x, float z) { + // find percentage for each 'unit' in radius + Vector2f point = new Vector2f(x, z); + float val = point.length() / radius; + val = 1 - val; + if (val <= 0) { + val = 0; + } + return heightFactor * val; + } + + private Vector3f getWorldIntersection() { + Vector3f origin = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); + Vector3f direction = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); + direction.subtractLocal(origin).normalizeLocal(); + + Ray ray = new Ray(origin, direction); + CollisionResults results = new CollisionResults(); + int numCollisions = terrain.collideWith(ray, results); + if (numCollisions > 0) { + CollisionResult hit = results.getClosestCollision(); + return hit.getContactPoint(); + } + return null; + } + + private void createTerrain() { + // First, we load up our textures and the heightmap texture for the terrain + + // TERRAIN TEXTURE material + matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matTerrain.setBoolean("useTriPlanarMapping", false); + matTerrain.setBoolean("WardIso", true); + matTerrain.setFloat("Shininess", 0); + + // ALPHA map (for splat textures) + matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + + // GRASS texture + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap", grass); + matTerrain.setFloat("DiffuseMap_0_scale", grassScale); + + // DIRT texture + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_1", dirt); + matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); + + // ROCK texture + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_2", rock); + matTerrain.setFloat("DiffuseMap_2_scale", rockScale); + + // HEIGHTMAP image (for the terrain heightmap) + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.5f); + heightmap.load(); + heightmap.smooth(0.9f, 1); + + } catch (Exception e) { + e.printStackTrace(); + } + + // CREATE THE TERRAIN + terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); + control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier + terrain.addControl(control); + terrain.setMaterial(matTerrain); + terrain.setLocalTranslation(0, -100, 0); + terrain.setLocalScale(2.5f, 0.5f, 2.5f); + rootNode.attachChild(terrain); + } + + private void createMarker() { + // collision marker + Sphere sphere = new Sphere(8, 8, 0.5f); + marker = new Geometry("Marker"); + marker.setMesh(sphere); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", new ColorRGBA(251f/255f, 130f/255f, 0f, 0.6f)); + mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); + + marker.setMaterial(mat); + rootNode.attachChild(marker); + + + // surface normal marker + Arrow arrow = new Arrow(new Vector3f(0,1,0)); + markerNormal = new Geometry("MarkerNormal"); + markerNormal.setMesh(arrow); + markerNormal.setMaterial(mat); + rootNode.attachChild(markerNormal); + } +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java new file mode 100644 index 0000000000..06a4f95776 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestReadWrite.java @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.terrain; + +import com.jme3.app.SimpleApplication; +import com.jme3.export.Savable; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.export.binary.BinaryImporter; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.terrain.Terrain; +import com.jme3.terrain.geomipmap.TerrainLodControl; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import java.io.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Saves and loads terrain. + * + * @author Brent Owens + */ +public class TerrainTestReadWrite extends SimpleApplication { + + private Terrain terrain; + final private float grassScale = 64; + final private float dirtScale = 16; + final private float rockScale = 128; + + public static void main(String[] args) { + TerrainTestReadWrite app = new TerrainTestReadWrite(); + app.start(); + //testHeightmapBuilding(); + } + + @Override + public void initialize() { + super.initialize(); + + loadHintText(); + } + + @Override + public void simpleInitApp() { + + + createControls(); + createMap(); + } + + private void createMap() { + Material matTerrain = new Material(assetManager, + "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matTerrain.setBoolean("useTriPlanarMapping", false); + matTerrain.setBoolean("WardIso", true); + + // ALPHA map (for splat textures) + matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + + // HEIGHTMAP image (for the terrain heightmap) + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + + // GRASS texture + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap", grass); + matTerrain.setFloat("DiffuseMap_0_scale", grassScale); + + + // DIRT texture + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_1", dirt); + matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); + + // ROCK texture + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap_2", rock); + matTerrain.setFloat("DiffuseMap_2_scale", rockScale); + + + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(WrapMode.Repeat); + matTerrain.setTexture("NormalMap", normalMap0); + matTerrain.setTexture("NormalMap_1", normalMap1); + matTerrain.setTexture("NormalMap_2", normalMap2); + + Material matWire = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + matWire.getAdditionalRenderState().setWireframe(true); + matWire.setColor("Color", ColorRGBA.Green); + + + // CREATE HEIGHTMAP + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f); + heightmap.load(); + + } catch (Exception e) { + e.printStackTrace(); + } + + if (new File("terrainsave.jme").exists()) { + loadTerrain(); + } else { + // create the terrain as normal, and give it a control for LOD management + TerrainQuad terrainQuad = new TerrainQuad("terrain", 65, 129, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations + TerrainLodControl control = new TerrainLodControl(terrainQuad, getCamera()); + control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier + terrainQuad.addControl(control); + terrainQuad.setMaterial(matTerrain); + terrainQuad.setLocalTranslation(0, -100, 0); + terrainQuad.setLocalScale(4f, 0.25f, 4f); + rootNode.attachChild(terrainQuad); + + this.terrain = terrainQuad; + } + + DirectionalLight light = new DirectionalLight(); + light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); + rootNode.addLight(light); + } + + /** + * Create the save and load actions and add them to the input listener + */ + private void createControls() { + flyCam.setMoveSpeed(50); + cam.setLocation(new Vector3f(0, 100, 0)); + cam.setRotation(new Quaternion(-0.1779f, 0.821934f, -0.39033f, -0.3747f)); + + inputManager.addMapping("save", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addListener(saveActionListener, "save"); + + inputManager.addMapping("load", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addListener(loadActionListener, "load"); + + inputManager.addMapping("clone", new KeyTrigger(KeyInput.KEY_C)); + inputManager.addListener(cloneActionListener, "clone"); + } + + public void loadHintText() { + BitmapText hintText = new BitmapText(guiFont); + hintText.setSize(guiFont.getCharSet().getRenderedSize()); + hintText.setLocalTranslation(0, getCamera().getHeight(), 0); + hintText.setText("Hit T to save, and Y to load"); + guiNode.attachChild(hintText); + } + final private ActionListener saveActionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean pressed, float tpf) { + if (name.equals("save") && !pressed) { + + FileOutputStream fos = null; + try { + long start = System.currentTimeMillis(); + fos = new FileOutputStream(new File("terrainsave.jme")); + + // we just use the exporter and pass in the terrain + BinaryExporter.getInstance().save((Savable)terrain, new BufferedOutputStream(fos)); + + fos.flush(); + float duration = (System.currentTimeMillis() - start) / 1000.0f; + System.out.println("Save took " + duration + " seconds"); + } catch (IOException ex) { + Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, e); + } + } + } + } + }; + + private void loadTerrain() { + FileInputStream fis = null; + try { + long start = System.currentTimeMillis(); + // remove the existing terrain and detach it from the root node. + if (terrain != null) { + Node existingTerrain = (Node)terrain; + existingTerrain.removeFromParent(); + existingTerrain.removeControl(TerrainLodControl.class); + existingTerrain.detachAllChildren(); + terrain = null; + } + + // import the saved terrain, and attach it back to the root node + File f = new File("terrainsave.jme"); + fis = new FileInputStream(f); + BinaryImporter imp = BinaryImporter.getInstance(); + imp.setAssetManager(assetManager); + terrain = (TerrainQuad) imp.load(new BufferedInputStream(fis)); + rootNode.attachChild((Node)terrain); + + float duration = (System.currentTimeMillis() - start) / 1000.0f; + System.out.println("Load took " + duration + " seconds"); + + // now we have to add back the camera to the LOD control + TerrainLodControl lodControl = ((Node)terrain).getControl(TerrainLodControl.class); + if (lodControl != null) + lodControl.setCamera(getCamera()); + + } catch (IOException ex) { + Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); + } finally { + try { + if (fis != null) { + fis.close(); + } + } catch (IOException ex) { + Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + final private ActionListener loadActionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean pressed, float tpf) { + if (name.equals("load") && !pressed) { + loadTerrain(); + } + } + }; + final private ActionListener cloneActionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean pressed, float tpf) { + if (name.equals("clone") && !pressed) { + + Terrain clone = (Terrain) ((Node)terrain).clone(); + ((Node)terrain).removeFromParent(); + terrain = clone; + getRootNode().attachChild((Node)terrain); + } + } + }; +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java new file mode 100644 index 0000000000..e4d60bd915 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/TerrainTestTile.java @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.terrain; + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.shape.Sphere; +import com.jme3.terrain.ProgressMonitor; +import com.jme3.terrain.Terrain; +import com.jme3.terrain.geomipmap.MultiTerrainLodControl; +import com.jme3.terrain.geomipmap.NeighbourFinder; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import java.util.List; + +/** + * Demonstrates the NeighbourFinder interface for TerrainQuads, + * allowing you to tile terrains together without having to use + * TerrainGrid. It also introduces the MultiTerrainLodControl that + * will seam the edges of all the terrains supplied. + * + * @author sploreg + */ +public class TerrainTestTile extends SimpleApplication { + + private TiledTerrain terrain; + private Material matTerrain; + private Material matWire; + private boolean wireframe = false; + final private float grassScale = 256; + + + public static void main(String[] args) { + TerrainTestTile app = new TerrainTestTile(); + app.start(); + } + + + + @Override + public void simpleInitApp() { + loadHintText(); + setupKeys(); + + // WIREFRAME material + matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matWire.getAdditionalRenderState().setWireframe(true); + matWire.setColor("Color", ColorRGBA.Green); + + terrain = new TiledTerrain(); + rootNode.attachChild(terrain); + + DirectionalLight light = new DirectionalLight(); + light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); + rootNode.addLight(light); + + AmbientLight ambLight = new AmbientLight(); + ambLight.setColor(new ColorRGBA(1f, 1f, 0.8f, 0.2f)); + rootNode.addLight(ambLight); + + cam.setLocation(new Vector3f(0, 256, 0)); + cam.lookAtDirection(new Vector3f(0, -1, -1).normalizeLocal(), Vector3f.UNIT_Y); + + + Sphere s = new Sphere(12, 12, 3); + Geometry g = new Geometry("marker"); + g.setMesh(s); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.Red); + g.setMaterial(mat); + g.setLocalTranslation(0, -100, 0); + rootNode.attachChild(g); + + Geometry g2 = new Geometry("marker"); + g2.setMesh(s); + mat.setColor("Color", ColorRGBA.Red); + g2.setMaterial(mat); + g2.setLocalTranslation(10, -100, 0); + rootNode.attachChild(g2); + + Geometry g3 = new Geometry("marker"); + g3.setMesh(s); + mat.setColor("Color", ColorRGBA.Red); + g3.setMaterial(mat); + g3.setLocalTranslation(0, -100, 10); + rootNode.attachChild(g3); + } + + public void loadHintText() { + BitmapText hintText = new BitmapText(guiFont); + hintText.setLocalTranslation(0, getCamera().getHeight(), 0); + hintText.setText("Press T to toggle wireframe"); + guiNode.attachChild(hintText); + } + + + private void setupKeys() { + flyCam.setMoveSpeed(100); + inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addListener(actionListener, "wireframe"); + } + final private ActionListener actionListener = new ActionListener() { + + @Override + public void onAction(String name, boolean pressed, float tpf) { + if (name.equals("wireframe") && !pressed) { + wireframe = !wireframe; + if (wireframe) { + terrain.setMaterial(matWire); + } else { + terrain.setMaterial(matTerrain); + } + } + } + }; + + /** + * A sample class (node in this case) that demonstrates + * the use of NeighbourFinder. + * It just links up the left,right,top,bottom TerrainQuads + * so LOD can work. + * It does not implement many of the Terrain interface's methods, + * you will want to do that for your own implementations. + */ + private class TiledTerrain extends Node implements Terrain, NeighbourFinder { + + final private TerrainQuad terrain1; + final private TerrainQuad terrain2; + final private TerrainQuad terrain3; + final private TerrainQuad terrain4; + + TiledTerrain() { + // TERRAIN TEXTURE material + matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matTerrain.setBoolean("useTriPlanarMapping", false); + matTerrain.setBoolean("WardIso", true); + matTerrain.setFloat("Shininess", 0); + + // GRASS texture + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matTerrain.setTexture("DiffuseMap", grass); + matTerrain.setFloat("DiffuseMap_0_scale", grassScale); + + // CREATE THE TERRAIN + terrain1 = new TerrainQuad("terrain 1", 65, 513, null); + terrain1.setMaterial(matTerrain); + terrain1.setLocalTranslation(-256, -100, -256); + terrain1.setLocalScale(1f, 1f, 1f); + this.attachChild(terrain1); + + terrain2 = new TerrainQuad("terrain 2", 65, 513, null); + terrain2.setMaterial(matTerrain); + terrain2.setLocalTranslation(-256, -100, 256); + terrain2.setLocalScale(1f, 1f, 1f); + this.attachChild(terrain2); + + terrain3 = new TerrainQuad("terrain 3", 65, 513, null); + terrain3.setMaterial(matTerrain); + terrain3.setLocalTranslation(256, -100, -256); + terrain3.setLocalScale(1f, 1f, 1f); + this.attachChild(terrain3); + + terrain4 = new TerrainQuad("terrain 4", 65, 513, null); + terrain4.setMaterial(matTerrain); + terrain4.setLocalTranslation(256, -100, 256); + terrain4.setLocalScale(1f, 1f, 1f); + this.attachChild(terrain4); + + terrain1.setNeighbourFinder(this); + terrain2.setNeighbourFinder(this); + terrain3.setNeighbourFinder(this); + terrain4.setNeighbourFinder(this); + + MultiTerrainLodControl lodControl = new MultiTerrainLodControl(getCamera()); + lodControl.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier + lodControl.addTerrain(terrain1); + lodControl.addTerrain(terrain2); + lodControl.addTerrain(terrain3);// order of these seems to matter + lodControl.addTerrain(terrain4); + this.addControl(lodControl); + + } + + /** + * 1 3 + * 2 4 + */ + @Override + public TerrainQuad getRightQuad(TerrainQuad center) { + //System.out.println("lookup neighbour"); + if (center == terrain1) + return terrain3; + if (center == terrain2) + return terrain4; + + return null; + } + + /** + * 1 3 + * 2 4 + */ + @Override + public TerrainQuad getLeftQuad(TerrainQuad center) { + //System.out.println("lookup neighbour"); + if (center == terrain3) + return terrain1; + if (center == terrain4) + return terrain2; + + return null; + } + + /** + * 1 3 + * 2 4 + */ + @Override + public TerrainQuad getTopQuad(TerrainQuad center) { + //System.out.println("lookup neighbour"); + if (center == terrain2) + return terrain1; + if (center == terrain4) + return terrain3; + + return null; + } + + /** + * 1 3 + * 2 4 + */ + @Override + public TerrainQuad getDownQuad(TerrainQuad center) { + //System.out.println("lookup neighbour"); + if (center == terrain1) + return terrain2; + if (center == terrain3) + return terrain4; + + return null; + } + + @Override + public float getHeight(Vector2f xz) { + // you will have to offset the coordinate for each terrain, to center on it + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Vector3f getNormal(Vector2f xz) { + // you will have to offset the coordinate for each terrain, to center on it + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public float getHeightmapHeight(Vector2f xz) { + // you will have to offset the coordinate for each terrain, to center on it + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setHeight(Vector2f xzCoordinate, float height) { + // you will have to offset the coordinate for each terrain, to center on it + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setHeight(List xz, List height) { + // you will have to offset the coordinate for each terrain, to center on it + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void adjustHeight(Vector2f xzCoordinate, float delta) { + // you will have to offset the coordinate for each terrain, to center on it + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void adjustHeight(List xz, List height) { + // you will have to offset the coordinate for each terrain, to center on it + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public float[] getHeightMap() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getMaxLod() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setLocked(boolean locked) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void generateEntropy(ProgressMonitor monitor) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Material getMaterial() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Material getMaterial(Vector3f worldLocation) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getTerrainSize() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getNumMajorSubdivisions() { + throw new UnsupportedOperationException("Not supported yet."); + } + + + + } +} diff --git a/jme3-examples/src/main/java/jme3test/terrain/package-info.java b/jme3-examples/src/main/java/jme3test/terrain/package-info.java new file mode 100644 index 0000000000..6cb10c70d3 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/terrain/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for modeling terrain + */ +package jme3test.terrain; diff --git a/jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java b/jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java new file mode 100755 index 0000000000..16ba966618 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestAnisotropicFilter.java @@ -0,0 +1,117 @@ +package jme3test.texture; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.AssetManager; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Limits; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.RectangleMesh; +import com.jme3.texture.Image; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import com.jme3.texture.image.ColorSpace; +import com.jme3.texture.image.ImageRaster; +import com.jme3.util.BufferUtils; + +public class TestAnisotropicFilter extends SimpleApplication implements ActionListener { + + private int globalAniso = 1; + private int maxAniso = 1; + + @Override + public void simpleInitApp() { + maxAniso = renderer.getLimits().get(Limits.TextureAnisotropy); + + flyCam.setDragToRotate(true); + flyCam.setMoveSpeed(100); + cam.setLocation(new Vector3f(197.02617f, 4.6769195f, -194.89545f)); + cam.setRotation(new Quaternion(0.07921988f, 0.8992258f, -0.18292196f, 0.38943136f)); + + RectangleMesh rm = new RectangleMesh( + new Vector3f(-500, 0, 500), + new Vector3f(500, 0, 500), + new Vector3f(-500, 0, -500)); + rm.scaleTextureCoordinates(new Vector2f(1000, 1000)); + Geometry geom = new Geometry("rectangle", rm); + geom.setMaterial(createCheckerBoardMaterial(assetManager)); + rootNode.attachChild(geom); + + inputManager.addMapping("higher", new KeyTrigger(KeyInput.KEY_1)); + inputManager.addMapping("lower", new KeyTrigger(KeyInput.KEY_2)); + inputManager.addListener(this, "higher"); + inputManager.addListener(this, "lower"); + } + + private static Material createCheckerBoardMaterial(AssetManager assetManager) { + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + Texture tex = createCheckerBoardTexture(); // assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.dds"); + tex.setMagFilter(Texture.MagFilter.Bilinear); + tex.setMinFilter(Texture.MinFilter.Trilinear); + tex.setWrap(Texture.WrapMode.Repeat); + mat.setTexture("ColorMap", tex); + return mat; + } + + private static Texture2D createCheckerBoardTexture() { + Image image = new Image(Format.RGBA8, 1024, 1024, BufferUtils.createByteBuffer(1024 * 1024 * 4), ColorSpace.sRGB); + + ImageRaster raster = ImageRaster.create(image); + for (int y = 0; y < 1024; y++) { + for (int x = 0; x < 1024; x++) { + if (y < 512) { + if (x < 512) { + raster.setPixel(x, y, ColorRGBA.Black); + } else { + raster.setPixel(x, y, ColorRGBA.White); + } + } else { + if (x < 512) { + raster.setPixel(x, y, ColorRGBA.White); + } else { + raster.setPixel(x, y, ColorRGBA.Black); + } + } + } + } + + return new Texture2D(image); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + return; + } + switch (name) { + case "higher": + globalAniso++; + if (globalAniso > 32) { + globalAniso = 32; + } + renderer.setDefaultAnisotropicFilter(globalAniso); + System.out.format("Global Aniso: %d / %d\r\n", globalAniso, maxAniso); + break; + case "lower": + globalAniso--; + if (globalAniso < 1) { + globalAniso = 1; + } + renderer.setDefaultAnisotropicFilter(globalAniso); + System.out.format("Global Aniso: %d / %d\r\n", globalAniso, maxAniso); + break; + } + } + + public static void main(String[] args) { + TestAnisotropicFilter app = new TestAnisotropicFilter(); + app.start(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java b/jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java new file mode 100644 index 0000000000..5288d4ffe6 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestImageRaster.java @@ -0,0 +1,139 @@ +package jme3test.texture; + + +import com.jme3.app.SimpleApplication; +import com.jme3.font.BitmapFont; +import com.jme3.font.BitmapText; +import com.jme3.font.Rectangle; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Image; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.MagFilter; +import com.jme3.texture.Texture.MinFilter; +import com.jme3.texture.Texture2D; +import com.jme3.texture.image.ImageRaster; +import com.jme3.util.BufferUtils; +import java.nio.ByteBuffer; + +public class TestImageRaster extends SimpleApplication { + + private Image convertImage(Image image, Format newFormat) { + int width = image.getWidth(); + int height = image.getHeight(); + ByteBuffer data = BufferUtils.createByteBuffer( (int)Math.ceil(newFormat.getBitsPerPixel() / 8.0) * width * height); + Image convertedImage = new Image(newFormat, width, height, data,null, image.getColorSpace()); + + ImageRaster sourceReader = ImageRaster.create(image); + ImageRaster targetWriter = ImageRaster.create(convertedImage); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + ColorRGBA color = sourceReader.getPixel(x, y); + targetWriter.setPixel(x, y, color); + } + } + + return convertedImage; + } + + private void convertAndPutImage(Image image, float posX, float posY) { + Texture tex = new Texture2D(image); + tex.setMagFilter(MagFilter.Nearest); + tex.setMinFilter(MinFilter.NearestNoMipMaps); + tex.setAnisotropicFilter(16); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", tex); + + Quad q = new Quad(5, 5); + Geometry g = new Geometry("quad", q); + g.setLocalTranslation(posX, posY - 5, -0.0001f); + g.setMaterial(mat); + rootNode.attachChild(g); + + BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); + BitmapText txt = new BitmapText(fnt); + txt.setBox(new Rectangle(0, 0, 5, 5)); + txt.setQueueBucket(RenderQueue.Bucket.Transparent); + txt.setSize(0.5f); + txt.setText(image.getFormat().name()); + txt.setLocalTranslation(posX, posY, 0); + rootNode.attachChild(txt); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(16, 6, 36)); + flyCam.setMoveSpeed(10); + + Texture tex = assetManager.loadTexture("com/jme3/app/Monkey.png"); +// Texture tex = assetManager.loadTexture("Textures/HdrTest/Memorial.hdr"); + Image originalImage = tex.getImage(); + + Image image = convertImage(originalImage, Format.RGBA32F); + convertAndPutImage(image, 0, 0); + + image = convertImage(image, Format.RGB32F); + convertAndPutImage(image, 5, 0); + + image = convertImage(image, Format.RGBA16F); + convertAndPutImage(image, 10, 0); + + image = convertImage(image, Format.RGB16F); + convertAndPutImage(image, 15, 0); + + image = convertImage(image, Format.RGB16F_to_RGB9E5); + convertAndPutImage(image, 20, 0); + + image = convertImage(image, Format.RGB16F_to_RGB111110F); + convertAndPutImage(image, 25, 0); + + image = convertImage(image, Format.RGBA8); + convertAndPutImage(image, 10, 5); + + image = convertImage(image, Format.RGB8); + convertAndPutImage(image, 15, 5); + + image = convertImage(image, Format.ABGR8); + convertAndPutImage(image, 20, 5); + + image = convertImage(image, Format.BGR8); + convertAndPutImage(image, 25, 5); + + image = convertImage(image, Format.ARGB8); + convertAndPutImage(image, 30, 5); + + image = convertImage(image, Format.BGRA8); + convertAndPutImage(image, 35, 5); + + image = convertImage(image, Format.RGB5A1); + convertAndPutImage(image, 0, 10); + + image = convertImage(image, Format.RGB565); + convertAndPutImage(image, 5, 10); + + image = convertImage(image, Format.Luminance32F); + convertAndPutImage(image, 0, 15); + + image = convertImage(image, Format.Luminance16FAlpha16F); + convertAndPutImage(image, 5, 15); + + image = convertImage(image, Format.Luminance16F); + convertAndPutImage(image, 10, 15); + + image = convertImage(image, Format.Luminance8Alpha8); + convertAndPutImage(image, 15, 15); + + image = convertImage(image, Format.Luminance8); + convertAndPutImage(image, 20, 15); + } + + public static void main(String[] args) { + TestImageRaster app = new TestImageRaster(); + app.start(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java b/jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java new file mode 100644 index 0000000000..21c1b590b9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestSkyLoading.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.texture; + +import com.jme3.app.SimpleApplication; +import com.jme3.scene.Spatial; +import com.jme3.texture.Texture; +import com.jme3.util.SkyFactory; + +public class TestSkyLoading extends SimpleApplication { + + public static void main(String[] args){ + TestSkyLoading app = new TestSkyLoading(); + app.start(); + } + + @Override + public void simpleInitApp() { + Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg"); + Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg"); + Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg"); + Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg"); + Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg"); + Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg"); + + Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down); + rootNode.attachChild(sky); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java b/jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java new file mode 100644 index 0000000000..89c0718733 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestSkyRotation.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2017-2021 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. + */ +package jme3test.texture; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.util.SkyFactory; + +/** + * Simple application to test sky rotation with a cube-mapped sky. + * + * Press "T" to rotate the sky and floor to the camera's left. Press "Y" to + * rotate the sky and floor to the camera's right. Both should appear to move by + * the same amount in the same direction. + * + * See issue #651 for further information. + * + * @author Stephen Gold + */ +public class TestSkyRotation extends SimpleApplication implements ActionListener { + + /** + * objects visible in the scene + */ + private Spatial floor, sky; + /** + * Y-axis rotation angle in radians + */ + private float angle = 0f; + + public static void main(String[] arguments) { + TestSkyRotation application = new TestSkyRotation(); + application.start(); + } + + @Override + public void simpleInitApp() { + /* + * Configure the camera. + */ + flyCam.setEnabled(false); + Vector3f location = new Vector3f(-7f, 4f, 8f); + cam.setLocation(location); + Quaternion orientation; + orientation = new Quaternion(0.0037f, 0.944684f, -0.01067f, 0.327789f); + assert FastMath.approximateEquals(orientation.norm(), 1f); + cam.setRotation(orientation); + /* + * Attach a cube-mapped sky to the scene graph. + */ + sky = SkyFactory.createSky(assetManager, + "Scenes/Beach/FullskiesSunset0068.dds", + SkyFactory.EnvMapType.CubeMap); + rootNode.attachChild(sky); + /* + * Attach a "floor" geometry to the scene graph. + */ + Mesh floorMesh = new Box(10f, 0.1f, 10f); + floor = new Geometry("floor", floorMesh); + Material floorMaterial = new Material(assetManager, + "Common/MatDefs/Misc/Unshaded.j3md"); + floorMaterial.setTexture("ColorMap", + assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + floor.setMaterial(floorMaterial); + rootNode.attachChild(floor); + /* + * Configure mappings and listeners for keyboard input. + */ + inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addListener(this, "left"); + inputManager.addListener(this, "right"); + } + + /** + * Handle an input action from the user. + * + * @param name the name of the action + * @param ongoing true→depress key, false→release key + * @param ignored ignored + */ + @Override + public void onAction(String name, boolean ongoing, float ignored) { + if (!ongoing) { + return; + } + /* + * Update the Y-axis rotation angle based on which key was pressed. + */ + if (name.equals("left")) { + angle += 0.1f; // radians + System.out.print("rotate floor and sky leftward ..."); + } else if (name.equals("right")) { + angle -= 0.1f; // radians + System.out.printf("rotate floor and sky spatials rightward ..."); + } else { + return; + } + /* + * Update the local rotations of both objects based on the angle. + */ + System.out.printf(" to %.1f radians left of start%n", angle); + Quaternion rotation = new Quaternion(); + rotation.fromAngleNormalAxis(angle, Vector3f.UNIT_Y); + floor.setLocalRotation(rotation); + sky.setLocalRotation(rotation); + } +} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java b/jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java new file mode 100644 index 0000000000..e3f41b6fee --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestTexture3D.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.texture; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.scene.VertexBuffer.Usage; +import com.jme3.scene.shape.Sphere; +import com.jme3.texture.Image; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; +import com.jme3.texture.image.ColorSpace; +import com.jme3.util.BufferUtils; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.ArrayList; + +public class TestTexture3D extends SimpleApplication { + + public static void main(String[] args) { + TestTexture3D app = new TestTexture3D(); + app.start(); + } + + @Override + public void simpleInitApp() { + //mouseInput.setCursorVisible(true); + flyCam.setMoveSpeed(10); + //creating a sphere + Sphere sphere = new Sphere(32, 32, 1); + // getting the bounding box + sphere.updateBound(); + BoundingBox bb = (BoundingBox) sphere.getBound(); + Vector3f min = bb.getMin(null); + float[] ext = new float[]{bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2}; + //we need to change the UV coordinates (the sphere is assumed to be inside the 3D image box) + sphere.clearBuffer(Type.TexCoord); + VertexBuffer vb = sphere.getBuffer(Type.Position); + FloatBuffer fb = (FloatBuffer) vb.getData(); + float[] uvCoordinates = BufferUtils.getFloatArray(fb); + //now transform the coordinates so that they are in the range of <0; 1> + for (int i = 0; i < uvCoordinates.length; i += 3) { + uvCoordinates[i] = (uvCoordinates[i] - min.x) / ext[0]; + uvCoordinates[i + 1] = (uvCoordinates[i + 1] - min.y) / ext[1]; + uvCoordinates[i + 2] = (uvCoordinates[i + 2] - min.z) / ext[2]; + } + //apply new texture coordinates + VertexBuffer uvCoordsBuffer = new VertexBuffer(Type.TexCoord); + uvCoordsBuffer.setupData(Usage.Static, 3, com.jme3.scene.VertexBuffer.Format.Float, + BufferUtils.createFloatBuffer(uvCoordinates)); + sphere.setBuffer(uvCoordsBuffer); + //create geometry, and apply material and our 3D texture + Geometry g = new Geometry("sphere", sphere); + Material material = new Material(assetManager, "jme3test/texture/tex3D.j3md"); + try { + Texture texture = this.getTexture(); + material.setTexture("Texture", texture); + } catch (IOException e) { + e.printStackTrace(); + } + g.setMaterial(material); + rootNode.attachChild(g); + //add some light so that it is visible + PointLight light = new PointLight(); + light.setColor(ColorRGBA.White); + light.setPosition(new Vector3f(5, 5, 5)); + light.setRadius(20); + rootNode.addLight(light); + light = new PointLight(); + light.setColor(ColorRGBA.White); + light.setPosition(new Vector3f(-5, -5, -5)); + light.setRadius(20); + rootNode.addLight(light); + } + + /** + * This method creates an RGB8 texture with the sizes of 10x10x10 pixels. + */ + private Texture getTexture() throws IOException { + ArrayList data = new ArrayList<>(1); + ByteBuffer bb = BufferUtils.createByteBuffer(10 * 10 * 10 * 3);//all data must be inside one buffer + for (int i = 0; i < 10; ++i) { + for (int j = 0; j < 10 * 10; ++j) { + bb.put((byte) (255f*i/10f)); + bb.put((byte) (255f*i/10f)); + bb.put((byte) (255f)); + } + } + bb.rewind(); + data.add(bb); + return new Texture3D(new Image(Format.RGB8, 10, 10, 10, data, null, ColorSpace.Linear)); + } +} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java b/jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java new file mode 100644 index 0000000000..ada3f1fffe --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestTexture3DLoading.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.texture; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Texture; + +public class TestTexture3DLoading extends SimpleApplication { + + public static void main(String[] args) { + TestTexture3DLoading app = new TestTexture3DLoading(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + flyCam.setEnabled(false); + + + Quad q = new Quad(10, 10); + + Geometry geom = new Geometry("Quad", q); + Material material = new Material(assetManager, "jme3test/texture/tex3DThumb.j3md"); + TextureKey key = new TextureKey("Textures/3D/flame.dds"); + key.setGenerateMips(true); + key.setTextureTypeHint(Texture.Type.ThreeDimensional); + + Texture t = assetManager.loadTexture(key); + + int rows = 4;//4 * 4 + + q.scaleTextureCoordinates(new Vector2f(rows, rows)); + + // The image has only 8 pictures, and we have 16 thumbs, so the data will be interpolated by the GPU. + material.setFloat("InvDepth", 1f / 16f); + material.setInt("Rows", rows); + material.setTexture("Texture", t); + geom.setMaterial(material); + + rootNode.attachChild(geom); + + cam.setLocation(new Vector3f(4.7444625f, 5.160054f, 13.1939f)); + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java b/jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java new file mode 100644 index 0000000000..ba56b3ff2a --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestTextureArray.java @@ -0,0 +1,87 @@ +package jme3test.texture; + + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Caps; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.texture.Image; +import com.jme3.texture.Texture; +import com.jme3.texture.TextureArray; +import com.jme3.util.BufferUtils; +import java.util.ArrayList; +import java.util.List; + +public class TestTextureArray extends SimpleApplication +{ + + @Override + public void simpleInitApp() + { + Material mat = new Material(assetManager, "jme3test/texture/UnshadedArray.j3md"); + + for (Caps caps : renderManager.getRenderer().getCaps()) { + System.out.println(caps.name()); + } + if(!renderManager.getRenderer().getCaps().contains(Caps.TextureArray)){ + throw new UnsupportedOperationException("Your hardware does not support TextureArray"); + } + + + Texture tex1 = assetManager.loadTexture( "Textures/Terrain/Pond/Pond.jpg"); + Texture tex2 = assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg"); + List images = new ArrayList<>(); + images.add(tex1.getImage()); + images.add(tex2.getImage()); + TextureArray tex3 = new TextureArray(images); + tex3.setMinFilter(Texture.MinFilter.Trilinear); + mat.setTexture("ColorMap", tex3); + + Mesh m = new Mesh(); + Vector3f[] vertices = new Vector3f[8]; + vertices[0] = new Vector3f(0, 0, 0); + vertices[1] = new Vector3f(3, 0, 0); + vertices[2] = new Vector3f(0, 3, 0); + vertices[3] = new Vector3f(3, 3, 0); + + vertices[4] = new Vector3f(3, 0, 0); + vertices[5] = new Vector3f(6, 0, 0); + vertices[6] = new Vector3f(3, 3, 0); + vertices[7] = new Vector3f(6, 3, 0); + + Vector3f[] texCoord = new Vector3f[8]; + texCoord[0] = new Vector3f(0, 0, 0); + texCoord[1] = new Vector3f(1, 0, 0); + texCoord[2] = new Vector3f(0, 1, 0); + texCoord[3] = new Vector3f(1, 1, 0); + + texCoord[4] = new Vector3f(0, 0, 1); + texCoord[5] = new Vector3f(1, 0, 1); + texCoord[6] = new Vector3f(0, 1, 1); + texCoord[7] = new Vector3f(1, 1, 1); + + int[] indexes = { 2, 0, 1, 1, 3, 2 , 6, 4, 5, 5, 7, 6}; + + m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices)); + m.setBuffer(Type.TexCoord, 3, BufferUtils.createFloatBuffer(texCoord)); + m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes)); + m.updateBound(); + + Geometry geom = new Geometry("Mesh", m); + geom.setMaterial(mat); + rootNode.attachChild(geom); + } + + /** + * @param args ignored + */ + public static void main(String[] args) + { + TestTextureArray app = new TestTextureArray(); + app.start(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java b/jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java new file mode 100644 index 0000000000..0af064f557 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestTextureArrayCompressed.java @@ -0,0 +1,87 @@ +package jme3test.texture; + + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.renderer.Caps; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.texture.Image; +import com.jme3.texture.Texture; +import com.jme3.texture.TextureArray; +import com.jme3.util.BufferUtils; +import java.util.ArrayList; +import java.util.List; + +public class TestTextureArrayCompressed extends SimpleApplication +{ + + @Override + public void simpleInitApp() + { + Material mat = new Material(assetManager, "jme3test/texture/UnshadedArray.j3md"); + + for (Caps caps : renderManager.getRenderer().getCaps()) { + System.out.println(caps.name()); + } + if(!renderManager.getRenderer().getCaps().contains(Caps.TextureArray)){ + throw new UnsupportedOperationException("Your hardware does not support TextureArray"); + } + + + Texture tex1 = assetManager.loadTexture( "Textures/Terrain/Pond/Pond_dxt5.dds"); + Texture tex2 = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall_dxt5.dds"); + List images = new ArrayList<>(); + images.add(tex1.getImage()); + images.add(tex2.getImage()); + TextureArray tex3 = new TextureArray(images); + tex3.setMinFilter(Texture.MinFilter.Trilinear); + mat.setTexture("ColorMap", tex3); + + Mesh m = new Mesh(); + Vector3f[] vertices = new Vector3f[8]; + vertices[0] = new Vector3f(0, 0, 0); + vertices[1] = new Vector3f(3, 0, 0); + vertices[2] = new Vector3f(0, 3, 0); + vertices[3] = new Vector3f(3, 3, 0); + + vertices[4] = new Vector3f(3, 0, 0); + vertices[5] = new Vector3f(6, 0, 0); + vertices[6] = new Vector3f(3, 3, 0); + vertices[7] = new Vector3f(6, 3, 0); + + Vector3f[] texCoord = new Vector3f[8]; + texCoord[0] = new Vector3f(0, 0, 0); + texCoord[1] = new Vector3f(1, 0, 0); + texCoord[2] = new Vector3f(0, 1, 0); + texCoord[3] = new Vector3f(1, 1, 0); + + texCoord[4] = new Vector3f(0, 0, 1); + texCoord[5] = new Vector3f(1, 0, 1); + texCoord[6] = new Vector3f(0, 1, 1); + texCoord[7] = new Vector3f(1, 1, 1); + + int[] indexes = { 2, 0, 1, 1, 3, 2 , 6, 4, 5, 5, 7, 6}; + + m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices)); + m.setBuffer(Type.TexCoord, 3, BufferUtils.createFloatBuffer(texCoord)); + m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes)); + m.updateBound(); + + Geometry geom = new Geometry("Mesh", m); + geom.setMaterial(mat); + rootNode.attachChild(geom); + } + + /** + * @param args ignored + */ + public static void main(String[] args) + { + TestTextureArrayCompressed app = new TestTextureArrayCompressed(); + app.start(); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java b/jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java new file mode 100644 index 0000000000..bcf4b4d8b1 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.texture.dds; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.TextureKey; +import com.jme3.math.ColorRGBA; +import com.jme3.renderer.RenderManager; +import com.jme3.texture.Texture2D; +import com.jme3.texture.plugins.DDSLoader; +import com.jme3.ui.Picture; + +/** + * Test various supported BC* textures in DDS file format + * + * @author Toni Helenius + */ +public class TestLoadDds extends SimpleApplication { + + public static void main(String[] args) { + TestLoadDds app = new TestLoadDds(); + //app.setShowSettings(false); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + assetManager.registerLoader(DDSLoader.class, "dds"); + + loadTexture(0, "Textures/dds/Monkey_PNG_BC7_1.DDS", "BC7"); + loadTexture(1, "Textures/dds/Monkey_PNG_BC6H_3.DDS", "BC6"); + loadTexture(2, "Textures/dds/Monkey_PNG_BC6H_SF_2.DDS", "BC6_SF"); + loadTexture(3, "Textures/dds/Monkey_PNG_BC5_S_6.DDS", "BC5_S"); + loadTexture(4, "Textures/dds/Monkey_PNG_BC5_7.DDS", "BC5"); + loadTexture(5, "Textures/dds/Monkey_PNG_BC4_S_8.DDS", "BC4_S"); + loadTexture(6, "Textures/dds/Monkey_PNG_BC4_9.DDS", "BC4"); + loadTexture(7, "Textures/dds/Monkey_PNG_BC3_10.DDS", "BC3"); + loadTexture(8, "Textures/dds/Monkey_PNG_BC2_11.DDS", "BC2"); + loadTexture(9, "Textures/dds/Monkey_PNG_BC1_12.DDS", "BC1"); + + flyCam.setDragToRotate(true); + + } + + private void loadTexture(int index, String texture, String description) { + Texture2D t = (Texture2D)assetManager.loadTexture(new TextureKey(texture, false)); + Picture p = new Picture(description, true); + p.setTexture(assetManager, t, false); + p.setLocalTranslation((index % 4) * 200, Math.floorDiv(index, 4) * 200, 0); + p.setWidth(200); + p.setHeight(200); + guiNode.attachChild(p); + } + + + @Override + public void simpleUpdate(float tpf) { + //TODO: add update code + } + + @Override + public void simpleRender(RenderManager rm) { + //TODO: add render code + } +} diff --git a/jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java b/jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java new file mode 100644 index 0000000000..8c69c0a7ac --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/ktx/TestLoadKtx.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2009-2015 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. + */ +package jme3test.texture.ktx; + +import com.jme3.app.SimpleApplication; +import com.jme3.math.ColorRGBA; +import com.jme3.renderer.RenderManager; +import com.jme3.texture.Texture2D; +import com.jme3.texture.plugins.ktx.KTXLoader; +import com.jme3.ui.Picture; + +/** + * test + * @author nehon + */ +public class TestLoadKtx extends SimpleApplication { + + public static void main(String[] args) { + TestLoadKtx app = new TestLoadKtx(); + //app.setShowSettings(false); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + assetManager.registerLoader(KTXLoader.class, "ktx"); + + + Texture2D t = (Texture2D)assetManager.loadTexture("Textures/ktx/down-reference.ktx"); + Picture p = new Picture("bla", false); + p.setTexture(assetManager, t, false); + p.setLocalTranslation(200, 200, 0); + p.setWidth(t.getImage().getWidth()); + p.setHeight(t.getImage().getHeight()); + guiNode.attachChild(p); + + + Texture2D t2 = (Texture2D)assetManager.loadTexture("Textures/ktx/up-reference.ktx"); + Picture p2 = new Picture("bla", false); + p2.setTexture(assetManager, t2, false); + p2.setLocalTranslation(400, 200, 0); + p2.setWidth(t2.getImage().getWidth()); + p2.setHeight(t2.getImage().getHeight()); + guiNode.attachChild(p2); + + Texture2D t3 = (Texture2D)assetManager.loadTexture("Textures/ktx/rgba-reference.ktx"); + Picture p3 = new Picture("bla", false); + p3.setTexture(assetManager, t3, false); + p3.setLocalTranslation(200, 400, 0); + p3.setWidth(t3.getImage().getWidth()); + p3.setHeight(t3.getImage().getHeight()); + guiNode.attachChild(p3); + + + Texture2D t4 = (Texture2D)assetManager.loadTexture("Textures/ktx/rgb-amg-reference.ktx"); + Picture p4 = new Picture("bla", false); + p4.setTexture(assetManager, t4, false); + p4.setLocalTranslation(400, 400, 0); + p4.setWidth(t4.getImage().getWidth()); + p4.setHeight(t4.getImage().getHeight()); + guiNode.attachChild(p4); + + + flyCam.setDragToRotate(true); + + } + + + @Override + public void simpleUpdate(float tpf) { + //TODO: add update code + } + + @Override + public void simpleRender(RenderManager rm) { + //TODO: add render code + } +} diff --git a/jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java b/jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java new file mode 100644 index 0000000000..65f87771b4 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/ktx/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for textures in KTX (Khronos Texture) + * format + */ +package jme3test.texture.ktx; diff --git a/jme3-examples/src/main/java/jme3test/texture/package-info.java b/jme3-examples/src/main/java/jme3test/texture/package-info.java new file mode 100644 index 0000000000..64d258c788 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for textures + */ +package jme3test.texture; diff --git a/jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java b/jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java new file mode 100644 index 0000000000..2c54a5bdc9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009-2020 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. + */ +package jme3test.tools; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import jme3tools.savegame.SaveGame; + +public class TestSaveGame extends SimpleApplication { + + public static void main(String[] args) { + + TestSaveGame app = new TestSaveGame(); + app.start(); + } + + @Override + public void simpleUpdate(float tpf) { + } + + @Override + public void simpleInitApp() { + + // Create a Node to store player data. + Node myPlayer = new Node(); + myPlayer.setName("PlayerNode"); + myPlayer.setUserData("name", "Mario"); + myPlayer.setUserData("health", 100.0f); + myPlayer.setUserData("points", 0); + + // Attach the model to the Node. + Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + myPlayer.attachChild(model); + + // Before saving the game, detach the model since it doesn't need to be saved. + myPlayer.detachAllChildren(); + SaveGame.saveGame("mycompany/mygame", "savegame_001", myPlayer); + + // Later, the game is loaded again ... + Node player = (Node) SaveGame.loadGame("mycompany/mygame", "savegame_001"); + player.attachChild(model); + rootNode.attachChild(player); + + // and the player data are available. + System.out.println("Name: " + player.getUserData("name")); + System.out.println("Health: " + player.getUserData("health")); + System.out.println("Points: " + player.getUserData("points")); + + AmbientLight al = new AmbientLight(); + rootNode.addLight(al); + + // Note that your custom classes can also implement the Savable interface. + } +} diff --git a/jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java b/jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java new file mode 100644 index 0000000000..5c3d6c98cb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/tools/TestTextureAtlas.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009-2012 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. + */ +package jme3test.tools; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Quad; +import jme3tools.optimize.TextureAtlas; + +public class TestTextureAtlas extends SimpleApplication { + + public static void main(String[] args) { + TestTextureAtlas app = new TestTextureAtlas(); + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(50); + Node scene = new Node("Scene"); + Spatial obj1 = assetManager.loadModel("Models/Ferrari/Car.scene"); + obj1.setLocalTranslation(-4, 0, 0); + Spatial obj2 = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + obj2.setLocalTranslation(-2, 0, 0); + Spatial obj3 = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml"); + obj3.setLocalTranslation(-0, 0, 0); + Spatial obj4 = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); + obj4.setLocalTranslation(2, 0, 0); + Spatial obj5 = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); + obj5.setLocalTranslation(4, 0, 0); + scene.attachChild(obj1); + scene.attachChild(obj2); + scene.attachChild(obj3); + scene.attachChild(obj4); + scene.attachChild(obj5); + + Geometry geom = TextureAtlas.makeAtlasBatch(scene, assetManager, 2048); + + AmbientLight al = new AmbientLight(); + rootNode.addLight(al); + + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(0.69077975f, -0.6277887f, -0.35875428f).normalizeLocal()); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + rootNode.addLight(sun); + + rootNode.attachChild(geom); + + //quad to display material + Geometry box = new Geometry("displayquad", new Quad(4, 4)); + box.setMaterial(geom.getMaterial()); + box.setLocalTranslation(0, 1, 3); + rootNode.attachChild(box); + } +} diff --git a/jme3-examples/src/main/java/jme3test/tools/package-info.java b/jme3-examples/src/main/java/jme3test/tools/package-info.java new file mode 100644 index 0000000000..db76f10763 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/tools/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for miscellaneous tools + */ +package jme3test.tools; diff --git a/jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java b/jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java new file mode 100644 index 0000000000..2784d59fa1 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/water/TestMultiPostWater.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.water; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.Camera; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.system.AppSettings; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.texture.Texture2D; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; +import com.jme3.water.WaterFilter; +import java.util.ArrayList; +import java.util.List; + +/** + * test + * + * @author normenhansen + */ +public class TestMultiPostWater extends SimpleApplication { + + final private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f); + final private static float WATER_HEIGHT = 90; + + public static void main(String[] args) { + TestMultiPostWater app = new TestMultiPostWater(); + AppSettings s = new AppSettings(true); + s.setRenderer(AppSettings.LWJGL_OPENGL2); + s.setAudioRenderer(AppSettings.LWJGL_OPENAL); + app.setSettings(s); + + app.start(); + } + + @Override + public void simpleInitApp() { + +// setDisplayFps(false); +// setDisplayStatView(false); + + Node mainScene = new Node("Main Scene"); + rootNode.attachChild(mainScene); + + createTerrain(mainScene); + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(lightDir); + sun.setColor(ColorRGBA.White.clone().multLocal(1.7f)); + mainScene.addLight(sun); + + flyCam.setMoveSpeed(100); + + //cam.setLocation(new Vector3f(-700, 100, 300)); + //cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z)); + cam.setLocation(new Vector3f(-327.21957f, 251.6459f, 126.884346f)); + cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0})); + + + Spatial sky = SkyFactory.createSky(assetManager, + "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); + sky.setLocalScale(350); + + mainScene.attachChild(sky); + cam.setFrustumFar(4000); + + + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + + WaterFilter water = new WaterFilter(rootNode, lightDir); + water.setCenter(new Vector3f(9.628218f, -15.830074f, 199.23595f)); + water.setRadius(260); + water.setWaveScale(0.003f); + water.setMaxAmplitude(2f); + water.setFoamExistence(new Vector3f(1f, 4, 0.5f)); + water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); + water.setRefractionStrength(0.2f); + water.setWaterHeight(WATER_HEIGHT); + fpp.addFilter(water); + + WaterFilter water2 = new WaterFilter(rootNode, lightDir); + water2.setCenter(new Vector3f(-280.46027f, -24.971727f, -271.71976f)); + water2.setRadius(260); + water2.setWaterHeight(WATER_HEIGHT); + water2.setUseFoam(false); + water2.setUseRipples(false); + water2.setDeepWaterColor(ColorRGBA.Brown); + water2.setWaterColor(ColorRGBA.Brown.mult(2.0f)); + water2.setWaterTransparency(0.2f); + water2.setMaxAmplitude(0.3f); + water2.setWaveScale(0.008f); + water2.setSpeed(0.7f); + water2.setShoreHardness(1.0f); + water2.setRefractionConstant(0.2f); + water2.setShininess(0.3f); + water2.setSunScale(1.0f); + water2.setColorExtinction(new Vector3f(10.0f, 20.0f, 30.0f)); + fpp.addFilter(water2); + + + WaterFilter water3 = new WaterFilter(rootNode, lightDir); + water3.setCenter(new Vector3f(319.6663f, -18.367947f, -236.67674f)); + water3.setRadius(260); + water3.setWaterHeight(WATER_HEIGHT); + water3.setWaveScale(0.003f); + water3.setMaxAmplitude(2f); + water3.setFoamExistence(new Vector3f(1f, 4, 0.5f)); + water3.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); + water3.setRefractionStrength(0.2f); + water3.setDeepWaterColor(ColorRGBA.Red); + water3.setWaterColor(ColorRGBA.Red.mult(2.0f)); + water3.setLightColor(ColorRGBA.Red); + fpp.addFilter(water3); + + viewPort.addProcessor(fpp); + + //fpp.setNumSamples(4); + } + + private void createTerrain(Node rootNode) { + Material matRock = new Material(assetManager, + "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matRock.setBoolean("useTriPlanarMapping", false); + matRock.setBoolean("WardIso", true); + matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/pools.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap", grass); + matRock.setFloat("DiffuseMap_0_scale", 64); + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_1", dirt); + matRock.setFloat("DiffuseMap_1_scale", 16); + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_2", rock); + matRock.setFloat("DiffuseMap_2_scale", 128); + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(WrapMode.Repeat); + matRock.setTexture("NormalMap", normalMap0); + matRock.setTexture("NormalMap_1", normalMap1); + matRock.setTexture("NormalMap_2", normalMap2); + + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); + heightmap.load(); + } catch (Exception e) { + e.printStackTrace(); + } + TerrainQuad terrain + = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + List cameras = new ArrayList<>(); + cameras.add(getCamera()); + terrain.setMaterial(matRock); + terrain.setLocalScale(new Vector3f(5, 5, 5)); + terrain.setLocalTranslation(new Vector3f(0, -30, 0)); + terrain.setLocked(false); // unlock it so we can edit the height + + terrain.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(terrain); + + } + + @Override + public void simpleUpdate(float tpf) { + } +} diff --git a/jme3-examples/src/main/java/jme3test/water/TestPostWater.java b/jme3-examples/src/main/java/jme3test/water/TestPostWater.java new file mode 100644 index 0000000000..384d88f7f9 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/water/TestPostWater.java @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2009-2022 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. + */ +package jme3test.water; + +import com.jme3.app.SimpleApplication; +import com.jme3.audio.AudioData.DataType; +import com.jme3.audio.AudioNode; +import com.jme3.audio.Filter; +import com.jme3.audio.LowPassFilter; +import com.jme3.font.BitmapText; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.AmbientLight; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.post.filters.DepthOfFieldFilter; +import com.jme3.post.filters.FXAAFilter; +import com.jme3.post.filters.LightScatteringFilter; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.texture.Texture2D; +import com.jme3.util.SkyFactory; +import com.jme3.util.SkyFactory.EnvMapType; +import com.jme3.water.WaterFilter; + +/** + * test + * + * @author normenhansen + */ +public class TestPostWater extends SimpleApplication { + + final private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f); + private WaterFilter water; + private AudioNode waves; + final private LowPassFilter aboveWaterAudioFilter = new LowPassFilter(1, 1); + final private Filter underWaterAudioFilter = new LowPassFilter(0.5f, 0.1f); + private boolean useDryFilter = true; + + public static void main(String[] args) { + TestPostWater app = new TestPostWater(); + app.start(); + } + + @Override + public void simpleInitApp() { + + setDisplayFps(false); + setDisplayStatView(false); + + Node mainScene = new Node("Main Scene"); + rootNode.attachChild(mainScene); + + createTerrain(mainScene); + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(lightDir); + sun.setColor(ColorRGBA.White.clone().multLocal(1f)); + mainScene.addLight(sun); + + AmbientLight al = new AmbientLight(); + al.setColor(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f)); + mainScene.addLight(al); + + flyCam.setMoveSpeed(50); + + //cam.setLocation(new Vector3f(-700, 100, 300)); + //cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z)); +// cam.setLocation(new Vector3f(-327.21957f, 61.6459f, 126.884346f)); +// cam.setRotation(new Quaternion(0.052168474f, 0.9443102f, -0.18395276f, 0.2678024f)); + + + cam.setLocation(new Vector3f(-370.31592f, 182.04016f, 196.81192f)); + cam.setRotation(new Quaternion(0.015302252f, 0.9304095f, -0.039101653f, 0.3641086f)); + + + + + Spatial sky = SkyFactory.createSky(assetManager, + "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); + sky.setLocalScale(350); + + mainScene.attachChild(sky); + cam.setFrustumFar(4000); + + //Water Filter + water = new WaterFilter(rootNode, lightDir); + water.setWaterColor(new ColorRGBA().setAsSrgb(0.0078f, 0.3176f, 0.5f, 1.0f)); + water.setDeepWaterColor(new ColorRGBA().setAsSrgb(0.0039f, 0.00196f, 0.145f, 1.0f)); + water.setUnderWaterFogDistance(80); + water.setWaterTransparency(0.12f); + water.setFoamIntensity(0.4f); + water.setFoamHardness(0.3f); + water.setFoamExistence(new Vector3f(0.8f, 8f, 1f)); + water.setReflectionDisplace(50); + water.setRefractionConstant(0.25f); + water.setColorExtinction(new Vector3f(30, 50, 70)); + water.setCausticsIntensity(0.4f); + water.setWaveScale(0.003f); + water.setMaxAmplitude(2f); + water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); + water.setRefractionStrength(0.2f); + water.setWaterHeight(initialWaterHeight); + + //Bloom Filter + BloomFilter bloom = new BloomFilter(); + bloom.setExposurePower(55); + bloom.setBloomIntensity(1.0f); + + //Light Scattering Filter + LightScatteringFilter lsf = new LightScatteringFilter(lightDir.mult(-300)); + lsf.setLightDensity(0.5f); + + //Depth of field Filter + DepthOfFieldFilter dof = new DepthOfFieldFilter(); + dof.setFocusDistance(0); + dof.setFocusRange(100); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + + fpp.addFilter(water); + fpp.addFilter(bloom); + fpp.addFilter(dof); + fpp.addFilter(lsf); + fpp.addFilter(new FXAAFilter()); + +// fpp.addFilter(new TranslucentBucketFilter()); + int numSamples = getContext().getSettings().getSamples(); + if (numSamples > 0) { + fpp.setNumSamples(numSamples); + } + + + uw = cam.getLocation().y < waterHeight; + + waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", + DataType.Buffer); + waves.setLooping(true); + updateAudio(); + audioRenderer.playSource(waves); + // + viewPort.addProcessor(fpp); + + setText(0, 50, "1 - Set Foam Texture to Foam.jpg"); + setText(0, 80, "2 - Set Foam Texture to Foam2.jpg"); + setText(0, 110, "3 - Set Foam Texture to Foam3.jpg"); + setText(0, 140, "4 - Turn Dry Filter under water On/Off"); + setText(0, 240, "PgUp - Larger Reflection Map"); + setText(0, 270, "PgDn - Smaller Reflection Map"); + + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + if (name.equals("foam1")) { + water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg")); + } + if (name.equals("foam2")) { + water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); + } + if (name.equals("foam3")) { + water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg")); + } + + if (name.equals("upRM")) { + water.setReflectionMapSize(Math.min(water.getReflectionMapSize() * 2, 4096)); + System.out.println("Reflection map size : " + water.getReflectionMapSize()); + } + if (name.equals("downRM")) { + water.setReflectionMapSize(Math.max(water.getReflectionMapSize() / 2, 32)); + System.out.println("Reflection map size : " + water.getReflectionMapSize()); + } + if (name.equals("dryFilter")) { + useDryFilter = !useDryFilter; + } + } + } + }, "foam1", "foam2", "foam3", "upRM", "downRM", "dryFilter"); + inputManager.addMapping("foam1", new KeyTrigger(KeyInput.KEY_1)); + inputManager.addMapping("foam2", new KeyTrigger(KeyInput.KEY_2)); + inputManager.addMapping("foam3", new KeyTrigger(KeyInput.KEY_3)); + inputManager.addMapping("dryFilter", new KeyTrigger(KeyInput.KEY_4)); + inputManager.addMapping("upRM", new KeyTrigger(KeyInput.KEY_PGUP)); + inputManager.addMapping("downRM", new KeyTrigger(KeyInput.KEY_PGDN)); + } + + private void createTerrain(Node rootNode) { + Material matRock = new Material(assetManager, + "Common/MatDefs/Terrain/TerrainLighting.j3md"); + matRock.setBoolean("useTriPlanarMapping", false); + matRock.setBoolean("WardIso", true); + matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); + Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); + grass.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap", grass); + matRock.setFloat("DiffuseMap_0_scale", 64); + Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); + dirt.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_1", dirt); + matRock.setFloat("DiffuseMap_1_scale", 16); + Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); + rock.setWrap(WrapMode.Repeat); + matRock.setTexture("DiffuseMap_2", rock); + matRock.setFloat("DiffuseMap_2_scale", 128); + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); + normalMap0.setWrap(WrapMode.Repeat); + Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); + normalMap1.setWrap(WrapMode.Repeat); + Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); + normalMap2.setWrap(WrapMode.Repeat); + matRock.setTexture("NormalMap", normalMap0); + matRock.setTexture("NormalMap_1", normalMap1); + matRock.setTexture("NormalMap_2", normalMap2); + + AbstractHeightMap heightmap = null; + try { + heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); + heightmap.load(); + } catch (Exception e) { + e.printStackTrace(); + } + TerrainQuad terrain + = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); + terrain.setMaterial(matRock); + terrain.setLocalScale(new Vector3f(5, 5, 5)); + terrain.setLocalTranslation(new Vector3f(0, -30, 0)); + terrain.setLocked(false); // unlock it so we can edit the height + + terrain.setShadowMode(ShadowMode.Receive); + rootNode.attachChild(terrain); + + } + //This part is to emulate tides, slightly varying the height of the water plane + private float time = 0.0f; + private float waterHeight = 0.0f; + final private float initialWaterHeight = 90f;//0.8f; + private boolean uw = false; + + @Override + public void simpleUpdate(float tpf) { + super.simpleUpdate(tpf); + // box.updateGeometricState(); + time += tpf; + waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f; + water.setWaterHeight(initialWaterHeight + waterHeight); + uw = water.isUnderWater(); + updateAudio(); + } + + protected void setText(int x, int y, String text) { + BitmapText txt2 = new BitmapText(guiFont); + txt2.setText(text); + txt2.setLocalTranslation(x, cam.getHeight() - y, 0); + txt2.setColor(ColorRGBA.Red); + guiNode.attachChild(txt2); + } + + /** + * Update the audio settings (dry filter and reverb) + * based on boolean fields ({@code uw} and {@code useDryFilter}). + */ + protected void updateAudio() { + Filter newDryFilter; + if (!useDryFilter) { + newDryFilter = null; + } else if (uw) { + newDryFilter = underWaterAudioFilter; + } else { + newDryFilter = aboveWaterAudioFilter; + } + Filter oldDryFilter = waves.getDryFilter(); + if (oldDryFilter != newDryFilter) { + System.out.println("dry filter : " + newDryFilter); + waves.setDryFilter(newDryFilter); + } + + boolean newReverbEnabled = !uw; + boolean oldReverbEnabled = waves.isReverbEnabled(); + if (oldReverbEnabled != newReverbEnabled) { + System.out.println("reverb enabled : " + newReverbEnabled); + waves.setReverbEnabled(newReverbEnabled); + } + } +} \ No newline at end of file diff --git a/jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java b/jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java new file mode 100644 index 0000000000..3ac2c47ba0 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/water/TestPostWaterLake.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009-2021 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. + */ +package jme3test.water; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.asset.plugins.ZipLocator; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.scene.Spatial; +import com.jme3.util.SkyFactory; +import com.jme3.water.WaterFilter; +import java.io.File; + +public class TestPostWaterLake extends SimpleApplication { + + private static boolean useHttp = false; + + public static void main(String[] args) { + TestPostWaterLake app = new TestPostWaterLake(); + app.start(); + } + + @Override + public void simpleInitApp() { + File file = new File("wildhouse.zip"); + if (!file.exists()) { + useHttp = true; + } + + this.flyCam.setMoveSpeed(10); + cam.setLocation(new Vector3f(-27.0f, 1.0f, 75.0f)); + // cam.setRotation(new Quaternion(0.03f, 0.9f, 0f, 0.4f)); + + // load sky + rootNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + + // create the geometry and attach it + // load the level from zip or http zip + if (useHttp) { + assetManager.registerLocator( + "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", + HttpZipLocator.class); + } else { + assetManager.registerLocator("wildhouse.zip", ZipLocator.class); + } + Spatial scene = assetManager.loadModel("main.scene"); + rootNode.attachChild(scene); + + DirectionalLight sun = new DirectionalLight(); + Vector3f lightDir = new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); + sun.setDirection(lightDir); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + scene.addLight(sun); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + final WaterFilter water = new WaterFilter(rootNode, lightDir); + water.setWaterHeight(-20); + water.setUseFoam(false); + water.setUseRipples(false); + water.setDeepWaterColor(ColorRGBA.Brown); + water.setWaterColor(ColorRGBA.Brown.mult(2.0f)); + water.setWaterTransparency(0.2f); + water.setMaxAmplitude(0.3f); + water.setWaveScale(0.008f); + water.setSpeed(0.7f); + water.setShoreHardness(1.0f); + water.setRefractionConstant(0.2f); + water.setShininess(0.3f); + water.setSunScale(1.0f); + water.setColorExtinction(new Vector3f(10.0f, 20.0f, 30.0f)); + fpp.addFilter(water); + viewPort.addProcessor(fpp); + + inputManager.addListener(new ActionListener() { + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if(isPressed){ + if(water.isUseHQShoreline()){ + water.setUseHQShoreline(false); + }else{ + water.setUseHQShoreline(true); + } + } + } + }, "HQ"); + + inputManager.addMapping("HQ", new KeyTrigger(KeyInput.KEY_SPACE)); + } +} diff --git a/jme3-examples/src/main/java/jme3test/water/TestSceneWater.java b/jme3-examples/src/main/java/jme3test/water/TestSceneWater.java new file mode 100644 index 0000000000..c0f29cff8d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/water/TestSceneWater.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +package jme3test.water; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.HttpZipLocator; +import com.jme3.asset.plugins.ZipLocator; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.*; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.RectangleMesh; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.SkyFactory; +import com.jme3.water.SimpleWaterProcessor; +import java.io.File; + +public class TestSceneWater extends SimpleApplication { + + // set default for applets + private static boolean useHttp = false; + + public static void main(String[] args) { + + TestSceneWater app = new TestSceneWater(); + app.start(); + } + + @Override + public void simpleInitApp() { + File file = new File("wildhouse.zip"); + if (!file.exists()) { + useHttp = true; + } + + this.flyCam.setMoveSpeed(10); + Node mainScene=new Node(); + cam.setLocation(new Vector3f(-27.0f, 1.0f, 75.0f)); + cam.setRotation(new Quaternion(0.03f, 0.9f, 0f, 0.4f)); + + // load sky + mainScene.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + + + // create the geometry and attach it + // load the level from zip or http zip + if (useHttp) { + assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip", HttpZipLocator.class); + } else { + assetManager.registerLocator("wildhouse.zip", ZipLocator.class); + } + Spatial scene = assetManager.loadModel("main.scene"); + + DirectionalLight sun = new DirectionalLight(); + Vector3f lightDir=new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); + sun.setDirection(lightDir); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + scene.addLight(sun); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + //add lightPos Geometry + Sphere lite=new Sphere(8, 8, 3.0f); + Geometry lightSphere=new Geometry("lightsphere", lite); + lightSphere.setMaterial(mat); + Vector3f lightPos=lightDir.multLocal(-400); + lightSphere.setLocalTranslation(lightPos); + rootNode.attachChild(lightSphere); + + + SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager); + waterProcessor.setReflectionScene(mainScene); + waterProcessor.setDebug(false); + waterProcessor.setLightPosition(lightPos); + waterProcessor.setRefractionClippingOffset(1.0f); + + + //setting the water plane + Vector3f waterLocation=new Vector3f(0,-20,0); + waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y))); + WaterUI waterUi=new WaterUI(inputManager, waterProcessor); + waterProcessor.setWaterColor(ColorRGBA.Brown); + waterProcessor.setDebug(true); + //lower render size for higher performance +// waterProcessor.setRenderSize(128,128); + //raise depth to see through water +// waterProcessor.setWaterDepth(20); + //lower the distortion scale if the waves appear too strong +// waterProcessor.setDistortionScale(0.1f); + //lower the speed of the waves if they are too fast +// waterProcessor.setWaveSpeed(0.01f); + + RectangleMesh rect = new RectangleMesh( + new Vector3f(-200, -20, 250), + new Vector3f(200, -20, 250), + new Vector3f(-200, -20, -150)); + + //the texture coordinates define the general size of the waves + rect.scaleTextureCoordinates(new Vector2f(6f, 6f)); + + Geometry water = new Geometry("water", rect); + water.setShadowMode(ShadowMode.Receive); + water.setMaterial(waterProcessor.getMaterial()); + + rootNode.attachChild(water); + + viewPort.addProcessor(waterProcessor); + + mainScene.attachChild(scene); + rootNode.attachChild(mainScene); + } +} diff --git a/jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java b/jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java new file mode 100644 index 0000000000..5bc6604a91 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/water/TestSimpleWater.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.water; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.ActionListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.SkyFactory; +import com.jme3.water.SimpleWaterProcessor; + +/** + * + * @author normenhansen + */ +public class TestSimpleWater extends SimpleApplication implements ActionListener { + + private Material mat; + private Spatial waterPlane; + private Geometry lightSphere; + private SimpleWaterProcessor waterProcessor; + private Node sceneNode; + private boolean useWater = true; + final private Vector3f lightPos = new Vector3f(33,12,-29); + + + public static void main(String[] args) { + TestSimpleWater app = new TestSimpleWater(); + app.start(); + } + + @Override + public void simpleInitApp() { + initInput(); + initScene(); + + //create processor + waterProcessor = new SimpleWaterProcessor(assetManager); + waterProcessor.setReflectionScene(sceneNode); + waterProcessor.setDebug(true); + viewPort.addProcessor(waterProcessor); + + waterProcessor.setLightPosition(lightPos); + + //create water quad + //waterPlane = waterProcessor.createWaterGeometry(100, 100); + waterPlane = assetManager.loadModel("Models/WaterTest/WaterTest.mesh.xml"); + waterPlane.setMaterial(waterProcessor.getMaterial()); + waterPlane.setLocalScale(40); + waterPlane.setLocalTranslation(-5, 0, 5); + + rootNode.attachChild(waterPlane); + } + + private void initScene() { + //init cam location + cam.setLocation(new Vector3f(0, 10, 10)); + cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + //init scene + sceneNode = new Node("Scene"); + mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); + Box b = new Box(1, 1, 1); + Geometry geom = new Geometry("Box", b); + geom.setMaterial(mat); + sceneNode.attachChild(geom); + + // load sky + sceneNode.attachChild(SkyFactory.createSky(assetManager, + "Textures/Sky/Bright/BrightSky.dds", + SkyFactory.EnvMapType.CubeMap)); + rootNode.attachChild(sceneNode); + + //add lightPos Geometry + Sphere lite=new Sphere(8, 8, 3.0f); + lightSphere=new Geometry("lightsphere", lite); + lightSphere.setMaterial(mat); + lightSphere.setLocalTranslation(lightPos); + rootNode.attachChild(lightSphere); + } + + protected void initInput() { + flyCam.setMoveSpeed(3); + //init input + inputManager.addMapping("use_water", new KeyTrigger(KeyInput.KEY_O)); + inputManager.addListener(this, "use_water"); + inputManager.addMapping("lightup", new KeyTrigger(KeyInput.KEY_T)); + inputManager.addListener(this, "lightup"); + inputManager.addMapping("lightdown", new KeyTrigger(KeyInput.KEY_G)); + inputManager.addListener(this, "lightdown"); + inputManager.addMapping("lightleft", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addListener(this, "lightleft"); + inputManager.addMapping("lightright", new KeyTrigger(KeyInput.KEY_K)); + inputManager.addListener(this, "lightright"); + inputManager.addMapping("lightforward", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addListener(this, "lightforward"); + inputManager.addMapping("lightback", new KeyTrigger(KeyInput.KEY_J)); + inputManager.addListener(this, "lightback"); + } + + @Override + public void simpleUpdate(float tpf) { + fpsText.setText("Light Position: "+lightPos.toString()+" Change Light position with [U], [H], [J], [K] and [T], [G] Turn off water with [O]"); + lightSphere.setLocalTranslation(lightPos); + waterProcessor.setLightPosition(lightPos); + } + + @Override + public void onAction(String name, boolean value, float tpf) { + if (name.equals("use_water") && value) { + if (!useWater) { + useWater = true; + waterPlane.setMaterial(waterProcessor.getMaterial()); + } else { + useWater = false; + waterPlane.setMaterial(mat); + } + } else if (name.equals("lightup") && value) { + lightPos.y++; + } else if (name.equals("lightdown") && value) { + lightPos.y--; + } else if (name.equals("lightleft") && value) { + lightPos.x--; + } else if (name.equals("lightright") && value) { + lightPos.x++; + } else if (name.equals("lightforward") && value) { + lightPos.z--; + } else if (name.equals("lightback") && value) { + lightPos.z++; + } + } +} diff --git a/jme3-examples/src/main/java/jme3test/water/WaterUI.java b/jme3-examples/src/main/java/jme3test/water/WaterUI.java new file mode 100644 index 0000000000..f2713d885c --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/water/WaterUI.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2009-2021 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. + */ + +package jme3test.water; + +import com.jme3.input.InputManager; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.water.SimpleWaterProcessor; + +/** + * + * @author nehon + */ +public class WaterUI { + private SimpleWaterProcessor processor; + public WaterUI(InputManager inputManager, SimpleWaterProcessor proc) { + processor=proc; + + + System.out.println("----------------- Water UI Debugger --------------------"); + System.out.println("-- Water transparency : press Y to increase, H to decrease"); + System.out.println("-- Water depth : press U to increase, J to decrease"); +// System.out.println("-- AO scale : press I to increase, K to decrease"); +// System.out.println("-- AO bias : press O to increase, P to decrease"); +// System.out.println("-- Toggle AO on/off : press space bar"); +// System.out.println("-- Use only AO : press Num pad 0"); +// System.out.println("-- Output config declaration : press P"); + System.out.println("-------------------------------------------------------"); + + inputManager.addMapping("transparencyUp", new KeyTrigger(KeyInput.KEY_Y)); + inputManager.addMapping("transparencyDown", new KeyTrigger(KeyInput.KEY_H)); + inputManager.addMapping("depthUp", new KeyTrigger(KeyInput.KEY_U)); + inputManager.addMapping("depthDown", new KeyTrigger(KeyInput.KEY_J)); +// inputManager.addMapping("scaleUp", new KeyTrigger(KeyInput.KEY_I)); +// inputManager.addMapping("scaleDown", new KeyTrigger(KeyInput.KEY_K)); +// inputManager.addMapping("biasUp", new KeyTrigger(KeyInput.KEY_O)); +// inputManager.addMapping("biasDown", new KeyTrigger(KeyInput.KEY_L)); +// inputManager.addMapping("outputConfig", new KeyTrigger(KeyInput.KEY_P)); +// inputManager.addMapping("toggleUseAO", new KeyTrigger(KeyInput.KEY_SPACE)); +// inputManager.addMapping("toggleUseOnlyAo", new KeyTrigger(KeyInput.KEY_NUMPAD0)); + +// ActionListener acl = new ActionListener() { +// +// public void onAction(String name, boolean keyPressed, float tpf) { +// +// if (name.equals("toggleUseAO") && keyPressed) { +// ssaoConfig.setUseAo(!ssaoConfig.isUseAo()); +// System.out.println("use AO : "+ssaoConfig.isUseAo()); +// } +// if (name.equals("toggleUseOnlyAo") && keyPressed) { +// ssaoConfig.setUseOnlyAo(!ssaoConfig.isUseOnlyAo()); +// System.out.println("use Only AO : "+ssaoConfig.isUseOnlyAo()); +// +// } +// if (name.equals("outputConfig") && keyPressed) { +// System.out.println("new SSAOConfig("+ssaoConfig.getSampleRadius()+"f,"+ssaoConfig.getIntensity()+"f,"+ssaoConfig.getScale()+"f,"+ssaoConfig.getBias()+"f,"+ssaoConfig.isUseOnlyAo()+","+ssaoConfig.isUseAo()+");"); +// } +// +// } +// }; + + AnalogListener anl = new AnalogListener() { + + @Override + public void onAnalog(String name, float value, float tpf) { + if (name.equals("transparencyUp")) { + processor.setWaterTransparency(processor.getWaterTransparency()+0.001f); + System.out.println("Water transparency : "+processor.getWaterTransparency()); + } + if (name.equals("transparencyDown")) { + processor.setWaterTransparency(processor.getWaterTransparency()-0.001f); + System.out.println("Water transparency : "+processor.getWaterTransparency()); + } + if (name.equals("depthUp")) { + processor.setWaterDepth(processor.getWaterDepth()+0.001f); + System.out.println("Water depth : "+processor.getWaterDepth()); + } + if (name.equals("depthDown")) { + processor.setWaterDepth(processor.getWaterDepth()-0.001f); + System.out.println("Water depth : "+processor.getWaterDepth()); + } + + } + }; + // inputManager.addListener(acl,"toggleUseAO","toggleUseOnlyAo","outputConfig"); + inputManager.addListener(anl, "transparencyUp","transparencyDown","depthUp","depthDown"); + + } + + + +} diff --git a/jme3-examples/src/main/java/jme3test/water/package-info.java b/jme3-examples/src/main/java/jme3test/water/package-info.java new file mode 100644 index 0000000000..8885d8452b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/water/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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. + */ +/** + * example apps and non-automated tests for water effects + */ +package jme3test.water; From 8ddb04bec341c0cede10c667d5d36fc21ae727d8 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Sat, 23 Sep 2023 10:32:11 -0500 Subject: [PATCH 15/18] changing naming to "Display" instead of "Monitor" --- .../com/jme3/system/android/OGLESContext.java | 4 +- .../java/com/jme3/app/LegacyApplication.java | 26 +++++ .../java/com/jme3/system/AppSettings.java | 23 ++-- .../java/com/jme3/system/DisplayInfo.java | 66 +++++++++++ .../main/java/com/jme3/system/Displays.java | 106 ++++++++++++++++++ .../main/java/com/jme3/system/JmeContext.java | 4 +- .../java/com/jme3/system/NullContext.java | 4 +- .../main/java/com/jme3/system/AWTContext.java | 4 +- .../com/jme3/system/awt/AwtPanelsContext.java | 4 +- .../java/jme3test/app/TestMonitorApp.java | 28 ++--- .../com/jme3/system/ios/IGLESContext.java | 4 +- .../com/jme3/system/lwjgl/LwjglCanvas.java | 6 +- .../com/jme3/system/lwjgl/LwjglDisplay.java | 6 +- .../system/lwjgl/LwjglOffscreenBuffer.java | 6 +- .../com/jme3/system/lwjgl/LwjglDisplay.java | 14 +++ .../com/jme3/system/lwjgl/LwjglWindow.java | 58 +++++----- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 6 +- 17 files changed, 290 insertions(+), 79 deletions(-) create mode 100644 jme3-core/src/main/java/com/jme3/system/DisplayInfo.java create mode 100644 jme3-core/src/main/java/com/jme3/system/Displays.java diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index 005a579b7e..e15dbeb930 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -557,13 +557,13 @@ private Rect getSurfaceFrame() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index 3f2e13cfcf..7a26efa940 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -50,6 +50,7 @@ import com.jme3.renderer.Renderer; import com.jme3.renderer.ViewPort; import com.jme3.system.AppSettings; +import com.jme3.system.Displays; import com.jme3.system.JmeContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystem; @@ -882,4 +883,29 @@ public Object call() { return null; } } + + + /** + * This call will return a list of Monitors that glfwGetMonitors() + * returns and information about the monitor, like width, height, + * and refresh rate. + * + * @return returns a list of monitors and their information. + */ + public Displays getDisplays() + { + return context.getDisplays(); + } + + /** + * Use this to get the positional number of the primary + * monitor from the glfwGetMonitors() function call. + * + * @return the position of the value in the arraylist of + * the primary monitor. + */ + public int getPrimaryDisplay() + { + return context.getPrimaryDisplay(); + } } diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java index b878dde298..5f8519f86c 100644 --- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java +++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java @@ -266,7 +266,7 @@ public final class AppSettings extends HashMap { public static final String JOAL = "JOAL"; static { - defaults.put("Monitor", 0); + defaults.put("Display", 0); defaults.put("CenterWindow", true); defaults.put("Width", 640); defaults.put("Height", 480); @@ -1483,31 +1483,30 @@ public void setWindowYPosition(int pos) { /** - * Gets the monitor number used when creating a window. + * Gets the display number used when creating a window. * *

- * This setting is used only with LWJGL3, it defines which monitor to use when creating a OpenGL + * This setting is used only with LWJGL3, it defines which display to use when creating a OpenGL * window. * - * @return the desired monitor used when creating a OpenGL window - * @see #setMonitor(long) + * @return the desired display used when creating a OpenGL window */ - public int getMonitor() { - return getInteger("Monitor"); + public int getDisplay() { + return getInteger("Display"); } /** - * Sets the monitor number used when creating a window. The position number is the number in the + * Sets the display number used when creating a window. The position number is the number in the * list of monitors GlfwGetMonitors returns. * *

- * This setting is used only with LWJGL3, it defines which monitor to use when creating a OpenGL + * This setting is used only with LWJGL3, it defines which display to use when creating a OpenGL * window. its default value is 0. * - * @param mon the desired monitor used when creating a OpenGL window + * @param mon the desired display used when creating a OpenGL window * */ - public void setMonitor(int mon) { - putInteger("Monitor", mon); + public void setDisplay(int mon) { + putInteger("Display", mon); } } diff --git a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java new file mode 100644 index 0000000000..70b2f3c32e --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.system; + +/** + * This class holds information about the display that was returned by glfwGetMonitors() calls in + * the context class + * + * @author Kevin Bales + */ +public class DisplayInfo { + + /** + * displayID - display id that was return from Lwjgl3. + */ + public long displayID = 0; + + /** + * width - width that was return from Lwjgl3. + */ + public int width = 1080; + + /** + * height - height that was return from Lwjgl3. + */ + public int height = 1920; + + /** + * rate - refresh rate that was return from Lwjgl3. + */ + public int rate = 60; + + /** + * primary - indicates if the display is the primary monitor. + */ + public boolean primary = false; + + /** + * name - display name that was return from Lwjgl3. + */ + public String name = "Generic Monitor"; + +} diff --git a/jme3-core/src/main/java/com/jme3/system/Displays.java b/jme3-core/src/main/java/com/jme3/system/Displays.java new file mode 100644 index 0000000000..847c16eadc --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/system/Displays.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2009-2023 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. + */ +package com.jme3.system; + +import java.util.ArrayList; + +/** + * This class holds all information about all displays that where return from the glfwGetMonitors() + * call. It stores them into an ArrayList + * + * @author Kevin Bales + */ +public class Displays { + + private ArrayList displays = new ArrayList(); + + public int addNewMonitor(long displaysID) { + DisplayInfo info = new DisplayInfo(); + info.displayID = displaysID; + displays.add(info); + return displays.size() - 1; + } + + /** + * This function returns the size of the display ArrayList + * + * @return the + */ + public int size() { + return displays.size(); + } + + /** + * Call to get display information on a certain display. + * + * @param pos the position in the ArrayList of the display information that you want to get. + * @return returns the DisplayInfo data for the display called for. + */ + public DisplayInfo get(int pos) { + if (pos < displays.size()) + return displays.get(pos); + + return null; + } + + /** + * Set information about this display stored in displayPos display in the array list. + * + * @param displayPos ArrayList position of display to update + * @param name name of the display + * @param width the current width the display is displaying + * @param height the current height the display is displaying + * @param rate the current refresh rate the display is set to + */ + public void setInfo(int displayPos, String name, int width, int height, int rate) { + if (displayPos < displays.size()) { + DisplayInfo info = displays.get(displayPos); + if (info != null) { + info.width = width; + info.height = height; + info.rate = rate; + info.name = name; + } + } + } + + /** + * This function will mark a certain display as the primary display. + * + * @param displayPos the position in the ArrayList of which display is the primary display + */ + public void setPrimaryDisplay(int displayPos) { + if (displayPos < displays.size()) { + DisplayInfo info = displays.get(displayPos); + if (info != null) + info.primary = true; + } + + } + + + +} diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index 258639634f..34e4971f63 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -232,7 +232,7 @@ public enum Type { * * @return returns a list of monitors and their information. */ - public Monitors getMonitors(); + public Displays getDisplays(); /** * Use this to get the positional number of the primary monitor from the glfwGetMonitors() @@ -240,5 +240,5 @@ public enum Type { * * @return the position of the value in the arraylist of the primary monitor. */ - public int getPrimaryMonitor(); + public int getPrimaryDisplay(); } diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index e58f143b45..b317ce24ed 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -308,13 +308,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java index c58b2c44af..095bcd6691 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java @@ -277,13 +277,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index afb8003fcd..fc165bb1fd 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -330,13 +330,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index bf3b837fdd..064a6deb31 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -49,8 +49,8 @@ import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.system.AppSettings; -import com.jme3.system.MonitorInfo; -import com.jme3.system.Monitors; +import com.jme3.system.DisplayInfo; +import com.jme3.system.Displays; /** * Tests the capability to change which monitor the window will be created on. @@ -67,7 +67,7 @@ public class TestMonitorApp extends SimpleApplication private BitmapText selectedMonitorTxt; private BitmapText fullScreenTxt; private int monitorSelected = 0; - private Monitors monitors = null; + private Displays monitors = null; public static void main(String[] args) { TestMonitorApp app = new TestMonitorApp(); @@ -75,7 +75,7 @@ public static void main(String[] args) { settings.setResizable(false); app.setShowSettings(true); settings.setRenderer(AppSettings.LWJGL_OPENGL33); - settings.setMonitor(0); + settings.setDisplay(0); settings.setResolution(800, 600); settings.setFullscreen(true); @@ -115,8 +115,8 @@ public void simpleInitApp() { } // Get the selected monitor - monitorSelected = settings.getMonitor(); - monitors = context.getMonitors(); + monitorSelected = settings.getDisplay(); + monitors = context.getDisplays(); if (monitors != null) numMonitors = monitors.size(); @@ -134,7 +134,7 @@ public void simpleInitApp() { if (!settings.isFullscreen()) txt.setText("Window is on Monitor N/A (fullscreen only feature)"); else - txt.setText("Window is on Monitor " + settings.getMonitor()); + txt.setText("Window is on Monitor " + settings.getDisplay()); txt.setLocalTranslation(0, settings.getHeight() - 40, 0); guiNode.attachChild(txt); @@ -143,11 +143,11 @@ public void simpleInitApp() { selectedMonitorTxt = new BitmapText(loadGuiFont()); // Lets display information about selected monitor String label = "Selected Monitor " + "Name: " - + monitors.get(settings.getMonitor()).name + " " + + monitors.get(settings.getDisplay()).name + " " + monitorSelected + " Res: " - + monitors.get(settings.getMonitor()).width + "," - + monitors.get(settings.getMonitor()).height + " refresh: " - + monitors.get(settings.getMonitor()).rate; + + monitors.get(settings.getDisplay()).width + "," + + monitors.get(settings.getDisplay()).height + " refresh: " + + monitors.get(settings.getDisplay()).rate; selectedMonitorTxt.setText(label); selectedMonitorTxt.setLocalTranslation(0, settings.getHeight() - 80, 0); @@ -155,7 +155,7 @@ public void simpleInitApp() { // Let's loop through all the monitors and display on the screen for (int i = 0; i < monitors.size(); i++) { - MonitorInfo monitor = monitors.get(i); + DisplayInfo monitor = monitors.get(i); labelValue = "Mon : " + i + " " + monitor.name + " " + monitor.width + "," + monitor.height + " refresh: " + monitor.rate; txt = new BitmapText(loadGuiFont()); @@ -212,11 +212,11 @@ public void onAction(String name, boolean isPressed, float tpf) { public void saveSettings() { try { - settings.setMonitor(monitorSelected); + settings.setDisplay(monitorSelected); OutputStream out = new FileOutputStream("TestMonitorApp.prefs"); settings.save(out); - int monitorSelected = settings.getMonitor(); + int monitorSelected = settings.getDisplay(); String label = "Selected Monitor " + monitorSelected + " " + monitors.get(monitorSelected).name + " Res: " + monitors.get(monitorSelected).width + "," diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index 2a18b56569..0343dadbd8 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -269,13 +269,13 @@ public int getWindowYPosition() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 7728c11257..cea21d1f56 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -27,10 +27,10 @@ package com.jme3.system.lwjgl; import com.jme3.system.AppSettings; +import com.jme3.system.Displays; import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystem; -import com.jme3.system.Monitors; import com.jme3.system.Platform; import java.awt.Canvas; import java.util.logging.Level; @@ -484,13 +484,13 @@ protected void createContext(AppSettings settings) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 020746256b..51b342d257 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -33,8 +33,8 @@ package com.jme3.system.lwjgl; import com.jme3.system.AppSettings; +import com.jme3.system.Displays; import com.jme3.system.JmeContext.Type; -import com.jme3.system.Monitors; import java.awt.Graphics2D; import java.awt.image.BufferedImage; @@ -285,13 +285,13 @@ private ByteBuffer imageToByteBuffer(BufferedImage image) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 86add690a4..727890a981 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -38,7 +38,7 @@ import com.jme3.input.TouchInput; import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -221,13 +221,13 @@ public void setTitle(String title) { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 3eb749adcf..35637c16db 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -31,6 +31,8 @@ */ package com.jme3.system.lwjgl; +import com.jme3.system.Displays; + /** * @author Daniel Johansson */ @@ -39,4 +41,16 @@ public class LwjglDisplay extends LwjglWindow { public LwjglDisplay() { super(Type.Display); } + + @Override + public Displays getDisplays() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryDisplay() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index d9f23baeeb..04b07d1923 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -41,9 +41,9 @@ import com.jme3.input.lwjgl.GlfwMouseInput; import com.jme3.math.Vector2f; import com.jme3.system.AppSettings; +import com.jme3.system.Displays; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; -import com.jme3.system.Monitors; import com.jme3.system.NanoTimer; import com.jme3.util.BufferUtils; import com.jme3.util.SafeArrayList; @@ -292,11 +292,11 @@ public void invoke(int error, long description) { // long monitor = NULL; /** - * Let's grab the monitor selected, if not found it will return - * primaryMonitor. if not full screen just use primary monitor data. + * Let's grab the display selected, if not found it will return + * primaryMonitor. if not full screen just use primary display data. */ if (settings.isFullscreen()) { - monitor = getMonitor(settings.getMonitor()); + monitor = getDisplay(settings.getDisplay()); } else { monitor = glfwGetPrimaryMonitor(); } @@ -882,12 +882,12 @@ public int getWindowYPosition() { * @return returns the Primary Monitor Position. */ @Override - public int getPrimaryMonitor() + public int getPrimaryDisplay() { long prim = glfwGetPrimaryMonitor(); - Monitors monitors = getMonitors(); + Displays monitors = getDisplays(); for ( int i = 0; i < monitors.size(); i++ ) { - long monitorI = monitors.get(i).monitorID; + long monitorI = monitors.get(i).displayID; if (monitorI == prim) return i; } @@ -898,41 +898,41 @@ public int getPrimaryMonitor() /** - * This routines return the monitor ID by position in an array of monitors returned + * This routines return the display ID by position in an array of display returned * by glfwGetMonitors(). * - * @param pos the position of the monitor in the list of monitors returned. - * @return return the monitorID if found otherwise return Primary Monitor + * @param pos the position of the display in the list of displays returned. + * @return return the displayID if found otherwise return Primary display */ - private long getMonitor(int pos) { - Monitors monitors = getMonitors(); - if (pos < monitors.size()) - return monitors.get(pos).monitorID; + private long getDisplay(int pos) { + Displays displays = getDisplays(); + if (pos < displays.size()) + return displays.get(pos).displayID; - LOGGER.log(Level.SEVERE,"Couldn't locate Monitor requested in the list of Monitors. pos:"+pos+" size: "+ monitors.size()); + LOGGER.log(Level.SEVERE,"Couldn't locate Display requested in the list of Displays. pos:"+pos+" size: "+ displays.size()); return glfwGetPrimaryMonitor(); } /** - * This returns an arraylist of all the monitors returned by OpenGL get Monitor - * call. It will also has some limited information about each monitor, like: + * This returns an arraylist of all the Display returned by OpenGL get Monitor + * call. It will also has some limited information about each display, like: * width, height and refresh rate. * - * @return returns an ArrayList of all Monitors returned by glfwGetMonitors() + * @return returns an ArrayList of all Display returned by glfwGetMonitors() */ @Override - public Monitors getMonitors() { - PointerBuffer monitors = glfwGetMonitors(); + public Displays getDisplays() { + PointerBuffer displays = glfwGetMonitors(); long primary = glfwGetPrimaryMonitor(); - Monitors monitorList = new Monitors(); + Displays displayList = new Displays(); - for ( int i = 0; i < monitors.limit(); i++ ) { - long monitorI = monitors.get(i); - int monPos = monitorList.addNewMonitor(monitorI); - //lets check if this monitor is the primary monitor. If use mark it as such. + for ( int i = 0; i < displays.limit(); i++ ) { + long monitorI = displays.get(i); + int monPos = displayList.addNewMonitor(monitorI); + //lets check if this display is the primary display. If use mark it as such. if (primary == monitorI) - monitorList.setPrimaryMonitor(monPos); + displayList.setPrimaryDisplay(monPos); final GLFWVidMode modes = glfwGetVideoMode(monitorI); String name = glfwGetMonitorName(monitorI); @@ -940,9 +940,9 @@ public Monitors getMonitors() { int width = modes.width(); int height = modes.height(); int rate = modes.refreshRate(); - monitorList.setInfo(monPos, name, width, height, rate); - LOGGER.log(Level.INFO, "Monitor id: "+monitorI+" Resolution: " + width + " x " + height + " @ " + rate); + displayList.setInfo(monPos, name, width, height, rate); + LOGGER.log(Level.INFO, "Display id: "+monitorI+" Resolution: " + width + " x " + height + " @ " + rate); } - return monitorList; + return displayList; } } diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index f7f08126ba..2f557d8ae5 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -32,7 +32,7 @@ package com.jme3.system.lwjgl; import com.jme3.opencl.Context; -import com.jme3.system.Monitors; +import com.jme3.system.Displays; /** * A VR oriented LWJGL display. @@ -54,13 +54,13 @@ public Context getOpenCLContext() { } @Override - public Monitors getMonitors() { + public Displays getDisplays() { // TODO Auto-generated method stub return null; } @Override - public int getPrimaryMonitor() { + public int getPrimaryDisplay() { // TODO Auto-generated method stub return 0; } From 2f39669ab518a799616e254f3a0bce639b83de13 Mon Sep 17 00:00:00 2001 From: bob0bob Date: Sat, 23 Sep 2023 15:33:39 +0000 Subject: [PATCH 16/18] auto-format --- .../com/jme3/system/android/OGLESContext.java | 228 ++-- .../java/com/jme3/app/LegacyApplication.java | 21 +- .../java/com/jme3/system/AppSettings.java | 34 +- .../java/com/jme3/system/DisplayInfo.java | 51 +- .../main/java/com/jme3/system/Displays.java | 116 +- .../main/java/com/jme3/system/JmeContext.java | 11 +- .../java/com/jme3/system/NullContext.java | 77 +- .../main/java/com/jme3/system/AWTContext.java | 363 +++--- .../com/jme3/system/awt/AwtPanelsContext.java | 54 +- .../java/jme3test/app/TestMonitorApp.java | 378 +++--- .../com/jme3/system/ios/IGLESContext.java | 40 +- .../com/jme3/system/lwjgl/LwjglCanvas.java | 1016 +++++++++-------- .../com/jme3/system/lwjgl/LwjglDisplay.java | 624 +++++----- .../system/lwjgl/LwjglOffscreenBuffer.java | 468 ++++---- .../com/jme3/system/lwjgl/LwjglDisplay.java | 20 +- .../com/jme3/system/lwjgl/LwjglWindow.java | 457 ++++---- .../com/jme3/system/lwjgl/LwjglDisplayVR.java | 135 +-- 17 files changed, 2100 insertions(+), 1993 deletions(-) diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index e15dbeb930..b52f4ac08e 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -59,7 +59,6 @@ import com.jme3.system.*; import com.jme3.util.BufferAllocatorFactory; import com.jme3.util.PrimitiveAllocator; - import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -79,7 +78,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex protected SystemListener listener; protected boolean autoFlush = true; protected AndroidInputHandler androidInput; - protected long minFrameDuration = 0; // No FPS cap + protected long minFrameDuration = 0; // No FPS cap protected long lastUpdateTime = 0; static { @@ -90,8 +89,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex } } - public OGLESContext() { - } + public OGLESContext() {} @Override public Type getType() { @@ -115,9 +113,11 @@ public GLSurfaceView createView(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { // below 4.0, check OpenGL ES 2.0 support. if (info.reqGlEsVersion < 0x20000) { - throw new UnsupportedOperationException("OpenGL ES 2.0 or better is not supported on this device"); + throw new UnsupportedOperationException( + "OpenGL ES 2.0 or better is not supported on this device" + ); } - } else if (Build.VERSION.SDK_INT < 9){ + } else if (Build.VERSION.SDK_INT < 9) { throw new UnsupportedOperationException("jME3 requires Android 2.3 or later"); } @@ -127,7 +127,7 @@ public GLSurfaceView createView(Context context) { if (androidInput == null) { if (Build.VERSION.SDK_INT >= 14) { androidInput = new AndroidInputHandler14(); - } else if (Build.VERSION.SDK_INT >= 9){ + } else if (Build.VERSION.SDK_INT >= 9) { androidInput = new AndroidInputHandler(); } } @@ -137,7 +137,7 @@ public GLSurfaceView createView(Context context) { // setEGLContextClientVersion must be set before calling setRenderer // this means it cannot be set in AndroidConfigChooser (too late) // use proper openGL ES version - view.setEGLContextClientVersion(info.reqGlEsVersion>>16); + view.setEGLContextClientVersion(info.reqGlEsVersion >> 16); view.setFocusableInTouchMode(true); view.setFocusable(true); @@ -200,22 +200,35 @@ protected void initInThread() { logger.log(Level.FINE, "Running on thread: {0}", Thread.currentThread().getName()); // Setup unhandled Exception Handler - Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread thread, Throwable thrown) { - listener.handleError("Exception thrown in " + thread.toString(), thrown); - } - }); + Thread + .currentThread() + .setUncaughtExceptionHandler( + new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable thrown) { + listener.handleError("Exception thrown in " + thread.toString(), thrown); + } + } + ); timer = new NanoTimer(); GL gl = new AndroidGL(); if (settings.getBoolean("GraphicsDebug")) { - gl = (GL) GLDebug.createProxy(gl, gl, GL.class, GL2.class, GLES_30.class, GLFbo.class, GLExt.class); + gl = + (GL) GLDebug.createProxy( + gl, + gl, + GL.class, + GL2.class, + GLES_30.class, + GLFbo.class, + GLExt.class + ); } if (settings.getBoolean("GraphicsTrace")) { - gl = (GL)GLTracer.createGlesTracer(gl, GL.class, GLES_30.class, GLFbo.class, GLExt.class); + gl = (GL) GLTracer.createGlesTracer(gl, GL.class, GLES_30.class, GLFbo.class, GLExt.class); } - renderer = new GLRenderer(gl, (GLExt)gl, (GLFbo)gl); + renderer = new GLRenderer(gl, (GLExt) gl, (GLFbo) gl); renderer.initialize(); JmeSystem.setSoftTextDialogInput(this); @@ -254,7 +267,7 @@ public void setSettings(AppSettings settings) { } if (settings.getFrameRate() > 0) { - minFrameDuration = (long)(1000d / settings.getFrameRate()); // ms + minFrameDuration = (long) (1000d / settings.getFrameRate()); // ms logger.log(Level.FINE, "Setting min tpf: {0}ms", minFrameDuration); } else { minFrameDuration = 0; @@ -312,8 +325,7 @@ public Timer getTimer() { } @Override - public void setTitle(String title) { - } + public void setTitle(String title) {} @Override public boolean isCreated() { @@ -329,7 +341,11 @@ public void setAutoFlushFrames(boolean enabled) { @Override public void onSurfaceChanged(GL10 gl, int width, int height) { if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "GL Surface changed, width: {0} height: {1}", new Object[]{width, height}); + logger.log( + Level.FINE, + "GL Surface changed, width: {0} height: {1}", + new Object[] { width, height } + ); } // update the application settings with the new resolution settings.setResolution(width, height); @@ -372,16 +388,14 @@ public void onDrawFrame(GL10 gl) { // Enforce a FPS cap if (updateDelta < minFrameDuration) { -// logger.log(Level.INFO, "lastUpdateTime: {0}, updateDelta: {1}, minTimePerFrame: {2}", -// new Object[]{lastUpdateTime, updateDelta, minTimePerFrame}); + // logger.log(Level.INFO, "lastUpdateTime: {0}, updateDelta: {1}, minTimePerFrame: {2}", + // new Object[]{lastUpdateTime, updateDelta, minTimePerFrame}); try { Thread.sleep(minFrameDuration - updateDelta); - } catch (InterruptedException e) { - } + } catch (InterruptedException e) {} } lastUpdateTime = System.currentTimeMillis(); - } } @@ -402,8 +416,7 @@ public void create() { } @Override - public void restart() { - } + public void restart() {} @Override public void destroy(boolean waitFor) { @@ -421,76 +434,99 @@ protected void waitFor(boolean createdVal) { while (renderable.get() != createdVal) { try { Thread.sleep(10); - } catch (InterruptedException ex) { - } + } catch (InterruptedException ex) {} } } @Override - public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) { + public void requestDialog( + final int id, + final String title, + final String initialValue, + final SoftTextDialogInputListener listener + ) { if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "requestDialog: title: {0}, initialValue: {1}", - new Object[]{title, initialValue}); + logger.log( + Level.FINE, + "requestDialog: title: {0}, initialValue: {1}", + new Object[] { title, initialValue } + ); } final View view = JmeAndroidSystem.getView(); - view.getHandler().post(new Runnable() { - @Override - public void run() { - - final FrameLayout layoutTextDialogInput = new FrameLayout(view.getContext()); - final EditText editTextDialogInput = new EditText(view.getContext()); - editTextDialogInput.setWidth(LayoutParams.FILL_PARENT); - editTextDialogInput.setHeight(LayoutParams.FILL_PARENT); - editTextDialogInput.setPadding(20, 20, 20, 20); - editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL); - //editTextDialogInput.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); - - editTextDialogInput.setText(initialValue); - - switch (id) { - case SoftTextDialogInput.TEXT_ENTRY_DIALOG: - - editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT); - break; - - case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG: - - editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED); - break; - - case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG: - - editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE); - break; - - default: - break; + view + .getHandler() + .post( + new Runnable() { + @Override + public void run() { + final FrameLayout layoutTextDialogInput = new FrameLayout(view.getContext()); + final EditText editTextDialogInput = new EditText(view.getContext()); + editTextDialogInput.setWidth(LayoutParams.FILL_PARENT); + editTextDialogInput.setHeight(LayoutParams.FILL_PARENT); + editTextDialogInput.setPadding(20, 20, 20, 20); + editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL); + //editTextDialogInput.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); + + editTextDialogInput.setText(initialValue); + + switch (id) { + case SoftTextDialogInput.TEXT_ENTRY_DIALOG: + editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT); + break; + case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG: + editTextDialogInput.setInputType( + InputType.TYPE_CLASS_NUMBER | + InputType.TYPE_NUMBER_FLAG_DECIMAL | + InputType.TYPE_NUMBER_FLAG_SIGNED + ); + break; + case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG: + editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE); + break; + default: + break; + } + + layoutTextDialogInput.addView(editTextDialogInput); + + AlertDialog dialogTextInput = new AlertDialog.Builder(view.getContext()) + .setTitle(title) + .setView(layoutTextDialogInput) + .setPositiveButton( + "OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int whichButton) { + /* User clicked OK, send COMPLETE action + * and text */ + listener.onSoftText( + SoftTextDialogInputListener.COMPLETE, + editTextDialogInput.getText().toString() + ); + } + } + ) + .setNegativeButton( + "Cancel", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int whichButton) { + /* User clicked CANCEL, send CANCEL action + * and text */ + listener.onSoftText( + SoftTextDialogInputListener.CANCEL, + editTextDialogInput.getText().toString() + ); + } + } + ) + .create(); + + dialogTextInput.show(); + } } - - layoutTextDialogInput.addView(editTextDialogInput); - - AlertDialog dialogTextInput = new AlertDialog.Builder(view.getContext()).setTitle(title).setView(layoutTextDialogInput).setPositiveButton("OK", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - /* User clicked OK, send COMPLETE action - * and text */ - listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString()); - } - }).setNegativeButton("Cancel", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - /* User clicked CANCEL, send CANCEL action - * and text */ - listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString()); - } - }).create(); - - dialogTextInput.show(); - } - }); + ); } @Override @@ -542,11 +578,11 @@ public int getWindowXPosition() { public int getWindowYPosition() { throw new UnsupportedOperationException("not implemented yet"); } - + /** * Retrieves the dimensions of the input surface. Note: do not modify the * returned object. - * + * * @return the dimensions (in pixels, left and top are 0) */ private Rect getSurfaceFrame() { @@ -558,13 +594,13 @@ private Rect getSurfaceFrame() { @Override public Displays getDisplays() { - // TODO Auto-generated method stub - return null; + // TODO Auto-generated method stub + return null; } @Override public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; + // TODO Auto-generated method stub + return 0; } - } +} diff --git a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java index 7a26efa940..1e0a75daf7 100644 --- a/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java +++ b/jme3-core/src/main/java/com/jme3/app/LegacyApplication.java @@ -883,29 +883,26 @@ public Object call() { return null; } } - - + /** * This call will return a list of Monitors that glfwGetMonitors() - * returns and information about the monitor, like width, height, + * returns and information about the monitor, like width, height, * and refresh rate. - * + * * @return returns a list of monitors and their information. */ - public Displays getDisplays() - { - return context.getDisplays(); + public Displays getDisplays() { + return context.getDisplays(); } - + /** * Use this to get the positional number of the primary * monitor from the glfwGetMonitors() function call. - * + * * @return the position of the value in the arraylist of * the primary monitor. */ - public int getPrimaryDisplay() - { - return context.getPrimaryDisplay(); + public int getPrimaryDisplay() { + return context.getPrimaryDisplay(); } } diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java index 5f8519f86c..d5653a5d71 100644 --- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java +++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java @@ -86,7 +86,6 @@ public final class AppSettings extends HashMap { @Deprecated public static final String LWJGL_OPENGL3 = "LWJGL-OpenGL3"; - /** * Use LWJGL as the display system and force using the core OpenGL3.0 renderer. *

@@ -437,7 +436,9 @@ public void load(String preferencesKey) throws BackingStoreException { put(key.substring(2), prefs.getBoolean(key, false)); break; default: - throw new UnsupportedOperationException("Undefined setting type: " + key.charAt(0)); + throw new UnsupportedOperationException( + "Undefined setting type: " + key.charAt(0) + ); } } else { // Use old method for compatibility with older preferences @@ -719,7 +720,7 @@ public void setRenderer(String renderer) { * @param clazz The custom context class. * (Default: not set) */ - public void setCustomRenderer(Class clazz){ + public void setCustomRenderer(Class clazz) { put("Renderer", "CUSTOM" + clazz.getName()); } @@ -767,7 +768,7 @@ public void setResolution(int width, int height) { /** * Set the size of the window - * + * * @param width The width in pixels (default = width of the default framebuffer) * @param height The height in pixels (default = height of the default framebuffer) */ @@ -803,8 +804,6 @@ public void setMinResolution(int width, int height) { setMinHeight(height); } - - /** * Set the frequency, also known as refresh rate, for the * rendering display. @@ -826,7 +825,7 @@ public void setFrequency(int value) { * * @param value The depth bits */ - public void setDepthBits(int value){ + public void setDepthBits(int value) { putInteger("DepthBits", value); } @@ -845,7 +844,7 @@ public void setDepthBits(int value){ * * @param value The alpha bits */ - public void setAlphaBits(int value){ + public void setAlphaBits(int value) { putInteger("AlphaBits", value); } @@ -860,7 +859,7 @@ public void setAlphaBits(int value){ * * @param value Number of stencil bits */ - public void setStencilBits(int value){ + public void setStencilBits(int value) { putInteger("StencilBits", value); } @@ -922,7 +921,7 @@ public void setVSync(boolean value) { * * @param value true to enable 3-D stereo, false to disable (default=false) */ - public void setStereo3D(boolean value){ + public void setStereo3D(boolean value) { putBoolean("Stereo3D", value); } @@ -1181,7 +1180,7 @@ public String getAudioRenderer() { * @return true if 3-D stereo is enabled, otherwise false * @see #setStereo3D(boolean) */ - public boolean useStereo3D(){ + public boolean useStereo3D() { return getBoolean("Stereo3D"); } @@ -1302,7 +1301,7 @@ public String getOpenCLPlatformChooser() { * Without this, many openGL calls might fail without notice, so turning it on is recommended for development. * Graphics Debug mode will also label native objects and group calls on supported renderers. Compatible * graphics debuggers will be able to use this data to show a better outlook of your application - * + * * @return whether the context will be run in Graphics Debug Mode or not * @see #setGraphicsDebug(boolean) */ @@ -1480,8 +1479,7 @@ public int getWindowYPosition() { public void setWindowYPosition(int pos) { putInteger("WindowYPosition", pos); } - - + /** * Gets the display number used when creating a window. * @@ -1492,7 +1490,7 @@ public void setWindowYPosition(int pos) { * @return the desired display used when creating a OpenGL window */ public int getDisplay() { - return getInteger("Display"); + return getInteger("Display"); } /** @@ -1504,9 +1502,9 @@ public int getDisplay() { * window. its default value is 0. * * @param mon the desired display used when creating a OpenGL window - * + * */ public void setDisplay(int mon) { - putInteger("Display", mon); + putInteger("Display", mon); } - } +} diff --git a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java index 70b2f3c32e..08c3bab6c6 100644 --- a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java @@ -28,39 +28,38 @@ /** * This class holds information about the display that was returned by glfwGetMonitors() calls in * the context class - * + * * @author Kevin Bales */ public class DisplayInfo { - /** - * displayID - display id that was return from Lwjgl3. - */ - public long displayID = 0; - - /** - * width - width that was return from Lwjgl3. - */ - public int width = 1080; + /** + * displayID - display id that was return from Lwjgl3. + */ + public long displayID = 0; - /** - * height - height that was return from Lwjgl3. - */ - public int height = 1920; + /** + * width - width that was return from Lwjgl3. + */ + public int width = 1080; - /** - * rate - refresh rate that was return from Lwjgl3. - */ - public int rate = 60; + /** + * height - height that was return from Lwjgl3. + */ + public int height = 1920; - /** - * primary - indicates if the display is the primary monitor. - */ - public boolean primary = false; + /** + * rate - refresh rate that was return from Lwjgl3. + */ + public int rate = 60; - /** - * name - display name that was return from Lwjgl3. - */ - public String name = "Generic Monitor"; + /** + * primary - indicates if the display is the primary monitor. + */ + public boolean primary = false; + /** + * name - display name that was return from Lwjgl3. + */ + public String name = "Generic Monitor"; } diff --git a/jme3-core/src/main/java/com/jme3/system/Displays.java b/jme3-core/src/main/java/com/jme3/system/Displays.java index 847c16eadc..01592866b4 100644 --- a/jme3-core/src/main/java/com/jme3/system/Displays.java +++ b/jme3-core/src/main/java/com/jme3/system/Displays.java @@ -30,77 +30,71 @@ /** * This class holds all information about all displays that where return from the glfwGetMonitors() * call. It stores them into an ArrayList - * + * * @author Kevin Bales */ public class Displays { - private ArrayList displays = new ArrayList(); - - public int addNewMonitor(long displaysID) { - DisplayInfo info = new DisplayInfo(); - info.displayID = displaysID; - displays.add(info); - return displays.size() - 1; - } - - /** - * This function returns the size of the display ArrayList - * - * @return the - */ - public int size() { - return displays.size(); - } - - /** - * Call to get display information on a certain display. - * - * @param pos the position in the ArrayList of the display information that you want to get. - * @return returns the DisplayInfo data for the display called for. - */ - public DisplayInfo get(int pos) { - if (pos < displays.size()) - return displays.get(pos); + private ArrayList displays = new ArrayList(); - return null; - } - - /** - * Set information about this display stored in displayPos display in the array list. - * - * @param displayPos ArrayList position of display to update - * @param name name of the display - * @param width the current width the display is displaying - * @param height the current height the display is displaying - * @param rate the current refresh rate the display is set to - */ - public void setInfo(int displayPos, String name, int width, int height, int rate) { - if (displayPos < displays.size()) { - DisplayInfo info = displays.get(displayPos); - if (info != null) { - info.width = width; - info.height = height; - info.rate = rate; - info.name = name; - } + public int addNewMonitor(long displaysID) { + DisplayInfo info = new DisplayInfo(); + info.displayID = displaysID; + displays.add(info); + return displays.size() - 1; } - } - /** - * This function will mark a certain display as the primary display. - * - * @param displayPos the position in the ArrayList of which display is the primary display - */ - public void setPrimaryDisplay(int displayPos) { - if (displayPos < displays.size()) { - DisplayInfo info = displays.get(displayPos); - if (info != null) - info.primary = true; + /** + * This function returns the size of the display ArrayList + * + * @return the + */ + public int size() { + return displays.size(); } - } + /** + * Call to get display information on a certain display. + * + * @param pos the position in the ArrayList of the display information that you want to get. + * @return returns the DisplayInfo data for the display called for. + */ + public DisplayInfo get(int pos) { + if (pos < displays.size()) return displays.get(pos); + return null; + } + /** + * Set information about this display stored in displayPos display in the array list. + * + * @param displayPos ArrayList position of display to update + * @param name name of the display + * @param width the current width the display is displaying + * @param height the current height the display is displaying + * @param rate the current refresh rate the display is set to + */ + public void setInfo(int displayPos, String name, int width, int height, int rate) { + if (displayPos < displays.size()) { + DisplayInfo info = displays.get(displayPos); + if (info != null) { + info.width = width; + info.height = height; + info.rate = rate; + info.name = name; + } + } + } + /** + * This function will mark a certain display as the primary display. + * + * @param displayPos the position in the ArrayList of which display is the primary display + */ + public void setPrimaryDisplay(int displayPos) { + if (displayPos < displays.size()) { + DisplayInfo info = displays.get(displayPos); + if (info != null) info.primary = true; + } + } } diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java index 34e4971f63..c2ffe912ef 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java @@ -41,7 +41,6 @@ * Represents a rendering context within the engine. */ public interface JmeContext { - /** * The type of context. */ @@ -77,7 +76,7 @@ public enum Type { * any drawable surface. The implementation does not provide any * display, input, or sound support. */ - Headless; + Headless, } /** @@ -102,7 +101,7 @@ public enum Type { /** * Sets the listener that will receive events relating to context * creation, update, and destroy. - * + * * @param listener the desired listener */ public void setSystemListener(SystemListener listener); @@ -229,7 +228,7 @@ public enum Type { /** * This call will return a list of Monitors that glfwGetMonitors() returns and information about * the monitor, like width, height, and refresh rate. - * + * * @return returns a list of monitors and their information. */ public Displays getDisplays(); @@ -237,8 +236,8 @@ public enum Type { /** * Use this to get the positional number of the primary monitor from the glfwGetMonitors() * function call. - * + * * @return the position of the value in the arraylist of the primary monitor. */ public int getPrimaryDisplay(); - } +} diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java index b317ce24ed..2f2518f8c3 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullContext.java +++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java @@ -48,7 +48,7 @@ public class NullContext implements JmeContext, Runnable { protected static final Logger logger = Logger.getLogger(NullContext.class.getName()); protected static final String THREAD_NAME = "jME3 Headless Main"; - + protected AtomicBoolean created = new AtomicBoolean(false); protected AtomicBoolean needClose = new AtomicBoolean(false); protected final Object createdLock = new Object(); @@ -75,26 +75,28 @@ public SystemListener getSystemListener() { } @Override - public void setSystemListener(SystemListener listener){ + public void setSystemListener(SystemListener listener) { this.listener = listener; } - protected void initInThread(){ + protected void initInThread() { logger.fine("NullContext created."); if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Running on thread: {0}", Thread.currentThread().getName()); } - Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread thread, Throwable thrown) { - listener.handleError("Uncaught exception thrown in "+thread.toString(), thrown); + Thread.setDefaultUncaughtExceptionHandler( + new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable thrown) { + listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown); + } } - }); + ); timer = new NanoTimer(); renderer = new NullRenderer(); - synchronized (createdLock){ + synchronized (createdLock) { created.set(true); createdLock.notifyAll(); } @@ -102,10 +104,10 @@ public void uncaughtException(Thread thread, Throwable thrown) { listener.initialize(); } - protected void deinitInThread(){ + protected void deinitInThread() { listener.destroy(); timer = null; - synchronized (createdLock){ + synchronized (createdLock) { created.set(false); createdLock.notifyAll(); } @@ -142,7 +144,7 @@ public void sync(int fps) { } @Override - public void run(){ + public void run() { initInThread(); do { @@ -159,31 +161,27 @@ public void run(){ } @Override - public void destroy(boolean waitFor){ + public void destroy(boolean waitFor) { needClose.set(true); - if (waitFor) - waitFor(false); + if (waitFor) waitFor(false); } @Override - public void create(boolean waitFor){ - if (created.get()){ + public void create(boolean waitFor) { + if (created.get()) { logger.warning("create() called when NullContext is already created!"); return; } new Thread(this, THREAD_NAME).start(); - if (waitFor) - waitFor(true); + if (waitFor) waitFor(true); } @Override - public void restart() { - } + public void restart() {} @Override - public void setAutoFlushFrames(boolean enabled){ - } + public void setAutoFlushFrames(boolean enabled) {} @Override public MouseInput getMouseInput() { @@ -206,30 +204,28 @@ public TouchInput getTouchInput() { } @Override - public void setTitle(String title) { - } + public void setTitle(String title) {} - public void create(){ + public void create() { create(false); } - public void destroy(){ + public void destroy() { destroy(false); } - protected void waitFor(boolean createdVal){ - synchronized (createdLock){ - while (created.get() != createdVal){ + protected void waitFor(boolean createdVal) { + synchronized (createdLock) { + while (created.get() != createdVal) { try { createdLock.wait(); - } catch (InterruptedException ex) { - } + } catch (InterruptedException ex) {} } } } @Override - public boolean isCreated(){ + public boolean isCreated() { return created.get(); } @@ -237,12 +233,11 @@ public boolean isCreated(){ public void setSettings(AppSettings settings) { this.settings.copyFrom(settings); frameRate = settings.getFrameRate(); - if (frameRate <= 0) - frameRate = 60; // use default update rate. + if (frameRate <= 0) frameRate = 60; // use default update rate. } @Override - public AppSettings getSettings(){ + public AppSettings getSettings() { return settings; } @@ -259,7 +254,7 @@ public Timer getTimer() { @Override public boolean isRenderable() { return true; // Doesn't really matter if true or false. Either way - // RenderManager won't render anything. + // RenderManager won't render anything. } @Override @@ -309,13 +304,13 @@ public int getWindowYPosition() { @Override public Displays getDisplays() { - // TODO Auto-generated method stub - return null; + // TODO Auto-generated method stub + return null; } @Override public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; + // TODO Auto-generated method stub + return 0; } } diff --git a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java index 095bcd6691..d1911e3482 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/AWTContext.java @@ -31,7 +31,6 @@ */ package com.jme3.system; - import com.jme3.input.AWTKeyInput; import com.jme3.input.AWTMouseInput; import com.jme3.input.JoyInput; @@ -49,104 +48,104 @@ */ public class AWTContext implements JmeContext { - /** - * The settings. - */ - protected final AppSettings settings; - - /** - * The key input. - */ - protected final AWTKeyInput keyInput; - - /** - * The mouse input. - */ - protected final AWTMouseInput mouseInput; - - /** - * The current width. - */ - private volatile int width; - - /** - * The current height. - */ - private volatile int height; - - /** - * The background context. - */ - protected JmeContext backgroundContext; - - public AWTContext() { - this.keyInput = new AWTKeyInput(this); - this.mouseInput = new AWTMouseInput(this); - this.settings = createSettings(); - this.backgroundContext = createBackgroundContext(); - this.height = 1; - this.width = 1; - } - - /** - * @return the current height. - */ - public int getHeight() { - return height; - } - - /** - * @param height the current height. - */ - public void setHeight(final int height) { - this.height = height; - } - - /** - * @return the current width. - */ - public int getWidth() { - return width; - } - - /** - * @param width the current width. - */ - public void setWidth(final int width) { - this.width = width; - } - - /** - * @return new settings. - */ - protected AppSettings createSettings() { - final AppSettings settings = new AppSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL32); - return settings; - } - - /** - * @return new context/ - */ - protected JmeContext createBackgroundContext() { - return JmeSystem.newContext(settings, Type.OffscreenSurface); - } - - @Override - public Type getType() { - return Type.OffscreenSurface; - } - - @Override - public void setSettings(AppSettings settings) { - this.settings.copyFrom(settings); - this.settings.setRenderer(AppSettings.LWJGL_OPENGL32); - this.backgroundContext.setSettings(settings); - } + /** + * The settings. + */ + protected final AppSettings settings; + + /** + * The key input. + */ + protected final AWTKeyInput keyInput; + + /** + * The mouse input. + */ + protected final AWTMouseInput mouseInput; + + /** + * The current width. + */ + private volatile int width; + + /** + * The current height. + */ + private volatile int height; + + /** + * The background context. + */ + protected JmeContext backgroundContext; + + public AWTContext() { + this.keyInput = new AWTKeyInput(this); + this.mouseInput = new AWTMouseInput(this); + this.settings = createSettings(); + this.backgroundContext = createBackgroundContext(); + this.height = 1; + this.width = 1; + } + + /** + * @return the current height. + */ + public int getHeight() { + return height; + } + + /** + * @param height the current height. + */ + public void setHeight(final int height) { + this.height = height; + } + + /** + * @return the current width. + */ + public int getWidth() { + return width; + } + + /** + * @param width the current width. + */ + public void setWidth(final int width) { + this.width = width; + } + + /** + * @return new settings. + */ + protected AppSettings createSettings() { + final AppSettings settings = new AppSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL32); + return settings; + } + + /** + * @return new context/ + */ + protected JmeContext createBackgroundContext() { + return JmeSystem.newContext(settings, Type.OffscreenSurface); + } + + @Override + public Type getType() { + return Type.OffscreenSurface; + } + + @Override + public void setSettings(AppSettings settings) { + this.settings.copyFrom(settings); + this.settings.setRenderer(AppSettings.LWJGL_OPENGL32); + this.backgroundContext.setSettings(settings); + } /** * Accesses the listener that receives events related to this context. - * + * * @return the pre-existing instance */ @Override @@ -154,87 +153,85 @@ public SystemListener getSystemListener() { return backgroundContext.getSystemListener(); } - @Override - public void setSystemListener(final SystemListener listener) { - backgroundContext.setSystemListener(listener); - } - - @Override - public AppSettings getSettings() { - return settings; - } - - @Override - public Renderer getRenderer() { - return backgroundContext.getRenderer(); - } - - @Override - public Context getOpenCLContext() { - return null; - } - - @Override - public AWTMouseInput getMouseInput() { - return mouseInput; - } - - @Override - public AWTKeyInput getKeyInput() { - return keyInput; - } - - @Override - public JoyInput getJoyInput() { - return null; - } - - @Override - public TouchInput getTouchInput() { - return null; - } - - @Override - public Timer getTimer() { - return backgroundContext.getTimer(); - } - - @Override - public void setTitle(final String title) { - } - - @Override - public boolean isCreated() { - return backgroundContext != null && backgroundContext.isCreated(); - } - - @Override - public boolean isRenderable() { - return backgroundContext != null && backgroundContext.isRenderable(); - } - - @Override - public void setAutoFlushFrames(final boolean enabled) { - // TODO Auto-generated method stub - } - - @Override - public void create(final boolean waitFor) { + @Override + public void setSystemListener(final SystemListener listener) { + backgroundContext.setSystemListener(listener); + } + + @Override + public AppSettings getSettings() { + return settings; + } + + @Override + public Renderer getRenderer() { + return backgroundContext.getRenderer(); + } + + @Override + public Context getOpenCLContext() { + return null; + } + + @Override + public AWTMouseInput getMouseInput() { + return mouseInput; + } + + @Override + public AWTKeyInput getKeyInput() { + return keyInput; + } + + @Override + public JoyInput getJoyInput() { + return null; + } + + @Override + public TouchInput getTouchInput() { + return null; + } + + @Override + public Timer getTimer() { + return backgroundContext.getTimer(); + } + + @Override + public void setTitle(final String title) {} + + @Override + public boolean isCreated() { + return backgroundContext != null && backgroundContext.isCreated(); + } + + @Override + public boolean isRenderable() { + return backgroundContext != null && backgroundContext.isRenderable(); + } + + @Override + public void setAutoFlushFrames(final boolean enabled) { + // TODO Auto-generated method stub + } + + @Override + public void create(final boolean waitFor) { String render = System.getProperty("awt.background.render", AppSettings.LWJGL_OPENGL33); backgroundContext.getSettings().setRenderer(render); backgroundContext.create(waitFor); - } + } - @Override - public void restart() { - } + @Override + public void restart() {} - @Override - public void destroy(final boolean waitFor) { - if (backgroundContext == null) throw new IllegalStateException("Not created"); - // destroy wrapped context - backgroundContext.destroy(waitFor); -} + @Override + public void destroy(final boolean waitFor) { + if (backgroundContext == null) throw new IllegalStateException("Not created"); + // destroy wrapped context + backgroundContext.destroy(waitFor); + } /** * Returns the height of the framebuffer. @@ -276,15 +273,15 @@ public int getWindowYPosition() { throw new UnsupportedOperationException("not implemented yet"); } - @Override - public Displays getDisplays() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; - } + @Override + public Displays getDisplays() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryDisplay() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java index fc165bb1fd..a25f25379e 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java +++ b/jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanelsContext.java @@ -109,9 +109,8 @@ public void destroy() { } } - public void setInputSource(AwtPanel panel){ - if (!panels.contains(panel)) - throw new IllegalArgumentException(); + public void setInputSource(AwtPanel panel) { + if (!panels.contains(panel)) throw new IllegalArgumentException(); inputSource = panel; mouseInput.setInputSource(panel); @@ -187,42 +186,41 @@ public boolean isRenderable() { public Context getOpenCLContext() { return actualContext.getOpenCLContext(); } - - public AwtPanelsContext(){ - } - public AwtPanel createPanel(PaintMode paintMode){ + public AwtPanelsContext() {} + + public AwtPanel createPanel(PaintMode paintMode) { AwtPanel panel = new AwtPanel(paintMode); panels.add(panel); return panel; } - - public AwtPanel createPanel(PaintMode paintMode, boolean srgb){ + + public AwtPanel createPanel(PaintMode paintMode, boolean srgb) { AwtPanel panel = new AwtPanel(paintMode, srgb); panels.add(panel); return panel; } - private void initInThread(){ + private void initInThread() { listener.initialize(); } - private void updateInThread(){ + private void updateInThread() { // Check if throttle required boolean needThrottle = true; - for (AwtPanel panel : panels){ - if (panel.isActiveDrawing()){ + for (AwtPanel panel : panels) { + if (panel.isActiveDrawing()) { needThrottle = false; break; } } - if (lastThrottleState != needThrottle){ + if (lastThrottleState != needThrottle) { lastThrottleState = needThrottle; - if (lastThrottleState){ + if (lastThrottleState) { System.out.println("OGL: Throttling update loop."); - }else{ + } else { System.out.println("OGL: Ceased throttling update loop."); } } @@ -230,18 +228,17 @@ private void updateInThread(){ if (needThrottle) { try { Thread.sleep(100); - } catch (InterruptedException ex) { - } + } catch (InterruptedException ex) {} } listener.update(); - - for (AwtPanel panel : panels){ + + for (AwtPanel panel : panels) { panel.onFrameEnd(); } } - private void destroyInThread(){ + private void destroyInThread() { listener.destroy(); } @@ -249,14 +246,14 @@ private void destroyInThread(){ public void setSettings(AppSettings settings) { this.settings.copyFrom(settings); this.settings.setRenderer(AppSettings.LWJGL_OPENGL2); - if (actualContext != null){ + if (actualContext != null) { actualContext.setSettings(settings); } } @Override public void create(boolean waitFor) { - if (actualContext != null){ + if (actualContext != null) { throw new IllegalStateException("Already created"); } @@ -267,8 +264,7 @@ public void create(boolean waitFor) { @Override public void destroy(boolean waitFor) { - if (actualContext == null) - throw new IllegalStateException("Not created"); + if (actualContext == null) throw new IllegalStateException("Not created"); // destroy parent context actualContext.destroy(waitFor); @@ -331,13 +327,13 @@ public int getWindowYPosition() { @Override public Displays getDisplays() { - // TODO Auto-generated method stub - return null; + // TODO Auto-generated method stub + return null; } @Override public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; + // TODO Auto-generated method stub + return 0; } } diff --git a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java index 064a6deb31..c8f77387f8 100644 --- a/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java +++ b/jme3-examples/src/main/java/jme3test/app/TestMonitorApp.java @@ -31,15 +31,6 @@ */ package jme3test.app; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.logging.Level; -import java.util.logging.Logger; - import com.jme3.app.SimpleApplication; import com.jme3.font.BitmapText; import com.jme3.input.KeyInput; @@ -51,190 +42,203 @@ import com.jme3.system.AppSettings; import com.jme3.system.DisplayInfo; import com.jme3.system.Displays; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Tests the capability to change which monitor the window will be created on. * Also, shows that you can force JME to center the window. Also, it shows to to * force JME to set the window to x,y coords. Center window and window position * doesn't apply if in fullscreen. - * + * * @author Kevin Bales */ -public class TestMonitorApp extends SimpleApplication - implements ActionListener { - - private BitmapText txt; - private BitmapText selectedMonitorTxt; - private BitmapText fullScreenTxt; - private int monitorSelected = 0; - private Displays monitors = null; - - public static void main(String[] args) { - TestMonitorApp app = new TestMonitorApp(); - AppSettings settings = new AppSettings(true); - settings.setResizable(false); - app.setShowSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL33); - settings.setDisplay(0); - settings.setResolution(800, 600); - - settings.setFullscreen(true); - - // Force JME to center the window, this only applies if it is - // not fullscreen. - settings.setCenterWindow(true); - - // If center window is not turned on, you can force JME to - // open the window at certain x,y coords. These are ignored - // if the screen is set to "fullscreen". - settings.setWindowXPosition(0); - settings.setWindowYPosition(0); - - try { - // Let's try and load the AppSetting parameters back into memory - InputStream out = new FileInputStream("TestMonitorApp.prefs"); - settings.load(out); - } catch (IOException e) { - System.out.println("failed to load settings, reverting to defaults"); - } - app.setSettings(settings); - - app.start(); - } - - @Override - public void simpleInitApp() { - flyCam.setDragToRotate(true); - int numMonitors = 1; - - // If monitor is define, Jme supports multiple monitors. Setup to keys - if (monitors == null) { - inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN)); - inputManager.addMapping("fullscreen", new KeyTrigger(KeyInput.KEY_F)); - inputManager.addListener(this, "down", "fullscreen"); - } - - // Get the selected monitor - monitorSelected = settings.getDisplay(); - monitors = context.getDisplays(); - if (monitors != null) - numMonitors = monitors.size(); - - // Let's define the labels for users to see what is going on with Multiple - // Monitor - String labelValue = ""; - labelValue = "There are " + numMonitors - + " monitor(s) hooked up to this computer."; - txt = new BitmapText(loadGuiFont()); - txt.setText(labelValue); - txt.setLocalTranslation(0, settings.getHeight(), 0); - guiNode.attachChild(txt); - - txt = new BitmapText(loadGuiFont()); - if (!settings.isFullscreen()) - txt.setText("Window is on Monitor N/A (fullscreen only feature)"); - else - txt.setText("Window is on Monitor " + settings.getDisplay()); - - txt.setLocalTranslation(0, settings.getHeight() - 40, 0); - guiNode.attachChild(txt); - - if (monitors != null) { - selectedMonitorTxt = new BitmapText(loadGuiFont()); - // Lets display information about selected monitor - String label = "Selected Monitor " + "Name: " - + monitors.get(settings.getDisplay()).name + " " - + monitorSelected + " Res: " - + monitors.get(settings.getDisplay()).width + "," - + monitors.get(settings.getDisplay()).height + " refresh: " - + monitors.get(settings.getDisplay()).rate; - selectedMonitorTxt.setText(label); - selectedMonitorTxt.setLocalTranslation(0, settings.getHeight() - 80, - 0); - guiNode.attachChild(selectedMonitorTxt); - - // Let's loop through all the monitors and display on the screen - for (int i = 0; i < monitors.size(); i++) { - DisplayInfo monitor = monitors.get(i); - labelValue = "Mon : " + i + " " + monitor.name + " " + monitor.width - + "," + monitor.height + " refresh: " + monitor.rate; - txt = new BitmapText(loadGuiFont()); - txt.setText(labelValue); - txt.setLocalTranslation(0, settings.getHeight() - 160 - (40 * i), - 0); - guiNode.attachChild(txt); - } - } - - // Lets put a label up there for FullScreen/Window toggle - fullScreenTxt = new BitmapText(loadGuiFont()); - if (!settings.isFullscreen()) - fullScreenTxt.setText("(f) Window Screen"); - else - fullScreenTxt.setText("(f) Fullscreen"); - - fullScreenTxt.setLocalTranslation(00, settings.getHeight() - 240, 0); - guiNode.attachChild(fullScreenTxt); - - BitmapText infoTxt = new BitmapText(loadGuiFont()); - infoTxt.setText("Restart is required to activate changes in settings."); - infoTxt.setLocalTranslation(0, settings.getHeight() - 300, 0); - guiNode.attachChild(infoTxt); - - } - - @Override - public void onAction(String name, boolean isPressed, float tpf) { - - if (monitors == null) - return; - - if (name.equals("down") && isPressed) { - monitorSelected++; - if (monitorSelected >= monitors.size()) - monitorSelected = 0; - saveSettings(); - } else if (name.equals("up") && isPressed) { - monitorSelected--; - if (monitorSelected < 0) - monitorSelected = monitors.size() - 1; - saveSettings(); - } else if (name.equals("fullscreen") && isPressed) { - settings.setFullscreen(!settings.isFullscreen()); - saveSettings(); - } - } - - /** - * This function saves out the AppSettings into a file to be loaded back in - * on start of application. - */ - public void saveSettings() { - - try { - settings.setDisplay(monitorSelected); - OutputStream out = new FileOutputStream("TestMonitorApp.prefs"); - settings.save(out); - - int monitorSelected = settings.getDisplay(); - String label = "Selected Monitor " + monitorSelected + " " - + monitors.get(monitorSelected).name + " Res: " - + monitors.get(monitorSelected).width + "," - + monitors.get(monitorSelected).height + "refresh: " - + monitors.get(monitorSelected).rate; - selectedMonitorTxt.setText(label); - if (!settings.isFullscreen()) - fullScreenTxt.setText("(f) Window Screen"); - else - fullScreenTxt.setText("(f) Fullscreen"); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - +public class TestMonitorApp extends SimpleApplication implements ActionListener { + + private BitmapText txt; + private BitmapText selectedMonitorTxt; + private BitmapText fullScreenTxt; + private int monitorSelected = 0; + private Displays monitors = null; + + public static void main(String[] args) { + TestMonitorApp app = new TestMonitorApp(); + AppSettings settings = new AppSettings(true); + settings.setResizable(false); + app.setShowSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL33); + settings.setDisplay(0); + settings.setResolution(800, 600); + + settings.setFullscreen(true); + + // Force JME to center the window, this only applies if it is + // not fullscreen. + settings.setCenterWindow(true); + + // If center window is not turned on, you can force JME to + // open the window at certain x,y coords. These are ignored + // if the screen is set to "fullscreen". + settings.setWindowXPosition(0); + settings.setWindowYPosition(0); + + try { + // Let's try and load the AppSetting parameters back into memory + InputStream out = new FileInputStream("TestMonitorApp.prefs"); + settings.load(out); + } catch (IOException e) { + System.out.println("failed to load settings, reverting to defaults"); + } + app.setSettings(settings); + + app.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setDragToRotate(true); + int numMonitors = 1; + + // If monitor is define, Jme supports multiple monitors. Setup to keys + if (monitors == null) { + inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN)); + inputManager.addMapping("fullscreen", new KeyTrigger(KeyInput.KEY_F)); + inputManager.addListener(this, "down", "fullscreen"); + } + + // Get the selected monitor + monitorSelected = settings.getDisplay(); + monitors = context.getDisplays(); + if (monitors != null) numMonitors = monitors.size(); + + // Let's define the labels for users to see what is going on with Multiple + // Monitor + String labelValue = ""; + labelValue = "There are " + numMonitors + " monitor(s) hooked up to this computer."; + txt = new BitmapText(loadGuiFont()); + txt.setText(labelValue); + txt.setLocalTranslation(0, settings.getHeight(), 0); + guiNode.attachChild(txt); + + txt = new BitmapText(loadGuiFont()); + if (!settings.isFullscreen()) txt.setText( + "Window is on Monitor N/A (fullscreen only feature)" + ); else txt.setText("Window is on Monitor " + settings.getDisplay()); + + txt.setLocalTranslation(0, settings.getHeight() - 40, 0); + guiNode.attachChild(txt); + + if (monitors != null) { + selectedMonitorTxt = new BitmapText(loadGuiFont()); + // Lets display information about selected monitor + String label = + "Selected Monitor " + + "Name: " + + monitors.get(settings.getDisplay()).name + + " " + + monitorSelected + + " Res: " + + monitors.get(settings.getDisplay()).width + + "," + + monitors.get(settings.getDisplay()).height + + " refresh: " + + monitors.get(settings.getDisplay()).rate; + selectedMonitorTxt.setText(label); + selectedMonitorTxt.setLocalTranslation(0, settings.getHeight() - 80, 0); + guiNode.attachChild(selectedMonitorTxt); + + // Let's loop through all the monitors and display on the screen + for (int i = 0; i < monitors.size(); i++) { + DisplayInfo monitor = monitors.get(i); + labelValue = + "Mon : " + + i + + " " + + monitor.name + + " " + + monitor.width + + "," + + monitor.height + + " refresh: " + + monitor.rate; + txt = new BitmapText(loadGuiFont()); + txt.setText(labelValue); + txt.setLocalTranslation(0, settings.getHeight() - 160 - (40 * i), 0); + guiNode.attachChild(txt); + } + } + + // Lets put a label up there for FullScreen/Window toggle + fullScreenTxt = new BitmapText(loadGuiFont()); + if (!settings.isFullscreen()) fullScreenTxt.setText("(f) Window Screen"); else fullScreenTxt.setText( + "(f) Fullscreen" + ); + + fullScreenTxt.setLocalTranslation(00, settings.getHeight() - 240, 0); + guiNode.attachChild(fullScreenTxt); + + BitmapText infoTxt = new BitmapText(loadGuiFont()); + infoTxt.setText("Restart is required to activate changes in settings."); + infoTxt.setLocalTranslation(0, settings.getHeight() - 300, 0); + guiNode.attachChild(infoTxt); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (monitors == null) return; + + if (name.equals("down") && isPressed) { + monitorSelected++; + if (monitorSelected >= monitors.size()) monitorSelected = 0; + saveSettings(); + } else if (name.equals("up") && isPressed) { + monitorSelected--; + if (monitorSelected < 0) monitorSelected = monitors.size() - 1; + saveSettings(); + } else if (name.equals("fullscreen") && isPressed) { + settings.setFullscreen(!settings.isFullscreen()); + saveSettings(); + } + } + + /** + * This function saves out the AppSettings into a file to be loaded back in + * on start of application. + */ + public void saveSettings() { + try { + settings.setDisplay(monitorSelected); + OutputStream out = new FileOutputStream("TestMonitorApp.prefs"); + settings.save(out); + + int monitorSelected = settings.getDisplay(); + String label = + "Selected Monitor " + + monitorSelected + + " " + + monitors.get(monitorSelected).name + + " Res: " + + monitors.get(monitorSelected).width + + "," + + monitors.get(monitorSelected).height + + "refresh: " + + monitors.get(monitorSelected).rate; + selectedMonitorTxt.setText(label); + if (!settings.isFullscreen()) fullScreenTxt.setText( + "(f) Window Screen" + ); else fullScreenTxt.setText("(f) Fullscreen"); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index 0343dadbd8..e314353bbf 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -42,7 +42,6 @@ import com.jme3.renderer.ios.IosGL; import com.jme3.renderer.opengl.*; import com.jme3.system.*; - import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -63,10 +62,10 @@ public class IGLESContext implements JmeContext { protected Timer timer; protected SystemListener listener; protected IosInputHandler input; - protected int minFrameDuration = 0; // No FPS cap + protected int minFrameDuration = 0; // No FPS cap public IGLESContext() { - logger.log(Level.FINE, "IGLESContext constructor"); + logger.log(Level.FINE, "IGLESContext constructor"); } @Override @@ -123,13 +122,13 @@ public KeyInput getKeyInput() { @Override public JoyInput getJoyInput() { - /* + /* if (androidSensorJoyInput == null) { androidSensorJoyInput = new AndroidSensorJoyInput(); } return androidSensorJoyInput; */ - return null;// new DummySensorJoyInput(); + return null; // new DummySensorJoyInput(); } @Override @@ -143,8 +142,7 @@ public Timer getTimer() { } @Override - public void setTitle(String title) { - } + public void setTitle(String title) {} @Override public boolean isCreated() { @@ -160,7 +158,7 @@ public void setAutoFlushFrames(boolean enabled) { @Override public boolean isRenderable() { logger.log(Level.FINE, "IGLESContext isRenderable"); - return true;// renderable.get(); + return true; // renderable.get(); } @Override @@ -169,18 +167,18 @@ public void create(boolean waitFor) { IosGL gl = new IosGL(); if (settings.getBoolean("GraphicsDebug")) { - gl = (IosGL)GLDebug.createProxy(gl, gl, GL.class, GLExt.class, GLFbo.class); + gl = (IosGL) GLDebug.createProxy(gl, gl, GL.class, GLExt.class, GLFbo.class); } renderer = new GLRenderer(gl, gl, gl); renderer.initialize(); - + input = new IosInputHandler(); timer = new NanoTimer(); -//synchronized (createdLock){ - created.set(true); - //createdLock.notifyAll(); + //synchronized (createdLock){ + created.set(true); + //createdLock.notifyAll(); //} listener.initialize(); @@ -196,8 +194,7 @@ public void create() { } @Override - public void restart() { - } + public void restart() {} @Override public void destroy(boolean waitFor) { @@ -217,8 +214,7 @@ protected void waitFor(boolean createdVal) { while (renderable.get() != createdVal) { try { Thread.sleep(10); - } catch (InterruptedException ex) { - } + } catch (InterruptedException ex) {} } } @@ -270,13 +266,13 @@ public int getWindowYPosition() { @Override public Displays getDisplays() { - // TODO Auto-generated method stub - return null; + // TODO Auto-generated method stub + return null; } @Override public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; + // TODO Auto-generated method stub + return 0; } -} \ No newline at end of file +} diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index cea21d1f56..5fa76754b2 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -1,497 +1,519 @@ -/* - * Copyright (c) 2009-2021 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. - */ - -package com.jme3.system.lwjgl; - -import com.jme3.system.AppSettings; -import com.jme3.system.Displays; -import com.jme3.system.JmeCanvasContext; -import com.jme3.system.JmeContext.Type; -import com.jme3.system.JmeSystem; -import com.jme3.system.Platform; -import java.awt.Canvas; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.SwingUtilities; -import org.lwjgl.LWJGLException; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.Display; -import org.lwjgl.opengl.Pbuffer; -import org.lwjgl.opengl.PixelFormat; - -public class LwjglCanvas extends LwjglAbstractDisplay implements JmeCanvasContext { - - protected static final int TASK_NOTHING = 0, TASK_DESTROY_DISPLAY = 1, TASK_CREATE_DISPLAY = 2, - TASK_COMPLETE = 3; - - // protected static final boolean USE_SHARED_CONTEXT = - // Boolean.parseBoolean(System.getProperty("jme3.canvas.sharedctx", "true")); - - protected static final boolean USE_SHARED_CONTEXT = false; - - private static final Logger logger = Logger.getLogger(LwjglDisplay.class.getName()); - private Canvas canvas; - private int width; - private int height; - - private final Object taskLock = new Object(); - private int desiredTask = TASK_NOTHING; - - private Thread renderThread; - private boolean runningFirstTime = true; - private boolean mouseWasGrabbed = false; - - private boolean mouseWasCreated = false; - private boolean keyboardWasCreated = false; - - private Pbuffer pbuffer; - private PixelFormat pbufferFormat; - private PixelFormat canvasFormat; - - private class GLCanvas extends Canvas { - @Override - public void addNotify() { - super.addNotify(); - - if (renderThread != null && renderThread.getState() == Thread.State.TERMINATED) { - return; // already destroyed. - } - - if (renderThread == null) { - logger.log(Level.FINE, "EDT: Creating OGL thread."); - - // Also set some settings on the canvas here. - // So we don't do it outside the AWT thread. - canvas.setFocusable(true); - canvas.setIgnoreRepaint(true); - - renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); - renderThread.start(); - } else if (needClose.get()) { - return; - } - - logger.log(Level.FINE, "EDT: Telling OGL to create display .."); - synchronized (taskLock) { - desiredTask = TASK_CREATE_DISPLAY; - // while (desiredTask != TASK_COMPLETE){ - // try { - // taskLock.wait(); - // } catch (InterruptedException ex) { - // return; - // } - // } - // desiredTask = TASK_NOTHING; - } - // logger.log(Level.FINE, "EDT: OGL has created the display"); - } - - @Override - public void removeNotify() { - if (needClose.get()) { - logger.log(Level.FINE, "EDT: Application is stopped. Not restoring canvas."); - super.removeNotify(); - return; - } - - // We must tell GL context to shut down and wait for it to - // shut down. Otherwise, issues will occur. - logger.log(Level.FINE, "EDT: Telling OGL to destroy display .."); - synchronized (taskLock) { - desiredTask = TASK_DESTROY_DISPLAY; - while (desiredTask != TASK_COMPLETE) { - try { - taskLock.wait(); - } catch (InterruptedException ex) { - super.removeNotify(); - return; - } - } - desiredTask = TASK_NOTHING; - } - - logger.log(Level.FINE, "EDT: Acknowledged receipt of canvas death"); - // GL context is dead at this point - - super.removeNotify(); - } - } - - public LwjglCanvas() { - super(); - canvas = new GLCanvas(); - } - - @Override - public Type getType() { - return Type.Canvas; - } - - @Override - public void create(boolean waitFor) { - if (renderThread == null) { - logger.log(Level.FINE, "MAIN: Creating OGL thread."); - - renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); - renderThread.start(); - } - // do not do anything. - // superclass's create() will be called at initInThread() - if (waitFor) { - waitFor(true); - } - } - - @Override - public void setTitle(String title) {} - - @Override - public void restart() { - frameRate = settings.getFrameRate(); - // TODO: Handle other cases, like change of pixel format, etc. - } - - @Override - public Canvas getCanvas() { - return canvas; - } - - @Override - protected void runLoop() { - if (desiredTask != TASK_NOTHING) { - synchronized (taskLock) { - switch (desiredTask) { - case TASK_CREATE_DISPLAY: - logger.log(Level.FINE, "OGL: Creating display .."); - restoreCanvas(); - listener.gainFocus(); - desiredTask = TASK_NOTHING; - break; - case TASK_DESTROY_DISPLAY: - logger.log(Level.FINE, "OGL: Destroying display .."); - listener.loseFocus(); - pauseCanvas(); - break; - } - desiredTask = TASK_COMPLETE; - taskLock.notifyAll(); - } - } - - if (renderable.get()) { - int newWidth = Math.max(canvas.getWidth(), 1); - int newHeight = Math.max(canvas.getHeight(), 1); - if (width != newWidth || height != newHeight) { - width = newWidth; - height = newHeight; - if (listener != null) { - listener.reshape(width, height); - } - } - } else { - if (frameRate <= 0) { - // NOTE: MUST be done otherwise - // Windows OS will freeze - Display.sync(30); - } - } - - super.runLoop(); - } - - private void pauseCanvas() { - if (Mouse.isCreated()) { - if (Mouse.isGrabbed()) { - Mouse.setGrabbed(false); - mouseWasGrabbed = true; - } - mouseWasCreated = true; - Mouse.destroy(); - } - if (Keyboard.isCreated()) { - keyboardWasCreated = true; - Keyboard.destroy(); - } - - renderable.set(false); - destroyContext(); - } - - /** - * Called to restore the canvas. - */ - private void restoreCanvas() { - logger.log(Level.FINE, "OGL: Waiting for canvas to become displayable.."); - while (!canvas.isDisplayable()) { - try { - Thread.sleep(10); - } catch (InterruptedException ex) { - logger.log(Level.SEVERE, "OGL: Interrupted! ", ex); - } - } - - logger.log(Level.FINE, "OGL: Creating display context .."); - - // Set renderable to true, since canvas is now displayable. - renderable.set(true); - createContext(settings); - - logger.log(Level.FINE, "OGL: Display is active!"); - - try { - if (mouseWasCreated) { - Mouse.create(); - if (mouseWasGrabbed) { - Mouse.setGrabbed(true); - mouseWasGrabbed = false; - } - } - if (keyboardWasCreated) { - Keyboard.create(); - keyboardWasCreated = false; - } - } catch (LWJGLException ex) { - logger.log(Level.SEVERE, "Encountered exception when restoring input", ex); - } - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - canvas.requestFocus(); - } - }); - } - - /** - * It seems it is best to use one pixel format for all shared contexts. - * - * @see http://developer.apple.com/library/mac/#qa/qa1248/_index.html - * - * @param forPbuffer true→zero samples, false→correct number of samples - * @return a new instance - */ - protected PixelFormat acquirePixelFormat(boolean forPbuffer) { - if (forPbuffer) { - // Use 0 samples for pbuffer format, prevents - // crashes on bad drivers - if (pbufferFormat == null) { - pbufferFormat = new PixelFormat(settings.getBitsPerPixel(), settings.getAlphaBits(), - settings.getDepthBits(), settings.getStencilBits(), 0, // samples - 0, 0, 0, settings.useStereo3D()); - } - return pbufferFormat; - } else { - if (canvasFormat == null) { - int samples = getNumSamplesToUse(); - canvasFormat = new PixelFormat(settings.getBitsPerPixel(), settings.getAlphaBits(), - settings.getDepthBits(), settings.getStencilBits(), samples, 0, 0, 0, - settings.useStereo3D()); - } - return canvasFormat; - } - } - - /** - * Makes sure the pbuffer is available and ready for use - * - * @throws LWJGLException if the buffer can't be made current - */ - protected void makePbufferAvailable() throws LWJGLException { - if (pbuffer != null && pbuffer.isBufferLost()) { - logger.log(Level.WARNING, "PBuffer was lost!"); - pbuffer.destroy(); - pbuffer = null; - } - - if (pbuffer == null) { - pbuffer = new Pbuffer(1, 1, acquirePixelFormat(true), null); - pbuffer.makeCurrent(); - logger.log(Level.FINE, "OGL: Pbuffer has been created"); - - // Any created objects are no longer valid - if (!runningFirstTime) { - renderer.resetGLObjects(); - } - } - - pbuffer.makeCurrent(); - if (!pbuffer.isCurrent()) { - throw new LWJGLException("Pbuffer cannot be made current"); - } - } - - protected void destroyPbuffer() { - if (pbuffer != null) { - if (!pbuffer.isBufferLost()) { - pbuffer.destroy(); - } - pbuffer = null; - } - } - - /** - * This is called: 1) When the context thread ends 2) Any time the canvas becomes non-displayable - */ - @Override - protected void destroyContext() { - try { - // invalidate the state so renderer can resume operation - if (!USE_SHARED_CONTEXT) { - renderer.cleanup(); - } - - if (Display.isCreated()) { - /* - * FIXES: org.lwjgl.LWJGLException: X Error BadWindow (invalid Window parameter) - * request_code: 2 minor_code: 0 - * - * Destroying keyboard early prevents the error above, triggered by destroying keyboard in - * by Display.destroy() or Display.setParent(null). Therefore, Keyboard.destroy() should - * precede any of these calls. - */ - if (Keyboard.isCreated()) { - // Should only happen if called in - // LwjglAbstractDisplay.deinitInThread(). - Keyboard.destroy(); - } - - // try { - // NOTE: On Windows XP, not calling setParent(null) - // freezes the application. - // On Mac it freezes the application. - // On Linux it fixes a crash with X Window System. - if (JmeSystem.getPlatform() == Platform.Windows32 - || JmeSystem.getPlatform() == Platform.Windows64) { - // Display.setParent(null); - } - // } catch (LWJGLException ex) { - // logger.log(Level.SEVERE, "Encountered exception when setting parent to null", ex); - // } - - Display.destroy(); - } - - // The canvas is no longer visible, - // but the context thread is still running. - if (!needClose.get()) { - // MUST make sure there's still a context current here. - // Display is dead, make PBuffer available to the system. - makePbufferAvailable(); - - renderer.invalidateState(); - } else { - // The context thread is no longer running. - // Destroy pbuffer. - destroyPbuffer(); - } - } catch (LWJGLException ex) { - listener.handleError("Failed make pbuffer available", ex); - } - } - - /** - * This is called: 1) When the context thread starts 2) Any time the canvas becomes displayable - * again. In the first call of this method, OpenGL context is not ready yet. Therefore, OpenCL - * context cannot be created. The second call of this method is done after "simpleInitApp" is - * called. Therefore, OpenCL won't be available in "simpleInitApp" if Canvas/Swing is used. To use - * OpenCL with Canvas/Swing, you need to use OpenCL in the rendering loop "simpleUpdate" and check - * for "context.getOpenCLContext()!=null". - */ - @Override - protected void createContext(AppSettings settings) { - // In case canvas is not visible, we still take framerate - // from settings to prevent "100% CPU usage" - frameRate = settings.getFrameRate(); - allowSwapBuffers = settings.isSwapBuffers(); - - try { - if (renderable.get()) { - if (!runningFirstTime) { - // because the display is a different opengl context - // must reset the context state. - if (!USE_SHARED_CONTEXT) { - renderer.cleanup(); - } - } - - // if the pbuffer is currently active, - // make sure to deactivate it - destroyPbuffer(); - - if (Keyboard.isCreated()) { - Keyboard.destroy(); - } - - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - } - - Display.setVSyncEnabled(settings.isVSync()); - Display.setParent(canvas); - - if (USE_SHARED_CONTEXT) { - Display.create(acquirePixelFormat(false), pbuffer); - } else { - Display.create(acquirePixelFormat(false)); - } - if (settings.isOpenCLSupport()) { - initOpenCL(); - } - - renderer.invalidateState(); - } else { - // First create the pbuffer, if it is needed. - makePbufferAvailable(); - } - - // At this point, the OpenGL context is active. - if (runningFirstTime) { - // THIS is the part that creates the renderer. - // It must always be called, now that we have the pbuffer workaround. - initContextFirstTime(); - runningFirstTime = false; - } - } catch (LWJGLException ex) { - listener.handleError("Failed to initialize OpenGL context", ex); - // TODO: Fix deadlock that happens after the error (throw runtime exception?) - } - } - - @Override - public Displays getDisplays() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; - } -} +/* + * Copyright (c) 2009-2021 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. + */ + +package com.jme3.system.lwjgl; + +import com.jme3.system.AppSettings; +import com.jme3.system.Displays; +import com.jme3.system.JmeCanvasContext; +import com.jme3.system.JmeContext.Type; +import com.jme3.system.JmeSystem; +import com.jme3.system.Platform; +import java.awt.Canvas; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.SwingUtilities; +import org.lwjgl.LWJGLException; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.Pbuffer; +import org.lwjgl.opengl.PixelFormat; + +public class LwjglCanvas extends LwjglAbstractDisplay implements JmeCanvasContext { + + protected static final int TASK_NOTHING = 0, TASK_DESTROY_DISPLAY = 1, TASK_CREATE_DISPLAY = + 2, TASK_COMPLETE = 3; + + // protected static final boolean USE_SHARED_CONTEXT = + // Boolean.parseBoolean(System.getProperty("jme3.canvas.sharedctx", "true")); + + protected static final boolean USE_SHARED_CONTEXT = false; + + private static final Logger logger = Logger.getLogger(LwjglDisplay.class.getName()); + private Canvas canvas; + private int width; + private int height; + + private final Object taskLock = new Object(); + private int desiredTask = TASK_NOTHING; + + private Thread renderThread; + private boolean runningFirstTime = true; + private boolean mouseWasGrabbed = false; + + private boolean mouseWasCreated = false; + private boolean keyboardWasCreated = false; + + private Pbuffer pbuffer; + private PixelFormat pbufferFormat; + private PixelFormat canvasFormat; + + private class GLCanvas extends Canvas { + + @Override + public void addNotify() { + super.addNotify(); + + if (renderThread != null && renderThread.getState() == Thread.State.TERMINATED) { + return; // already destroyed. + } + + if (renderThread == null) { + logger.log(Level.FINE, "EDT: Creating OGL thread."); + + // Also set some settings on the canvas here. + // So we don't do it outside the AWT thread. + canvas.setFocusable(true); + canvas.setIgnoreRepaint(true); + + renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); + renderThread.start(); + } else if (needClose.get()) { + return; + } + + logger.log(Level.FINE, "EDT: Telling OGL to create display .."); + synchronized (taskLock) { + desiredTask = TASK_CREATE_DISPLAY; + // while (desiredTask != TASK_COMPLETE){ + // try { + // taskLock.wait(); + // } catch (InterruptedException ex) { + // return; + // } + // } + // desiredTask = TASK_NOTHING; + } + // logger.log(Level.FINE, "EDT: OGL has created the display"); + } + + @Override + public void removeNotify() { + if (needClose.get()) { + logger.log(Level.FINE, "EDT: Application is stopped. Not restoring canvas."); + super.removeNotify(); + return; + } + + // We must tell GL context to shut down and wait for it to + // shut down. Otherwise, issues will occur. + logger.log(Level.FINE, "EDT: Telling OGL to destroy display .."); + synchronized (taskLock) { + desiredTask = TASK_DESTROY_DISPLAY; + while (desiredTask != TASK_COMPLETE) { + try { + taskLock.wait(); + } catch (InterruptedException ex) { + super.removeNotify(); + return; + } + } + desiredTask = TASK_NOTHING; + } + + logger.log(Level.FINE, "EDT: Acknowledged receipt of canvas death"); + // GL context is dead at this point + + super.removeNotify(); + } + } + + public LwjglCanvas() { + super(); + canvas = new GLCanvas(); + } + + @Override + public Type getType() { + return Type.Canvas; + } + + @Override + public void create(boolean waitFor) { + if (renderThread == null) { + logger.log(Level.FINE, "MAIN: Creating OGL thread."); + + renderThread = new Thread(LwjglCanvas.this, THREAD_NAME); + renderThread.start(); + } + // do not do anything. + // superclass's create() will be called at initInThread() + if (waitFor) { + waitFor(true); + } + } + + @Override + public void setTitle(String title) {} + + @Override + public void restart() { + frameRate = settings.getFrameRate(); + // TODO: Handle other cases, like change of pixel format, etc. + } + + @Override + public Canvas getCanvas() { + return canvas; + } + + @Override + protected void runLoop() { + if (desiredTask != TASK_NOTHING) { + synchronized (taskLock) { + switch (desiredTask) { + case TASK_CREATE_DISPLAY: + logger.log(Level.FINE, "OGL: Creating display .."); + restoreCanvas(); + listener.gainFocus(); + desiredTask = TASK_NOTHING; + break; + case TASK_DESTROY_DISPLAY: + logger.log(Level.FINE, "OGL: Destroying display .."); + listener.loseFocus(); + pauseCanvas(); + break; + } + desiredTask = TASK_COMPLETE; + taskLock.notifyAll(); + } + } + + if (renderable.get()) { + int newWidth = Math.max(canvas.getWidth(), 1); + int newHeight = Math.max(canvas.getHeight(), 1); + if (width != newWidth || height != newHeight) { + width = newWidth; + height = newHeight; + if (listener != null) { + listener.reshape(width, height); + } + } + } else { + if (frameRate <= 0) { + // NOTE: MUST be done otherwise + // Windows OS will freeze + Display.sync(30); + } + } + + super.runLoop(); + } + + private void pauseCanvas() { + if (Mouse.isCreated()) { + if (Mouse.isGrabbed()) { + Mouse.setGrabbed(false); + mouseWasGrabbed = true; + } + mouseWasCreated = true; + Mouse.destroy(); + } + if (Keyboard.isCreated()) { + keyboardWasCreated = true; + Keyboard.destroy(); + } + + renderable.set(false); + destroyContext(); + } + + /** + * Called to restore the canvas. + */ + private void restoreCanvas() { + logger.log(Level.FINE, "OGL: Waiting for canvas to become displayable.."); + while (!canvas.isDisplayable()) { + try { + Thread.sleep(10); + } catch (InterruptedException ex) { + logger.log(Level.SEVERE, "OGL: Interrupted! ", ex); + } + } + + logger.log(Level.FINE, "OGL: Creating display context .."); + + // Set renderable to true, since canvas is now displayable. + renderable.set(true); + createContext(settings); + + logger.log(Level.FINE, "OGL: Display is active!"); + + try { + if (mouseWasCreated) { + Mouse.create(); + if (mouseWasGrabbed) { + Mouse.setGrabbed(true); + mouseWasGrabbed = false; + } + } + if (keyboardWasCreated) { + Keyboard.create(); + keyboardWasCreated = false; + } + } catch (LWJGLException ex) { + logger.log(Level.SEVERE, "Encountered exception when restoring input", ex); + } + + SwingUtilities.invokeLater( + new Runnable() { + @Override + public void run() { + canvas.requestFocus(); + } + } + ); + } + + /** + * It seems it is best to use one pixel format for all shared contexts. + * + * @see http://developer.apple.com/library/mac/#qa/qa1248/_index.html + * + * @param forPbuffer true→zero samples, false→correct number of samples + * @return a new instance + */ + protected PixelFormat acquirePixelFormat(boolean forPbuffer) { + if (forPbuffer) { + // Use 0 samples for pbuffer format, prevents + // crashes on bad drivers + if (pbufferFormat == null) { + pbufferFormat = + new PixelFormat( + settings.getBitsPerPixel(), + settings.getAlphaBits(), + settings.getDepthBits(), + settings.getStencilBits(), + 0, // samples + 0, + 0, + 0, + settings.useStereo3D() + ); + } + return pbufferFormat; + } else { + if (canvasFormat == null) { + int samples = getNumSamplesToUse(); + canvasFormat = + new PixelFormat( + settings.getBitsPerPixel(), + settings.getAlphaBits(), + settings.getDepthBits(), + settings.getStencilBits(), + samples, + 0, + 0, + 0, + settings.useStereo3D() + ); + } + return canvasFormat; + } + } + + /** + * Makes sure the pbuffer is available and ready for use + * + * @throws LWJGLException if the buffer can't be made current + */ + protected void makePbufferAvailable() throws LWJGLException { + if (pbuffer != null && pbuffer.isBufferLost()) { + logger.log(Level.WARNING, "PBuffer was lost!"); + pbuffer.destroy(); + pbuffer = null; + } + + if (pbuffer == null) { + pbuffer = new Pbuffer(1, 1, acquirePixelFormat(true), null); + pbuffer.makeCurrent(); + logger.log(Level.FINE, "OGL: Pbuffer has been created"); + + // Any created objects are no longer valid + if (!runningFirstTime) { + renderer.resetGLObjects(); + } + } + + pbuffer.makeCurrent(); + if (!pbuffer.isCurrent()) { + throw new LWJGLException("Pbuffer cannot be made current"); + } + } + + protected void destroyPbuffer() { + if (pbuffer != null) { + if (!pbuffer.isBufferLost()) { + pbuffer.destroy(); + } + pbuffer = null; + } + } + + /** + * This is called: 1) When the context thread ends 2) Any time the canvas becomes non-displayable + */ + @Override + protected void destroyContext() { + try { + // invalidate the state so renderer can resume operation + if (!USE_SHARED_CONTEXT) { + renderer.cleanup(); + } + + if (Display.isCreated()) { + /* + * FIXES: org.lwjgl.LWJGLException: X Error BadWindow (invalid Window parameter) + * request_code: 2 minor_code: 0 + * + * Destroying keyboard early prevents the error above, triggered by destroying keyboard in + * by Display.destroy() or Display.setParent(null). Therefore, Keyboard.destroy() should + * precede any of these calls. + */ + if (Keyboard.isCreated()) { + // Should only happen if called in + // LwjglAbstractDisplay.deinitInThread(). + Keyboard.destroy(); + } + + // try { + // NOTE: On Windows XP, not calling setParent(null) + // freezes the application. + // On Mac it freezes the application. + // On Linux it fixes a crash with X Window System. + if ( + JmeSystem.getPlatform() == Platform.Windows32 || + JmeSystem.getPlatform() == Platform.Windows64 + ) { + // Display.setParent(null); + } + // } catch (LWJGLException ex) { + // logger.log(Level.SEVERE, "Encountered exception when setting parent to null", ex); + // } + + Display.destroy(); + } + + // The canvas is no longer visible, + // but the context thread is still running. + if (!needClose.get()) { + // MUST make sure there's still a context current here. + // Display is dead, make PBuffer available to the system. + makePbufferAvailable(); + + renderer.invalidateState(); + } else { + // The context thread is no longer running. + // Destroy pbuffer. + destroyPbuffer(); + } + } catch (LWJGLException ex) { + listener.handleError("Failed make pbuffer available", ex); + } + } + + /** + * This is called: 1) When the context thread starts 2) Any time the canvas becomes displayable + * again. In the first call of this method, OpenGL context is not ready yet. Therefore, OpenCL + * context cannot be created. The second call of this method is done after "simpleInitApp" is + * called. Therefore, OpenCL won't be available in "simpleInitApp" if Canvas/Swing is used. To use + * OpenCL with Canvas/Swing, you need to use OpenCL in the rendering loop "simpleUpdate" and check + * for "context.getOpenCLContext()!=null". + */ + @Override + protected void createContext(AppSettings settings) { + // In case canvas is not visible, we still take framerate + // from settings to prevent "100% CPU usage" + frameRate = settings.getFrameRate(); + allowSwapBuffers = settings.isSwapBuffers(); + + try { + if (renderable.get()) { + if (!runningFirstTime) { + // because the display is a different opengl context + // must reset the context state. + if (!USE_SHARED_CONTEXT) { + renderer.cleanup(); + } + } + + // if the pbuffer is currently active, + // make sure to deactivate it + destroyPbuffer(); + + if (Keyboard.isCreated()) { + Keyboard.destroy(); + } + + try { + Thread.sleep(1000); + } catch (InterruptedException ex) {} + + Display.setVSyncEnabled(settings.isVSync()); + Display.setParent(canvas); + + if (USE_SHARED_CONTEXT) { + Display.create(acquirePixelFormat(false), pbuffer); + } else { + Display.create(acquirePixelFormat(false)); + } + if (settings.isOpenCLSupport()) { + initOpenCL(); + } + + renderer.invalidateState(); + } else { + // First create the pbuffer, if it is needed. + makePbufferAvailable(); + } + + // At this point, the OpenGL context is active. + if (runningFirstTime) { + // THIS is the part that creates the renderer. + // It must always be called, now that we have the pbuffer workaround. + initContextFirstTime(); + runningFirstTime = false; + } + } catch (LWJGLException ex) { + listener.handleError("Failed to initialize OpenGL context", ex); + // TODO: Fix deadlock that happens after the error (throw runtime exception?) + } + } + + @Override + public Displays getDisplays() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryDisplay() { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 51b342d257..bec632f993 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -1,299 +1,325 @@ -/* - * Copyright (c) 2009-2023 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. - */ - -package com.jme3.system.lwjgl; - -import com.jme3.system.AppSettings; -import com.jme3.system.Displays; -import com.jme3.system.JmeContext.Type; - -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.lwjgl.LWJGLException; -import org.lwjgl.opengl.*; - -public class LwjglDisplay extends LwjglAbstractDisplay { - - private static final Logger logger = Logger.getLogger(LwjglDisplay.class.getName()); - - private final AtomicBoolean needRestart = new AtomicBoolean(false); - private PixelFormat pixelFormat; - - /** - * @param width The required display width - * @param height The required display height - * @param bpp The required bits per pixel. If -1 is passed it will return - * whatever bpp is found - * @param freq The required frequency, if -1 is passed it will return - * whatever frequency is found - * @return The {@link DisplayMode} matches with specified settings or - * return null if no matching display mode is found - */ - protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, int freq){ - try { - DisplayMode[] modes = Display.getAvailableDisplayModes(); - for (DisplayMode mode : modes) { - if (mode.getWidth() == width - && mode.getHeight() == height - && (mode.getBitsPerPixel() == bpp || (bpp == 24 && mode.getBitsPerPixel() == 32) || bpp == -1) - // Looks like AWT uses mathematical round to convert floating point - // frequency values to int while lwjgl 2 uses mathematical floor. - // For example if frequency is 59.83, AWT will return 60 but lwjgl2 - // will return 59. This is what I observed on Linux. - Ali-RS 2023-1-10 - && (Math.abs(mode.getFrequency() - freq) <= 1 || freq == -1)) { - return mode; - } - } - } catch (LWJGLException ex) { - listener.handleError("Failed to acquire fullscreen display mode!", ex); - } - return null; - } - - @Override - protected void createContext(AppSettings settings) throws LWJGLException{ - DisplayMode displayMode; - if (settings.getWidth() <= 0 || settings.getHeight() <= 0) { - displayMode = Display.getDesktopDisplayMode(); - settings.setResolution(displayMode.getWidth(), displayMode.getHeight()); - } else if (settings.isFullscreen()) { - displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), - settings.getBitsPerPixel(), settings.getFrequency()); - if (displayMode == null) { - // Fall back to whatever mode is available at the specified width & height - displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), -1, -1); - if (displayMode == null) { - throw new RuntimeException("Unable to find fullscreen display mode matching settings"); - } else { - logger.log(Level.WARNING, "Unable to find fullscreen display mode matching settings, falling back to: {0}", displayMode); - } - } - } else { - displayMode = new DisplayMode(settings.getWidth(), settings.getHeight()); - } - - int samples = getNumSamplesToUse(); - PixelFormat pf = new PixelFormat(settings.getBitsPerPixel(), - settings.getAlphaBits(), - settings.getDepthBits(), - settings.getStencilBits(), - samples, - 0, - 0, - 0, - settings.useStereo3D()); - - frameRate = settings.getFrameRate(); - allowSwapBuffers = settings.isSwapBuffers(); - logger.log(Level.FINE, "Selected display mode: {0}", displayMode); - - boolean pixelFormatChanged = false; - if (created.get() && (pixelFormat.getBitsPerPixel() != pf.getBitsPerPixel() - ||pixelFormat.getAlphaBits() != pf.getAlphaBits() - ||pixelFormat.getDepthBits() != pf.getDepthBits() - ||pixelFormat.getStencilBits() != pf.getStencilBits() - ||pixelFormat.getSamples() != pf.getSamples())){ - renderer.resetGLObjects(); - Display.destroy(); - pixelFormatChanged = true; - } - pixelFormat = pf; - - Display.setTitle(settings.getTitle()); - Display.setResizable(settings.isResizable()); - - if (settings.isFullscreen()) { - Display.setDisplayModeAndFullscreen(displayMode); - } else { - Display.setFullscreen(false); - Display.setDisplayMode(displayMode); - } - - if (settings.getIcons() != null) { - Display.setIcon(imagesToByteBuffers(settings.getIcons())); - } - - Display.setVSyncEnabled(settings.isVSync()); - - if (created.get() && !pixelFormatChanged) { - renderer.resetGLObjects(); - Display.releaseContext(); - Display.makeCurrent(); - Display.update(); - } - - if (!created.get() || pixelFormatChanged){ - ContextAttribs attr = createContextAttribs(); - if (attr != null) { - Display.create(pixelFormat, attr); - } else { - Display.create(pixelFormat); - } - renderable.set(true); - - if (pixelFormatChanged && pixelFormat.getSamples() > 1 - && GLContext.getCapabilities().GL_ARB_multisample){ - GL11.glEnable(ARBMultisample.GL_MULTISAMPLE_ARB); - } - } - - if (settings.isOpenCLSupport()) { - initOpenCL(); - } - } - - @Override - protected void destroyContext(){ - try { - renderer.cleanup(); - Display.releaseContext(); - Display.destroy(); - } catch (LWJGLException ex) { - listener.handleError("Failed to destroy context", ex); - } - } - - @Override - public void create(boolean waitFor){ - if (created.get()){ - logger.warning("create() called when display is already created!"); - return; - } - - new Thread(this, THREAD_NAME).start(); - if (waitFor) - waitFor(true); - } - - @Override - public void runLoop(){ - // This method is overridden to do restart - if (needRestart.getAndSet(false)) { - try { - createContext(settings); - } catch (LWJGLException ex) { - logger.log(Level.SEVERE, "Failed to set display settings!", ex); - } - listener.reshape(settings.getWidth(), settings.getHeight()); - if (renderable.get()) { - reinitContext(); - } else { - assert getType() == Type.Canvas; - } - logger.fine("Display restarted."); - } else if (Display.wasResized()) { - int newWidth = Display.getWidth(); - int newHeight = Display.getHeight(); - settings.setResolution(newWidth, newHeight); - listener.reshape(newWidth, newHeight); - } - - super.runLoop(); - } - - @Override - public void restart() { - if (created.get()){ - needRestart.set(true); - }else{ - logger.warning("Display is not created, cannot restart window."); - } - } - - @Override - public Type getType() { - return Type.Display; - } - - @Override - public void setTitle(String title){ - if (created.get()) - Display.setTitle(title); - } - - private ByteBuffer[] imagesToByteBuffers(Object[] images) { - ByteBuffer[] out = new ByteBuffer[images.length]; - for (int i = 0; i < images.length; i++) { - BufferedImage image = (BufferedImage) images[i]; - out[i] = imageToByteBuffer(image); - } - return out; - } - - private ByteBuffer imageToByteBuffer(BufferedImage image) { - if (image.getType() != BufferedImage.TYPE_INT_ARGB_PRE) { - BufferedImage convertedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); - Graphics2D g = convertedImage.createGraphics(); - double width = image.getWidth() * (double) 1; - double height = image.getHeight() * (double) 1; - g.drawImage(image, (int) ((convertedImage.getWidth() - width) / 2), - (int) ((convertedImage.getHeight() - height) / 2), - (int) (width), (int) (height), null); - g.dispose(); - image = convertedImage; - } - - byte[] imageBuffer = new byte[image.getWidth() * image.getHeight() * 4]; - int counter = 0; - for (int i = 0; i < image.getHeight(); i++) { - for (int j = 0; j < image.getWidth(); j++) { - int colorSpace = image.getRGB(j, i); - imageBuffer[counter + 0] = (byte) ((colorSpace << 8) >> 24); - imageBuffer[counter + 1] = (byte) ((colorSpace << 16) >> 24); - imageBuffer[counter + 2] = (byte) ((colorSpace << 24) >> 24); - imageBuffer[counter + 3] = (byte) (colorSpace >> 24); - counter += 4; - } - } - return ByteBuffer.wrap(imageBuffer); - } - - @Override - public Displays getDisplays() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; - } - -} +/* + * Copyright (c) 2009-2023 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. + */ + +package com.jme3.system.lwjgl; + +import com.jme3.system.AppSettings; +import com.jme3.system.Displays; +import com.jme3.system.JmeContext.Type; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.lwjgl.LWJGLException; +import org.lwjgl.opengl.*; + +public class LwjglDisplay extends LwjglAbstractDisplay { + + private static final Logger logger = Logger.getLogger(LwjglDisplay.class.getName()); + + private final AtomicBoolean needRestart = new AtomicBoolean(false); + private PixelFormat pixelFormat; + + /** + * @param width The required display width + * @param height The required display height + * @param bpp The required bits per pixel. If -1 is passed it will return + * whatever bpp is found + * @param freq The required frequency, if -1 is passed it will return + * whatever frequency is found + * @return The {@link DisplayMode} matches with specified settings or + * return null if no matching display mode is found + */ + protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, int freq) { + try { + DisplayMode[] modes = Display.getAvailableDisplayModes(); + for (DisplayMode mode : modes) { + if ( + mode.getWidth() == width && + mode.getHeight() == height && + (mode.getBitsPerPixel() == bpp || + (bpp == 24 && mode.getBitsPerPixel() == 32) || + bpp == -1) && + // Looks like AWT uses mathematical round to convert floating point + // frequency values to int while lwjgl 2 uses mathematical floor. + // For example if frequency is 59.83, AWT will return 60 but lwjgl2 + // will return 59. This is what I observed on Linux. - Ali-RS 2023-1-10 + (Math.abs(mode.getFrequency() - freq) <= 1 || freq == -1) + ) { + return mode; + } + } + } catch (LWJGLException ex) { + listener.handleError("Failed to acquire fullscreen display mode!", ex); + } + return null; + } + + @Override + protected void createContext(AppSettings settings) throws LWJGLException { + DisplayMode displayMode; + if (settings.getWidth() <= 0 || settings.getHeight() <= 0) { + displayMode = Display.getDesktopDisplayMode(); + settings.setResolution(displayMode.getWidth(), displayMode.getHeight()); + } else if (settings.isFullscreen()) { + displayMode = + getFullscreenDisplayMode( + settings.getWidth(), + settings.getHeight(), + settings.getBitsPerPixel(), + settings.getFrequency() + ); + if (displayMode == null) { + // Fall back to whatever mode is available at the specified width & height + displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), -1, -1); + if (displayMode == null) { + throw new RuntimeException("Unable to find fullscreen display mode matching settings"); + } else { + logger.log( + Level.WARNING, + "Unable to find fullscreen display mode matching settings, falling back to: {0}", + displayMode + ); + } + } + } else { + displayMode = new DisplayMode(settings.getWidth(), settings.getHeight()); + } + + int samples = getNumSamplesToUse(); + PixelFormat pf = new PixelFormat( + settings.getBitsPerPixel(), + settings.getAlphaBits(), + settings.getDepthBits(), + settings.getStencilBits(), + samples, + 0, + 0, + 0, + settings.useStereo3D() + ); + + frameRate = settings.getFrameRate(); + allowSwapBuffers = settings.isSwapBuffers(); + logger.log(Level.FINE, "Selected display mode: {0}", displayMode); + + boolean pixelFormatChanged = false; + if ( + created.get() && + (pixelFormat.getBitsPerPixel() != pf.getBitsPerPixel() || + pixelFormat.getAlphaBits() != pf.getAlphaBits() || + pixelFormat.getDepthBits() != pf.getDepthBits() || + pixelFormat.getStencilBits() != pf.getStencilBits() || + pixelFormat.getSamples() != pf.getSamples()) + ) { + renderer.resetGLObjects(); + Display.destroy(); + pixelFormatChanged = true; + } + pixelFormat = pf; + + Display.setTitle(settings.getTitle()); + Display.setResizable(settings.isResizable()); + + if (settings.isFullscreen()) { + Display.setDisplayModeAndFullscreen(displayMode); + } else { + Display.setFullscreen(false); + Display.setDisplayMode(displayMode); + } + + if (settings.getIcons() != null) { + Display.setIcon(imagesToByteBuffers(settings.getIcons())); + } + + Display.setVSyncEnabled(settings.isVSync()); + + if (created.get() && !pixelFormatChanged) { + renderer.resetGLObjects(); + Display.releaseContext(); + Display.makeCurrent(); + Display.update(); + } + + if (!created.get() || pixelFormatChanged) { + ContextAttribs attr = createContextAttribs(); + if (attr != null) { + Display.create(pixelFormat, attr); + } else { + Display.create(pixelFormat); + } + renderable.set(true); + + if ( + pixelFormatChanged && + pixelFormat.getSamples() > 1 && + GLContext.getCapabilities().GL_ARB_multisample + ) { + GL11.glEnable(ARBMultisample.GL_MULTISAMPLE_ARB); + } + } + + if (settings.isOpenCLSupport()) { + initOpenCL(); + } + } + + @Override + protected void destroyContext() { + try { + renderer.cleanup(); + Display.releaseContext(); + Display.destroy(); + } catch (LWJGLException ex) { + listener.handleError("Failed to destroy context", ex); + } + } + + @Override + public void create(boolean waitFor) { + if (created.get()) { + logger.warning("create() called when display is already created!"); + return; + } + + new Thread(this, THREAD_NAME).start(); + if (waitFor) waitFor(true); + } + + @Override + public void runLoop() { + // This method is overridden to do restart + if (needRestart.getAndSet(false)) { + try { + createContext(settings); + } catch (LWJGLException ex) { + logger.log(Level.SEVERE, "Failed to set display settings!", ex); + } + listener.reshape(settings.getWidth(), settings.getHeight()); + if (renderable.get()) { + reinitContext(); + } else { + assert getType() == Type.Canvas; + } + logger.fine("Display restarted."); + } else if (Display.wasResized()) { + int newWidth = Display.getWidth(); + int newHeight = Display.getHeight(); + settings.setResolution(newWidth, newHeight); + listener.reshape(newWidth, newHeight); + } + + super.runLoop(); + } + + @Override + public void restart() { + if (created.get()) { + needRestart.set(true); + } else { + logger.warning("Display is not created, cannot restart window."); + } + } + + @Override + public Type getType() { + return Type.Display; + } + + @Override + public void setTitle(String title) { + if (created.get()) Display.setTitle(title); + } + + private ByteBuffer[] imagesToByteBuffers(Object[] images) { + ByteBuffer[] out = new ByteBuffer[images.length]; + for (int i = 0; i < images.length; i++) { + BufferedImage image = (BufferedImage) images[i]; + out[i] = imageToByteBuffer(image); + } + return out; + } + + private ByteBuffer imageToByteBuffer(BufferedImage image) { + if (image.getType() != BufferedImage.TYPE_INT_ARGB_PRE) { + BufferedImage convertedImage = new BufferedImage( + image.getWidth(), + image.getHeight(), + BufferedImage.TYPE_INT_ARGB_PRE + ); + Graphics2D g = convertedImage.createGraphics(); + double width = image.getWidth() * (double) 1; + double height = image.getHeight() * (double) 1; + g.drawImage( + image, + (int) ((convertedImage.getWidth() - width) / 2), + (int) ((convertedImage.getHeight() - height) / 2), + (int) (width), + (int) (height), + null + ); + g.dispose(); + image = convertedImage; + } + + byte[] imageBuffer = new byte[image.getWidth() * image.getHeight() * 4]; + int counter = 0; + for (int i = 0; i < image.getHeight(); i++) { + for (int j = 0; j < image.getWidth(); j++) { + int colorSpace = image.getRGB(j, i); + imageBuffer[counter + 0] = (byte) ((colorSpace << 8) >> 24); + imageBuffer[counter + 1] = (byte) ((colorSpace << 16) >> 24); + imageBuffer[counter + 2] = (byte) ((colorSpace << 24) >> 24); + imageBuffer[counter + 3] = (byte) (colorSpace >> 24); + counter += 4; + } + } + return ByteBuffer.wrap(imageBuffer); + } + + @Override + public Displays getDisplays() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryDisplay() { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 727890a981..fc5c21c6ec 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -1,235 +1,233 @@ -/* - * Copyright (c) 2009-2020 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. - */ - -package com.jme3.system.lwjgl; - -import com.jme3.input.JoyInput; -import com.jme3.input.KeyInput; -import com.jme3.input.MouseInput; -import com.jme3.input.TouchInput; -import com.jme3.input.dummy.DummyKeyInput; -import com.jme3.input.dummy.DummyMouseInput; -import com.jme3.system.Displays; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.lwjgl.LWJGLException; -import org.lwjgl.Sys; -import org.lwjgl.opengl.*; - -public class LwjglOffscreenBuffer extends LwjglContext implements Runnable { - - private static final Logger logger = Logger.getLogger(LwjglOffscreenBuffer.class.getName()); - private Pbuffer pbuffer; - protected AtomicBoolean needClose = new AtomicBoolean(false); - private int width; - private int height; - private PixelFormat pixelFormat; - - protected void initInThread(){ - if ((Pbuffer.getCapabilities() & Pbuffer.PBUFFER_SUPPORTED) == 0){ - logger.severe("Offscreen surfaces are not supported."); - return; - } - - int samples = getNumSamplesToUse(); - pixelFormat = new PixelFormat(settings.getBitsPerPixel(), - settings.getAlphaBits(), - settings.getDepthBits(), - settings.getStencilBits(), - samples); - - width = settings.getWidth(); - height = settings.getHeight(); - try{ - Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread thread, Throwable thrown) { - listener.handleError("Uncaught exception thrown in "+thread.toString(), thrown); - } - }); - - pbuffer = new Pbuffer(width, height, pixelFormat, null, null, createContextAttribs()); - pbuffer.makeCurrent(); - - renderable.set(true); - - logger.fine("Offscreen buffer created."); - printContextInitInfo(); - } catch (LWJGLException ex){ - listener.handleError("Failed to create display", ex); - } finally { - // TODO: It is possible to avoid "Failed to find pixel format" - // error here by creating a default display. - } - super.internalCreate(); - listener.initialize(); - } - - protected boolean checkGLError(){ - try { - Util.checkGLError(); - } catch (OpenGLException ex){ - listener.handleError("An OpenGL error has occurred!", ex); - } - // NOTE: Always return true since this is used in an "assert" statement - return true; - } - - protected void runLoop(){ - if (!created.get()) { - throw new IllegalStateException(); - } - - if (pbuffer.isBufferLost()) { - pbuffer.destroy(); - - try { - pbuffer = new Pbuffer(width, height, pixelFormat, null); - pbuffer.makeCurrent(); - - // Context MUST be reset here to avoid invalid objects! - renderer.invalidateState(); - } catch (LWJGLException ex) { - listener.handleError("Failed to restore PBuffer content", ex); - } - } - - listener.update(); - assert checkGLError(); - - renderer.postFrame(); - - // Need to flush GL commands - // to see any result on the pbuffer's front buffer. - GL11.glFlush(); - - int frameRate = settings.getFrameRate(); - if (frameRate >= 1) { - Display.sync(frameRate); - } - } - - protected void deinitInThread(){ - renderable.set(false); - - listener.destroy(); - renderer.cleanup(); - pbuffer.destroy(); - logger.fine("Offscreen buffer destroyed."); - - super.internalDestroy(); - } - - @Override - public void run(){ - loadNatives(); - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "Using LWJGL {0}", Sys.getVersion()); - } - initInThread(); - while (!needClose.get()){ - runLoop(); - } - deinitInThread(); - } - - @Override - public void destroy(boolean waitFor){ - needClose.set(true); - if (waitFor) - waitFor(false); - } - - @Override - public void create(boolean waitFor){ - if (created.get()){ - logger.warning("create() called when pbuffer is already created!"); - return; - } - - new Thread(this, THREAD_NAME).start(); - if (waitFor) - waitFor(true); - } - - @Override - public void restart() { - } - - @Override - public void setAutoFlushFrames(boolean enabled){ - } - - @Override - public Type getType() { - return Type.OffscreenSurface; - } - - @Override - public MouseInput getMouseInput() { - return new DummyMouseInput(); - } - - @Override - public KeyInput getKeyInput() { - return new DummyKeyInput(); - } - - @Override - public JoyInput getJoyInput() { - return null; - } - - @Override - public TouchInput getTouchInput() { - return null; - } - - @Override - public void setTitle(String title) { - } - - @Override - public Displays getDisplays() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; - } - -} +/* + * Copyright (c) 2009-2020 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. + */ + +package com.jme3.system.lwjgl; + +import com.jme3.input.JoyInput; +import com.jme3.input.KeyInput; +import com.jme3.input.MouseInput; +import com.jme3.input.TouchInput; +import com.jme3.input.dummy.DummyKeyInput; +import com.jme3.input.dummy.DummyMouseInput; +import com.jme3.system.Displays; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; +import org.lwjgl.opengl.*; + +public class LwjglOffscreenBuffer extends LwjglContext implements Runnable { + + private static final Logger logger = Logger.getLogger(LwjglOffscreenBuffer.class.getName()); + private Pbuffer pbuffer; + protected AtomicBoolean needClose = new AtomicBoolean(false); + private int width; + private int height; + private PixelFormat pixelFormat; + + protected void initInThread() { + if ((Pbuffer.getCapabilities() & Pbuffer.PBUFFER_SUPPORTED) == 0) { + logger.severe("Offscreen surfaces are not supported."); + return; + } + + int samples = getNumSamplesToUse(); + pixelFormat = + new PixelFormat( + settings.getBitsPerPixel(), + settings.getAlphaBits(), + settings.getDepthBits(), + settings.getStencilBits(), + samples + ); + + width = settings.getWidth(); + height = settings.getHeight(); + try { + Thread.setDefaultUncaughtExceptionHandler( + new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable thrown) { + listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown); + } + } + ); + + pbuffer = new Pbuffer(width, height, pixelFormat, null, null, createContextAttribs()); + pbuffer.makeCurrent(); + + renderable.set(true); + + logger.fine("Offscreen buffer created."); + printContextInitInfo(); + } catch (LWJGLException ex) { + listener.handleError("Failed to create display", ex); + } finally { + // TODO: It is possible to avoid "Failed to find pixel format" + // error here by creating a default display. + } + super.internalCreate(); + listener.initialize(); + } + + protected boolean checkGLError() { + try { + Util.checkGLError(); + } catch (OpenGLException ex) { + listener.handleError("An OpenGL error has occurred!", ex); + } + // NOTE: Always return true since this is used in an "assert" statement + return true; + } + + protected void runLoop() { + if (!created.get()) { + throw new IllegalStateException(); + } + + if (pbuffer.isBufferLost()) { + pbuffer.destroy(); + + try { + pbuffer = new Pbuffer(width, height, pixelFormat, null); + pbuffer.makeCurrent(); + + // Context MUST be reset here to avoid invalid objects! + renderer.invalidateState(); + } catch (LWJGLException ex) { + listener.handleError("Failed to restore PBuffer content", ex); + } + } + + listener.update(); + assert checkGLError(); + + renderer.postFrame(); + + // Need to flush GL commands + // to see any result on the pbuffer's front buffer. + GL11.glFlush(); + + int frameRate = settings.getFrameRate(); + if (frameRate >= 1) { + Display.sync(frameRate); + } + } + + protected void deinitInThread() { + renderable.set(false); + + listener.destroy(); + renderer.cleanup(); + pbuffer.destroy(); + logger.fine("Offscreen buffer destroyed."); + + super.internalDestroy(); + } + + @Override + public void run() { + loadNatives(); + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, "Using LWJGL {0}", Sys.getVersion()); + } + initInThread(); + while (!needClose.get()) { + runLoop(); + } + deinitInThread(); + } + + @Override + public void destroy(boolean waitFor) { + needClose.set(true); + if (waitFor) waitFor(false); + } + + @Override + public void create(boolean waitFor) { + if (created.get()) { + logger.warning("create() called when pbuffer is already created!"); + return; + } + + new Thread(this, THREAD_NAME).start(); + if (waitFor) waitFor(true); + } + + @Override + public void restart() {} + + @Override + public void setAutoFlushFrames(boolean enabled) {} + + @Override + public Type getType() { + return Type.OffscreenSurface; + } + + @Override + public MouseInput getMouseInput() { + return new DummyMouseInput(); + } + + @Override + public KeyInput getKeyInput() { + return new DummyKeyInput(); + } + + @Override + public JoyInput getJoyInput() { + return null; + } + + @Override + public TouchInput getTouchInput() { + return null; + } + + @Override + public void setTitle(String title) {} + + @Override + public Displays getDisplays() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryDisplay() { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 35637c16db..a2e8d7221e 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -42,15 +42,15 @@ public LwjglDisplay() { super(Type.Display); } - @Override - public Displays getDisplays() { - // TODO Auto-generated method stub - return null; - } + @Override + public Displays getDisplays() { + // TODO Auto-generated method stub + return null; + } - @Override - public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; - } + @Override + public int getPrimaryDisplay() { + // TODO Auto-generated method stub + return 0; + } } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index 04b07d1923..e9c8aa2411 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -1,5 +1,5 @@ /* -* Copyright (c) 2009-2023 jMonkeyEngine + * Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,10 @@ package com.jme3.system.lwjgl; +import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.opengl.GL11.GL_FALSE; +import static org.lwjgl.system.MemoryUtil.NULL; + import com.jme3.input.JoyInput; import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; @@ -47,17 +51,6 @@ import com.jme3.system.NanoTimer; import com.jme3.util.BufferUtils; import com.jme3.util.SafeArrayList; - -import org.lwjgl.PointerBuffer; -import org.lwjgl.Version; -import org.lwjgl.glfw.GLFWErrorCallback; -import org.lwjgl.glfw.GLFWFramebufferSizeCallback; -import org.lwjgl.glfw.GLFWImage; -import org.lwjgl.glfw.GLFWVidMode; -import org.lwjgl.glfw.GLFWWindowFocusCallback; -import org.lwjgl.glfw.GLFWWindowSizeCallback; -import org.lwjgl.system.Platform; - import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; @@ -69,10 +62,15 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; - -import static org.lwjgl.glfw.GLFW.*; -import static org.lwjgl.opengl.GL11.GL_FALSE; -import static org.lwjgl.system.MemoryUtil.NULL; +import org.lwjgl.PointerBuffer; +import org.lwjgl.Version; +import org.lwjgl.glfw.GLFWErrorCallback; +import org.lwjgl.glfw.GLFWFramebufferSizeCallback; +import org.lwjgl.glfw.GLFWImage; +import org.lwjgl.glfw.GLFWVidMode; +import org.lwjgl.glfw.GLFWWindowFocusCallback; +import org.lwjgl.glfw.GLFWWindowSizeCallback; +import org.lwjgl.system.Platform; /** * A wrapper class over the GLFW framework in LWJGL 3. @@ -84,66 +82,99 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { private static final Logger LOGGER = Logger.getLogger(LwjglWindow.class.getName()); private static final EnumSet SUPPORTED_TYPES = EnumSet.of( - JmeContext.Type.Display, - JmeContext.Type.Canvas, - JmeContext.Type.OffscreenSurface); + JmeContext.Type.Display, + JmeContext.Type.Canvas, + JmeContext.Type.OffscreenSurface + ); private static final Map RENDER_CONFIGS = new HashMap<>(); static { - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL30, () -> { - // Based on GLFW docs for OpenGL version below 3.2, - // GLFW_OPENGL_ANY_PROFILE must be used. - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL31, () -> { - // Based on GLFW docs for OpenGL version below 3.2, - // GLFW_OPENGL_ANY_PROFILE must be used. - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL32, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL33, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL40, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL41, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL42, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL43, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL44, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); - }); - RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL45, () -> { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); - }); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL30, + () -> { + // Based on GLFW docs for OpenGL version below 3.2, + // GLFW_OPENGL_ANY_PROFILE must be used. + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL31, + () -> { + // Based on GLFW docs for OpenGL version below 3.2, + // GLFW_OPENGL_ANY_PROFILE must be used. + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL32, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL33, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL40, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL41, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL42, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL43, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL44, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); + } + ); + RENDER_CONFIGS.put( + AppSettings.LWJGL_OPENGL45, + () -> { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); + } + ); } protected final AtomicBoolean needClose = new AtomicBoolean(false); protected final AtomicBoolean needRestart = new AtomicBoolean(false); private final JmeContext.Type type; - private final SafeArrayList windowSizeListeners = new SafeArrayList<>(WindowSizeListener.class); + private final SafeArrayList windowSizeListeners = new SafeArrayList<>( + WindowSizeListener.class + ); private GLFWErrorCallback errorCallback; private GLFWWindowSizeCallback windowSizeCallback; @@ -170,7 +201,6 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { private final Vector2f oldScale = new Vector2f(1, 1); public LwjglWindow(final JmeContext.Type type) { - if (!SUPPORTED_TYPES.contains(type)) { throw new IllegalArgumentException("Unsupported type '" + type.name() + "' provided"); } @@ -234,13 +264,16 @@ public void restart() { * @param settings the settings to apply when creating the context. */ protected void createContext(final AppSettings settings) { - glfwSetErrorCallback(errorCallback = new GLFWErrorCallback() { - @Override - public void invoke(int error, long description) { - final String message = GLFWErrorCallback.getDescription(description); - listener.handleError(message, new Exception(message)); - } - }); + glfwSetErrorCallback( + errorCallback = + new GLFWErrorCallback() { + @Override + public void invoke(int error, long description) { + final String message = GLFWErrorCallback.getDescription(description); + listener.handleError(message, new Exception(message)); + } + } + ); if (!glfwInit()) { throw new IllegalStateException("Unable to initialize GLFW"); @@ -253,12 +286,18 @@ public void invoke(int error, long description) { glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - RENDER_CONFIGS.computeIfAbsent(renderer, s -> () -> { - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - }).run(); + RENDER_CONFIGS + .computeIfAbsent( + renderer, + s -> + () -> { + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + } + ) + .run(); if (settings.getBoolean("RendererDebug")) { glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); @@ -274,8 +313,14 @@ public void invoke(int error, long description) { glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits()); glfwWindowHint(GLFW_SAMPLES, settings.getSamples()); glfwWindowHint(GLFW_STEREO, settings.useStereo3D() ? GLFW_TRUE : GLFW_FALSE); - glfwWindowHint(GLFW_REFRESH_RATE, settings.getFrequency()<=0?GLFW_DONT_CARE:settings.getFrequency()); - glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, settings.isUseRetinaFrameBuffer() ? GLFW_TRUE : GLFW_FALSE); + glfwWindowHint( + GLFW_REFRESH_RATE, + settings.getFrequency() <= 0 ? GLFW_DONT_CARE : settings.getFrequency() + ); + glfwWindowHint( + GLFW_COCOA_RETINA_FRAMEBUFFER, + settings.isUseRetinaFrameBuffer() ? GLFW_TRUE : GLFW_FALSE + ); if (settings.getBitsPerPixel() == 24) { glfwWindowHint(GLFW_RED_BITS, 8); @@ -289,65 +334,65 @@ public void invoke(int error, long description) { glfwWindowHint(GLFW_ALPHA_BITS, settings.getAlphaBits()); -// long monitor = NULL; + // long monitor = NULL; /** * Let's grab the display selected, if not found it will return * primaryMonitor. if not full screen just use primary display data. */ if (settings.isFullscreen()) { - monitor = getDisplay(settings.getDisplay()); + monitor = getDisplay(settings.getDisplay()); } else { - monitor = glfwGetPrimaryMonitor(); + monitor = glfwGetPrimaryMonitor(); } final GLFWVidMode videoMode = glfwGetVideoMode(monitor); int requestWidth = settings.getWindowWidth(); int requestHeight = settings.getWindowHeight(); if (requestWidth <= 0 || requestHeight <= 0) { - requestWidth = videoMode.width(); - requestHeight = videoMode.height(); + requestWidth = videoMode.width(); + requestHeight = videoMode.height(); } - + // Lets use the monitor selected from AppSettings if FullScreen is // set. - if (settings.isFullscreen()) - window = glfwCreateWindow(requestWidth, requestHeight, - settings.getTitle(), monitor, NULL); - else - window = glfwCreateWindow(requestWidth, requestHeight, - settings.getTitle(), NULL, NULL); + if (settings.isFullscreen()) window = + glfwCreateWindow(requestWidth, requestHeight, settings.getTitle(), monitor, NULL); else window = + glfwCreateWindow(requestWidth, requestHeight, settings.getTitle(), NULL, NULL); if (window == NULL) { throw new RuntimeException("Failed to create the GLFW window"); } - glfwSetWindowFocusCallback(window, windowFocusCallback = new GLFWWindowFocusCallback() { - - @Override - public void invoke(final long window, final boolean focus) { - if (wasActive != focus) { - if (!wasActive) { - listener.gainFocus(); - timer.reset(); - } else { - listener.loseFocus(); + glfwSetWindowFocusCallback( + window, + windowFocusCallback = + new GLFWWindowFocusCallback() { + @Override + public void invoke(final long window, final boolean focus) { + if (wasActive != focus) { + if (!wasActive) { + listener.gainFocus(); + timer.reset(); + } else { + listener.loseFocus(); + } + wasActive = !wasActive; + } } - wasActive = !wasActive; } - } - }); + ); if (!settings.isFullscreen()) { if (settings.getCenterWindow()) { // Center the window - glfwSetWindowPos(window, - (videoMode.width() - requestWidth) / 2, - (videoMode.height() - requestHeight) / 2); + glfwSetWindowPos( + window, + (videoMode.width() - requestWidth) / 2, + (videoMode.height() - requestHeight) / 2 + ); } else { - glfwSetWindowPos(window, - settings.getWindowXPosition(), - settings.getWindowYPosition()); + glfwSetWindowPos(window, settings.getWindowXPosition(), settings.getWindowYPosition()); } } @@ -367,24 +412,30 @@ public void invoke(final long window, final boolean focus) { // HACK: the framebuffer seems to be initialized with the wrong size // on some HiDPI platforms until glfwPollEvents is called 2 or 3 times for (int i = 0; i < 4; i++) glfwPollEvents(); - - // Windows resize callback - glfwSetWindowSizeCallback(window, windowSizeCallback = new GLFWWindowSizeCallback() { - @Override - public void invoke(final long window, final int width, final int height) { - updateSizes(); - } - }); + // Windows resize callback + glfwSetWindowSizeCallback( + window, + windowSizeCallback = + new GLFWWindowSizeCallback() { + @Override + public void invoke(final long window, final int width, final int height) { + updateSizes(); + } + } + ); // Add a framebuffer resize callback which delegates to the listener - glfwSetFramebufferSizeCallback(window, framebufferSizeCallback = new GLFWFramebufferSizeCallback() { - - @Override - public void invoke(final long window, final int width, final int height) { - updateSizes(); - } - }); + glfwSetFramebufferSizeCallback( + window, + framebufferSizeCallback = + new GLFWFramebufferSizeCallback() { + @Override + public void invoke(final long window, final int width, final int height) { + updateSizes(); + } + } + ); allowSwapBuffers = settings.isSwapBuffers(); @@ -402,8 +453,7 @@ private void updateSizes() { glfwGetWindowSize(window, width, height); int windowWidth = width[0] < 1 ? 1 : width[0]; int windowHeight = height[0] < 1 ? 1 : height[0]; - if (settings.getWindowWidth() != windowWidth - || settings.getWindowHeight() != windowHeight) { + if (settings.getWindowWidth() != windowWidth || settings.getWindowHeight() != windowHeight) { settings.setWindowSize(windowWidth, windowHeight); for (WindowSizeListener wsListener : windowSizeListeners.getArray()) { wsListener.onWindowSizeChanged(windowWidth, windowHeight); @@ -413,8 +463,7 @@ private void updateSizes() { glfwGetFramebufferSize(window, width, height); int framebufferWidth = width[0]; int framebufferHeight = height[0]; - if (framebufferWidth != oldFramebufferWidth - || framebufferHeight != oldFramebufferHeight) { + if (framebufferWidth != oldFramebufferWidth || framebufferHeight != oldFramebufferHeight) { settings.setResolution(framebufferWidth, framebufferHeight); listener.reshape(framebufferWidth, framebufferHeight); @@ -441,14 +490,12 @@ protected void showWindow() { * @param settings settings for getting the icons */ protected void setWindowIcon(final AppSettings settings) { - final Object[] icons = settings.getIcons(); if (icons == null) return; final GLFWImage[] images = imagesToGLFWImages(icons); try (final GLFWImage.Buffer iconSet = GLFWImage.malloc(images.length)) { - for (int i = images.length - 1; i >= 0; i--) { final GLFWImage image = images[i]; iconSet.put(i, image); @@ -462,7 +509,6 @@ protected void setWindowIcon(final AppSettings settings) { * Convert array of images to array of {@link GLFWImage}. */ private GLFWImage[] imagesToGLFWImages(final Object[] images) { - final GLFWImage[] out = new GLFWImage[images.length]; for (int i = 0; i < images.length; i++) { @@ -477,10 +523,12 @@ private GLFWImage[] imagesToGLFWImages(final Object[] images) { * Convert the {@link BufferedImage} to the {@link GLFWImage}. */ private GLFWImage imageToGLFWImage(BufferedImage image) { - if (image.getType() != BufferedImage.TYPE_INT_ARGB_PRE) { - - final BufferedImage convertedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); + final BufferedImage convertedImage = new BufferedImage( + image.getWidth(), + image.getHeight(), + BufferedImage.TYPE_INT_ARGB_PRE + ); final Graphics2D graphics = convertedImage.createGraphics(); final int targetWidth = image.getWidth(); @@ -522,7 +570,6 @@ protected void destroyContext() { } if (errorCallback != null) { - // We need to specifically set this to null as we might set a new callback before we reinit GLFW glfwSetErrorCallback(null); @@ -549,7 +596,6 @@ protected void destroyContext() { glfwDestroyWindow(window); window = NULL; } - } catch (final Exception ex) { listener.handleError("Failed to destroy context", ex); } @@ -577,7 +623,6 @@ public void create(boolean waitFor) { waitFor(true); } } - } /** @@ -589,14 +634,16 @@ protected boolean initInThread() { try { if (!JmeSystem.isLowPermissions()) { // Enable uncaught exception handler only for current thread - Thread.currentThread().setUncaughtExceptionHandler((thread, thrown) -> { - listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown); - if (needClose.get()) { - // listener.handleError() has requested the - // context to close. Satisfy request. - deinitInThread(); - } - }); + Thread + .currentThread() + .setUncaughtExceptionHandler((thread, thrown) -> { + listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown); + if (needClose.get()) { + // listener.handleError() has requested the + // context to close. Satisfy request. + deinitInThread(); + } + }); } timer = new NanoTimer(); @@ -630,7 +677,6 @@ protected boolean initInThread() { return true; } - /** * execute one iteration of the render loop in the OpenGL thread */ @@ -644,7 +690,6 @@ protected void runLoop() { throw new IllegalStateException(); } - listener.update(); // All this does is call glfwSwapBuffers(). @@ -721,8 +766,9 @@ protected void deinitInThread() { @Override public void run() { if (listener == null) { - throw new IllegalStateException("SystemListener is not set on context!" - + "Must set with JmeContext.setSystemListener()."); + throw new IllegalStateException( + "SystemListener is not set on context!" + "Must set with JmeContext.setSystemListener()." + ); } LOGGER.log(Level.FINE, "Using LWJGL {0}", Version.getVersion()); @@ -733,7 +779,6 @@ public void run() { } while (true) { - runLoop(); if (needClose.get()) { @@ -873,76 +918,80 @@ public int getWindowYPosition() { int result = height[0]; return result; } - + /** * Returns the Primary Monitor position number from the list of monitors * returned by glfwGetPrimaryMonitor(). If primary monitor not found * it will return -1 and report the error. - * + * * @return returns the Primary Monitor Position. */ @Override - public int getPrimaryDisplay() - { - long prim = glfwGetPrimaryMonitor(); - Displays monitors = getDisplays(); - for ( int i = 0; i < monitors.size(); i++ ) { - long monitorI = monitors.get(i).displayID; - if (monitorI == prim) - return i; - } - - LOGGER.log(Level.SEVERE,"Couldn't locate Primary Monitor in the list of Monitors."); - return -1; - } - - + public int getPrimaryDisplay() { + long prim = glfwGetPrimaryMonitor(); + Displays monitors = getDisplays(); + for (int i = 0; i < monitors.size(); i++) { + long monitorI = monitors.get(i).displayID; + if (monitorI == prim) return i; + } + + LOGGER.log(Level.SEVERE, "Couldn't locate Primary Monitor in the list of Monitors."); + return -1; + } + /** * This routines return the display ID by position in an array of display returned * by glfwGetMonitors(). - * + * * @param pos the position of the display in the list of displays returned. * @return return the displayID if found otherwise return Primary display */ private long getDisplay(int pos) { - Displays displays = getDisplays(); - if (pos < displays.size()) - return displays.get(pos).displayID; - - LOGGER.log(Level.SEVERE,"Couldn't locate Display requested in the list of Displays. pos:"+pos+" size: "+ displays.size()); - return glfwGetPrimaryMonitor(); - } - + Displays displays = getDisplays(); + if (pos < displays.size()) return displays.get(pos).displayID; + + LOGGER.log( + Level.SEVERE, + "Couldn't locate Display requested in the list of Displays. pos:" + + pos + + " size: " + + displays.size() + ); + return glfwGetPrimaryMonitor(); + } + /** * This returns an arraylist of all the Display returned by OpenGL get Monitor * call. It will also has some limited information about each display, like: * width, height and refresh rate. - * + * * @return returns an ArrayList of all Display returned by glfwGetMonitors() */ - + @Override - public Displays getDisplays() { - PointerBuffer displays = glfwGetMonitors(); - long primary = glfwGetPrimaryMonitor(); - Displays displayList = new Displays(); - - for ( int i = 0; i < displays.limit(); i++ ) { - long monitorI = displays.get(i); - int monPos = displayList.addNewMonitor(monitorI); - //lets check if this display is the primary display. If use mark it as such. - if (primary == monitorI) - displayList.setPrimaryDisplay(monPos); - - final GLFWVidMode modes = glfwGetVideoMode(monitorI); - String name = glfwGetMonitorName(monitorI); - - int width = modes.width(); - int height = modes.height(); - int rate = modes.refreshRate(); - displayList.setInfo(monPos, name, width, height, rate); - LOGGER.log(Level.INFO, "Display id: "+monitorI+" Resolution: " + width + " x " + height + " @ " + rate); - } - return displayList; + public Displays getDisplays() { + PointerBuffer displays = glfwGetMonitors(); + long primary = glfwGetPrimaryMonitor(); + Displays displayList = new Displays(); + + for (int i = 0; i < displays.limit(); i++) { + long monitorI = displays.get(i); + int monPos = displayList.addNewMonitor(monitorI); + //lets check if this display is the primary display. If use mark it as such. + if (primary == monitorI) displayList.setPrimaryDisplay(monPos); + + final GLFWVidMode modes = glfwGetVideoMode(monitorI); + String name = glfwGetMonitorName(monitorI); + + int width = modes.width(); + int height = modes.height(); + int rate = modes.refreshRate(); + displayList.setInfo(monPos, name, width, height, rate); + LOGGER.log( + Level.INFO, + "Display id: " + monitorI + " Resolution: " + width + " x " + height + " @ " + rate + ); + } + return displayList; } } diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java index 2f557d8ae5..d311219b29 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglDisplayVR.java @@ -1,67 +1,68 @@ -/* - * Copyright (c) 2009-2012 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. - */ -package com.jme3.system.lwjgl; - -import com.jme3.opencl.Context; -import com.jme3.system.Displays; - -/** - * A VR oriented LWJGL display. - * @author Daniel Johansson - * @author reden - phr00t - https://github.com/phr00t - * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org - */ -public class LwjglDisplayVR extends LwjglWindowVR { - /** - * Create a new VR oriented LWJGL display. - */ - public LwjglDisplayVR() { - super(Type.Display); - } - - @Override - public Context getOpenCLContext() { - return null; - } - - @Override - public Displays getDisplays() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; - } -} +/* + * Copyright (c) 2009-2012 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. + */ +package com.jme3.system.lwjgl; + +import com.jme3.opencl.Context; +import com.jme3.system.Displays; + +/** + * A VR oriented LWJGL display. + * @author Daniel Johansson + * @author reden - phr00t - https://github.com/phr00t + * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + */ +public class LwjglDisplayVR extends LwjglWindowVR { + + /** + * Create a new VR oriented LWJGL display. + */ + public LwjglDisplayVR() { + super(Type.Display); + } + + @Override + public Context getOpenCLContext() { + return null; + } + + @Override + public Displays getDisplays() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getPrimaryDisplay() { + // TODO Auto-generated method stub + return 0; + } +} From 7010af60e9dc54d54aeae9fad379835dad2b6f86 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Sun, 24 Sep 2023 09:34:41 -0500 Subject: [PATCH 17/18] When merging into the main branch, I update a file I should not have and broke the lwjgl3. --- .../main/java/com/jme3/system/lwjgl/LwjglDisplay.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 35637c16db..f4a5582f33 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -42,15 +42,5 @@ public LwjglDisplay() { super(Type.Display); } - @Override - public Displays getDisplays() { - // TODO Auto-generated method stub - return null; - } - @Override - public int getPrimaryDisplay() { - // TODO Auto-generated method stub - return 0; - } } From f25ce69053b55ce9fdfa3bd106bce93b172b9db8 Mon Sep 17 00:00:00 2001 From: "KEVIN-DESKTOP\\kevinba" Date: Wed, 1 Nov 2023 07:13:09 -0500 Subject: [PATCH 18/18] forgot to remove old classes that got renamed to Displays --- .../java/com/jme3/system/MonitorInfo.java | 66 ----------- .../main/java/com/jme3/system/Monitors.java | 105 ------------------ 2 files changed, 171 deletions(-) delete mode 100644 jme3-core/src/main/java/com/jme3/system/MonitorInfo.java delete mode 100644 jme3-core/src/main/java/com/jme3/system/Monitors.java diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java deleted file mode 100644 index a7791d37b2..0000000000 --- a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package com.jme3.system; - -/** - * This class holds information about the monitor that was returned by glfwGetMonitors() calls in - * the context class - * - * @author Kevin Bales - */ -public class MonitorInfo { - - /** - * monitorID - monitor id that was return from Lwjgl3. - */ - public long monitorID = 0; - - /** - * width - width that was return from Lwjgl3. - */ - public int width = 1080; - - /** - * height - height that was return from Lwjgl3. - */ - public int height = 1920; - - /** - * rate - refresh rate that was return from Lwjgl3. - */ - public int rate = 60; - - /** - * primary - indicates if the monitor is the primary monitor. - */ - public boolean primary = false; - - /** - * name - monitor name that was return from Lwjgl3. - */ - public String name = "Generic Monitor"; - -} diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java deleted file mode 100644 index b834e518f8..0000000000 --- a/jme3-core/src/main/java/com/jme3/system/Monitors.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2009-2023 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. - */ -package com.jme3.system; - -import java.util.ArrayList; - -/** - * This class holds all information about all monitors that where return from the glfwGetMonitors() - * call. It stores them into an - * - * @author Kevin Bales - */ -public class Monitors { - - private ArrayList monitors = new ArrayList(); - - public int addNewMonitor(long monitorID) { - MonitorInfo info = new MonitorInfo(); - info.monitorID = monitorID; - monitors.add(info); - return monitors.size() - 1; - } - - /** - * This function returns the size of the monitor ArrayList - * - * @return the - */ - public int size() { - return monitors.size(); - } - - /** - * Call to get monitor information on a certain monitor. - * - * @param pos the position in the arraylist of the monitor information that you want to get. - * @return returns the MonitorInfo data for the monitor called for. - */ - public MonitorInfo get(int pos) { - if (pos < monitors.size()) - return monitors.get(pos); - - return null; - } - - /** - * Set information about this monitor stored in monPos position in the array list. - * - * @param monPos arraylist position of monitor to update - * @param width the current width the monitor is displaying - * @param height the current height the monitor is displaying - * @param rate the current refresh rate the monitor is set to - */ - public void setInfo(int monPos, String name, int width, int height, int rate) { - if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); - if (info != null) { - info.width = width; - info.height = height; - info.rate = rate; - info.name = name; - } - } - } - - /** - * This function will mark a certain monitor as the primary monitor. - * - * @param monPos the position in the arraylist of which monitor is the primary monitor - */ - public void setPrimaryMonitor(int monPos) { - if (monPos < monitors.size()) { - MonitorInfo info = monitors.get(monPos); - if (info != null) - info.primary = true; - } - - } - - - -}